ソースを参照

Refresh system cached Euicc profile info every time LUI is started

Peter Cai 3 年 前
コミット
67d03a0696

+ 5 - 0
app/src/main/java/im/angry/openeuicc/OpenEuiccApplication.kt

@@ -1,6 +1,7 @@
 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.util.*
@@ -15,6 +16,10 @@ class OpenEuiccApplication : Application() {
         EuiccChannelManager(this)
     }
 
+    val subscriptionManager by lazy {
+        getSystemService(SubscriptionManager::class.java)!!
+    }
+
     override fun onCreate() {
         super.onCreate()
         // Clean up channels left open in TelephonyManager

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

@@ -9,6 +9,7 @@ interface EuiccChannelStateManager {
 
 data class EuiccChannel(
     val slotId: Int,
+    val cardId: Int,
     val name: String,
     val lpa: LocalProfileAssistant,
     val stateManager: EuiccChannelStateManager

+ 8 - 4
app/src/main/java/im/angry/openeuicc/core/EuiccChannelManager.kt

@@ -56,10 +56,10 @@ class EuiccChannelManager(private val context: Context) {
             }
         }
 
-        val shouldTryTelephonyManager =
+        val (shouldTryTelephonyManager, cardId) =
             tm.uiccCardsInfo.find { it.slotIndex == slotId }?.let {
-                it.isEuicc && !it.isRemovable
-            } ?: false
+                Pair(it.isEuicc && !it.isRemovable, it.cardId)
+            } ?: Pair(false, 0)
 
         var apduChannel: ApduChannel? = null
         var stateManager: EuiccChannelStateManager? = null
@@ -81,7 +81,11 @@ class EuiccChannelManager(private val context: Context) {
                 } ?: return null
         }
 
-        val channel = EuiccChannel(slotId, "SIM $slotId", LocalProfileAssistantImpl(apduChannel), stateManager!!)
+        val channel = EuiccChannel(
+            slotId, cardId,
+            "SIM $slotId",
+            LocalProfileAssistantImpl(apduChannel),
+            stateManager!!)
         channels.add(channel)
         return channel
     }

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

@@ -15,9 +15,7 @@ import androidx.lifecycle.lifecycleScope
 import im.angry.openeuicc.R
 import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.databinding.ActivityMainBinding
-import im.angry.openeuicc.util.dsdsEnabled
-import im.angry.openeuicc.util.openEuiccApplication
-import im.angry.openeuicc.util.supportsDSDS
+import im.angry.openeuicc.util.*
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
@@ -99,6 +97,7 @@ class MainActivity : AppCompatActivity() {
             manager.knownChannels.forEach {
                 Log.d(TAG, it.name)
                 Log.d(TAG, it.lpa.eid)
+                openEuiccApplication.subscriptionManager.tryRefreshCachedEuiccInfo(it.cardId)
             }
         }
 

+ 21 - 1
app/src/main/java/im/angry/openeuicc/util/TelephonyUtils.kt

@@ -1,7 +1,9 @@
 package im.angry.openeuicc.util
 
 import android.telephony.IccOpenLogicalChannelResponse
+import android.telephony.SubscriptionManager
 import android.telephony.TelephonyManager
+import java.lang.Exception
 import java.lang.reflect.Method
 
 val TelephonyManager.supportsDSDS: Boolean
@@ -13,6 +15,16 @@ var TelephonyManager.dsdsEnabled: Boolean
         switchMultiSimConfig(if (value) { 2 } else {1})
     }
 
+fun SubscriptionManager.tryRefreshCachedEuiccInfo(cardId: Int) {
+    if (cardId != 0) {
+        try {
+            requestEmbeddedSubscriptionInfoListRefresh(cardId)
+        } catch (e: Exception) {
+            // Ignore
+        }
+    }
+}
+
 // Hidden APIs via reflection to enable building without AOSP source tree
 private val iccOpenLogicalChannelBySlot: Method by lazy {
     TelephonyManager::class.java.getMethod(
@@ -48,4 +60,12 @@ fun TelephonyManager.iccTransmitApduLogicalChannelBySlot(
 ): String? =
     iccTransmitApduLogicalChannelBySlot.invoke(
         this, slotId, channel, cla, instruction, p1, p2, p3, data
-    ) as String?
+    ) as String?
+
+private val requestEmbeddedSubscriptionInfoListRefresh: Method by lazy {
+    SubscriptionManager::class.java.getMethod("requestEmbeddedSubscriptionInfoListRefresh", Int::class.java)
+}
+
+fun SubscriptionManager.requestEmbeddedSubscriptionInfoListRefresh(cardId: Int): Unit {
+    requestEmbeddedSubscriptionInfoListRefresh.invoke(this, cardId)
+}