From fa56b43a839b242c4ce1010018eb01a03983a76a Mon Sep 17 00:00:00 2001 From: sim Date: Mon, 4 Nov 2024 14:24:50 +0000 Subject: [PATCH] Create stores to manage shared preferences --- .../distributor/nextpush/AppStore.kt | 20 +++++ .../unifiedpush/distributor/nextpush/Store.kt | 24 +++++ .../nextpush/account/AccountFactory.kt | 48 ++-------- .../nextpush/account/AccountStore.kt | 20 +++++ .../nextpush/account/AccountType.kt | 14 +++ .../nextpush/account/DirectAccount.kt | 87 ++++--------------- .../nextpush/account/DirectAccountStore.kt | 38 ++++++++ .../distributor/nextpush/api/Api.kt | 16 ++-- 8 files changed, 150 insertions(+), 117 deletions(-) create mode 100644 app/src/main/java/org/unifiedpush/distributor/nextpush/AppStore.kt create mode 100644 app/src/main/java/org/unifiedpush/distributor/nextpush/Store.kt create mode 100644 app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountStore.kt create mode 100644 app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountType.kt create mode 100644 app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccountStore.kt diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/AppStore.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/AppStore.kt new file mode 100644 index 0000000..425920f --- /dev/null +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/AppStore.kt @@ -0,0 +1,20 @@ +package org.unifiedpush.distributor.nextpush + +import android.content.Context +import org.unifiedpush.distributor.nextpush.account.AccountStore + +class AppStore(context: Context) : Store(context) { + val account = AccountStore(context) + + var deviceId: String? + get() = sharedPreferences + .getString(PREF_DEVICE_ID, null) + set(value) = sharedPreferences + .edit() + .putOrRemove(PREF_DEVICE_ID, value) + .apply() + + companion object { + private const val PREF_DEVICE_ID = "deviceId" + } +} diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/Store.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/Store.kt new file mode 100644 index 0000000..222817a --- /dev/null +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/Store.kt @@ -0,0 +1,24 @@ +package org.unifiedpush.distributor.nextpush + +import android.content.Context +import android.content.SharedPreferences + +open class Store(context: Context) { + val sharedPreferences: SharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + + /** + * Put value in sharedpref or remove if null. + */ + fun SharedPreferences.Editor.putOrRemove(key: String, value: String?): SharedPreferences.Editor { + value?.let { + this.putString(key, value) + } ?: run { + this.remove(key) + } + return this + } + + companion object { + internal const val PREF_NAME = "NextPush" + } +} diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountFactory.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountFactory.kt index 88d95a2..04e5cd4 100644 --- a/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountFactory.kt +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountFactory.kt @@ -2,54 +2,20 @@ package org.unifiedpush.distributor.nextpush.account import android.content.Context import android.util.Log +import org.unifiedpush.distributor.nextpush.AppStore import org.unifiedpush.distributor.nextpush.utils.TAG internal const val PREF_NAME = "NextPush" -private const val PREF_DEVICE_ID = "deviceId" -private const val PREF_ACCOUNT_TYPE = "account::type" - -enum class AccountType { - SSO, - Direct; - fun toInt(): Int { - return this.ordinal - } -} - -private fun Int.toAccountType(): AccountType { - return AccountType.entries.getOrNull(this) ?: AccountType.SSO -} object AccountFactory { private var account: Account? = null - var Context.accountType: AccountType - get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .getInt(PREF_ACCOUNT_TYPE, 0).toAccountType() - private set(value) = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().putInt(PREF_ACCOUNT_TYPE, value.toInt()) - .apply() - - var Context.npDeviceId: String? - get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .getString(PREF_DEVICE_ID, null) - set(value) { - this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit() - .apply { - value?.let { - putString(PREF_DEVICE_ID, it) - } ?: run { - remove(PREF_DEVICE_ID) - } - }.apply() - } - fun getAccount(context: Context, connected: Boolean = true): Account? { return account ?: run { - Log.d(TAG, "New account, type=${context.accountType}") - when (context.accountType) { + val accountType = AccountStore(context).accountType + Log.d(TAG, "New account, type=$accountType") + when (accountType) { AccountType.SSO -> SSOAccount(context) AccountType.Direct -> DirectAccount(context) }.takeIf { !connected || it.connected }.also { @@ -60,18 +26,18 @@ object AccountFactory { fun logout(context: Context) { getAccount(context)?.logout(context) - context.npDeviceId = null + AppStore(context).deviceId = null } fun Context.setTypeSSO() { account = null - accountType = AccountType.SSO + AccountStore(this).accountType = AccountType.SSO DirectAccount.setCredentials(this, null, null, null) } fun Context.setTypeDirect(url: String, username: String, password: String) { account = null - accountType = AccountType.Direct + AccountStore(this).accountType = AccountType.Direct DirectAccount.setCredentials(this, url, username, password) } } diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountStore.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountStore.kt new file mode 100644 index 0000000..02af0e1 --- /dev/null +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountStore.kt @@ -0,0 +1,20 @@ +package org.unifiedpush.distributor.nextpush.account + +import android.content.Context +import org.unifiedpush.distributor.nextpush.Store + +/** + * Manager SharedPreferences for Account related values + */ +open class AccountStore(context: Context) : Store(context) { + var accountType: AccountType + get() = sharedPreferences + .getInt(PREF_ACCOUNT_TYPE, 0).toAccountType() + set(value) = sharedPreferences + .edit().putInt(PREF_ACCOUNT_TYPE, value.toInt()) + .apply() + + companion object { + private const val PREF_ACCOUNT_TYPE = "account::type" + } +} diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountType.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountType.kt new file mode 100644 index 0000000..91abaed --- /dev/null +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/AccountType.kt @@ -0,0 +1,14 @@ +package org.unifiedpush.distributor.nextpush.account + +enum class AccountType { + SSO, + Direct; + + fun toInt(): Int { + return this.ordinal + } +} + +fun Int.toAccountType(): AccountType { + return AccountType.entries.getOrNull(this) ?: AccountType.SSO +} diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccount.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccount.kt index 4152e4b..0a84b13 100644 --- a/app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccount.kt +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccount.kt @@ -11,26 +11,22 @@ import org.unifiedpush.distributor.nextpush.api.provider.ApiProvider.Companion.m import java.io.IOException import java.util.concurrent.TimeUnit -private const val PREF_CONNECTED = "direct_account::connected" -private const val PREF_URL = "direct_account::url" -private const val PREF_USERNAME = "direct_account::username" -private const val PREF_PASSWORD = "direct_account::password" - class DirectAccount(context: Context) : Account { - override val name: String? = context.username - override val url: String? = context.url - override var connected = context.connected - - private fun setConnected(context: Context, value: Boolean) { - connected = value - context.connected = value - } + /** [DirectAccountStore] */ + private val daStore = DirectAccountStore(context) + override val name: String? = daStore.username + override val url: String? = daStore.url + override var connected = daStore.connected + set(value) { + daStore.connected = value + field = value + } override fun connect(activity: Activity) { - setConnected(activity, false) + connected = false val client = getClient(activity) ?: return retActivity(activity) - val url = activity.url ?: return retActivity(activity) + val url = daStore.url ?: return retActivity(activity) val request = try { Request.Builder() @@ -51,7 +47,7 @@ class DirectAccount(context: Context) : Account { override fun onResponse(call: Call, response: Response) { Log.d(TAG, "Status: ${response.code}") - setConnected(activity, response.code == 200) + connected = response.code == 200 response.close() retActivity(activity) } @@ -69,8 +65,8 @@ class DirectAccount(context: Context) : Account { } override fun getClient(context: Context): OkHttpClient? { - val username = context.username ?: return null - val password = context.password ?: return null + val username = daStore.username ?: return null + val password = daStore.password ?: return null return OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .authenticator(DirectAuth(username, password)) @@ -79,7 +75,7 @@ class DirectAccount(context: Context) : Account { } override fun logout(context: Context) { - setConnected(context, false) + connected = false setCredentials(context, null, null, null) } @@ -112,56 +108,11 @@ class DirectAccount(context: Context) : Account { } companion object { - private var Context.url: String? - get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .getString(PREF_URL, null) - set(value) = value?.let { - this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().putString(PREF_URL, it) - .apply() - } ?: run { - this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().remove(PREF_URL) - .apply() - } - - private var Context.username: String? - get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .getString(PREF_USERNAME, null) - set(value) = value?.let { - this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().putString(PREF_USERNAME, it) - .apply() - } ?: run { - this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().remove(PREF_USERNAME) - .apply() - } - - private var Context.password: String? - get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .getString(PREF_PASSWORD, null) - set(value) = value?.let { - this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().putString(PREF_PASSWORD, it) - .apply() - } ?: run { - this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().remove(PREF_PASSWORD) - .apply() - } - - private var Context.connected: Boolean - get() = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .getBoolean(PREF_CONNECTED, false) - set(value) = this.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) - .edit().putBoolean(PREF_CONNECTED, value) - .apply() - fun setCredentials(context: Context, url: String?, username: String?, password: String?) { - context.url = url - context.username = username - context.password = password + val daStore = DirectAccountStore(context) + daStore.url = url + daStore.username = username + daStore.password = password } } } diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccountStore.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccountStore.kt new file mode 100644 index 0000000..4367f7e --- /dev/null +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/account/DirectAccountStore.kt @@ -0,0 +1,38 @@ +package org.unifiedpush.distributor.nextpush.account + +import android.content.Context +import org.unifiedpush.distributor.nextpush.Store + +class DirectAccountStore(context: Context) : Store(context) { + var url: String? + get() = sharedPreferences + .getString(PREF_URL, null) + set(value) = sharedPreferences + .edit().putOrRemove(PREF_URL, value).apply() + + var username: String? + get() = sharedPreferences + .getString(PREF_USERNAME, null) + set(value) = sharedPreferences + .edit().putOrRemove(PREF_USERNAME, value).apply() + + var password: String? + get() = sharedPreferences + .getString(PREF_PASSWORD, null) + set(value) = sharedPreferences + .edit().putOrRemove(PREF_PASSWORD, value).apply() + + var connected: Boolean + get() = sharedPreferences + .getBoolean(PREF_CONNECTED, false) + set(value) = sharedPreferences + .edit().putBoolean(PREF_CONNECTED, value) + .apply() + + companion object { + private const val PREF_CONNECTED = "direct_account::connected" + private const val PREF_URL = "direct_account::url" + private const val PREF_USERNAME = "direct_account::username" + private const val PREF_PASSWORD = "direct_account::password" + } +} diff --git a/app/src/main/java/org/unifiedpush/distributor/nextpush/api/Api.kt b/app/src/main/java/org/unifiedpush/distributor/nextpush/api/Api.kt index 8a388cd..f75aed8 100644 --- a/app/src/main/java/org/unifiedpush/distributor/nextpush/api/Api.kt +++ b/app/src/main/java/org/unifiedpush/distributor/nextpush/api/Api.kt @@ -10,9 +10,8 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.sse.EventSource import okhttp3.sse.EventSources -import org.unifiedpush.distributor.nextpush.account.AccountFactory.accountType +import org.unifiedpush.distributor.nextpush.AppStore import org.unifiedpush.distributor.nextpush.account.AccountFactory.getAccount -import org.unifiedpush.distributor.nextpush.account.AccountFactory.npDeviceId import org.unifiedpush.distributor.nextpush.account.AccountType import org.unifiedpush.distributor.nextpush.api.provider.* // ktlint-disable no-wildcard-imports import org.unifiedpush.distributor.nextpush.api.provider.ApiProvider.Companion.mApiEndpoint @@ -23,21 +22,21 @@ import java.util.concurrent.atomic.AtomicReference class Api(context: Context) { - private val TAG = Api::class.java.simpleName private val context = context.applicationContext + private val store = AppStore(context) private val baseUrl: String get() = getAccount(context)?.url ?: "http://0.0.0.0/" private fun withApiProvider(block: (ApiProvider, then: () -> Unit) -> Unit) { - when (context.accountType) { + when (store.account.accountType) { AccountType.SSO -> ApiSSOFactory(context) AccountType.Direct -> ApiDirectFactory(context) }.getProviderAndExecute(block) } private fun tryWithDeviceId(block: (String) -> Unit) { - context.npDeviceId?.let { + store.deviceId?.let { block(it) } ?: run { @@ -52,7 +51,7 @@ class Api(context: Context) { ?.subscribe(object : DisposableObserver() { override fun onNext(response: ApiResponse) { response.deviceId.let { - context.npDeviceId = it + store.deviceId = it } } @@ -64,7 +63,7 @@ class Api(context: Context) { override fun onComplete() { // Sync once it is registered - context.npDeviceId?.let { + store.deviceId?.let { block(it) } Log.d(TAG, "mApi register: onComplete") @@ -132,7 +131,7 @@ class Api(context: Context) { then() } }) - context.npDeviceId = null + store.deviceId = null } } catch (e: NoProviderException) { e.printStackTrace() @@ -216,6 +215,7 @@ class Api(context: Context) { } companion object { + private const val TAG = "Api" private val syncSource: AtomicReference = AtomicReference(null) } }