Skip to content

Commit 8dc618c

Browse files
committed
Notify on background work cancellation
Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
1 parent ecce23a commit 8dc618c

1 file changed

Lines changed: 56 additions & 1 deletion

File tree

app/src/main/java/at/bitfire/icsdroid/BaseSyncWorker.kt

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44

55
package at.bitfire.icsdroid
66

7+
import android.app.PendingIntent
78
import android.content.ContentProviderClient
89
import android.content.ContentUris
910
import android.content.Context
11+
import android.content.Intent
12+
import android.os.Build
1013
import android.os.DeadObjectException
1114
import android.util.Log
15+
import androidx.core.app.NotificationCompat
1216
import androidx.work.CoroutineWorker
1317
import androidx.work.WorkerParameters
1418
import at.bitfire.ical4android.AndroidCalendar
@@ -17,10 +21,13 @@ import at.bitfire.icsdroid.calendar.LocalCalendar
1721
import at.bitfire.icsdroid.db.AppDatabase
1822
import at.bitfire.icsdroid.db.entity.Subscription
1923
import at.bitfire.icsdroid.ui.NotificationUtils
24+
import kotlinx.coroutines.currentCoroutineContext
25+
import kotlinx.coroutines.job
2026
import javax.inject.Inject
27+
import kotlin.coroutines.cancellation.CancellationException
2128

2229
abstract class BaseSyncWorker(
23-
context: Context,
30+
val context: Context,
2431
workerParams: WorkerParameters
2532
) : CoroutineWorker(context, workerParams) {
2633

@@ -42,6 +49,20 @@ abstract class BaseSyncWorker(
4249
private var forceReSync: Boolean = false
4350

4451
override suspend fun doWork(): Result {
52+
if (Build.VERSION.SDK_INT >= 31) {
53+
// Read reason from previous stop
54+
Log.d(Constants.TAG, "Previous worker stop reason: $stopReason")
55+
56+
// Observe cancellation
57+
currentCoroutineContext().job.invokeOnCompletion { e ->
58+
if (e is CancellationException) {
59+
Log.e(Constants.TAG, "Worker cancelled with reason: $stopReason")
60+
notifyError(context, e)
61+
}
62+
}
63+
}
64+
65+
// Check whether we should force a complete sync
4566
forceReSync = inputData.getBoolean(FORCE_RESYNC, false)
4667

4768
provider = try {
@@ -144,4 +165,38 @@ abstract class BaseSyncWorker(
144165
calendar.delete()
145166
}
146167
}
168+
169+
170+
/**
171+
* Sunik's Debug-Build only
172+
*/
173+
private fun notifyError(context: Context, exception: Exception?) {
174+
val exception = exception ?: return
175+
val message = exception.localizedMessage ?: exception.message ?: exception.toString()
176+
val errorIntent = Intent(context, MainActivity::class.java).apply {
177+
putExtra(MainActivity.EXTRA_ERROR_MESSAGE, message)
178+
putExtra(MainActivity.EXTRA_THROWABLE, exception)
179+
}
180+
181+
val notificationManager = NotificationUtils.createChannels(context)
182+
val notification = NotificationCompat.Builder(context, NotificationUtils.CHANNEL_SYNC)
183+
.setSmallIcon(R.drawable.ic_sync_problem_white)
184+
.setCategory(NotificationCompat.CATEGORY_ERROR)
185+
.setGroup(context.getString(R.string.app_name))
186+
.setContentTitle(context.getString(R.string.sync_error_title))
187+
.setContentText(message)
188+
.setAutoCancel(true)
189+
.setWhen(System.currentTimeMillis())
190+
.setOnlyAlertOnce(true)
191+
.setContentIntent(
192+
PendingIntent.getActivity(
193+
context,
194+
0,
195+
errorIntent,
196+
PendingIntent.FLAG_UPDATE_CURRENT + PendingIntent.FLAG_IMMUTABLE
197+
)
198+
)
199+
notificationManager.notify(9999999, notification.build())
200+
}
201+
147202
}

0 commit comments

Comments
 (0)