diff --git a/app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelFactory.kt b/app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelFactory.kt deleted file mode 100644 index 15e0191..0000000 --- a/app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelFactory.kt +++ /dev/null @@ -1,43 +0,0 @@ -package im.angry.openeuicc.core - -import android.content.Context -import android.se.omapi.SEService -import android.util.Log -import im.angry.openeuicc.util.* -import java.lang.IllegalArgumentException - -open class DefaultEuiccChannelFactory(protected val context: Context) : EuiccChannelFactory { - private var seService: SEService? = null - - private suspend fun ensureSEService() { - if (seService == null) { - seService = connectSEService(context) - } - } - - override suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? { - if (port.portIndex != 0) { - Log.w(DefaultEuiccChannelManager.TAG, "OMAPI channel attempted on non-zero portId, this may or may not work.") - } - - ensureSEService() - - Log.i(DefaultEuiccChannelManager.TAG, "Trying OMAPI for physical slot ${port.card.physicalSlotIndex}") - try { - return OmapiChannel(seService!!, port) - } catch (e: IllegalArgumentException) { - // Failed - Log.w( - DefaultEuiccChannelManager.TAG, - "OMAPI APDU interface unavailable for physical slot ${port.card.physicalSlotIndex}." - ) - } - - return null - } - - override fun cleanup() { - seService?.shutdown() - seService = null - } -} \ No newline at end of file diff --git a/app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelManager.kt b/app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelManager.kt index a978677..1883a11 100644 --- a/app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelManager.kt +++ b/app-common/src/main/java/im/angry/openeuicc/core/DefaultEuiccChannelManager.kt @@ -1,41 +1,69 @@ 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.di.AppContainer +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 appContainer: AppContainer, - protected val context: Context -) : EuiccChannelManager { +open class DefaultEuiccChannelManager(protected val context: Context) : EuiccChannelManager { companion object { const val TAG = "EuiccChannelManager" } private val channels = mutableListOf() + private var seService: SEService? = null + private val lock = Mutex() protected val tm by lazy { - appContainer.telephonyManager - } - - private val euiccChannelFactory by lazy { - appContainer.euiccChannelFactory + (context.applicationContext as OpenEuiccApplication).appContainer.telephonyManager } protected open val uiccCards: Collection get() = (0.. by preferencesDataStore(name = "prefs") val Context.preferenceRepository: PreferenceRepository - get() = (applicationContext as OpenEuiccApplication).appContainer.preferenceRepository + get() = (applicationContext as OpenEuiccApplication).preferenceRepository val Fragment.preferenceRepository: PreferenceRepository get() = requireContext().preferenceRepository diff --git a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelFactory.kt b/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelFactory.kt deleted file mode 100644 index 78acefe..0000000 --- a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelFactory.kt +++ /dev/null @@ -1,43 +0,0 @@ -package im.angry.openeuicc.core - -import android.content.Context -import android.util.Log -import im.angry.openeuicc.OpenEuiccApplication -import im.angry.openeuicc.util.* -import java.lang.IllegalArgumentException - -class PrivilegedEuiccChannelFactory(context: Context) : DefaultEuiccChannelFactory(context) { - private val tm by lazy { - (context.applicationContext as OpenEuiccApplication).appContainer.telephonyManager - } - - @Suppress("NAME_SHADOWING") - override suspend fun tryOpenEuiccChannel(port: UiccPortInfoCompat): EuiccChannel? { - val port = port as RealUiccPortInfoCompat - if (port.card.isRemovable) { - // Attempt unprivileged (OMAPI) before TelephonyManager - // but still try TelephonyManager in case OMAPI is broken - super.tryOpenEuiccChannel(port)?.let { return it } - } - - if (port.card.isEuicc) { - Log.i( - DefaultEuiccChannelManager.TAG, - "Trying TelephonyManager for slot ${port.card.physicalSlotIndex} port ${port.portIndex}" - ) - try { - return TelephonyManagerChannel( - port, tm - ) - } catch (e: IllegalArgumentException) { - // Failed - Log.w( - DefaultEuiccChannelManager.TAG, - "TelephonyManager APDU interface unavailable for slot ${port.card.physicalSlotIndex} port ${port.portIndex}, falling back" - ) - } - } - - return super.tryOpenEuiccChannel(port) - } -} \ No newline at end of file diff --git a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt b/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt index 1c5d132..0ebaa81 100644 --- a/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt +++ b/app/src/main/java/im/angry/openeuicc/core/PrivilegedEuiccChannelManager.kt @@ -1,15 +1,37 @@ package im.angry.openeuicc.core import android.content.Context -import im.angry.openeuicc.di.AppContainer +import android.util.Log +import im.angry.openeuicc.OpenEuiccApplication import im.angry.openeuicc.util.* import java.lang.Exception +import java.lang.IllegalArgumentException -class PrivilegedEuiccChannelManager(appContainer: AppContainer, context: Context) : - DefaultEuiccChannelManager(appContainer, context) { +class PrivilegedEuiccChannelManager(context: Context): DefaultEuiccChannelManager(context) { override val uiccCards: Collection get() = tm.uiccCardsInfoCompat + @Suppress("NAME_SHADOWING") + override fun tryOpenEuiccChannelPrivileged(port: UiccPortInfoCompat): EuiccChannel? { + val port = port as RealUiccPortInfoCompat + if (port.card.isRemovable) { + // Attempt unprivileged (OMAPI) before TelephonyManager + // but still try TelephonyManager in case OMAPI is broken + super.tryOpenEuiccChannelUnprivileged(port)?.let { return it } + } + + if (port.card.isEuicc) { + Log.i(TAG, "Trying TelephonyManager for slot ${port.card.physicalSlotIndex} port ${port.portIndex}") + try { + return TelephonyManagerChannel(port, tm) + } catch (e: IllegalArgumentException) { + // Failed + Log.w(TAG, "TelephonyManager APDU interface unavailable for slot ${port.card.physicalSlotIndex} port ${port.portIndex}, falling back") + } + } + return null + } + // Clean up channels left open in TelephonyManager // due to a (potentially) forced restart // This should be called every time the application is restarted @@ -26,7 +48,7 @@ class PrivilegedEuiccChannelManager(appContainer: AppContainer, context: Context } override fun notifyEuiccProfilesChanged(logicalSlotId: Int) { - appContainer.subscriptionManager.apply { + (context.applicationContext as OpenEuiccApplication).appContainer.subscriptionManager.apply { findEuiccChannelBySlotBlocking(logicalSlotId)?.let { tryRefreshCachedEuiccInfo(it.cardId) } diff --git a/app/src/main/java/im/angry/openeuicc/di/PrivilegedAppContainer.kt b/app/src/main/java/im/angry/openeuicc/di/PrivilegedAppContainer.kt index 5158352..dc3921e 100644 --- a/app/src/main/java/im/angry/openeuicc/di/PrivilegedAppContainer.kt +++ b/app/src/main/java/im/angry/openeuicc/di/PrivilegedAppContainer.kt @@ -2,19 +2,14 @@ package im.angry.openeuicc.di import android.content.Context import im.angry.openeuicc.core.EuiccChannelManager -import im.angry.openeuicc.core.PrivilegedEuiccChannelFactory import im.angry.openeuicc.core.PrivilegedEuiccChannelManager class PrivilegedAppContainer(context: Context) : DefaultAppContainer(context) { override val euiccChannelManager: EuiccChannelManager by lazy { - PrivilegedEuiccChannelManager(this, context) + PrivilegedEuiccChannelManager(context) } override val uiComponentFactory by lazy { PrivilegedUiComponentFactory() } - - override val euiccChannelFactory by lazy { - PrivilegedEuiccChannelFactory(context) - } } \ No newline at end of file