Compare commits
2 commits
8de0d86895
...
f71da0e4ff
Author | SHA1 | Date | |
---|---|---|---|
f71da0e4ff | |||
fe1319537a |
4 changed files with 27 additions and 1 deletions
|
@ -16,8 +16,10 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.onCompletion
|
import kotlinx.coroutines.flow.onCompletion
|
||||||
|
import kotlinx.coroutines.flow.takeWhile
|
||||||
import kotlinx.coroutines.flow.transformWhile
|
import kotlinx.coroutines.flow.transformWhile
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -129,9 +131,13 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
|
||||||
/**
|
/**
|
||||||
* Launch a potentially blocking foreground task in this service's lifecycle context.
|
* Launch a potentially blocking foreground task in this service's lifecycle context.
|
||||||
* This function does not block, but returns a Flow that emits ForegroundTaskState
|
* This function does not block, but returns a Flow that emits ForegroundTaskState
|
||||||
* updates associated with this task.
|
* updates associated with this task. The last update the returned flow will emit is
|
||||||
|
* always ForegroundTaskState.Done.
|
||||||
|
*
|
||||||
* The task closure is expected to update foregroundTaskState whenever appropriate.
|
* The task closure is expected to update foregroundTaskState whenever appropriate.
|
||||||
* If a foreground task is already running, this function returns null.
|
* If a foreground task is already running, this function returns null.
|
||||||
|
*
|
||||||
|
* The function will set the state back to Idle once it sees ForegroundTaskState.Done.
|
||||||
*/
|
*/
|
||||||
private fun launchForegroundTask(
|
private fun launchForegroundTask(
|
||||||
title: String,
|
title: String,
|
||||||
|
@ -176,6 +182,9 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
|
||||||
|
|
||||||
// We should be the only task running, so we can subscribe to foregroundTaskState
|
// We should be the only task running, so we can subscribe to foregroundTaskState
|
||||||
// until we encounter ForegroundTaskState.Done.
|
// until we encounter ForegroundTaskState.Done.
|
||||||
|
// Then, we complete the returned flow, but we also set the state back to Idle.
|
||||||
|
// The state update back to Idle won't show up in the returned stream, because
|
||||||
|
// it has been completed by that point.
|
||||||
return foregroundTaskState.transformWhile {
|
return foregroundTaskState.transformWhile {
|
||||||
// Also update our notification when we see an update
|
// Also update our notification when we see an update
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
@ -186,6 +195,14 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
|
||||||
}.onCompletion { foregroundTaskState.value = ForegroundTaskState.Idle }
|
}.onCompletion { foregroundTaskState.value = ForegroundTaskState.Idle }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isForegroundTaskRunning: Boolean
|
||||||
|
get() = foregroundTaskState.value != ForegroundTaskState.Idle
|
||||||
|
|
||||||
|
suspend fun waitForForegroundTask() {
|
||||||
|
foregroundTaskState.takeWhile { it != ForegroundTaskState.Idle }
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fun launchProfileDownloadTask(
|
fun launchProfileDownloadTask(
|
||||||
slotId: Int,
|
slotId: Int,
|
||||||
portId: Int,
|
portId: Int,
|
||||||
|
|
|
@ -155,6 +155,7 @@ open class EuiccManagementFragment : Fragment(), EuiccProfilesChangedListener,
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
ensureEuiccChannelManager()
|
ensureEuiccChannelManager()
|
||||||
|
euiccChannelManagerService.waitForForegroundTask()
|
||||||
|
|
||||||
if (!this@EuiccManagementFragment::disableSafeguardFlow.isInitialized) {
|
if (!this@EuiccManagementFragment::disableSafeguardFlow.isInitialized) {
|
||||||
disableSafeguardFlow =
|
disableSafeguardFlow =
|
||||||
|
|
|
@ -134,6 +134,8 @@ open class MainActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
|
||||||
loadingProgress.visibility = View.VISIBLE
|
loadingProgress.visibility = View.VISIBLE
|
||||||
viewPager.visibility = View.GONE
|
viewPager.visibility = View.GONE
|
||||||
tabs.visibility = View.GONE
|
tabs.visibility = View.GONE
|
||||||
|
// Prevent concurrent access with any running foreground task
|
||||||
|
euiccChannelManagerService.waitForForegroundTask()
|
||||||
|
|
||||||
val knownChannels = withContext(Dispatchers.IO) {
|
val knownChannels = withContext(Dispatchers.IO) {
|
||||||
euiccChannelManager.enumerateEuiccChannels().onEach {
|
euiccChannelManager.enumerateEuiccChannels().onEach {
|
||||||
|
|
|
@ -160,6 +160,12 @@ class ProfileDownloadFragment : BaseMaterialDialogFragment(),
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
ensureEuiccChannelManager()
|
ensureEuiccChannelManager()
|
||||||
|
if (euiccChannelManagerService.isForegroundTaskRunning) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch remaining NVRAM
|
// Fetch remaining NVRAM
|
||||||
val str = channel.lpa.euiccInfo2?.freeNvram?.also {
|
val str = channel.lpa.euiccInfo2?.freeNvram?.also {
|
||||||
|
|
Loading…
Add table
Reference in a new issue