diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt index 842f4ec..e02b7be 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt @@ -31,6 +31,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.floatingactionbutton.FloatingActionButton import net.typeblog.lpac_jni.LocalProfileInfo import im.angry.openeuicc.common.R +import im.angry.openeuicc.core.EuiccChannelManager import im.angry.openeuicc.service.EuiccChannelManagerService import im.angry.openeuicc.service.EuiccChannelManagerService.Companion.waitDone import im.angry.openeuicc.ui.wizard.DownloadWizardActivity @@ -131,31 +132,72 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener, inflater.inflate(R.menu.fragment_euicc, menu) } - override fun onOptionsItemSelected(item: MenuItem): Boolean = - when (item.itemId) { - R.id.show_notifications -> { - if (logicalSlotId != -1) { - Intent(requireContext(), NotificationsActivity::class.java).apply { - putExtra("logicalSlotId", logicalSlotId) - startActivity(this) - } - } - true - } + override fun onPrepareOptionsMenu(menu: Menu) { + super.onPrepareOptionsMenu(menu) + menu.findItem(R.id.show_notifications).isVisible = + logicalSlotId != -1 + menu.findItem(R.id.euicc_info).isVisible = + logicalSlotId != -1 + menu.findItem(R.id.euicc_memory_reset).isVisible = + logicalSlotId == EuiccChannelManager.USB_CHANNEL_ID + } - R.id.euicc_info -> { - if (logicalSlotId != -1) { - Intent(requireContext(), EuiccInfoActivity::class.java).apply { - putExtra("logicalSlotId", logicalSlotId) - startActivity(this) - } - } - true + override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { + R.id.show_notifications -> { + Intent(requireContext(), NotificationsActivity::class.java).apply { + putExtra("logicalSlotId", logicalSlotId) + startActivity(this) } - - else -> super.onOptionsItemSelected(item) + true } + R.id.euicc_info -> { + Intent(requireContext(), EuiccInfoActivity::class.java).apply { + putExtra("logicalSlotId", logicalSlotId) + startActivity(this) + } + true + } + + R.id.euicc_memory_reset -> { + AlertDialog.Builder(requireContext()).apply { + setTitle(R.string.euicc_memory_reset_title) + setMessage(R.string.euicc_memory_reset_message) + setPositiveButton(android.R.string.ok) { dialog, _ -> + dialog.dismiss() + lifecycleScope.launch { + ensureEuiccChannelManager() + euiccChannelManagerService.waitForForegroundTask() + +// val err = euiccChannelManagerService.launchMemoryResetTask( +// slotId, +// portId +// ).waitDone() +// +// if (err != null) { +// withContext(Dispatchers.Main) { +// AlertDialog.Builder(requireContext()).apply { +// setMessage(R.string.euicc_memory_reset_failed) +// setPositiveButton(android.R.string.ok) { dialog, _ -> +// dialog.dismiss() +// } +// show() +// } +// } +// } + } + } + setNegativeButton(android.R.string.cancel) { dialog, _ -> + dialog.dismiss() + } + show() + } + true + } + + else -> super.onOptionsItemSelected(item) + } + protected open suspend fun onCreateFooterViews( parent: ViewGroup, profiles: List 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..7fb27d9 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 @@ -4,6 +4,7 @@ import android.content.Intent import android.net.Uri import android.os.Build import android.os.Bundle +import android.os.Debug import android.provider.Settings import android.widget.Toast import androidx.lifecycle.lifecycleScope @@ -11,6 +12,7 @@ import androidx.preference.CheckBoxPreference import androidx.preference.Preference import androidx.preference.PreferenceCategory import androidx.preference.PreferenceFragmentCompat +import im.angry.openeuicc.common.BuildConfig import im.angry.openeuicc.common.R import im.angry.openeuicc.util.* import kotlinx.coroutines.flow.collect @@ -77,6 +79,9 @@ open class SettingsFragment: PreferenceFragmentCompat() { requirePreference("pref_developer_ignore_tls_certificate") .bindBooleanFlow(preferenceRepository.ignoreTLSCertificateFlow) + + requirePreference("pref_developer_euicc_memory_reset"). + bindBooleanFlow(preferenceRepository.euiccMemoryResetFlow) } protected fun requirePreference(key: CharSequence) = 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..25f3e86 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 @@ -33,6 +33,7 @@ internal object PreferenceKeys { val DEVELOPER_OPTIONS_ENABLED = booleanPreferencesKey("developer_options_enabled") val UNFILTERED_PROFILE_LIST = booleanPreferencesKey("unfiltered_profile_list") val IGNORE_TLS_CERTIFICATE = booleanPreferencesKey("ignore_tls_certificate") + val EUICC_MEMORY_RESET = booleanPreferencesKey("euicc_memory_reset") } class PreferenceRepository(private val context: Context) { @@ -50,6 +51,7 @@ class PreferenceRepository(private val context: Context) { val developerOptionsEnabledFlow = bindFlow(PreferenceKeys.DEVELOPER_OPTIONS_ENABLED, false) val unfilteredProfileListFlow = bindFlow(PreferenceKeys.UNFILTERED_PROFILE_LIST, false) val ignoreTLSCertificateFlow = bindFlow(PreferenceKeys.IGNORE_TLS_CERTIFICATE, false) + val euiccMemoryResetFlow = bindFlow(PreferenceKeys.EUICC_MEMORY_RESET, false) private fun bindFlow(key: Preferences.Key, defaultValue: T): PreferenceFlowWrapper = PreferenceFlowWrapper(context, key, defaultValue) diff --git a/app-common/src/main/res/menu/fragment_euicc.xml b/app-common/src/main/res/menu/fragment_euicc.xml index b54eaf1..61f7b7f 100644 --- a/app-common/src/main/res/menu/fragment_euicc.xml +++ b/app-common/src/main/res/menu/fragment_euicc.xml @@ -4,10 +4,18 @@ + + \ 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..5674c0d 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -143,6 +143,10 @@ Unknown eSIM CI Answer To Reset (ATR) + Erase the Chip + Erase the Chip + I confirm to clear all profiles on this chip and understand that this operation is irreversible. + Yes No @@ -175,6 +179,8 @@ Include non-production profiles in the list Ignore SM-DP+ TLS certificate Accept any TLS certificate used by the RSP server + Allow Erase Chip (USB only) + Don\'t erase your eSIM as a troubleshooting step unless directed to by your carrier. Info App Version Source Code diff --git a/app-common/src/main/res/xml/pref_settings.xml b/app-common/src/main/res/xml/pref_settings.xml index bb5bd50..eeec437 100644 --- a/app-common/src/main/res/xml/pref_settings.xml +++ b/app-common/src/main/res/xml/pref_settings.xml @@ -69,6 +69,11 @@ app:summary="@string/pref_developer_ignore_tls_certificate_desc" app:title="@string/pref_developer_ignore_tls_certificate" /> +