浏览代码

EuiccChannelManagerService: stop using blocking variants unnecessarily

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

+ 4 - 4
app-common/src/main/java/im/angry/openeuicc/service/EuiccChannelManagerService.kt

@@ -286,7 +286,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
             getString(R.string.task_profile_download_failure),
             R.drawable.ic_task_sim_card_download
         ) {
-            euiccChannelManager.beginTrackedOperationBlocking(slotId, portId) {
+            euiccChannelManager.beginTrackedOperation(slotId, portId) {
                 val channel = euiccChannelManager.findEuiccChannelByPort(slotId, portId)
                 val res = channel!!.lpa.downloadProfile(
                     smdp,
@@ -341,7 +341,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
             getString(R.string.task_profile_delete_failure),
             R.drawable.ic_task_delete
         ) {
-            euiccChannelManager.beginTrackedOperationBlocking(slotId, portId) {
+            euiccChannelManager.beginTrackedOperation(slotId, portId) {
                 euiccChannelManager.findEuiccChannelByPort(
                     slotId,
                     portId
@@ -365,8 +365,8 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
             getString(R.string.task_profile_switch_failure),
             R.drawable.ic_task_switch
         ) {
-            euiccChannelManager.beginTrackedOperationBlocking(slotId, portId) {
-                val channel = euiccChannelManager.findEuiccChannelByPortBlocking(slotId, portId)!!
+            euiccChannelManager.beginTrackedOperation(slotId, portId) {
+                val channel = euiccChannelManager.findEuiccChannelByPort(slotId, portId)!!
                 val (res, refreshed) =
                     if (!channel.lpa.switchProfile(iccid, enable, refresh = true)) {
                         // Sometimes, we *can* enable or disable the profile, but we cannot

+ 36 - 0
app-common/src/main/java/im/angry/openeuicc/util/LPAUtils.kt

@@ -73,6 +73,42 @@ fun LocalProfileAssistant.disableActiveProfileWithUndo(refreshOnDisable: Boolean
  * should be the concern of op() itself, and this function assumes that when
  * op() returns, the slotId and portId will correspond to a valid channel again.
  */
+suspend inline fun EuiccChannelManager.beginTrackedOperation(
+    slotId: Int,
+    portId: Int,
+    op: () -> Boolean
+) {
+    val latestSeq =
+        findEuiccChannelByPort(slotId, portId)!!.lpa.notifications.firstOrNull()?.seqNumber
+            ?: 0
+    Log.d(TAG, "Latest notification is $latestSeq before operation")
+    if (op()) {
+        Log.d(TAG, "Operation has requested notification handling")
+        try {
+            // Note that the exact instance of "channel" might have changed here if reconnected;
+            // so we MUST use the automatic getter for "channel"
+            findEuiccChannelByPort(
+                slotId,
+                portId
+            )?.lpa?.notifications?.filter { it.seqNumber > latestSeq }?.forEach {
+                Log.d(TAG, "Handling notification $it")
+                findEuiccChannelByPort(
+                    slotId,
+                    portId
+                )?.lpa?.handleNotification(it.seqNumber)
+            }
+        } catch (e: Exception) {
+            // Ignore any error during notification handling
+            e.printStackTrace()
+        }
+    }
+    Log.d(TAG, "Operation complete")
+}
+
+/**
+ * Same as beginTrackedOperation but uses blocking primitives.
+ * TODO: This function needs to be phased out of use.
+ */
 inline fun EuiccChannelManager.beginTrackedOperationBlocking(
     slotId: Int,
     portId: Int,