Fixed: the download notification controls was not working.

* Refactored/cleanup code.
* Added foreground permission in core module so that it can be used in both modules.
This commit is contained in:
MohitMaliFtechiz 2024-11-26 19:43:16 +05:30
parent 1f62caebbe
commit da9528b8ff
10 changed files with 128 additions and 221 deletions

View File

@ -8,9 +8,6 @@
tools:ignore="CoarseFineLocation" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="${permission}" />
<!-- Device with versions >= Pie need this permission -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission
android:name="android.permission.NEARBY_WIFI_DEVICES"
android:usesPermissionFlags="neverForLocation"

View File

@ -23,9 +23,7 @@ import android.app.Service
import android.content.Context
import dagger.Module
import dagger.Provides
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationActionsBroadcastReceiver
import org.kiwix.kiwixmobile.core.qr.GenerateQR
import org.kiwix.kiwixmobile.core.read_aloud.ReadAloudNotificationManger
import org.kiwix.kiwixmobile.di.ServiceScope
import org.kiwix.kiwixmobile.webserver.KiwixServer
import org.kiwix.kiwixmobile.webserver.WebServerHelper
@ -35,12 +33,6 @@ import org.kiwix.kiwixmobile.webserver.wifi_hotspot.IpAddressCallbacks
@Module
class ServiceModule {
@Provides
@ServiceScope
fun providesReadAloudNotificationManager(
notificationManager: NotificationManager,
context: Context
): ReadAloudNotificationManger = ReadAloudNotificationManger(notificationManager, context)
@Provides
@ServiceScope
@ -76,17 +68,4 @@ class ServiceModule {
@Provides
@ServiceScope
fun providesGenerateQr(): GenerateQR = GenerateQR()
@Provides
@ServiceScope
fun providesDownloadNotificationActionsBroadcastReceiverCallback(service: Service):
DownloadNotificationActionsBroadcastReceiver.Callback =
service as DownloadNotificationActionsBroadcastReceiver.Callback
@Provides
@ServiceScope
fun providesDownloadNotificationActionsBroadcastReceiver(
callBack: DownloadNotificationActionsBroadcastReceiver.Callback
): DownloadNotificationActionsBroadcastReceiver =
DownloadNotificationActionsBroadcastReceiver(callBack)
}

View File

@ -16,6 +16,9 @@
<uses-permission
android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<!-- Device with versions >= Pie need this permission -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<queries>
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />

View File

@ -35,8 +35,8 @@ const val CONNECTION_TIMEOUT = 10L
// increase the read and call timeout since the content is 19MB large so it takes
// more time to read on slow internet connection, and due to less read timeout
// the request is canceled.
const val READ_TIMEOUT = 180L
const val CALL_TIMEOUT = 180L
const val READ_TIMEOUT = 300L
const val CALL_TIMEOUT = 300L
const val USER_AGENT = "kiwix-android-version:${BuildConfig.VERSION_CODE}"
const val KIWIX_DOWNLOAD_URL = "https://mirror.download.kiwix.org/"

View File

@ -19,94 +19,82 @@
package org.kiwix.kiwixmobile.core.downloader.downloadManager
import android.app.DownloadManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import androidx.core.content.ContextCompat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
import org.kiwix.kiwixmobile.core.dao.entities.DownloadRoomEntity
import org.kiwix.kiwixmobile.core.downloader.DownloadMonitor
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_CANCEL
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_PAUSE
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_QUERY_DOWNLOAD_STATUS
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_RESUME
import javax.inject.Inject
class DownloadManagerMonitor @Inject constructor(
val downloadRoomDao: DownloadRoomDao,
private val context: Context
) : DownloadMonitor, DownloadManagerBroadcastReceiver.Callback, DownloadMonitorServiceCallback {
) : DownloadMonitor, DownloadManagerBroadcastReceiver.Callback {
private val lock = Any()
private var downloadMonitorService: DownloadMonitorService? = null
private val serviceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
downloadMonitorService =
(binder as? DownloadMonitorService.DownloadMonitorBinder)?.downloadMonitorService?.get()
downloadMonitorService?.registerCallback(this@DownloadManagerMonitor)
CoroutineScope(Dispatchers.IO).launch {
if (downloadRoomDao.downloads().blockingFirst().isNotEmpty()) {
startService()
}
}
}
override fun onServiceDisconnected(name: ComponentName?) {
downloadMonitorService = null
}
}
init {
bindService()
CoroutineScope(Dispatchers.IO).launch {
if (getActiveDownloads().isNotEmpty()) {
startService()
}
}
}
private fun bindService() {
val serviceIntent = Intent(context, DownloadMonitorService::class.java)
context.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE)
}
private suspend fun getActiveDownloads(): List<DownloadRoomEntity> =
downloadRoomDao.downloadRoomEntity().blockingFirst().filter {
it.status != Status.PAUSED && it.status != Status.CANCELLED
}
override fun downloadCompleteOrCancelled(intent: Intent) {
synchronized(lock) {
intent.extras?.let {
val downloadId = it.getLong(DownloadManager.EXTRA_DOWNLOAD_ID, -1L)
if (downloadId != -1L) {
downloadMonitorService?.queryDownloadStatus(downloadId)
context.startService(
getDownloadMonitorIntent(
ACTION_QUERY_DOWNLOAD_STATUS,
downloadId.toInt()
)
)
}
}
}
}
fun startMonitoringDownloads() {
bindService()
startService()
downloadMonitorService?.startMonitoringDownloads()
}
private fun startService() {
ContextCompat.startForegroundService(
context,
Intent(context, DownloadMonitorService::class.java)
)
context.startService(Intent(context, DownloadMonitorService::class.java))
}
fun pauseDownload(downloadId: Long) {
downloadMonitorService?.pauseDownload(downloadId)
context.startService(getDownloadMonitorIntent(ACTION_PAUSE, downloadId.toInt()))
}
fun resumeDownload(downloadId: Long) {
downloadMonitorService?.resumeDownload(downloadId)
context.startService(getDownloadMonitorIntent(ACTION_RESUME, downloadId.toInt()))
}
fun cancelDownload(downloadId: Long) {
downloadMonitorService?.cancelDownload(downloadId)
context.startService(getDownloadMonitorIntent(ACTION_CANCEL, downloadId.toInt()))
}
private fun getDownloadMonitorIntent(action: String, downloadId: Int): Intent =
Intent(context, DownloadMonitorService::class.java).apply {
putExtra(DownloadNotificationManager.NOTIFICATION_ACTION, action)
putExtra(DownloadNotificationManager.EXTRA_DOWNLOAD_ID, downloadId)
}
override fun init() {
// empty method to so class does not get reported unused
}
override fun onServiceDestroyed() {
downloadMonitorService?.registerCallback(null)
context.unbindService(serviceConnection)
downloadMonitorService = null
}
}

View File

@ -41,12 +41,7 @@ class DownloadManagerRequester @Inject constructor(
private val downloadManagerMonitor: DownloadManagerMonitor
) : DownloadRequester {
override fun enqueue(downloadRequest: DownloadRequest): Long =
downloadManager.enqueue(downloadRequest.toDownloadManagerRequest(sharedPreferenceUtil)).also {
Log.e(
"DOWNLOADING_STEP",
"enqueue: ${downloadRequest.toDownloadManagerRequest(sharedPreferenceUtil)}"
)
}
downloadManager.enqueue(downloadRequest.toDownloadManagerRequest(sharedPreferenceUtil))
override fun onDownloadAdded() {
// Start monitoring downloads after enqueuing a new download request.

View File

@ -26,7 +26,6 @@ import android.content.ContentValues
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.os.Binder
import android.os.IBinder
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
@ -35,10 +34,13 @@ import io.reactivex.subjects.PublishSubject
import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.dao.DownloadRoomDao
import org.kiwix.kiwixmobile.core.dao.entities.DownloadRoomEntity
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_CANCEL
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_PAUSE
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_QUERY_DOWNLOAD_STATUS
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_RESUME
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
import org.kiwix.kiwixmobile.core.downloader.model.DownloadState
import org.kiwix.kiwixmobile.core.utils.files.Log
import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@ -59,7 +61,7 @@ const val STATUS_PAUSED_BY_APP = 193
const val COLUMN_CONTROL = "control"
val downloadBaseUri: Uri = Uri.parse("content://downloads/my_downloads")
class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastReceiver.Callback {
class DownloadMonitorService : Service() {
@Inject
lateinit var downloadManager: DownloadManager
@ -73,19 +75,9 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
private var monitoringDisposable: Disposable? = null
private val downloadInfoMap = mutableMapOf<Long, DownloadInfo>()
private val updater = PublishSubject.create<() -> Unit>()
private val downloadMonitorBinder: IBinder = DownloadMonitorBinder(this)
private var downloadMonitorServiceCallback: DownloadMonitorServiceCallback? = null
private var isForeGroundServiceNotification: Boolean = true
private var foreGroundServiceInformation: Pair<Boolean, Int> = true to DEFAULT_INT_VALUE
// @set:Inject
// var downloadNotificationBroadcastReceiver: DownloadNotificationActionsBroadcastReceiver? = null
class DownloadMonitorBinder(downloadMonitorService: DownloadMonitorService) : Binder() {
val downloadMonitorService: WeakReference<DownloadMonitorService> =
WeakReference<DownloadMonitorService>(downloadMonitorService)
}
override fun onBind(intent: Intent?): IBinder = downloadMonitorBinder
override fun onBind(intent: Intent?): IBinder? = null
override fun onCreate() {
CoreApp.coreComponent
@ -96,13 +88,22 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
super.onCreate()
setupUpdater()
startMonitoringDownloads()
// downloadNotificationBroadcastReceiver?.let(this::registerReceiver)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = START_NOT_STICKY
fun registerCallback(downloadMonitorServiceCallback: DownloadMonitorServiceCallback?) {
this.downloadMonitorServiceCallback = downloadMonitorServiceCallback
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val downloadId =
intent?.getIntExtra(DownloadNotificationManager.EXTRA_DOWNLOAD_ID, DEFAULT_INT_VALUE)
?: DEFAULT_INT_VALUE
val notificationAction = intent?.getStringExtra(DownloadNotificationManager.NOTIFICATION_ACTION)
if (downloadId != DEFAULT_INT_VALUE) {
when (notificationAction) {
ACTION_PAUSE -> pauseDownload(downloadId.toLong())
ACTION_RESUME -> resumeDownload(downloadId.toLong())
ACTION_CANCEL -> cancelDownload(downloadId.toLong())
ACTION_QUERY_DOWNLOAD_STATUS -> queryDownloadStatus(downloadId.toLong())
}
}
return START_NOT_STICKY
}
@Suppress("CheckResult")
@ -122,8 +123,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
* when there are no ongoing downloads to avoid unnecessary resource usage.
*/
@Suppress("MagicNumber")
fun startMonitoringDownloads() {
Log.e("DOWNLOADING_STEP", "startMonitoringDownloads:")
private fun startMonitoringDownloads() {
// Check if monitoring is already active. If it is, do nothing.
if (monitoringDisposable?.isDisposed == false) return
monitoringDisposable = Observable.interval(ZERO.toLong(), 5, TimeUnit.SECONDS)
@ -142,7 +142,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
}
}
} catch (ignore: Exception) {
Log.i(
Log.e(
"DOWNLOAD_MONITOR",
"Couldn't get the downloads update. Original exception = $ignore"
)
@ -155,7 +155,6 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
@SuppressLint("Range")
private fun checkDownloads() {
synchronized(lock) {
Log.e("DOWNLOADING_STEP", "checkDownloads: lock")
val query = DownloadManager.Query().setFilterByStatus(
DownloadManager.STATUS_RUNNING or
DownloadManager.STATUS_PAUSED or
@ -163,7 +162,6 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
DownloadManager.STATUS_SUCCESSFUL
)
downloadManager.query(query).use { cursor ->
Log.e("DOWNLOADING_STEP", "checkDownloads:")
if (cursor.moveToFirst()) {
do {
val downloadId = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_ID))
@ -385,10 +383,8 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
) {
synchronized(lock) {
updater.onNext {
Log.e("DOWNLOADING_STEP", "updateDownloadStatus:")
downloadRoomDao.getEntityForDownloadId(downloadId)?.let { downloadEntity ->
if (shouldUpdateDownloadStatus(downloadEntity)) {
Log.e("DOWNLOADING_STEP", "shouldUpdateDownloadStatus:")
val downloadModel = DownloadModel(downloadEntity).apply {
if (shouldUpdateDownloadStatus(status, error, downloadEntity)) {
state = status
@ -406,7 +402,6 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
}
}
downloadRoomDao.update(downloadModel)
Log.e("DOWNLOADING_STEP", "updateNotification: $downloadModel")
updateNotification(downloadModel, downloadEntity.title, downloadEntity.description)
return@let
}
@ -472,14 +467,63 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
private fun cancelNotification(downloadId: Long) {
downloadNotificationManager.cancelNotification(downloadId.toInt())
assignNewForegroundNotification()
}
private fun assignNewForegroundNotification() {
val activeDownloads = getActiveDownloads()
if (activeDownloads.isNotEmpty()) {
// Promote the first active download to foreground
val downloadRoomEntity = activeDownloads.first()
foreGroundServiceInformation =
foreGroundServiceInformation.first to downloadRoomEntity.downloadId.toInt()
val downloadNotificationModel =
getDownloadNotificationModel(
DownloadModel(downloadRoomEntity),
downloadRoomEntity.title,
downloadRoomEntity.description
)
val notification = downloadNotificationManager.createNotification(downloadNotificationModel)
startForeground(foreGroundServiceInformation.second, notification)
} else {
// Stop the service if no active downloads remain
stopMonitoringDownloads()
}
}
private fun getActiveDownloads(): List<DownloadRoomEntity> =
downloadRoomDao.downloadRoomEntity().blockingFirst().filter {
it.status != Status.PAUSED && it.status != Status.CANCELLED
}
private fun updateNotification(
downloadModel: DownloadModel,
title: String,
description: String?
) {
val downloadNotificationModel = DownloadNotificationModel(
val downloadNotificationModel = getDownloadNotificationModel(downloadModel, title, description)
val notification = downloadNotificationManager.createNotification(downloadNotificationModel)
if (foreGroundServiceInformation.first) {
startForeground(downloadModel.downloadId.toInt(), notification)
foreGroundServiceInformation = false to downloadModel.downloadId.toInt()
} else {
downloadNotificationManager.updateNotification(
downloadNotificationModel,
object : AssignNewForegroundServiceNotification {
override fun assignNewForegroundServiceNotification(downloadId: Long) {
cancelNotification(downloadId)
}
}
)
}
}
private fun getDownloadNotificationModel(
downloadModel: DownloadModel,
title: String,
description: String?
): DownloadNotificationModel =
DownloadNotificationModel(
downloadId = downloadModel.downloadId.toInt(),
status = downloadModel.state,
progress = downloadModel.progress,
@ -493,28 +537,8 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
downloadModel.book.url
).toReadableState(this).toString()
)
val notification = downloadNotificationManager.createNotification(downloadNotificationModel)
if (isForeGroundServiceNotification) {
startForeground(downloadModel.downloadId.toInt(), notification)
isForeGroundServiceNotification = false
} else {
downloadNotificationManager.updateNotification(downloadNotificationModel)
}
}
override fun pauseDownloads(downloadId: Long) {
pauseDownload(downloadId)
}
override fun resumeDownloads(downloadId: Long) {
resumeDownload(downloadId)
}
override fun cancelDownloads(downloadId: Long) {
cancelNotification(downloadId)
}
fun pauseDownload(downloadId: Long) {
private fun pauseDownload(downloadId: Long) {
synchronized(lock) {
updater.onNext {
if (pauseResumeDownloadInDownloadManagerContentResolver(
@ -529,7 +553,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
}
}
fun resumeDownload(downloadId: Long) {
private fun resumeDownload(downloadId: Long) {
synchronized(lock) {
updater.onNext {
if (pauseResumeDownloadInDownloadManagerContentResolver(
@ -544,7 +568,7 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
}
}
fun cancelDownload(downloadId: Long) {
private fun cancelDownload(downloadId: Long) {
synchronized(lock) {
downloadManager.remove(downloadId)
handleCancelledDownload(downloadId)
@ -577,27 +601,23 @@ class DownloadMonitorService : Service(), DownloadNotificationActionsBroadcastRe
downloadRoomEntity.status != Status.COMPLETED
override fun onDestroy() {
// downloadNotificationBroadcastReceiver?.let(::unregisterReceiver)
monitoringDisposable?.dispose()
super.onDestroy()
}
private fun stopMonitoringDownloads() {
Log.e("DOWNLOADING_STEP", "stopMonitoringDownloads: ")
isForeGroundServiceNotification = true
foreGroundServiceInformation = true to DEFAULT_INT_VALUE
monitoringDisposable?.dispose()
downloadMonitorServiceCallback?.onServiceDestroyed()
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
}
companion object {
private const val CHANNEL_ID = "download_monitor_channel"
private const val ONGOING_NOTIFICATION_ID = 1
}
}
data class DownloadInfo(
var startTime: Long,
var initialBytesDownloaded: Int
)
interface AssignNewForegroundServiceNotification {
fun assignNewForegroundServiceNotification(downloadId: Long)
}

View File

@ -1,23 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2024 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.downloader.downloadManager
interface DownloadMonitorServiceCallback {
fun onServiceDestroyed()
}

View File

@ -1,56 +0,0 @@
/*
* Kiwix Android
* Copyright (c) 2024 Kiwix <android.kiwix.org>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.kiwix.kiwixmobile.core.downloader.downloadManager
import android.content.Context
import android.content.Intent
import org.kiwix.kiwixmobile.core.base.BaseBroadcastReceiver
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_CANCEL
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_PAUSE
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.ACTION_RESUME
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.EXTRA_DOWNLOAD_ID
import org.kiwix.kiwixmobile.core.downloader.downloadManager.DownloadNotificationManager.Companion.NOTIFICATION_ACTION
import javax.inject.Inject
const val DOWNLOAD_NOTIFICATION_ACTION = "org.kiwix.kiwixmobile.download_notification_action"
class DownloadNotificationActionsBroadcastReceiver @Inject constructor(
private val callback: Callback
) :
BaseBroadcastReceiver() {
override val action: String = DOWNLOAD_NOTIFICATION_ACTION
override fun onIntentWithActionReceived(context: Context, intent: Intent) {
val downloadId = intent.getIntExtra(EXTRA_DOWNLOAD_ID, -1)
val notificationAction = intent.getStringExtra(NOTIFICATION_ACTION)
if (downloadId != -1) {
when (notificationAction) {
ACTION_PAUSE -> callback.pauseDownloads(downloadId.toLong())
ACTION_RESUME -> callback.resumeDownloads(downloadId.toLong())
ACTION_CANCEL -> callback.cancelDownloads(downloadId.toLong())
}
}
}
interface Callback {
fun pauseDownloads(downloadId: Long)
fun resumeDownloads(downloadId: Long)
fun cancelDownloads(downloadId: Long)
}
}

View File

@ -54,7 +54,8 @@ class DownloadNotificationManager @Inject constructor(
}
fun updateNotification(
downloadNotificationModel: DownloadNotificationModel
downloadNotificationModel: DownloadNotificationModel,
assignNewForegroundServiceNotification: AssignNewForegroundServiceNotification
) {
synchronized(downloadNotificationsBuilderMap) {
if (shouldUpdateNotification(downloadNotificationModel)) {
@ -64,7 +65,9 @@ class DownloadNotificationManager @Inject constructor(
)
} else {
// the download is cancelled/paused so remove the notification.
cancelNotification(downloadNotificationModel.downloadId)
assignNewForegroundServiceNotification.assignNewForegroundServiceNotification(
downloadNotificationModel.downloadId.toLong()
)
}
}
}
@ -191,16 +194,16 @@ class DownloadNotificationManager @Inject constructor(
}
private fun getActionPendingIntent(action: String, downloadId: Int): PendingIntent {
val intent =
Intent(DOWNLOAD_NOTIFICATION_ACTION).apply {
val pendingIntent =
Intent(context, DownloadMonitorService::class.java).apply {
putExtra(NOTIFICATION_ACTION, action)
putExtra(EXTRA_DOWNLOAD_ID, downloadId)
}
val requestCode = downloadId + action.hashCode()
return PendingIntent.getBroadcast(
return PendingIntent.getService(
context,
requestCode,
intent,
pendingIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
}
@ -250,6 +253,7 @@ class DownloadNotificationManager @Inject constructor(
const val ACTION_PAUSE = "action_pause"
const val ACTION_RESUME = "action_resume"
const val ACTION_CANCEL = "action_cancel"
const val ACTION_QUERY_DOWNLOAD_STATUS = "action_query_download_status"
const val EXTRA_DOWNLOAD_ID = "extra_download_id"
}
}