|
@@ -5,11 +5,13 @@ import androidx.datastore.core.DataStore
|
|
|
import androidx.datastore.preferences.core.Preferences
|
|
import androidx.datastore.preferences.core.Preferences
|
|
|
import androidx.datastore.preferences.core.booleanPreferencesKey
|
|
import androidx.datastore.preferences.core.booleanPreferencesKey
|
|
|
import androidx.datastore.preferences.core.edit
|
|
import androidx.datastore.preferences.core.edit
|
|
|
|
|
+import androidx.datastore.preferences.core.stringPreferencesKey
|
|
|
import androidx.datastore.preferences.preferencesDataStore
|
|
import androidx.datastore.preferences.preferencesDataStore
|
|
|
import androidx.fragment.app.Fragment
|
|
import androidx.fragment.app.Fragment
|
|
|
import im.angry.openeuicc.OpenEuiccApplication
|
|
import im.angry.openeuicc.OpenEuiccApplication
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
import kotlinx.coroutines.flow.map
|
|
import kotlinx.coroutines.flow.map
|
|
|
|
|
+import java.util.Base64
|
|
|
|
|
|
|
|
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "prefs")
|
|
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "prefs")
|
|
|
|
|
|
|
@@ -35,6 +37,20 @@ internal object PreferenceKeys {
|
|
|
val UNFILTERED_PROFILE_LIST = booleanPreferencesKey("unfiltered_profile_list")
|
|
val UNFILTERED_PROFILE_LIST = booleanPreferencesKey("unfiltered_profile_list")
|
|
|
val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate")
|
|
val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate")
|
|
|
val EUICC_MEMORY_RESET = booleanPreferencesKey("euicc_memory_reset")
|
|
val EUICC_MEMORY_RESET = booleanPreferencesKey("euicc_memory_reset")
|
|
|
|
|
+ val ISDR_AID_LIST = stringPreferencesKey("isdr_aid_list")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const val EUICC_DEFAULT_ISDR_AID = "A0000005591010FFFFFFFF8900000100"
|
|
|
|
|
+
|
|
|
|
|
+internal object PreferenceConstants {
|
|
|
|
|
+ val DEFAULT_AID_LIST = """
|
|
|
|
|
+ # One AID per line. Comment lines start with #.
|
|
|
|
|
+ # eUICC standard
|
|
|
|
|
+ $EUICC_DEFAULT_ISDR_AID
|
|
|
|
|
+
|
|
|
|
|
+ # 5ber
|
|
|
|
|
+ A0000005591010FFFFFFFF8900050500
|
|
|
|
|
+ """.trimIndent()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
open class PreferenceRepository(private val context: Context) {
|
|
open class PreferenceRepository(private val context: Context) {
|
|
@@ -54,20 +70,46 @@ open class PreferenceRepository(private val context: Context) {
|
|
|
val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false)
|
|
val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false)
|
|
|
val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false)
|
|
val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false)
|
|
|
val euiccMemoryResetFlow = bindFlow(PreferenceKeys.EUICC_MEMORY_RESET, false)
|
|
val euiccMemoryResetFlow = bindFlow(PreferenceKeys.EUICC_MEMORY_RESET, false)
|
|
|
|
|
+ val isdrAidListFlow = bindFlow(
|
|
|
|
|
+ PreferenceKeys.ISDR_AID_LIST,
|
|
|
|
|
+ PreferenceConstants.DEFAULT_AID_LIST,
|
|
|
|
|
+ { Base64.getEncoder().encodeToString(it.encodeToByteArray()) },
|
|
|
|
|
+ { Base64.getDecoder().decode(it).decodeToString() })
|
|
|
|
|
|
|
|
- protected fun <T> bindFlow(key: Preferences.Key<T>, defaultValue: T): PreferenceFlowWrapper<T> =
|
|
|
|
|
- PreferenceFlowWrapper(context, key, defaultValue)
|
|
|
|
|
|
|
+ protected fun <T> bindFlow(
|
|
|
|
|
+ key: Preferences.Key<T>,
|
|
|
|
|
+ defaultValue: T,
|
|
|
|
|
+ encoder: (T) -> T = { it },
|
|
|
|
|
+ decoder: (T) -> T = { it }
|
|
|
|
|
+ ): PreferenceFlowWrapper<T> =
|
|
|
|
|
+ PreferenceFlowWrapper(context, key, defaultValue, encoder, decoder)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
class PreferenceFlowWrapper<T> private constructor(
|
|
class PreferenceFlowWrapper<T> private constructor(
|
|
|
private val context: Context,
|
|
private val context: Context,
|
|
|
private val key: Preferences.Key<T>,
|
|
private val key: Preferences.Key<T>,
|
|
|
inner: Flow<T>,
|
|
inner: Flow<T>,
|
|
|
|
|
+ private val encoder: (T) -> T,
|
|
|
) : Flow<T> by inner {
|
|
) : Flow<T> by inner {
|
|
|
- internal constructor(context: Context, key: Preferences.Key<T>, defaultValue: T) :
|
|
|
|
|
- this(context, key, context.dataStore.data.map { it[key] ?: defaultValue })
|
|
|
|
|
|
|
+ internal constructor(
|
|
|
|
|
+ context: Context,
|
|
|
|
|
+ key: Preferences.Key<T>,
|
|
|
|
|
+ defaultValue: T,
|
|
|
|
|
+ encoder: (T) -> T,
|
|
|
|
|
+ decoder: (T) -> T
|
|
|
|
|
+ ) :
|
|
|
|
|
+ this(
|
|
|
|
|
+ context,
|
|
|
|
|
+ key,
|
|
|
|
|
+ context.dataStore.data.map { it[key]?.let(decoder) ?: defaultValue },
|
|
|
|
|
+ encoder
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
suspend fun updatePreference(value: T) {
|
|
suspend fun updatePreference(value: T) {
|
|
|
- context.dataStore.edit { it[key] = value }
|
|
|
|
|
|
|
+ context.dataStore.edit { it[key] = encoder(value) }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ suspend fun removePreference() {
|
|
|
|
|
+ context.dataStore.edit { it.remove(key) }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|