Browse Source

Disable all profiles when switching DSDS state as well

Peter Cai 2 years ago
parent
commit
f583e35697

+ 8 - 1
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<LocalProfileInfo>.operational: List<LocalProfileInfo>
     get() = filter {
         it.profileClass == LocalProfileInfo.Clazz.Operational
-    }
+    }
+
+fun LocalProfileAssistant.disableActiveProfileWithUndo(): () -> Unit =
+    profiles.find { it.state == LocalProfileInfo.State.Enabled }?.let {
+        disableProfile(it.iccid)
+        return { enableProfile(it.iccid) }
+    } ?: { }

+ 1 - 1
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

+ 20 - 10
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<UiccSlotMapping>) {
-    val unmapped = simSlotMapping.filterNot { mapping ->
+fun TelephonyManager.updateSimSlotMapping(
+    euiccManager: EuiccChannelManager, newMapping: Collection<UiccSlotMapping>,
+    currentMapping: Collection<UiccSlotMapping> = 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()
         }
     }