From 2a6002d053770176caecbd1f133e936588bf7000 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sat, 20 Jan 2024 11:16:01 -0500 Subject: [PATCH 1/2] EuiccManagementFragment: hide the "disable" option for removable eSIMs --- .../openeuicc/ui/EuiccManagementFragment.kt | 22 +++++++++---------- .../java/im/angry/openeuicc/util/Utils.kt | 6 ++++- .../src/main/res/menu/profile_options.xml | 1 + .../ui/PrivilegedEuiccManagementFragment.kt | 14 ++++++++++++ 4 files changed, 30 insertions(+), 13 deletions(-) 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 d6ffa32..2d0b67d 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 @@ -29,7 +29,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import net.typeblog.lpac_jni.LocalProfileNotification import java.lang.Exception open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfilesChangedListener { @@ -159,6 +158,14 @@ open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfi preferenceRepository.notificationDisableFlow.first() } + protected open fun populatePopupWithProfileActions(popup: PopupMenu, profile: LocalProfileInfo) { + popup.inflate(R.menu.profile_options) + if (profile.isEnabled) { + popup.menu.findItem(R.id.enable).isVisible = false + popup.menu.findItem(R.id.delete).isVisible = false + } + } + sealed class ViewHolder(root: View) : RecyclerView.ViewHolder(root) { enum class Type(val value: Int) { PROFILE(0), @@ -208,7 +215,7 @@ open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfi name.text = profile.displayName state.setText( - if (isEnabled()) { + if (profile.isEnabled) { R.string.enabled } else { R.string.disabled @@ -219,19 +226,10 @@ open class EuiccManagementFragment : Fragment(), EuiccFragmentMarker, EuiccProfi iccid.transformationMethod = PasswordTransformationMethod.getInstance() } - private fun isEnabled(): Boolean = - profile.state == LocalProfileInfo.State.Enabled - private fun showOptionsMenu() { PopupMenu(root.context, profileMenu).apply { setOnMenuItemClickListener(::onMenuItemClicked) - inflate(R.menu.profile_options) - if (isEnabled()) { - menu.findItem(R.id.enable).isVisible = false - menu.findItem(R.id.delete).isVisible = false - } else { - menu.findItem(R.id.disable).isVisible = false - } + populatePopupWithProfileActions(this, profile) show() } } diff --git a/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt b/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt index e5a7d2e..6e6f162 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/Utils.kt @@ -2,6 +2,7 @@ package im.angry.openeuicc.util import android.content.Context import android.content.pm.PackageManager +import net.typeblog.lpac_jni.LocalProfileInfo import java.lang.RuntimeException val Context.selfAppVersion: String @@ -11,4 +12,7 @@ val Context.selfAppVersion: String pInfo.versionName } catch (e: PackageManager.NameNotFoundException) { throw RuntimeException(e) - } \ No newline at end of file + } + +val LocalProfileInfo.isEnabled: Boolean + get() = state == LocalProfileInfo.State.Enabled \ No newline at end of file diff --git a/app-common/src/main/res/menu/profile_options.xml b/app-common/src/main/res/menu/profile_options.xml index 4c9bede..6add53d 100644 --- a/app-common/src/main/res/menu/profile_options.xml +++ b/app-common/src/main/res/menu/profile_options.xml @@ -6,6 +6,7 @@ Date: Sat, 20 Jan 2024 11:20:56 -0500 Subject: [PATCH 2/2] PrivilegedTelephonyUtils: do not disable profiles on external eUICCs --- .../openeuicc/util/PrivilegedTelephonyUtils.kt | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt b/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt index a544804..4675ab9 100644 --- a/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt +++ b/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt @@ -19,9 +19,11 @@ fun TelephonyManager.setDsdsEnabled(euiccManager: EuiccChannelManager, enabled: euiccManager.enumerateEuiccChannels() } - // Disable all eSIM profiles before performing a DSDS switch + // Disable all eSIM profiles before performing a DSDS switch (only for internal eSIMs) euiccManager.knownChannels.forEach { - it.lpa.disableActiveProfileWithUndo() + if (!it.removable) { + it.lpa.disableActiveProfileWithUndo() + } } switchMultiSimConfig(if (enabled) { 2 } else { 1 }) @@ -42,7 +44,13 @@ fun TelephonyManager.updateSimSlotMapping( val undo = unmapped.mapNotNull { mapping -> euiccManager.findEuiccChannelByPortBlocking(mapping.physicalSlotIndex, mapping.portIndex)?.let { channel -> - return@mapNotNull channel.lpa.disableActiveProfileWithUndo() + if (!channel.removable) { + return@mapNotNull channel.lpa.disableActiveProfileWithUndo() + } else { + // Do not do anything for external eUICCs -- we can't really trust them to work properly + // with no profile enabled. + return@mapNotNull null + } } }