Fix race-condition when cancelling current download

This commit is contained in:
Niels van Velzen
2026-08-11 15:55:07 +02:00
committed by Niels van Velzen
parent b2e0658d81
commit 13abdff1cf
3 changed files with 20 additions and 9 deletions
@@ -95,24 +95,26 @@ class DownloadManager(
}
suspend fun cancel(id: Long) = withContext(Dispatchers.IO) {
val download = downloadDao.getDownload(id)
if (download != null) {
DownloadWorker.stop(context)
downloadDao.update(download.copy(status = DownloadStatus.CANCELLED))
DownloadWorker.start(context, appPreferences)
val download = downloadDao.getDownload(id) ?: return@withContext
downloadDao.update(download.copy(status = DownloadStatus.CANCELLED))
if (download.status == DownloadStatus.DOWNLOADING) {
DownloadWorker.restart(context, appPreferences)
}
}
suspend fun delete(id: Long, deleteFiles: Boolean) = withContext(Dispatchers.IO) {
val download = downloadDao.getDownload(id) ?: return@withContext
if (download.status == DownloadStatus.DOWNLOADING) DownloadWorker.stop(context)
downloadDao.delete(id)
if (download.status == DownloadStatus.DOWNLOADING) {
DownloadWorker.restart(context, appPreferences)
}
if (deleteFiles) {
val storageLocation = storageManager.getStorageLocation()
storageLocation?.findFile(download.path)?.delete()
}
downloadDao.delete(id)
}
}
@@ -72,7 +72,11 @@ class DownloadQueue(
notificationProgressCallback.onEnd()
downloadDao.update(downloadWithFiles.download.copy(status = DownloadStatus.DOWNLOADED))
} catch (e: CancellationException) {
downloadDao.update(downloadWithFiles.download.copy(status = DownloadStatus.QUEUED))
// The download could've been canceled by the app, in which case we need to refresh it before making changes
val download = downloadDao.getDownload(downloadWithFiles.download.id)
if (download?.status == DownloadStatus.DOWNLOADING) {
downloadDao.update(download.copy(status = DownloadStatus.QUEUED))
}
throw e
} catch (e: IOException) {
downloadDao.update(downloadWithFiles.download.copy(status = DownloadStatus.QUEUED))
@@ -48,6 +48,11 @@ class DownloadWorker(
WorkManager.getInstance(context).cancelUniqueWork(tag).await()
}
suspend fun restart(context: Context, appPreferences: AppPreferences) {
stop(context)
start(context, appPreferences)
}
suspend fun isActive(context: Context): Boolean = WorkManager.getInstance(context)
.getWorkInfosForUniqueWork(tag)
.await()