Browse Source

Make foreground tasks block UI reloads

Peter Cai 1 year ago
parent
commit
fe1319537a

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

@@ -16,8 +16,10 @@ import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.onCompletion
+import kotlinx.coroutines.flow.takeWhile
 import kotlinx.coroutines.flow.transformWhile
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
@@ -186,6 +188,14 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
         }.onCompletion { foregroundTaskState.value = ForegroundTaskState.Idle }
     }
 
+    val isForegroundTaskRunning: Boolean
+        get() = foregroundTaskState.value != ForegroundTaskState.Idle
+
+    suspend fun waitForForegroundTask() {
+        foregroundTaskState.takeWhile { it != ForegroundTaskState.Idle }
+            .collect()
+    }
+
     fun launchProfileDownloadTask(
         slotId: Int,
         portId: Int,

+ 1 - 0
app-common/src/main/java/im/angry/openeuicc/ui/EuiccManagementFragment.kt

@@ -155,6 +155,7 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
 
         lifecycleScope.launch {
             ensureEuiccChannelManager()
+            euiccChannelManagerService.waitForForegroundTask()
 
             if (!this@EuiccManagementFragment::disableSafeguardFlow.isInitialized) {
                 disableSafeguardFlow =

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

@@ -134,6 +134,8 @@ open class MainActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
         loadingProgress.visibility = View.VISIBLE
         viewPager.visibility = View.GONE
         tabs.visibility = View.GONE
+        // Prevent concurrent access with any running foreground task
+        euiccChannelManagerService.waitForForegroundTask()
 
         val knownChannels = withContext(Dispatchers.IO) {
             euiccChannelManager.enumerateEuiccChannels().onEach {

+ 6 - 0
app-common/src/main/java/im/angry/openeuicc/ui/ProfileDownloadFragment.kt

@@ -160,6 +160,12 @@ class ProfileDownloadFragment : BaseMaterialDialogFragment(),
 
         lifecycleScope.launch(Dispatchers.IO) {
             ensureEuiccChannelManager()
+            if (euiccChannelManagerService.isForegroundTaskRunning) {
+                withContext(Dispatchers.Main) {
+                    dismiss()
+                }
+                return@launch
+            }
 
             // Fetch remaining NVRAM
             val str = channel.lpa.euiccInfo2?.freeNvram?.also {