|
|
@@ -2,6 +2,7 @@ package im.angry.openeuicc.util
|
|
|
|
|
|
import android.util.Log
|
|
|
import im.angry.openeuicc.core.EuiccChannel
|
|
|
+import im.angry.openeuicc.core.EuiccChannelManager
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
import kotlinx.coroutines.runBlocking
|
|
|
import kotlinx.coroutines.withContext
|
|
|
@@ -51,23 +52,39 @@ fun LocalProfileAssistant.disableActiveProfileWithUndo(refreshOnDisable: Boolean
|
|
|
* Begin a "tracked" operation where notifications may be generated by the eSIM
|
|
|
* Automatically handle any newly generated notification during the operation
|
|
|
* if the function "op" returns true.
|
|
|
+ *
|
|
|
+ * This requires the EuiccChannelManager object and a slotId / portId instead of
|
|
|
+ * just an LPA object, because a LPA might become invalid during an operation
|
|
|
+ * that generates notifications. As such, we will end up having to reconnect
|
|
|
+ * when this happens.
|
|
|
+ *
|
|
|
+ * Note that however, if reconnect is required and will not be instant, waiting
|
|
|
+ * 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 fun LocalProfileAssistant.beginTrackedOperation(op: suspend () -> Boolean) =
|
|
|
- withContext(Dispatchers.IO) {
|
|
|
- beginTrackedOperationBlocking { op() }
|
|
|
- }
|
|
|
-
|
|
|
-inline fun LocalProfileAssistant.beginTrackedOperationBlocking(op: () -> Boolean) {
|
|
|
- val latestSeq = notifications.firstOrNull()?.seqNumber ?: 0
|
|
|
+inline fun EuiccChannelManager.beginTrackedOperationBlocking(
|
|
|
+ slotId: Int,
|
|
|
+ portId: Int,
|
|
|
+ op: () -> Boolean
|
|
|
+) {
|
|
|
+ val latestSeq =
|
|
|
+ findEuiccChannelByPortBlocking(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"
|
|
|
- notifications.filter { it.seqNumber > latestSeq }.forEach {
|
|
|
+ findEuiccChannelByPortBlocking(
|
|
|
+ slotId,
|
|
|
+ portId
|
|
|
+ )?.lpa?.notifications?.filter { it.seqNumber > latestSeq }?.forEach {
|
|
|
Log.d(TAG, "Handling notification $it")
|
|
|
- handleNotification(it.seqNumber)
|
|
|
+ findEuiccChannelByPortBlocking(
|
|
|
+ slotId,
|
|
|
+ portId
|
|
|
+ )?.lpa?.handleNotification(it.seqNumber)
|
|
|
}
|
|
|
} catch (e: Exception) {
|
|
|
// Ignore any error during notification handling
|