浏览代码

refactor: IEuiccChannelManager -> EuiccChannelManager

Peter Cai 1 年之前
父节点
当前提交
7c6b4ebee5

+ 174 - 0
app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelManager.kt

@@ -0,0 +1,174 @@
+package im.angry.openeuicc.core
+
+import android.content.Context
+import android.se.omapi.SEService
+import android.telephony.SubscriptionManager
+import android.util.Log
+import im.angry.openeuicc.OpenEuiccApplication
+import im.angry.openeuicc.util.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.sync.withLock
+import kotlinx.coroutines.withContext
+import java.lang.IllegalArgumentException
+
+open class DefaultEuiccChannelManager(protected val context: Context) : EuiccChannelManager {
+    companion object {
+        const val TAG = "EuiccChannelManager"
+    }
+
+    private val channels = mutableListOf<EuiccChannel>()
+
+    private var seService: SEService? = null
+
+    private val lock = Mutex()
+
+    protected val tm by lazy {
+        (context.applicationContext as OpenEuiccApplication).appContainer.telephonyManager
+    }
+
+    protected open val uiccCards: Collection<UiccCardInfoCompat>
+        get() = (0..<tm.activeModemCountCompat).map { FakeUiccCardInfoCompat(it) }
+
+    private suspend fun ensureSEService() {
+        if (seService == null) {
+            seService = connectSEService(context)
+        }
+    }
+
+    protected open fun tryOpenEuiccChannelPrivileged(port: UiccPortInfoCompat): EuiccChannel? {
+        // No-op when unprivileged
+        return null
+    }
+
+    protected fun tryOpenEuiccChannelUnprivileged(port: UiccPortInfoCompat): EuiccChannel? {
+        if (port.portIndex != 0) {
+            Log.w(TAG, "OMAPI channel attempted on non-zero portId, this may or may not work.")
+        }
+
+        Log.i(TAG, "Trying OMAPI for physical slot ${port.card.physicalSlotIndex}")
+        try {
+            return OmapiChannel(seService!!, port)
+        } catch (e: IllegalArgumentException) {
+            // Failed
+            Log.w(
+                TAG,
+                "OMAPI APDU interface unavailable for physical slot ${port.card.physicalSlotIndex}."
+            )
+        }
+
+        return null
+    }
+
+    private suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? {
+        lock.withLock {
+            ensureSEService()
+            val existing =
+                channels.find { it.slotId == port.card.physicalSlotIndex && it.portId == port.portIndex }
+            if (existing != null) {
+                if (existing.valid && port.logicalSlotIndex == existing.logicalSlotId) {
+                    return existing
+                } else {
+                    existing.close()
+                    channels.remove(existing)
+                }
+            }
+
+            if (port.logicalSlotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+                // We can only open channels on ports that are actually enabled
+                return null
+            }
+
+            var euiccChannel: EuiccChannel? = tryOpenEuiccChannelPrivileged(port)
+
+            if (euiccChannel == null) {
+                euiccChannel = tryOpenEuiccChannelUnprivileged(port)
+            }
+
+            if (euiccChannel != null) {
+                channels.add(euiccChannel)
+            }
+
+            return euiccChannel
+        }
+    }
+
+    override fun findEuiccChannelBySlotBlocking(logicalSlotId: Int): EuiccChannel? =
+        runBlocking {
+            withContext(Dispatchers.IO) {
+                for (card in uiccCards) {
+                    for (port in card.ports) {
+                        if (port.logicalSlotIndex == logicalSlotId) {
+                            return@withContext tryOpenEuiccChannel(port)
+                        }
+                    }
+                }
+
+                null
+            }
+        }
+
+    override fun findEuiccChannelByPhysicalSlotBlocking(physicalSlotId: Int): EuiccChannel? =
+        runBlocking {
+            withContext(Dispatchers.IO) {
+                for (card in uiccCards) {
+                    if (card.physicalSlotIndex != physicalSlotId) continue
+                    for (port in card.ports) {
+                        tryOpenEuiccChannel(port)?.let { return@withContext it }
+                    }
+                }
+
+                null
+            }
+        }
+
+    override fun findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId: Int): List<EuiccChannel>? =
+        runBlocking {
+            for (card in uiccCards) {
+                if (card.physicalSlotIndex != physicalSlotId) continue
+                return@runBlocking card.ports.mapNotNull { tryOpenEuiccChannel(it) }
+                    .ifEmpty { null }
+            }
+            return@runBlocking null
+        }
+
+    override fun findEuiccChannelByPortBlocking(physicalSlotId: Int, portId: Int): EuiccChannel? =
+        runBlocking {
+            withContext(Dispatchers.IO) {
+                uiccCards.find { it.physicalSlotIndex == physicalSlotId }?.let { card ->
+                    card.ports.find { it.portIndex == portId }?.let { tryOpenEuiccChannel(it) }
+                }
+            }
+        }
+
+    override suspend fun enumerateEuiccChannels() {
+        withContext(Dispatchers.IO) {
+            ensureSEService()
+
+            for (uiccInfo in uiccCards) {
+                for (port in uiccInfo.ports) {
+                    if (tryOpenEuiccChannel(port) != null) {
+                        Log.d(
+                            TAG,
+                            "Found eUICC on slot ${uiccInfo.physicalSlotIndex} port ${port.portIndex}"
+                        )
+                    }
+                }
+            }
+        }
+    }
+
+    override val knownChannels: List<EuiccChannel>
+        get() = channels.toList()
+
+    override fun invalidate() {
+        for (channel in channels) {
+            channel.close()
+        }
+
+        channels.clear()
+        seService?.shutdown()
+        seService = null
+    }
+}

+ 43 - 170
app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt

@@ -1,174 +1,47 @@
 package im.angry.openeuicc.core
 
-import android.content.Context
-import android.se.omapi.SEService
-import android.telephony.SubscriptionManager
-import android.util.Log
-import im.angry.openeuicc.OpenEuiccApplication
-import im.angry.openeuicc.util.*
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.sync.Mutex
-import kotlinx.coroutines.sync.withLock
-import kotlinx.coroutines.withContext
-import java.lang.IllegalArgumentException
-
-open class EuiccChannelManager(protected val context: Context) : IEuiccChannelManager {
-    companion object {
-        const val TAG = "EuiccChannelManager"
-    }
-
-    private val channels = mutableListOf<EuiccChannel>()
-
-    private var seService: SEService? = null
-
-    private val lock = Mutex()
-
-    protected val tm by lazy {
-        (context.applicationContext as OpenEuiccApplication).appContainer.telephonyManager
-    }
-
-    protected open val uiccCards: Collection<UiccCardInfoCompat>
-        get() = (0..<tm.activeModemCountCompat).map { FakeUiccCardInfoCompat(it) }
-
-    private suspend fun ensureSEService() {
-        if (seService == null) {
-            seService = connectSEService(context)
-        }
-    }
-
-    protected open fun tryOpenEuiccChannelPrivileged(port: UiccPortInfoCompat): EuiccChannel? {
-        // No-op when unprivileged
-        return null
-    }
-
-    protected fun tryOpenEuiccChannelUnprivileged(port: UiccPortInfoCompat): EuiccChannel? {
-        if (port.portIndex != 0) {
-            Log.w(TAG, "OMAPI channel attempted on non-zero portId, this may or may not work.")
-        }
-
-        Log.i(TAG, "Trying OMAPI for physical slot ${port.card.physicalSlotIndex}")
-        try {
-            return OmapiChannel(seService!!, port)
-        } catch (e: IllegalArgumentException) {
-            // Failed
-            Log.w(
-                TAG,
-                "OMAPI APDU interface unavailable for physical slot ${port.card.physicalSlotIndex}."
-            )
-        }
-
-        return null
-    }
-
-    private suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? {
-        lock.withLock {
-            ensureSEService()
-            val existing =
-                channels.find { it.slotId == port.card.physicalSlotIndex && it.portId == port.portIndex }
-            if (existing != null) {
-                if (existing.valid && port.logicalSlotIndex == existing.logicalSlotId) {
-                    return existing
-                } else {
-                    existing.close()
-                    channels.remove(existing)
-                }
-            }
-
-            if (port.logicalSlotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-                // We can only open channels on ports that are actually enabled
-                return null
-            }
-
-            var euiccChannel: EuiccChannel? = tryOpenEuiccChannelPrivileged(port)
-
-            if (euiccChannel == null) {
-                euiccChannel = tryOpenEuiccChannelUnprivileged(port)
-            }
-
-            if (euiccChannel != null) {
-                channels.add(euiccChannel)
-            }
-
-            return euiccChannel
-        }
-    }
-
-    override fun findEuiccChannelBySlotBlocking(logicalSlotId: Int): EuiccChannel? =
-        runBlocking {
-            withContext(Dispatchers.IO) {
-                for (card in uiccCards) {
-                    for (port in card.ports) {
-                        if (port.logicalSlotIndex == logicalSlotId) {
-                            return@withContext tryOpenEuiccChannel(port)
-                        }
-                    }
-                }
-
-                null
-            }
-        }
-
-    override fun findEuiccChannelByPhysicalSlotBlocking(physicalSlotId: Int): EuiccChannel? =
-        runBlocking {
-            withContext(Dispatchers.IO) {
-                for (card in uiccCards) {
-                    if (card.physicalSlotIndex != physicalSlotId) continue
-                    for (port in card.ports) {
-                        tryOpenEuiccChannel(port)?.let { return@withContext it }
-                    }
-                }
-
-                null
-            }
-        }
-
-    override fun findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId: Int): List<EuiccChannel>? =
-        runBlocking {
-            for (card in uiccCards) {
-                if (card.physicalSlotIndex != physicalSlotId) continue
-                return@runBlocking card.ports.mapNotNull { tryOpenEuiccChannel(it) }
-                    .ifEmpty { null }
-            }
-            return@runBlocking null
-        }
-
-    override fun findEuiccChannelByPortBlocking(physicalSlotId: Int, portId: Int): EuiccChannel? =
-        runBlocking {
-            withContext(Dispatchers.IO) {
-                uiccCards.find { it.physicalSlotIndex == physicalSlotId }?.let { card ->
-                    card.ports.find { it.portIndex == portId }?.let { tryOpenEuiccChannel(it) }
-                }
-            }
-        }
-
-    override suspend fun enumerateEuiccChannels() {
-        withContext(Dispatchers.IO) {
-            ensureSEService()
-
-            for (uiccInfo in uiccCards) {
-                for (port in uiccInfo.ports) {
-                    if (tryOpenEuiccChannel(port) != null) {
-                        Log.d(
-                            TAG,
-                            "Found eUICC on slot ${uiccInfo.physicalSlotIndex} port ${port.portIndex}"
-                        )
-                    }
-                }
-            }
-        }
-    }
-
-    override val knownChannels: List<EuiccChannel>
-        get() = channels.toList()
-
-    override fun invalidate() {
-        for (channel in channels) {
-            channel.close()
-        }
-
-        channels.clear()
-        seService?.shutdown()
-        seService = null
+interface EuiccChannelManager {
+    val knownChannels: List<EuiccChannel>
+
+    /**
+     * Scan all possible sources for EuiccChannels and have them cached for future use
+     */
+    suspend fun enumerateEuiccChannels()
+
+    /**
+     * Returns the EuiccChannel corresponding to a **logical** slot
+     */
+    fun findEuiccChannelBySlotBlocking(logicalSlotId: Int): EuiccChannel?
+
+    /**
+     * Returns the first EuiccChannel corresponding to a **physical** slot
+     * If the physical slot supports MEP and has multiple ports, it is undefined
+     * which of the two channels will be returned.
+     */
+    fun findEuiccChannelByPhysicalSlotBlocking(physicalSlotId: Int): EuiccChannel?
+
+    /**
+     * Returns all EuiccChannels corresponding to a **physical** slot
+     * Multiple channels are possible in the case of MEP
+     */
+    fun findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId: Int): List<EuiccChannel>?
+
+    /**
+     * Returns the EuiccChannel corresponding to a **physical** slot and a port ID
+     */
+    fun findEuiccChannelByPortBlocking(physicalSlotId: Int, portId: Int): EuiccChannel?
+
+    /**
+     * Invalidate all EuiccChannels previously known by this Manager
+     */
+    fun invalidate()
+
+    /**
+     * If possible, trigger the system to update the cached list of profiles
+     * This is only expected to be implemented when the application is privileged
+     * TODO: Remove this from the common interface
+     */
+    fun notifyEuiccProfilesChanged(logicalSlotId: Int) {
+        // no-op by default
     }
 }

+ 0 - 47
app-common/src/main/java/im/angry/openeuicc/core/IEuiccChannelManager.kt

@@ -1,47 +0,0 @@
-package im.angry.openeuicc.core
-
-interface IEuiccChannelManager {
-    val knownChannels: List<EuiccChannel>
-
-    /**
-     * Scan all possible sources for EuiccChannels and have them cached for future use
-     */
-    suspend fun enumerateEuiccChannels()
-
-    /**
-     * Returns the EuiccChannel corresponding to a **logical** slot
-     */
-    fun findEuiccChannelBySlotBlocking(logicalSlotId: Int): EuiccChannel?
-
-    /**
-     * Returns the first EuiccChannel corresponding to a **physical** slot
-     * If the physical slot supports MEP and has multiple ports, it is undefined
-     * which of the two channels will be returned.
-     */
-    fun findEuiccChannelByPhysicalSlotBlocking(physicalSlotId: Int): EuiccChannel?
-
-    /**
-     * Returns all EuiccChannels corresponding to a **physical** slot
-     * Multiple channels are possible in the case of MEP
-     */
-    fun findAllEuiccChannelsByPhysicalSlotBlocking(physicalSlotId: Int): List<EuiccChannel>?
-
-    /**
-     * Returns the EuiccChannel corresponding to a **physical** slot and a port ID
-     */
-    fun findEuiccChannelByPortBlocking(physicalSlotId: Int, portId: Int): EuiccChannel?
-
-    /**
-     * Invalidate all EuiccChannels previously known by this Manager
-     */
-    fun invalidate()
-
-    /**
-     * If possible, trigger the system to update the cached list of profiles
-     * This is only expected to be implemented when the application is privileged
-     * TODO: Remove this from the common interface
-     */
-    fun notifyEuiccProfilesChanged(logicalSlotId: Int) {
-        // no-op by default
-    }
-}

+ 2 - 2
app-common/src/main/java/im/angry/openeuicc/di/AppContainer.kt

@@ -2,12 +2,12 @@ package im.angry.openeuicc.di
 
 import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
-import im.angry.openeuicc.core.IEuiccChannelManager
+import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.util.*
 
 interface AppContainer {
     val telephonyManager: TelephonyManager
-    val euiccChannelManager: IEuiccChannelManager
+    val euiccChannelManager: EuiccChannelManager
     val subscriptionManager: SubscriptionManager
     val preferenceRepository: PreferenceRepository
     val uiComponentFactory: UiComponentFactory

+ 3 - 3
app-common/src/main/java/im/angry/openeuicc/di/DefaultAppContainer.kt

@@ -3,8 +3,8 @@ package im.angry.openeuicc.di
 import android.content.Context
 import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
+import im.angry.openeuicc.core.DefaultEuiccChannelManager
 import im.angry.openeuicc.core.EuiccChannelManager
-import im.angry.openeuicc.core.IEuiccChannelManager
 import im.angry.openeuicc.util.*
 
 open class DefaultAppContainer(context: Context) : AppContainer {
@@ -12,8 +12,8 @@ open class DefaultAppContainer(context: Context) : AppContainer {
         context.getSystemService(TelephonyManager::class.java)!!
     }
 
-    override val euiccChannelManager: IEuiccChannelManager by lazy {
-        EuiccChannelManager(context)
+    override val euiccChannelManager: EuiccChannelManager by lazy {
+        DefaultEuiccChannelManager(context)
     }
 
     override val subscriptionManager by lazy {

+ 2 - 2
app-common/src/main/java/im/angry/openeuicc/util/Utils.kt

@@ -7,7 +7,7 @@ import android.telephony.TelephonyManager
 import androidx.fragment.app.Fragment
 import im.angry.openeuicc.OpenEuiccApplication
 import im.angry.openeuicc.core.EuiccChannel
-import im.angry.openeuicc.core.IEuiccChannelManager
+import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.di.AppContainer
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.runBlocking
@@ -52,7 +52,7 @@ interface OpenEuiccContextMarker {
     val appContainer: AppContainer
         get() = openEuiccApplication.appContainer
 
-    val euiccChannelManager: IEuiccChannelManager
+    val euiccChannelManager: EuiccChannelManager
         get() = appContainer.euiccChannelManager
 
     val telephonyManager: TelephonyManager

+ 1 - 1
app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt

@@ -7,7 +7,7 @@ import im.angry.openeuicc.util.*
 import java.lang.Exception
 import java.lang.IllegalArgumentException
 
-class PrivilegedEuiccChannelManager(context: Context): EuiccChannelManager(context) {
+class PrivilegedEuiccChannelManager(context: Context): DefaultEuiccChannelManager(context) {
     override val uiccCards: Collection<UiccCardInfoCompat>
         get() = tm.uiccCardsInfoCompat
 

+ 2 - 2
app/src/main/java/im/angry/openeuicc/di/PrivilegedAppContainer.kt

@@ -1,11 +1,11 @@
 package im.angry.openeuicc.di
 
 import android.content.Context
-import im.angry.openeuicc.core.IEuiccChannelManager
+import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.core.PrivilegedEuiccChannelManager
 
 class PrivilegedAppContainer(context: Context) : DefaultAppContainer(context) {
-    override val euiccChannelManager: IEuiccChannelManager by lazy {
+    override val euiccChannelManager: EuiccChannelManager by lazy {
         PrivilegedEuiccChannelManager(context)
     }
 

+ 3 - 3
app/src/main/java/im/angry/openeuicc/util/PrivilegedTelephonyUtils.kt

@@ -4,7 +4,7 @@ import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
 import android.telephony.UiccSlotMapping
 import im.angry.openeuicc.core.EuiccChannel
-import im.angry.openeuicc.core.IEuiccChannelManager
+import im.angry.openeuicc.core.EuiccChannelManager
 import kotlinx.coroutines.runBlocking
 import java.lang.Exception
 
@@ -14,7 +14,7 @@ val TelephonyManager.supportsDSDS: Boolean
 val TelephonyManager.dsdsEnabled: Boolean
     get() = activeModemCount >= 2
 
-fun TelephonyManager.setDsdsEnabled(euiccManager: IEuiccChannelManager, enabled: Boolean) {
+fun TelephonyManager.setDsdsEnabled(euiccManager: EuiccChannelManager, enabled: Boolean) {
     runBlocking {
         euiccManager.enumerateEuiccChannels()
     }
@@ -32,7 +32,7 @@ fun TelephonyManager.setDsdsEnabled(euiccManager: IEuiccChannelManager, enabled:
 // Disable eSIM profiles before switching the slot mapping
 // This ensures that unmapped eSIM ports never have "ghost" profiles enabled
 fun TelephonyManager.updateSimSlotMapping(
-    euiccManager: IEuiccChannelManager, newMapping: Collection<UiccSlotMapping>,
+    euiccManager: EuiccChannelManager, newMapping: Collection<UiccSlotMapping>,
     currentMapping: Collection<UiccSlotMapping> = simSlotMapping
 ) {
     val unmapped = currentMapping.filterNot { mapping ->