Move workers to foreground service context a bit more safely (#10202)

The system will crash the app if the worker that calls setForeground() finished
before the service runner be able to call Service.startForeground(). This edge
case is not handled by WorkManager and there is no way to check if the required
calls are done.

So here we suspend the worker by an arbitrary duration assuming the transition
to foreground service is done by then.
This commit is contained in:
Ivan Iskandar
2023-12-02 23:46:59 +07:00
committed by GitHub
parent dfa5c229b3
commit 24e1b4034e
7 changed files with 41 additions and 41 deletions
@@ -16,11 +16,10 @@ import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
import eu.kanade.tachiyomi.util.system.isOnline
import eu.kanade.tachiyomi.util.system.notificationBuilder
import eu.kanade.tachiyomi.util.system.setForegroundSafely
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import logcat.LogPriority
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.download.service.DownloadPreferences
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -51,21 +50,18 @@ class DownloadJob(context: Context, workerParams: WorkerParameters) : CoroutineW
}
override suspend fun doWork(): Result {
try {
setForeground(getForegroundInfo())
} catch (e: IllegalStateException) {
logcat(LogPriority.ERROR, e) { "Not allowed to set foreground job" }
var active = checkConnectivity() && downloadManager.downloaderStart()
if (!active) {
return Result.failure()
}
var networkCheck = checkConnectivity()
var active = networkCheck
downloadManager.downloaderStart()
setForegroundSafely()
// Keep the worker running when needed
while (active) {
delay(100)
networkCheck = checkConnectivity()
active = !isStopped && networkCheck && downloadManager.isRunning
active = !isStopped && downloadManager.isRunning && checkConnectivity()
}
return Result.success()