浏览代码

refactor: [2/n] Move TelephonyApduInterface to privileged code only

Peter Cai 2 年之前
父节点
当前提交
5ed4c84bf2

+ 3 - 10
app-common/src/main/java/im/angry/openeuicc/OpenEuiccApplication.kt → app-common/src/main/java/im/angry/openeuicc/BaseOpenEuiccApplication.kt

@@ -3,23 +3,16 @@ package im.angry.openeuicc
 import android.app.Application
 import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
-import im.angry.openeuicc.core.EuiccChannelManager
+import im.angry.openeuicc.core.BaseEuiccChannelManager
 
-class OpenEuiccApplication : Application() {
+abstract class BaseOpenEuiccApplication : Application() {
     val telephonyManager by lazy {
         getSystemService(TelephonyManager::class.java)!!
     }
 
-    val euiccChannelManager by lazy {
-        EuiccChannelManager(this)
-    }
+    abstract val euiccChannelManager: BaseEuiccChannelManager
 
     val subscriptionManager by lazy {
         getSystemService(SubscriptionManager::class.java)!!
     }
-
-    override fun onCreate() {
-        super.onCreate()
-        euiccChannelManager.closeAllStaleChannels()
-    }
 }

+ 9 - 34
app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt → app-common/src/main/java/im/angry/openeuicc/core/BaseEuiccChannelManager.kt

@@ -6,21 +6,19 @@ import android.os.HandlerThread
 import android.se.omapi.SEService
 import android.telephony.UiccCardInfo
 import android.util.Log
-import im.angry.openeuicc.OpenEuiccApplication
-import im.angry.openeuicc.util.*
+import im.angry.openeuicc.BaseOpenEuiccApplication
 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.Exception
 import java.lang.IllegalArgumentException
 import kotlin.coroutines.resume
 import kotlin.coroutines.suspendCoroutine
 
-class EuiccChannelManager(private val context: Context) {
+abstract class BaseEuiccChannelManager(private val context: Context) {
     companion object {
-        const val TAG = "EuiccChannelManager"
+        const val TAG = "BaseEuiccChannelManager"
     }
 
     private val channels = mutableListOf<EuiccChannel>()
@@ -29,11 +27,11 @@ class EuiccChannelManager(private val context: Context) {
 
     private val lock = Mutex()
 
-    private val tm by lazy {
-        (context.applicationContext as OpenEuiccApplication).telephonyManager
+    protected val tm by lazy {
+        (context.applicationContext as BaseOpenEuiccApplication).telephonyManager
     }
 
-    private val handler = Handler(HandlerThread("EuiccChannelManager").also { it.start() }.looper)
+    private val handler = Handler(HandlerThread("BaseEuiccChannelManager").also { it.start() }.looper)
 
     private suspend fun connectSEService(): SEService = suspendCoroutine { cont ->
         handler.post {
@@ -50,6 +48,8 @@ class EuiccChannelManager(private val context: Context) {
          }
     }
 
+    abstract fun tryOpenEuiccChannelPrivileged(uiccInfo: UiccCardInfo, channelInfo: EuiccChannelInfo): EuiccChannel?
+
     private suspend fun tryOpenEuiccChannel(uiccInfo: UiccCardInfo): EuiccChannel? {
         lock.withLock {
             ensureSEService()
@@ -71,17 +71,7 @@ class EuiccChannelManager(private val context: Context) {
                 uiccInfo.isRemovable
             )
 
-            var euiccChannel: EuiccChannel? = null
-
-            if (uiccInfo.isEuicc && !uiccInfo.isRemovable) {
-                Log.d(TAG, "Using TelephonyManager for slot ${uiccInfo.slotIndex}")
-                // TODO: On Tiramisu, we should also connect all available "ports" for MEP support
-                try {
-                    euiccChannel = TelephonyManagerChannel(channelInfo, tm)
-                } catch (e: IllegalArgumentException) {
-                    // Failed
-                }
-            }
+            var euiccChannel: EuiccChannel? = tryOpenEuiccChannelPrivileged(uiccInfo, channelInfo)
 
             if (euiccChannel == null) {
                 try {
@@ -135,19 +125,4 @@ class EuiccChannelManager(private val context: Context) {
         seService?.shutdown()
         seService = null
     }
-
-    // Clean up channels left open in TelephonyManager
-    // due to a (potentially) forced restart
-    // This should be called every time the application is restarted
-    fun closeAllStaleChannels() {
-        for (card in tm.uiccCardsInfo) {
-            for (channel in 0 until 10) {
-                try {
-                    tm.iccCloseLogicalChannelBySlot(card.slotIndex, channel)
-                } catch (_: Exception) {
-                    // We do not care
-                }
-            }
-        }
-    }
 }

+ 2 - 2
app-common/src/main/java/im/angry/openeuicc/ui/EuiccChannelFragmentUtils.kt

@@ -2,8 +2,8 @@ package im.angry.openeuicc.ui
 
 import android.os.Bundle
 import androidx.fragment.app.Fragment
+import im.angry.openeuicc.core.BaseEuiccChannelManager
 import im.angry.openeuicc.core.EuiccChannel
-import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.util.openEuiccApplication
 
 interface EuiccFragmentMarker
@@ -19,7 +19,7 @@ fun <T> newInstanceEuicc(clazz: Class<T>, slotId: Int): T where T: Fragment, T:
 val <T> T.slotId: Int where T: Fragment, T: EuiccFragmentMarker
     get() = requireArguments().getInt("slotId")
 
-val <T> T.euiccChannelManager: EuiccChannelManager where T: Fragment, T: EuiccFragmentMarker
+val <T> T.euiccChannelManager: BaseEuiccChannelManager where T: Fragment, T: EuiccFragmentMarker
     get() = openEuiccApplication.euiccChannelManager
 
 val <T> T.channel: EuiccChannel where T: Fragment, T: EuiccFragmentMarker

+ 2 - 2
app-common/src/main/java/im/angry/openeuicc/ui/MainActivity.kt

@@ -13,7 +13,7 @@ import android.widget.Toast
 import androidx.appcompat.app.AppCompatActivity
 import androidx.lifecycle.lifecycleScope
 import im.angry.openeuicc.common.R
-import im.angry.openeuicc.core.EuiccChannelManager
+import im.angry.openeuicc.core.BaseEuiccChannelManager
 import im.angry.openeuicc.util.*
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -24,7 +24,7 @@ class MainActivity : AppCompatActivity() {
         const val TAG = "MainActivity"
     }
 
-    private lateinit var manager: EuiccChannelManager
+    private lateinit var manager: BaseEuiccChannelManager
 
     private lateinit var spinnerAdapter: ArrayAdapter<String>
     private lateinit var spinner: Spinner

+ 4 - 4
app-common/src/main/java/im/angry/openeuicc/util/UiUtils.kt

@@ -6,12 +6,12 @@ import android.graphics.Rect
 import android.view.ViewGroup
 import androidx.fragment.app.DialogFragment
 import androidx.fragment.app.Fragment
-import im.angry.openeuicc.OpenEuiccApplication
+import im.angry.openeuicc.BaseOpenEuiccApplication
 
-val Activity.openEuiccApplication: OpenEuiccApplication
-    get() = application as OpenEuiccApplication
+val Activity.openEuiccApplication: BaseOpenEuiccApplication
+    get() = application as BaseOpenEuiccApplication
 
-val Fragment.openEuiccApplication: OpenEuiccApplication
+val Fragment.openEuiccApplication: BaseOpenEuiccApplication
     get() = requireActivity().openEuiccApplication
 
 // Source: <https://stackoverflow.com/questions/12478520/how-to-set-dialogfragments-width-and-height>

+ 1 - 1
app/src/main/AndroidManifest.xml

@@ -5,7 +5,7 @@
     package="im.angry.openeuicc">
 
     <application
-        android:name=".OpenEuiccApplication"
+        android:name=".PrivilegedOpenEuiccApplication"
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"

+ 15 - 0
app/src/main/java/im/angry/openeuicc/PrivilegedOpenEuiccApplication.kt

@@ -0,0 +1,15 @@
+package im.angry.openeuicc
+
+import im.angry.openeuicc.core.BaseEuiccChannelManager
+import im.angry.openeuicc.core.PrivilegedEuiccChannelManager
+
+class PrivilegedOpenEuiccApplication: BaseOpenEuiccApplication() {
+    override val euiccChannelManager: BaseEuiccChannelManager by lazy {
+        PrivilegedEuiccChannelManager(this)
+    }
+
+    override fun onCreate() {
+        super.onCreate()
+        (euiccChannelManager as PrivilegedEuiccChannelManager).closeAllStaleChannels()
+    }
+}

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

@@ -0,0 +1,38 @@
+package im.angry.openeuicc.core
+
+import android.content.Context
+import android.telephony.UiccCardInfo
+import android.util.Log
+import im.angry.openeuicc.util.*
+import java.lang.Exception
+import java.lang.IllegalArgumentException
+
+class PrivilegedEuiccChannelManager(context: Context): BaseEuiccChannelManager(context) {
+    override fun tryOpenEuiccChannelPrivileged(uiccInfo: UiccCardInfo, channelInfo: EuiccChannelInfo): EuiccChannel? {
+        if (uiccInfo.isEuicc && !uiccInfo.isRemovable) {
+            Log.d(TAG, "Using TelephonyManager for slot ${uiccInfo.slotIndex}")
+            // TODO: On Tiramisu, we should also connect all available "ports" for MEP support
+            try {
+                return TelephonyManagerChannel(channelInfo, tm)
+            } catch (e: IllegalArgumentException) {
+                // Failed
+            }
+        }
+        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
+    fun closeAllStaleChannels() {
+        for (card in tm.uiccCardsInfo) {
+            for (channel in 0 until 10) {
+                try {
+                    tm.iccCloseLogicalChannelBySlot(card.slotIndex, channel)
+                } catch (_: Exception) {
+                    // We do not care
+                }
+            }
+        }
+    }
+}

+ 0 - 0
app-common/src/main/java/im/angry/openeuicc/core/TelephonyManagerApduInterface.kt → app/src/main/java/im/angry/openeuicc/core/TelephonyManagerApduInterface.kt


+ 2 - 2
app/src/main/java/im/angry/openeuicc/service/OpenEuiccService.kt

@@ -4,13 +4,13 @@ import android.service.euicc.*
 import android.telephony.euicc.DownloadableSubscription
 import android.telephony.euicc.EuiccInfo
 import net.typeblog.lpac_jni.LocalProfileInfo
-import im.angry.openeuicc.OpenEuiccApplication
+import im.angry.openeuicc.BaseOpenEuiccApplication
 import im.angry.openeuicc.core.EuiccChannel
 import im.angry.openeuicc.util.*
 
 class OpenEuiccService : EuiccService() {
     private val openEuiccApplication
-        get() = application as OpenEuiccApplication
+        get() = application as BaseOpenEuiccApplication
 
     private fun findChannel(slotId: Int): EuiccChannel? =
         openEuiccApplication.euiccChannelManager