Browse Source

refactor: tryOpenEuiccChannel should always return all SEs for a port

Peter Cai 1 month ago
parent
commit
65a4c887f1

+ 21 - 13
app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelManager.kt

@@ -114,22 +114,25 @@ open class DefaultEuiccChannelManager(
 
 
     private suspend fun tryOpenEuiccChannel(
     private suspend fun tryOpenEuiccChannel(
         port: UiccPortInfoCompat,
         port: UiccPortInfoCompat,
-        seId: EuiccChannel.SecureElementId = EuiccChannel.SecureElementId.DEFAULT
-    ): EuiccChannel? {
+    ): List<EuiccChannel>? {
         lock.withLock {
         lock.withLock {
             if (port.card.physicalSlotIndex == EuiccChannelManager.USB_CHANNEL_ID) {
             if (port.card.physicalSlotIndex == EuiccChannelManager.USB_CHANNEL_ID) {
-                // We only compare seId because we assume we can only open 1 card from USB
-                return usbChannels.find { it.seId == seId }
+                return usbChannels
             }
             }
 
 
+            // First get all channels for the requested port
             val existing =
             val existing =
-                channelCache.find { it.slotId == port.card.physicalSlotIndex && it.portId == port.portIndex && it.seId == seId }
-            if (existing != null) {
-                if (existing.valid && port.logicalSlotIndex == existing.logicalSlotId) {
+                channelCache.filter { it.slotId == port.card.physicalSlotIndex && it.portId == port.portIndex }
+            if (existing.isNotEmpty()) {
+                if (existing.all { it.valid && it.logicalSlotId == port.logicalSlotIndex }) {
                     return existing
                     return existing
                 } else {
                 } else {
-                    existing.close()
-                    channelCache.remove(existing)
+                    // If any channel shouldn't be considered valid anymore, close all existing for the same slot / port
+                    // and reopen
+                    existing.forEach {
+                        it.close()
+                        channelCache.remove(it)
+                    }
                 }
                 }
             }
             }
 
 
@@ -149,7 +152,7 @@ open class DefaultEuiccChannelManager(
 
 
             if (channels.isNotEmpty()) {
             if (channels.isNotEmpty()) {
                 channelCache.addAll(channels)
                 channelCache.addAll(channels)
-                return channels.find { it.seId == seId }
+                return channels
             } else {
             } else {
                 Log.i(
                 Log.i(
                     TAG,
                     TAG,
@@ -172,7 +175,7 @@ open class DefaultEuiccChannelManager(
             for (card in uiccCards) {
             for (card in uiccCards) {
                 for (port in card.ports) {
                 for (port in card.ports) {
                     if (port.logicalSlotIndex == logicalSlotId) {
                     if (port.logicalSlotIndex == logicalSlotId) {
-                        return@withContext tryOpenEuiccChannel(port, seId)
+                        return@withContext tryOpenEuiccChannel(port)?.find { it.seId == seId }
                     }
                     }
                 }
                 }
             }
             }
@@ -180,6 +183,10 @@ open class DefaultEuiccChannelManager(
             null
             null
         }
         }
 
 
+    /**
+     * Find all EuiccChannels associated with a _physical_ slot, including all secure elements
+     * on cards with multiple of them.
+     */
     private suspend fun findAllEuiccChannelsByPhysicalSlot(physicalSlotId: Int): List<EuiccChannel>? {
     private suspend fun findAllEuiccChannelsByPhysicalSlot(physicalSlotId: Int): List<EuiccChannel>? {
         if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) {
         if (physicalSlotId == EuiccChannelManager.USB_CHANNEL_ID) {
             return usbChannels.ifEmpty { null }
             return usbChannels.ifEmpty { null }
@@ -188,6 +195,7 @@ open class DefaultEuiccChannelManager(
         for (card in uiccCards) {
         for (card in uiccCards) {
             if (card.physicalSlotIndex != physicalSlotId) continue
             if (card.physicalSlotIndex != physicalSlotId) continue
             return card.ports.mapNotNull { tryOpenEuiccChannel(it) }
             return card.ports.mapNotNull { tryOpenEuiccChannel(it) }
+                .flatten()
                 .ifEmpty { null }
                 .ifEmpty { null }
         }
         }
         return null
         return null
@@ -204,8 +212,8 @@ open class DefaultEuiccChannelManager(
             }
             }
 
 
             uiccCards.find { it.physicalSlotIndex == physicalSlotId }?.let { card ->
             uiccCards.find { it.physicalSlotIndex == physicalSlotId }?.let { card ->
-                card.ports.find { it.portIndex == portId }?.let { tryOpenEuiccChannel(it, seId) }
-            }
+                card.ports.find { it.portIndex == portId }?.let { tryOpenEuiccChannel(it) }
+            }?.find { it.seId == seId }
         }
         }
 
 
     override suspend fun findFirstAvailablePort(physicalSlotId: Int): Int =
     override suspend fun findFirstAvailablePort(physicalSlotId: Int): Int =