Compare commits

..

3 commits

Author SHA1 Message Date
7197501cca ProfileDownloadFragment: Stop catching all exceptions
Some checks failed
/ build-debug (push) Failing after 37s
..instead, use the error value returned in the foreground task result.

Catching all exceptions will result in cancellation being ignored when
the fragment is destroyed.
2024-10-19 21:13:07 -04:00
4709b6994f Don't call stopSelf() if the coroutine is cancelled 2024-10-19 19:14:14 -04:00
349c8179b0 Force foreground tasks to always complete (i.e. not cancelled) 2024-10-19 19:09:35 -04:00
2 changed files with 20 additions and 12 deletions

View file

@ -14,6 +14,7 @@ import im.angry.openeuicc.common.R
import im.angry.openeuicc.core.EuiccChannelManager import im.angry.openeuicc.core.EuiccChannelManager
import im.angry.openeuicc.util.* import im.angry.openeuicc.util.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
@ -24,6 +25,7 @@ import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.flow.transformWhile import kotlinx.coroutines.flow.transformWhile
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
@ -194,7 +196,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
updateForegroundNotification(title, iconRes) updateForegroundNotification(title, iconRes)
try { try {
withContext(Dispatchers.IO) { withContext(Dispatchers.IO + NonCancellable) { // Any LPA-related task must always complete
this@EuiccChannelManagerService.task() this@EuiccChannelManagerService.task()
} }
// This update will be sent by the subscriber (as shown below) // This update will be sent by the subscriber (as shown below)
@ -204,7 +206,9 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
Log.e(TAG, Log.getStackTraceString(t)) Log.e(TAG, Log.getStackTraceString(t))
foregroundTaskState.value = ForegroundTaskState.Done(t) foregroundTaskState.value = ForegroundTaskState.Done(t)
} finally { } finally {
stopSelf() if (isActive) {
stopSelf()
}
} }
} }

View file

@ -215,18 +215,22 @@ class ProfileDownloadFragment : BaseMaterialDialogFragment(),
lifecycleScope.launch { lifecycleScope.launch {
ensureEuiccChannelManager() ensureEuiccChannelManager()
euiccChannelManagerService.waitForForegroundTask() euiccChannelManagerService.waitForForegroundTask()
try { val res = doDownloadProfile(server, code, confirmationCode, imei)
doDownloadProfile(server, code, confirmationCode, imei)
} catch (e: Exception) { if (res == null || res.error != null) {
Log.d(TAG, "Error downloading profile") Log.d(TAG, "Error downloading profile")
Log.d(TAG, Log.getStackTraceString(e))
Toast.makeText(context, R.string.profile_download_failed, Toast.LENGTH_LONG).show() if (res?.error != null) {
} finally { Log.d(TAG, Log.getStackTraceString(res.error))
if (parentFragment is EuiccProfilesChangedListener) {
(parentFragment as EuiccProfilesChangedListener).onEuiccProfilesChanged()
} }
dismiss()
Toast.makeText(requireContext(), R.string.profile_download_failed, Toast.LENGTH_LONG).show()
} }
if (parentFragment is EuiccProfilesChangedListener) {
(parentFragment as EuiccProfilesChangedListener).onEuiccProfilesChanged()
}
dismiss()
} }
} }
@ -254,7 +258,7 @@ class ProfileDownloadFragment : BaseMaterialDialogFragment(),
} }
}.last() }.last()
(res as? EuiccChannelManagerService.ForegroundTaskState.Done)?.error?.let { throw it } res as? EuiccChannelManagerService.ForegroundTaskState.Done
} }
override fun onDismiss(dialog: DialogInterface) { override fun onDismiss(dialog: DialogInterface) {