Compare commits

...

2 commits

Author SHA1 Message Date
aac457f4b5 Don't dismiss DialogFragment's when in background
All checks were successful
/ build-debug (push) Successful in 5m43s
They shall be dismissed automatically. Doing it here may cause
IllegalStateException.

Note that even if they are dismissed, the corresponding tasks will
continue to be executed by EuiccChannelManagerService and will not be
cancelled.
2024-10-20 11:47:27 -04:00
2337ad035d Post a notification to signify task failure from service 2024-10-20 11:44:20 -04:00
6 changed files with 53 additions and 4 deletions

View file

@ -55,6 +55,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
private const val TAG = "EuiccChannelManagerService"
private const val CHANNEL_ID = "tasks"
private const val FOREGROUND_ID = 1000
private const val TASK_FAILURE_ID = 1001
}
inner class LocalBinder : Binder() {
@ -108,7 +109,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
}
}
private suspend fun updateForegroundNotification(title: String, iconRes: Int) {
private fun ensureForegroundTaskNotificationChannel() {
val nm = NotificationManagerCompat.from(this)
if (nm.getNotificationChannelCompat(CHANNEL_ID) == null) {
val channel =
@ -121,7 +122,12 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
.build()
nm.createNotificationChannel(channel)
}
}
private suspend fun updateForegroundNotification(title: String, iconRes: Int) {
ensureForegroundTaskNotificationChannel()
val nm = NotificationManagerCompat.from(this)
val state = foregroundTaskState.value
if (state is ForegroundTaskState.InProgress) {
@ -148,6 +154,18 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
}
}
private fun postForegroundTaskFailureNotification(title: String) {
if (checkSelfPermission(android.Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
return
}
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle(title)
.setSmallIcon(R.drawable.ic_x_black)
.build()
NotificationManagerCompat.from(this).notify(TASK_FAILURE_ID, notification)
}
/**
* Launch a potentially blocking foreground task in this service's lifecycle context.
* This function does not block, but returns a Flow that emits ForegroundTaskState
@ -164,6 +182,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
*/
private fun launchForegroundTask(
title: String,
failureTitle: String,
iconRes: Int,
task: suspend EuiccChannelManagerService.() -> Unit
): Flow<ForegroundTaskState>? {
@ -205,6 +224,10 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
Log.e(TAG, "Foreground task encountered an error")
Log.e(TAG, Log.getStackTraceString(t))
foregroundTaskState.value = ForegroundTaskState.Done(t)
if (isActive) {
postForegroundTaskFailureNotification(failureTitle)
}
} finally {
if (isActive) {
stopSelf()
@ -260,6 +283,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
): Flow<ForegroundTaskState>? =
launchForegroundTask(
getString(R.string.task_profile_download),
getString(R.string.task_profile_download_failure),
R.drawable.ic_task_sim_card_download
) {
euiccChannelManager.beginTrackedOperationBlocking(slotId, portId) {
@ -294,6 +318,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
): Flow<ForegroundTaskState>? =
launchForegroundTask(
getString(R.string.task_profile_rename),
getString(R.string.task_profile_rename_failure),
R.drawable.ic_task_rename
) {
val res = euiccChannelManager.findEuiccChannelByPort(slotId, portId)!!.lpa.setNickname(
@ -313,6 +338,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
): Flow<ForegroundTaskState>? =
launchForegroundTask(
getString(R.string.task_profile_delete),
getString(R.string.task_profile_delete_failure),
R.drawable.ic_task_delete
) {
euiccChannelManager.beginTrackedOperationBlocking(slotId, portId) {
@ -336,6 +362,7 @@ class EuiccChannelManagerService : LifecycleService(), OpenEuiccContextMarker {
): Flow<ForegroundTaskState>? =
launchForegroundTask(
getString(R.string.task_profile_switch),
getString(R.string.task_profile_switch_failure),
R.drawable.ic_task_switch
) {
euiccChannelManager.beginTrackedOperationBlocking(slotId, portId) {

View file

@ -81,7 +81,11 @@ class ProfileDeleteFragment : DialogFragment(), EuiccChannelFragmentMarker {
(parentFragment as EuiccProfilesChangedListener).onEuiccProfilesChanged()
}
dismiss()
try {
dismiss()
} catch (e: IllegalStateException) {
// Ignored
}
}.collect()
}
}

View file

@ -230,7 +230,12 @@ class ProfileDownloadFragment : BaseMaterialDialogFragment(),
if (parentFragment is EuiccProfilesChangedListener) {
(parentFragment as EuiccProfilesChangedListener).onEuiccProfilesChanged()
}
dismiss()
try {
dismiss()
} catch (e: IllegalStateException) {
// Ignored
}
}
}

View file

@ -106,7 +106,11 @@ class ProfileRenameFragment : BaseMaterialDialogFragment(), EuiccChannelFragment
(parentFragment as EuiccProfilesChangedListener).onEuiccProfilesChanged()
}
dismiss()
try {
dismiss()
} catch (e: IllegalStateException) {
// Ignored
}
}
}
}

View file

@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
<path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View file

@ -35,9 +35,13 @@
<string name="task_notification">Long-running Tasks</string>
<string name="task_profile_download">Downloading eSIM profile</string>
<string name="task_profile_download_failure">Failed to download eSIM profile</string>
<string name="task_profile_rename">Renaming eSIM profile</string>
<string name="task_profile_rename_failure">Failed to rename eSIM profile</string>
<string name="task_profile_delete">Deleting eSIM profile</string>
<string name="task_profile_delete_failure">Failed to delete eSIM profile</string>
<string name="task_profile_switch">Switching eSIM profile</string>
<string name="task_profile_switch_failure">Failed to switch eSIM profile</string>
<string name="profile_download">New eSIM</string>
<string name="profile_download_server">Server (RSP / SM-DP+)</string>