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