Make DownloadManager the sole entry point for DownloadService (#9140)

* Rename functions for DownloadService internal use

* Call DownloadService.start via DownloadManager

* Inline DownloadService.stop into pauseDownloads

* Inline DownloadService.stop into clearQueue

NotificationReceiver will now also stop the DownloadService when
receiving ACTION_CLEAR_DOWNLOADS.

* Provide DownloadService.isRunning via DownloadManager
This commit is contained in:
Two-Ai 2023-02-24 22:07:30 -05:00 committed by GitHub
parent 7ec87e76db
commit 86b9262a7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 34 additions and 44 deletions

View file

@ -48,22 +48,18 @@ class DownloadManager(
val queue: DownloadQueue val queue: DownloadQueue
get() = downloader.queue get() = downloader.queue
/** // For use by DownloadService only
* Tells the downloader to begin downloads. fun downloaderStart() = downloader.start()
* fun downloaderStop(reason: String? = null) = downloader.stop(reason)
* @return true if it's started, false otherwise (empty queue).
*/ val isDownloaderRunning
fun startDownloads(): Boolean { get() = DownloadService.isRunning
return downloader.start()
}
/** /**
* Tells the downloader to stop downloads. * Tells the downloader to begin downloads.
*
* @param reason an optional reason for being stopped, used to notify the user.
*/ */
fun stopDownloads(reason: String? = null) { fun startDownloads() {
downloader.stop(reason) DownloadService.start(context)
} }
/** /**
@ -71,6 +67,7 @@ class DownloadManager(
*/ */
fun pauseDownloads() { fun pauseDownloads() {
downloader.pause() downloader.pause()
DownloadService.stop(context)
} }
/** /**
@ -78,6 +75,7 @@ class DownloadManager(
*/ */
fun clearQueue() { fun clearQueue() {
downloader.clearQueue() downloader.clearQueue()
DownloadService.stop(context)
} }
/** /**

View file

@ -95,7 +95,7 @@ class DownloadService : Service() {
override fun onDestroy() { override fun onDestroy() {
scope.cancel() scope.cancel()
_isRunning.value = false _isRunning.value = false
downloadManager.stopDownloads() downloadManager.downloaderStop()
if (wakeLock.isHeld) { if (wakeLock.isHeld) {
wakeLock.release() wakeLock.release()
} }
@ -111,8 +111,8 @@ class DownloadService : Service() {
return null return null
} }
private fun stopDownloads(@StringRes string: Int) { private fun downloaderStop(@StringRes string: Int) {
downloadManager.stopDownloads(getString(string)) downloadManager.downloaderStop(getString(string))
} }
private fun listenNetworkChanges() { private fun listenNetworkChanges() {
@ -122,13 +122,13 @@ class DownloadService : Service() {
withUIContext { withUIContext {
if (isOnline()) { if (isOnline()) {
if (downloadPreferences.downloadOnlyOverWifi().get() && !isConnectedToWifi()) { if (downloadPreferences.downloadOnlyOverWifi().get() && !isConnectedToWifi()) {
stopDownloads(R.string.download_notifier_text_only_wifi) downloaderStop(R.string.download_notifier_text_only_wifi)
} else { } else {
val started = downloadManager.startDownloads() val started = downloadManager.downloaderStart()
if (!started) stopSelf() if (!started) stopSelf()
} }
} else { } else {
stopDownloads(R.string.download_notifier_no_network) downloaderStop(R.string.download_notifier_no_network)
} }
} }
} }

View file

@ -27,7 +27,6 @@ import eu.kanade.domain.track.model.toDomainTrack
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.DEVICE_BATTERY_NOT_LOW import eu.kanade.tachiyomi.data.preference.DEVICE_BATTERY_NOT_LOW
import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING import eu.kanade.tachiyomi.data.preference.DEVICE_CHARGING
@ -309,7 +308,7 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
if (newUpdates.isNotEmpty()) { if (newUpdates.isNotEmpty()) {
notifier.showUpdateNotifications(newUpdates) notifier.showUpdateNotifications(newUpdates)
if (hasDownloads.get()) { if (hasDownloads.get()) {
DownloadService.start(context) downloadManager.startDownloads()
} }
} }

View file

@ -12,7 +12,6 @@ import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupRestoreService import eu.kanade.tachiyomi.data.backup.BackupRestoreService
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.updater.AppUpdateService import eu.kanade.tachiyomi.data.updater.AppUpdateService
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
@ -56,12 +55,9 @@ class NotificationReceiver : BroadcastReceiver() {
// Dismiss notification // Dismiss notification
ACTION_DISMISS_NOTIFICATION -> dismissNotification(context, intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1)) ACTION_DISMISS_NOTIFICATION -> dismissNotification(context, intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1))
// Resume the download service // Resume the download service
ACTION_RESUME_DOWNLOADS -> DownloadService.start(context) ACTION_RESUME_DOWNLOADS -> downloadManager.startDownloads()
// Pause the download service // Pause the download service
ACTION_PAUSE_DOWNLOADS -> { ACTION_PAUSE_DOWNLOADS -> downloadManager.pauseDownloads()
DownloadService.stop(context)
downloadManager.pauseDownloads()
}
// Clear the download queue // Clear the download queue
ACTION_CLEAR_DOWNLOADS -> downloadManager.clearQueue() ACTION_CLEAR_DOWNLOADS -> downloadManager.clearQueue()
// Launch share activity and dismiss notification // Launch share activity and dismiss notification

View file

@ -31,7 +31,6 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -51,7 +50,6 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.OverflowMenu import eu.kanade.presentation.components.OverflowMenu
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.databinding.DownloadListBinding import eu.kanade.tachiyomi.databinding.DownloadListBinding
import tachiyomi.core.util.lang.launchUI import tachiyomi.core.util.lang.launchUI
import tachiyomi.presentation.core.components.Pill import tachiyomi.presentation.core.components.Pill
@ -64,7 +62,6 @@ object DownloadQueueScreen : Screen() {
@Composable @Composable
override fun Content() { override fun Content() {
val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val screenModel = rememberScreenModel { DownloadQueueScreenModel() } val screenModel = rememberScreenModel { DownloadQueueScreenModel() }
@ -182,7 +179,7 @@ object DownloadQueueScreen : Screen() {
androidx.compose.material3.DropdownMenuItem( androidx.compose.material3.DropdownMenuItem(
text = { Text(text = stringResource(R.string.action_cancel_all)) }, text = { Text(text = stringResource(R.string.action_cancel_all)) },
onClick = { onClick = {
screenModel.clearQueue(context) screenModel.clearQueue()
closeMenu() closeMenu()
}, },
) )
@ -198,7 +195,7 @@ object DownloadQueueScreen : Screen() {
enter = fadeIn(), enter = fadeIn(),
exit = fadeOut(), exit = fadeOut(),
) { ) {
val isRunning by DownloadService.isRunning.collectAsState() val isRunning by screenModel.isDownloaderRunning.collectAsState()
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
text = { text = {
val id = if (isRunning) { val id = if (isRunning) {
@ -218,10 +215,9 @@ object DownloadQueueScreen : Screen() {
}, },
onClick = { onClick = {
if (isRunning) { if (isRunning) {
DownloadService.stop(context)
screenModel.pauseDownloads() screenModel.pauseDownloads()
} else { } else {
DownloadService.start(context) screenModel.startDownloads()
} }
}, },
expanded = fabExpanded, expanded = fabExpanded,

View file

@ -1,12 +1,10 @@
package eu.kanade.tachiyomi.ui.download package eu.kanade.tachiyomi.ui.download
import android.content.Context
import android.view.MenuItem import android.view.MenuItem
import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.coroutineScope import cafe.adriel.voyager.core.model.coroutineScope
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.databinding.DownloadListBinding import eu.kanade.tachiyomi.databinding.DownloadListBinding
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
@ -135,15 +133,21 @@ class DownloadQueueScreenModel(
adapter = null adapter = null
} }
val isDownloaderRunning
get() = downloadManager.isDownloaderRunning
fun getDownloadStatusFlow() = downloadManager.queue.statusFlow() fun getDownloadStatusFlow() = downloadManager.queue.statusFlow()
fun getDownloadProgressFlow() = downloadManager.queue.progressFlow() fun getDownloadProgressFlow() = downloadManager.queue.progressFlow()
fun startDownloads() {
downloadManager.startDownloads()
}
fun pauseDownloads() { fun pauseDownloads() {
downloadManager.pauseDownloads() downloadManager.pauseDownloads()
} }
fun clearQueue(context: Context) { fun clearQueue() {
DownloadService.stop(context)
downloadManager.clearQueue() downloadManager.clearQueue()
} }

View file

@ -26,7 +26,6 @@ import eu.kanade.presentation.manga.components.ChapterDownloadAction
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadCache import eu.kanade.tachiyomi.data.download.DownloadCache
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.track.EnhancedTrackService import eu.kanade.tachiyomi.data.track.EnhancedTrackService
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
@ -589,7 +588,7 @@ class MangaInfoScreenModel(
ChapterDownloadAction.START -> { ChapterDownloadAction.START -> {
startDownload(items.map { it.chapter }, false) startDownload(items.map { it.chapter }, false)
if (items.any { it.downloadState == Download.State.ERROR }) { if (items.any { it.downloadState == Download.State.ERROR }) {
DownloadService.start(context) downloadManager.startDownloads()
} }
} }
ChapterDownloadAction.START_NOW -> { ChapterDownloadAction.START_NOW -> {

View file

@ -23,7 +23,6 @@ import eu.kanade.presentation.more.MoreScreen
import eu.kanade.presentation.util.Tab import eu.kanade.presentation.util.Tab
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.ui.category.CategoryScreen import eu.kanade.tachiyomi.ui.category.CategoryScreen
import eu.kanade.tachiyomi.ui.download.DownloadQueueScreen import eu.kanade.tachiyomi.ui.download.DownloadQueueScreen
import eu.kanade.tachiyomi.ui.setting.SettingsScreen import eu.kanade.tachiyomi.ui.setting.SettingsScreen
@ -94,7 +93,7 @@ private class MoreScreenModel(
// Handle running/paused status change and queue progress updating // Handle running/paused status change and queue progress updating
coroutineScope.launchIO { coroutineScope.launchIO {
combine( combine(
DownloadService.isRunning, downloadManager.isDownloaderRunning,
downloadManager.queue.state, downloadManager.queue.state,
) { isRunning, downloadQueue -> Pair(isRunning, downloadQueue.size) } ) { isRunning, downloadQueue -> Pair(isRunning, downloadQueue.size) }
.collectLatest { (isDownloading, downloadQueueSize) -> .collectLatest { (isDownloading, downloadQueueSize) ->

View file

@ -18,7 +18,6 @@ import eu.kanade.presentation.manga.components.ChapterDownloadAction
import eu.kanade.presentation.updates.UpdatesUiModel import eu.kanade.presentation.updates.UpdatesUiModel
import eu.kanade.tachiyomi.data.download.DownloadCache import eu.kanade.tachiyomi.data.download.DownloadCache
import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
@ -168,7 +167,7 @@ class UpdatesScreenModel(
ChapterDownloadAction.START -> { ChapterDownloadAction.START -> {
downloadChapters(items) downloadChapters(items)
if (items.any { it.downloadStateProvider() == Download.State.ERROR }) { if (items.any { it.downloadStateProvider() == Download.State.ERROR }) {
DownloadService.start(Injekt.get<Application>()) downloadManager.startDownloads()
} }
} }
ChapterDownloadAction.START_NOW -> { ChapterDownloadAction.START_NOW -> {