From 10709bc2b5a4480b9eb94032b0d9e74d6b61295c Mon Sep 17 00:00:00 2001 From: septs Date: Thu, 27 Feb 2025 14:59:00 +0800 Subject: [PATCH 1/9] feat: disable refresh after switch --- .../openeuicc/service/EuiccChannelManagerService.kt | 8 ++++++-- .../java/im/angry/openeuicc/ui/SettingsFragment.kt | 2 +- .../java/im/angry/openeuicc/util/PreferenceUtils.kt | 12 +++++++++++- app-common/src/main/res/values/strings.xml | 2 ++ app-common/src/main/res/xml/pref_settings.xml | 5 +++++ .../openeuicc/ui/UnprivilegedSettingsFragment.kt | 7 +++++++ .../src/main/res/xml/pref_unprivileged_settings.xml | 10 ++++++++++ 7 files changed, 42 insertions(+), 4 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt index 760f1af..a19e4d7 100644 --- a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt +++ b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt @@ -452,24 +452,28 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker { getString(R.string.task_profile_switch_failure), R.drawable.ic_task_switch ) { + val flow = preferenceRepository.refreshAfterSwitchFlow euiccChannelManager.beginTrackedOperation(slotId, portId) { val (res, refreshed) = euiccChannelManager.withEuiccChannel( slotId, portId ) { channel -> - if (!channel.lpa.switchProfile(iccid, enable, refresh = true)) { + val refresh = preferenceRepository.refreshAfterSwitchFlow.first() + if (!channel.lpa.switchProfile(iccid, enable, refresh = refresh)) { // Sometimes, we *can* enable or disable the profile, but we cannot // send the refresh command to the modem because the profile somehow // makes the modem "busy". In this case, we can still switch by setting // refresh to false, but then the switch cannot take effect until the // user resets the modem manually by toggling airplane mode or rebooting. + flow.updatePreference(false) Pair(channel.lpa.switchProfile(iccid, enable, refresh = false), false) } else { - Pair(true, true) + Pair(true, refresh) } } if (!res) { + preferenceRepository.refreshAfterSwitchFlow.updatePreference(false) throw RuntimeException("Could not switch profile") } diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt index fab680f..c54d6a1 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt @@ -122,7 +122,7 @@ open class SettingsFragment: PreferenceFragmentCompat() { return true } - private fun CheckBoxPreference.bindBooleanFlow(flow: PreferenceFlowWrapper) { + protected fun CheckBoxPreference.bindBooleanFlow(flow: PreferenceFlowWrapper) { lifecycleScope.launch { flow.collect { isChecked = it } } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index f5e3ca2..90782b9 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -5,11 +5,15 @@ import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.preferencesDataStore import androidx.fragment.app.Fragment import im.angry.openeuicc.OpenEuiccApplication import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.map +import kotlinx.coroutines.runBlocking private val Context.dataStore: DataStore by preferencesDataStore(name = "prefs") @@ -26,6 +30,7 @@ internal object PreferenceKeys { val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch") // ---- Advanced ---- + val REFRESH_AFTER_SWITCH = booleanPreferencesKey("refresh_after_switch") val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim") val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging") @@ -43,6 +48,7 @@ class PreferenceRepository(private val context: Context) { val notificationSwitchFlow = bindFlow(PreferenceKeys.NOTIFICATION_SWITCH, false) // ---- Advanced ---- + val refreshAfterSwitchFlow = bindFlow(PreferenceKeys.REFRESH_AFTER_SWITCH, true) val disableSafeguardFlow = bindFlow(PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM, false) val verboseLoggingFlow = bindFlow(PreferenceKeys.VERBOSE_LOGGING, false) @@ -69,4 +75,8 @@ class PreferenceFlowWrapper private constructor( suspend fun updatePreference(value: T) { context.dataStore.edit { it[key] = value } } -} \ No newline at end of file + + internal fun with(flow: Flow) = PreferenceFlowWrapper(context, key, flow) +} + +fun PreferenceFlowWrapper.negative() = with(map { !it }) diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 71e2418..3249d88 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -157,6 +157,8 @@ Switching Send notifications for switching profiles\nNote that this type of notification is unreliable. Advanced + Disable refresh status after switching + Avoid OMAPI crash after switch Allow Disabling / Deleting Active Profile By default, this app prevents you from disabling the active profile on a removable eSIM inserted in the device, because doing so may sometimes render it inaccessible.\nCheck this box to remove this safeguard. Verbose Logging diff --git a/app-common/src/main/res/xml/pref_settings.xml b/app-common/src/main/res/xml/pref_settings.xml index bb5bd50..6073ef7 100644 --- a/app-common/src/main/res/xml/pref_settings.xml +++ b/app-common/src/main/res/xml/pref_settings.xml @@ -23,17 +23,20 @@ @@ -41,12 +44,14 @@ app:iconSpaceReserved="false" app:isPreferenceVisible="false" app:key="pref_advanced_language" + app:order="12" app:summary="@string/pref_advanced_language_desc" app:title="@string/pref_advanced_language" /> diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt index 23589a6..db84113 100644 --- a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt +++ b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt @@ -6,9 +6,12 @@ import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.widget.Toast +import androidx.preference.CheckBoxPreference import androidx.preference.Preference import im.angry.easyeuicc.R import im.angry.openeuicc.util.encodeHex +import im.angry.openeuicc.util.negative +import im.angry.openeuicc.util.preferenceRepository import java.security.MessageDigest class UnprivilegedSettingsFragment : SettingsFragment() { @@ -29,8 +32,12 @@ class UnprivilegedSettingsFragment : SettingsFragment() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { super.onCreatePreferences(savedInstanceState, rootKey) addPreferencesFromResource(R.xml.pref_unprivileged_settings) + mergePreferenceOverlay("pref_advanced_overlay", "pref_advanced") mergePreferenceOverlay("pref_info_overlay", "pref_info") + requirePreference("pref_advanced_disable_refreshed_after_switch") + .bindBooleanFlow(preferenceRepository.refreshAfterSwitchFlow.negative()) + requirePreference("pref_info_ara_m").apply { summary = firstSigner.encodeHex() setOnPreferenceClickListener { diff --git a/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml b/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml index 3281caf..9d0901c 100644 --- a/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml +++ b/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml @@ -1,5 +1,15 @@ + + + From 30761139c02646d494d42cfea71f1ab8ce7b4446 Mon Sep 17 00:00:00 2001 From: septs Date: Thu, 27 Feb 2025 15:09:33 +0800 Subject: [PATCH 2/9] app-common --- .../im/angry/openeuicc/service/EuiccChannelManagerService.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt index a19e4d7..a0d81b3 100644 --- a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt +++ b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt @@ -452,7 +452,6 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker { getString(R.string.task_profile_switch_failure), R.drawable.ic_task_switch ) { - val flow = preferenceRepository.refreshAfterSwitchFlow euiccChannelManager.beginTrackedOperation(slotId, portId) { val (res, refreshed) = euiccChannelManager.withEuiccChannel( slotId, @@ -465,7 +464,6 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker { // makes the modem "busy". In this case, we can still switch by setting // refresh to false, but then the switch cannot take effect until the // user resets the modem manually by toggling airplane mode or rebooting. - flow.updatePreference(false) Pair(channel.lpa.switchProfile(iccid, enable, refresh = false), false) } else { Pair(true, refresh) @@ -473,7 +471,6 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker { } if (!res) { - preferenceRepository.refreshAfterSwitchFlow.updatePreference(false) throw RuntimeException("Could not switch profile") } From e6d7fb1b649ccbc90d524df1dcc754019ad73165 Mon Sep 17 00:00:00 2001 From: septs Date: Thu, 27 Feb 2025 15:11:52 +0800 Subject: [PATCH 3/9] chore: reduce imports --- .../src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index 90782b9..062aab1 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -5,15 +5,11 @@ import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit -import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.preferencesDataStore import androidx.fragment.app.Fragment import im.angry.openeuicc.OpenEuiccApplication import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.map -import kotlinx.coroutines.runBlocking private val Context.dataStore: DataStore by preferencesDataStore(name = "prefs") From 0bd64a0ab61e599111141a7765706ea4b499f3d4 Mon Sep 17 00:00:00 2001 From: septs Date: Thu, 27 Feb 2025 17:09:21 +0800 Subject: [PATCH 4/9] fix: PreferenceFlowWrapper --- .../java/im/angry/openeuicc/util/PreferenceUtils.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index 062aab1..9639044 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -60,7 +60,8 @@ class PreferenceRepository(private val context: Context) { class PreferenceFlowWrapper private constructor( private val context: Context, private val key: Preferences.Key, - inner: Flow + inner: Flow, + private val setter: suspend (T) -> T = { it } ) : Flow by inner { internal constructor(context: Context, key: Preferences.Key, defaultValue: T) : this( context, @@ -69,10 +70,11 @@ class PreferenceFlowWrapper private constructor( ) suspend fun updatePreference(value: T) { - context.dataStore.edit { it[key] = value } + context.dataStore.edit { it[key] = setter(value) } } - internal fun with(flow: Flow) = PreferenceFlowWrapper(context, key, flow) + internal fun with(flow: Flow = this, setter: suspend (T) -> T) = + PreferenceFlowWrapper(context, key, flow, setter) } -fun PreferenceFlowWrapper.negative() = with(map { !it }) +fun PreferenceFlowWrapper.negative() = with(map { !it }, { !it }) From 36afc1df71b1b6b864b0e66547e5a2de3c358c9a Mon Sep 17 00:00:00 2001 From: septs Date: Thu, 27 Feb 2025 17:58:21 +0800 Subject: [PATCH 5/9] fix: PreferenceFlowWrapper --- .../main/java/im/angry/openeuicc/util/PreferenceUtils.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index 9639044..1fe55a3 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -63,11 +63,8 @@ class PreferenceFlowWrapper private constructor( inner: Flow, private val setter: suspend (T) -> T = { it } ) : Flow by inner { - internal constructor(context: Context, key: Preferences.Key, defaultValue: T) : this( - context, - key, - context.dataStore.data.map { it[key] ?: defaultValue } - ) + internal constructor(context: Context, key: Preferences.Key, defaultValue: T) : + this(context, key, context.dataStore.data.map { it[key] ?: defaultValue }) suspend fun updatePreference(value: T) { context.dataStore.edit { it[key] = setter(value) } @@ -77,4 +74,4 @@ class PreferenceFlowWrapper private constructor( PreferenceFlowWrapper(context, key, flow, setter) } -fun PreferenceFlowWrapper.negative() = with(map { !it }, { !it }) +fun PreferenceFlowWrapper.negative() = with(map { !it }) { !it } From e8b5c5c99cd470c4147078ec9644720234e6b0f6 Mon Sep 17 00:00:00 2001 From: septs Date: Wed, 5 Mar 2025 10:16:04 +0800 Subject: [PATCH 6/9] chore: move to developer options --- .../java/im/angry/openeuicc/util/PreferenceUtils.kt | 10 ++-------- app-common/src/main/res/values/strings.xml | 4 ++-- .../angry/openeuicc/ui/UnprivilegedSettingsFragment.kt | 7 +++---- .../src/main/res/xml/pref_unprivileged_settings.xml | 8 ++++---- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index 1fe55a3..b38eb5d 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -44,11 +44,11 @@ class PreferenceRepository(private val context: Context) { val notificationSwitchFlow = bindFlow(PreferenceKeys.NOTIFICATION_SWITCH, false) // ---- Advanced ---- - val refreshAfterSwitchFlow = bindFlow(PreferenceKeys.REFRESH_AFTER_SWITCH, true) val disableSafeguardFlow = bindFlow(PreferenceKeys.DISABLE_SAFEGUARD_REMOVABLE_ESIM, false) val verboseLoggingFlow = bindFlow(PreferenceKeys.VERBOSE_LOGGING, false) // ---- Developer Options ---- + val refreshAfterSwitchFlow = bindFlow(PreferenceKeys.REFRESH_AFTER_SWITCH, true) val developerOptionsEnabledFlow = bindFlow(PreferenceKeys.DEVELOPER_OPTIONS_ENABLED, false) val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false) val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false) @@ -61,17 +61,11 @@ class PreferenceFlowWrapper private constructor( private val context: Context, private val key: Preferences.Key, inner: Flow, - private val setter: suspend (T) -> T = { it } ) : Flow by inner { internal constructor(context: Context, key: Preferences.Key, defaultValue: T) : this(context, key, context.dataStore.data.map { it[key] ?: defaultValue }) suspend fun updatePreference(value: T) { - context.dataStore.edit { it[key] = setter(value) } + context.dataStore.edit { it[key] = value } } - - internal fun with(flow: Flow = this, setter: suspend (T) -> T) = - PreferenceFlowWrapper(context, key, flow, setter) } - -fun PreferenceFlowWrapper.negative() = with(map { !it }) { !it } diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index fd4166c..a0c2d98 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -162,8 +162,8 @@ Switching Send notifications for switching profiles\nNote that this type of notification is unreliable. Advanced - Disable refresh status after switching - Avoid OMAPI crash after switch + Refresh status after switching + If crash after switch, Please trying disable the function Allow Disabling / Deleting Active Profile By default, this app prevents you from disabling the active profile on a removable eSIM inserted in the device, because doing so may sometimes render it inaccessible.\nCheck this box to remove this safeguard. Verbose Logging diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt index db84113..31c9a77 100644 --- a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt +++ b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt @@ -10,7 +10,6 @@ import androidx.preference.CheckBoxPreference import androidx.preference.Preference import im.angry.easyeuicc.R import im.angry.openeuicc.util.encodeHex -import im.angry.openeuicc.util.negative import im.angry.openeuicc.util.preferenceRepository import java.security.MessageDigest @@ -32,11 +31,11 @@ class UnprivilegedSettingsFragment : SettingsFragment() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { super.onCreatePreferences(savedInstanceState, rootKey) addPreferencesFromResource(R.xml.pref_unprivileged_settings) - mergePreferenceOverlay("pref_advanced_overlay", "pref_advanced") + mergePreferenceOverlay("pref_developer_overlay", "pref_developer") mergePreferenceOverlay("pref_info_overlay", "pref_info") - requirePreference("pref_advanced_disable_refreshed_after_switch") - .bindBooleanFlow(preferenceRepository.refreshAfterSwitchFlow.negative()) + requirePreference("pref_developer_refreshed_after_switch") + .bindBooleanFlow(preferenceRepository.refreshAfterSwitchFlow) requirePreference("pref_info_ara_m").apply { summary = firstSigner.encodeHex() diff --git a/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml b/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml index 9d0901c..df5bfee 100644 --- a/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml +++ b/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml @@ -2,13 +2,13 @@ + app:key="pref_developer_overlay"> + app:summary="@string/pref_advanced_refresh_after_switch_desc" + app:title="@string/pref_advanced_refresh_after_switch" /> Date: Wed, 5 Mar 2025 10:42:44 +0800 Subject: [PATCH 7/9] fix: settings order --- app-common/src/main/res/xml/pref_settings.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app-common/src/main/res/xml/pref_settings.xml b/app-common/src/main/res/xml/pref_settings.xml index 6073ef7..3d12e44 100644 --- a/app-common/src/main/res/xml/pref_settings.xml +++ b/app-common/src/main/res/xml/pref_settings.xml @@ -30,13 +30,11 @@ app:key="pref_advanced_disable_safeguard_removable_esim" app:iconSpaceReserved="false" app:title="@string/pref_advanced_disable_safeguard_removable_esim" - app:order="10" app:summary="@string/pref_advanced_disable_safeguard_removable_esim_desc" /> @@ -44,7 +42,6 @@ app:iconSpaceReserved="false" app:isPreferenceVisible="false" app:key="pref_advanced_language" - app:order="12" app:summary="@string/pref_advanced_language_desc" app:title="@string/pref_advanced_language" /> @@ -65,12 +62,14 @@ From 37775cbc4a6cfd95ad83502da08fd8f7917c8b4e Mon Sep 17 00:00:00 2001 From: septs Date: Wed, 5 Mar 2025 10:43:36 +0800 Subject: [PATCH 8/9] fix: settings order --- app-common/src/main/res/xml/pref_settings.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/app-common/src/main/res/xml/pref_settings.xml b/app-common/src/main/res/xml/pref_settings.xml index 3d12e44..9d2f189 100644 --- a/app-common/src/main/res/xml/pref_settings.xml +++ b/app-common/src/main/res/xml/pref_settings.xml @@ -23,7 +23,6 @@ From 71368b6fc56c1afbfafe593637174cc605ded852 Mon Sep 17 00:00:00 2001 From: septs Date: Wed, 5 Mar 2025 10:44:40 +0800 Subject: [PATCH 9/9] feat: refresh after switch in settings --- .../openeuicc/service/EuiccChannelManagerService.kt | 5 +++-- .../java/im/angry/openeuicc/ui/SettingsFragment.kt | 2 +- .../java/im/angry/openeuicc/util/PreferenceUtils.kt | 13 ++++++------- app-common/src/main/res/values/strings.xml | 2 ++ app-common/src/main/res/xml/pref_settings.xml | 2 ++ .../openeuicc/ui/UnprivilegedSettingsFragment.kt | 6 ++++++ .../src/main/res/xml/pref_unprivileged_settings.xml | 10 ++++++++++ 7 files changed, 30 insertions(+), 10 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt index 760f1af..a0d81b3 100644 --- a/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt +++ b/app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt @@ -457,7 +457,8 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker { slotId, portId ) { channel -> - if (!channel.lpa.switchProfile(iccid, enable, refresh = true)) { + val refresh = preferenceRepository.refreshAfterSwitchFlow.first() + if (!channel.lpa.switchProfile(iccid, enable, refresh = refresh)) { // Sometimes, we *can* enable or disable the profile, but we cannot // send the refresh command to the modem because the profile somehow // makes the modem "busy". In this case, we can still switch by setting @@ -465,7 +466,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker { // user resets the modem manually by toggling airplane mode or rebooting. Pair(channel.lpa.switchProfile(iccid, enable, refresh = false), false) } else { - Pair(true, true) + Pair(true, refresh) } } diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt index fab680f..c54d6a1 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/SettingsFragment.kt @@ -122,7 +122,7 @@ open class SettingsFragment: PreferenceFragmentCompat() { return true } - private fun CheckBoxPreference.bindBooleanFlow(flow: PreferenceFlowWrapper) { + protected fun CheckBoxPreference.bindBooleanFlow(flow: PreferenceFlowWrapper) { lifecycleScope.launch { flow.collect { isChecked = it } } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt index f5e3ca2..b38eb5d 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/PreferenceUtils.kt @@ -26,6 +26,7 @@ internal object PreferenceKeys { val NOTIFICATION_SWITCH = booleanPreferencesKey("notification_switch") // ---- Advanced ---- + val REFRESH_AFTER_SWITCH = booleanPreferencesKey("refresh_after_switch") val DISABLE_SAFEGUARD_REMOVABLE_ESIM = booleanPreferencesKey("disable_safeguard_removable_esim") val VERBOSE_LOGGING = booleanPreferencesKey("verbose_logging") @@ -47,6 +48,7 @@ class PreferenceRepository(private val context: Context) { val verboseLoggingFlow = bindFlow(PreferenceKeys.VERBOSE_LOGGING, false) // ---- Developer Options ---- + val refreshAfterSwitchFlow = bindFlow(PreferenceKeys.REFRESH_AFTER_SWITCH, true) val developerOptionsEnabledFlow = bindFlow(PreferenceKeys.DEVELOPER_OPTIONS_ENABLED, false) val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false) val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false) @@ -58,15 +60,12 @@ class PreferenceRepository(private val context: Context) { class PreferenceFlowWrapper private constructor( private val context: Context, private val key: Preferences.Key, - inner: Flow + inner: Flow, ) : Flow by inner { - internal constructor(context: Context, key: Preferences.Key, defaultValue: T) : this( - context, - key, - context.dataStore.data.map { it[key] ?: defaultValue } - ) + internal constructor(context: Context, key: Preferences.Key, defaultValue: T) : + this(context, key, context.dataStore.data.map { it[key] ?: defaultValue }) suspend fun updatePreference(value: T) { context.dataStore.edit { it[key] = value } } -} \ No newline at end of file +} diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index a45ce1f..a0c2d98 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -162,6 +162,8 @@ Switching Send notifications for switching profiles\nNote that this type of notification is unreliable. Advanced + Refresh status after switching + If crash after switch, Please trying disable the function Allow Disabling / Deleting Active Profile By default, this app prevents you from disabling the active profile on a removable eSIM inserted in the device, because doing so may sometimes render it inaccessible.\nCheck this box to remove this safeguard. Verbose Logging diff --git a/app-common/src/main/res/xml/pref_settings.xml b/app-common/src/main/res/xml/pref_settings.xml index bb5bd50..9d2f189 100644 --- a/app-common/src/main/res/xml/pref_settings.xml +++ b/app-common/src/main/res/xml/pref_settings.xml @@ -60,12 +60,14 @@ diff --git a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt index 23589a6..31c9a77 100644 --- a/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt +++ b/app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedSettingsFragment.kt @@ -6,9 +6,11 @@ import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.widget.Toast +import androidx.preference.CheckBoxPreference import androidx.preference.Preference import im.angry.easyeuicc.R import im.angry.openeuicc.util.encodeHex +import im.angry.openeuicc.util.preferenceRepository import java.security.MessageDigest class UnprivilegedSettingsFragment : SettingsFragment() { @@ -29,8 +31,12 @@ class UnprivilegedSettingsFragment : SettingsFragment() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { super.onCreatePreferences(savedInstanceState, rootKey) addPreferencesFromResource(R.xml.pref_unprivileged_settings) + mergePreferenceOverlay("pref_developer_overlay", "pref_developer") mergePreferenceOverlay("pref_info_overlay", "pref_info") + requirePreference("pref_developer_refreshed_after_switch") + .bindBooleanFlow(preferenceRepository.refreshAfterSwitchFlow) + requirePreference("pref_info_ara_m").apply { summary = firstSigner.encodeHex() setOnPreferenceClickListener { diff --git a/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml b/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml index 3281caf..df5bfee 100644 --- a/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml +++ b/app-unpriv/src/main/res/xml/pref_unprivileged_settings.xml @@ -1,5 +1,15 @@ + + +