From f583e3569760331a267f3808034fb4261e6aebd8 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Thu, 28 Dec 2023 17:10:13 -0500 Subject: [PATCH] Disable all profiles when switching DSDS state as well --- .../java/im/angry/openeuicc/util/LPAUtils.kt | 9 +++++- .../openeuicc/ui/PrivilegedMainActivity.kt | 2 +- .../util/PrivilegedTelephonyUtils.kt | 30 ++++++++++++------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt b/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt index e07a113..e5c2f52 100644 --- a/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt +++ b/app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt @@ -1,5 +1,6 @@ package im.angry.openeuicc.util +import net.typeblog.lpac_jni.LocalProfileAssistant import net.typeblog.lpac_jni.LocalProfileInfo val LocalProfileInfo.displayName: String @@ -8,4 +9,10 @@ val LocalProfileInfo.displayName: String val List.operational: List get() = filter { it.profileClass == LocalProfileInfo.Clazz.Operational - } \ No newline at end of file + } + +fun LocalProfileAssistant.disableActiveProfileWithUndo(): () -> Unit = + profiles.find { it.state == LocalProfileInfo.State.Enabled }?.let { + disableProfile(it.iccid) + return { enableProfile(it.iccid) } + } ?: { } \ No newline at end of file diff --git a/app/src/main/java/im/angry/openeuicc/ui/PrivilegedMainActivity.kt b/app/src/main/java/im/angry/openeuicc/ui/PrivilegedMainActivity.kt index 8a1ff00..64e8ca9 100644 --- a/app/src/main/java/im/angry/openeuicc/ui/PrivilegedMainActivity.kt +++ b/app/src/main/java/im/angry/openeuicc/ui/PrivilegedMainActivity.kt @@ -26,7 +26,7 @@ class PrivilegedMainActivity : MainActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { R.id.dsds -> { - tm.dsdsEnabled = !item.isChecked + tm.setDsdsEnabled(openEuiccApplication.euiccChannelManager, !item.isChecked) Toast.makeText(this, R.string.toast_dsds_switched, Toast.LENGTH_LONG).show() finish() true 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 a875d8a..8fd4d62 100644 --- a/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt +++ b/app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt @@ -4,22 +4,35 @@ import android.telephony.SubscriptionManager import android.telephony.TelephonyManager import android.telephony.UiccSlotMapping import im.angry.openeuicc.core.EuiccChannelManager -import net.typeblog.lpac_jni.LocalProfileInfo +import kotlinx.coroutines.runBlocking import java.lang.Exception val TelephonyManager.supportsDSDS: Boolean get() = supportedModemCount == 2 -var TelephonyManager.dsdsEnabled: Boolean +val TelephonyManager.dsdsEnabled: Boolean get() = activeModemCount >= 2 - set(value) { - switchMultiSimConfig(if (value) { 2 } else {1}) + +fun TelephonyManager.setDsdsEnabled(euiccManager: EuiccChannelManager, enabled: Boolean) { + runBlocking { + euiccManager.enumerateEuiccChannels() } + // Disable all eSIM profiles before performing a DSDS switch + euiccManager.knownChannels.forEach { + it.lpa.disableActiveProfileWithUndo() + } + + switchMultiSimConfig(if (enabled) { 2 } else { 1 }) +} + // Disable eSIM profiles before switching the slot mapping // This ensures that unmapped eSIM ports never have "ghost" profiles enabled -fun TelephonyManager.updateSimSlotMapping(euiccManager: EuiccChannelManager, newMapping: Collection) { - val unmapped = simSlotMapping.filterNot { mapping -> +fun TelephonyManager.updateSimSlotMapping( + euiccManager: EuiccChannelManager, newMapping: Collection, + currentMapping: Collection = simSlotMapping +) { + val unmapped = currentMapping.filterNot { mapping -> // If the same physical slot + port pair is not found in the new mapping, it is unmapped newMapping.any { it.physicalSlotIndex == mapping.physicalSlotIndex && it.portIndex == mapping.portIndex @@ -28,10 +41,7 @@ fun TelephonyManager.updateSimSlotMapping(euiccManager: EuiccChannelManager, new val undo = unmapped.mapNotNull { mapping -> euiccManager.findEuiccChannelByPortBlocking(mapping.physicalSlotIndex, mapping.portIndex)?.let { channel -> - channel.lpa.profiles.find { it.state == LocalProfileInfo.State.Enabled }?.let { profile -> - channel.lpa.disableProfile(profile.iccid) - return@mapNotNull { channel.lpa.enableProfile(profile.iccid) } - } + return@mapNotNull channel.lpa.disableActiveProfileWithUndo() } }