From e3c261dd9ee9b46cb055e61e3035e732a6208ad9 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Thu, 27 Feb 2025 20:55:14 +0530 Subject: [PATCH] Fixed: Duplicate download completed notifications showing. * Two notifications were shown for a completed download when the app was in the background, the download was about to complete, and the app was then opened. * This occurred because `DownloadMonitorService` pushed a download complete notification before detaching, while the app's lifecycle triggered Fetch to push another notification for the same completed download. * The fix ensures that any previously completed notification is removed before showing a new one. --- .../downloadManager/DownloadMonitorService.kt | 8 +++++-- .../FetchDownloadNotificationManager.kt | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt index a52b9fbb9..bb8e750e7 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/DownloadMonitorService.kt @@ -48,6 +48,8 @@ import org.kiwix.kiwixmobile.core.main.CoreMainActivity import org.kiwix.kiwixmobile.core.utils.DOWNLOAD_NOTIFICATION_CHANNEL_ID import javax.inject.Inject +const val THIRTY_TREE = 33 + class DownloadMonitorService : Service() { private val updater = PublishSubject.create<() -> Unit>() private var updaterDisposable: Disposable? = null @@ -265,7 +267,6 @@ class DownloadMonitorService : Service() { } } - @Suppress("MagicNumber") private fun showDownloadCompletedNotification(download: Download) { downloadNotificationChannel() val notificationBuilder = getNotificationBuilder(download.id) @@ -287,7 +288,10 @@ class DownloadMonitorService : Service() { // notification. If we use the same ID, changing the foreground notification for another // ongoing download cancels the previous notification for that id, preventing the download // complete notification from being displayed. - val downloadCompleteNotificationId = download.id + 33 + val downloadCompleteNotificationId = download.id + THIRTY_TREE + // Cancel the complete download notification if already shown due to the application's + // lifecycle fetch. See #4237 for more details. + cancelNotificationForId(download.id - THIRTY_TREE) notificationManager.notify(downloadCompleteNotificationId, notificationBuilder.build()) } diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/FetchDownloadNotificationManager.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/FetchDownloadNotificationManager.kt index e4da6d4b8..073078480 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/FetchDownloadNotificationManager.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/downloader/downloadManager/FetchDownloadNotificationManager.kt @@ -181,6 +181,28 @@ class FetchDownloadNotificationManager @Inject constructor( else -> notificationBuilder.setTimeoutAfter(DEFAULT_NOTIFICATION_TIMEOUT_AFTER_RESET) } notificationCustomisation(downloadNotification, notificationBuilder, context) + // Remove the already shown notification if any, because fetch now pushes a + // download complete notification. + removeNotificationIfAlreadyShowingForCompletedDownload(downloadNotification) + } + + /** + * We are adding 33 to the groupId (which is the download ID) because the download + * complete notification is shown by DownloadMonitorService. If the application resumes + * just before the download completes, Fetch in the application might also push a + * download complete notification. + * + * To avoid duplicate notifications, we clear the previous notification if it is already shown. + * See #4237 for more information. + * + * @see DownloadMonitorService.showDownloadCompletedNotification + */ + private fun removeNotificationIfAlreadyShowingForCompletedDownload( + downloadNotification: DownloadNotification + ) { + if (downloadNotification.isCompleted) { + downloadNotificationManager.cancel(downloadNotification.groupId + THIRTY_TREE) + } } @SuppressLint("UnspecifiedImmutableFlag")