mirror of
https://github.com/aniyomiorg/aniyomi.git
synced 2024-11-23 21:27:40 +03:00
fix(notifications): Revert parallelize downloads
This commit is contained in:
parent
4ffae67048
commit
0c0bf51663
4 changed files with 36 additions and 86 deletions
|
@ -1,6 +1,5 @@
|
|||
package eu.kanade.tachiyomi.data.download.anime
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
|
@ -12,8 +11,8 @@ import eu.kanade.tachiyomi.data.notification.NotificationHandler
|
|||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import eu.kanade.tachiyomi.util.lang.chop
|
||||
import eu.kanade.tachiyomi.util.system.cancelNotification
|
||||
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||
import eu.kanade.tachiyomi.util.system.notify
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.regex.Pattern
|
||||
|
@ -46,16 +45,6 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
*/
|
||||
private var isDownloading = false
|
||||
|
||||
/**
|
||||
* Updated when paused
|
||||
*/
|
||||
var paused = false
|
||||
|
||||
/**
|
||||
* Map to store notification IDs for each download
|
||||
*/
|
||||
private val notificationIdMap: MutableMap<Long, Int> = mutableMapOf()
|
||||
|
||||
/**
|
||||
* Shows a notification from this builder.
|
||||
*
|
||||
|
@ -69,10 +58,8 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
* Dismiss the downloader's notification. Downloader error notifications use a different id, so
|
||||
* those can only be dismissed by the user.
|
||||
*/
|
||||
fun dismissProgress(download: AnimeDownload) {
|
||||
val notificationId = notificationIdMap[download.episode.id] ?: return
|
||||
context.cancelNotification(notificationId)
|
||||
notificationIdMap.remove(download.episode.id)
|
||||
fun dismissProgress() {
|
||||
context.notificationManager.cancel(Notifications.ID_DOWNLOAD_EPISODE_PROGRESS)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,12 +67,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
*
|
||||
* @param download download object containing download information.
|
||||
*/
|
||||
@SuppressLint("RestrictedApi", "StringFormatInvalid")
|
||||
fun onProgressChange(download: AnimeDownload) {
|
||||
val notificationId = notificationIdMap.getOrPut(download.episode.id) {
|
||||
download.episode.id.hashCode()
|
||||
}
|
||||
|
||||
with(progressNotificationBuilder) {
|
||||
if (!isDownloading) {
|
||||
setSmallIcon(android.R.drawable.stat_sys_download)
|
||||
|
@ -93,6 +75,12 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
// Open download manager when clicked
|
||||
setContentIntent(NotificationHandler.openAnimeDownloadManagerPendingActivity(context))
|
||||
isDownloading = true
|
||||
// Pause action
|
||||
addAction(
|
||||
R.drawable.ic_pause_24dp,
|
||||
context.getString(R.string.action_pause),
|
||||
NotificationReceiver.pauseAnimeDownloadsPendingBroadcast(context),
|
||||
)
|
||||
}
|
||||
|
||||
val downloadingProgressText = if (download.totalProgress == 0) {
|
||||
|
@ -118,28 +106,14 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
}
|
||||
setOngoing(true)
|
||||
|
||||
show(notificationId)
|
||||
}
|
||||
|
||||
// Add pause action if not already added
|
||||
val pauseActionIntent = NotificationReceiver.pauseAnimeDownloadsPendingBroadcast(context)
|
||||
val pauseActionAdded = progressNotificationBuilder.mActions.any { it.actionIntent == pauseActionIntent }
|
||||
if (!paused && !pauseActionAdded) {
|
||||
progressNotificationBuilder.addAction(
|
||||
R.drawable.ic_pause_24dp,
|
||||
context.getString(R.string.action_pause),
|
||||
pauseActionIntent,
|
||||
)
|
||||
paused = true
|
||||
show(Notifications.ID_DOWNLOAD_EPISODE_PROGRESS)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notification when download is paused.
|
||||
*/
|
||||
fun onPaused(download: AnimeDownload) {
|
||||
val notificationId = notificationIdMap[download.episode.id] ?: return
|
||||
|
||||
fun onPaused() {
|
||||
with(progressNotificationBuilder) {
|
||||
setContentTitle(context.getString(R.string.download_paused))
|
||||
setContentText(context.getString(R.string.download_notifier_download_paused_episodes))
|
||||
|
@ -162,23 +136,21 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
NotificationReceiver.clearAnimeDownloadsPendingBroadcast(context),
|
||||
)
|
||||
|
||||
show(notificationId)
|
||||
show(Notifications.ID_DOWNLOAD_EPISODE_PROGRESS)
|
||||
}
|
||||
|
||||
// Reset initial values
|
||||
isDownloading = false
|
||||
paused = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state once downloads are completed.
|
||||
*/
|
||||
fun onComplete(download: AnimeDownload) {
|
||||
dismissProgress(download)
|
||||
fun onComplete() {
|
||||
dismissProgress()
|
||||
|
||||
// Reset states to default
|
||||
isDownloading = false
|
||||
paused = false
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +170,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
timeout?.let { setTimeoutAfter(it) }
|
||||
contentIntent?.let { setContentIntent(it) }
|
||||
|
||||
show(Notifications.ID_DOWNLOAD_CHAPTER_ERROR)
|
||||
show(Notifications.ID_DOWNLOAD_EPISODE_ERROR)
|
||||
}
|
||||
|
||||
// Reset download information
|
||||
|
@ -212,11 +184,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
* @param error string containing error information.
|
||||
* @param episode string containing episode title.
|
||||
*/
|
||||
fun onError(download: AnimeDownload, error: String? = null, episode: String? = null, animeTitle: String? = null) {
|
||||
val notificationId = notificationIdMap.getOrPut(download.episode.id) {
|
||||
download.episode.id.hashCode()
|
||||
}
|
||||
|
||||
fun onError(error: String? = null, episode: String? = null, animeTitle: String? = null) {
|
||||
// Create notification
|
||||
with(errorNotificationBuilder) {
|
||||
setContentTitle(
|
||||
|
@ -228,7 +196,7 @@ internal class AnimeDownloadNotifier(private val context: Context) {
|
|||
setContentIntent(NotificationHandler.openAnimeDownloadManagerPendingActivity(context))
|
||||
setProgress(0, 0, false)
|
||||
|
||||
show(notificationId)
|
||||
show(Notifications.ID_DOWNLOAD_EPISODE_ERROR)
|
||||
}
|
||||
|
||||
// Reset download information
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.app.Notification
|
|||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.os.PowerManager
|
||||
import androidx.annotation.StringRes
|
||||
|
@ -90,14 +89,9 @@ class AnimeDownloadService : Service() {
|
|||
|
||||
override fun onCreate() {
|
||||
scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||
startForeground(Notifications.ID_DOWNLOAD_EPISODE_PROGRESS, getPlaceholderNotification())
|
||||
wakeLock = acquireWakeLock(javaClass.name)
|
||||
_isRunning.value = true
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForeground(1, getPlaceholderNotification())
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
startForeground(1, Notification())
|
||||
}
|
||||
listenNetworkChanges()
|
||||
}
|
||||
|
||||
|
|
|
@ -160,20 +160,14 @@ class AnimeDownloader(
|
|||
.forEach { it.status = AnimeDownload.State.ERROR }
|
||||
|
||||
if (reason != null) {
|
||||
queueState.value.forEach {
|
||||
notifier.onWarning(reason)
|
||||
return
|
||||
}
|
||||
notifier.onWarning(reason)
|
||||
return
|
||||
}
|
||||
|
||||
if (isPaused && queueState.value.isNotEmpty()) {
|
||||
queueState.value.forEach {
|
||||
notifier.onPaused(it)
|
||||
}
|
||||
notifier.onPaused()
|
||||
} else {
|
||||
queueState.value.forEach {
|
||||
notifier.onComplete(it)
|
||||
}
|
||||
notifier.onComplete()
|
||||
}
|
||||
|
||||
isPaused = false
|
||||
|
@ -201,10 +195,8 @@ class AnimeDownloader(
|
|||
fun clearQueue() {
|
||||
destroySubscription()
|
||||
|
||||
queueState.value.forEach {
|
||||
notifier.dismissProgress(it)
|
||||
}
|
||||
_clearQueue()
|
||||
notifier.dismissProgress()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -214,8 +206,8 @@ class AnimeDownloader(
|
|||
// Unsubscribe the previous subscription if it exists
|
||||
destroySubscription()
|
||||
|
||||
subscription = downloadsRelay
|
||||
.flatMapIterable { it }
|
||||
subscription = downloadsRelay.flatMapIterable { it }
|
||||
// Concurrently download from 3 different sources
|
||||
.groupBy { it.source }
|
||||
.flatMap(
|
||||
{ bySource ->
|
||||
|
@ -228,7 +220,7 @@ class AnimeDownloader(
|
|||
downloadPreferences.numberOfDownloads().get(),
|
||||
)
|
||||
},
|
||||
downloadPreferences.numberOfDownloads().get(), // Set the maximum number of concurrent downloads here
|
||||
3,
|
||||
)
|
||||
.subscribe(
|
||||
{ completedDownload ->
|
||||
|
@ -236,9 +228,7 @@ class AnimeDownloader(
|
|||
},
|
||||
{ error ->
|
||||
logcat(LogPriority.ERROR, error)
|
||||
queueState.value.forEach {
|
||||
notifier.onError(it, error.message, it.episode.name, it.anime.title)
|
||||
}
|
||||
notifier.onError(error.message)
|
||||
stop()
|
||||
},
|
||||
)
|
||||
|
@ -299,7 +289,7 @@ class AnimeDownloader(
|
|||
|
||||
// Start downloader if needed
|
||||
if (autoStart && wasEmpty) {
|
||||
val queuedDownloads = queueState.value.filter { it: AnimeDownload -> it.source !is UnmeteredSource }.count()
|
||||
val queuedDownloads = queueState.value.count { it: AnimeDownload -> it.source !is UnmeteredSource }
|
||||
val maxDownloadsFromSource = queueState.value
|
||||
.groupBy { it.source }
|
||||
.filterKeys { it !is UnmeteredSource }
|
||||
|
@ -334,7 +324,7 @@ class AnimeDownloader(
|
|||
val availSpace = DiskUtil.getAvailableStorageSpace(animeDir)
|
||||
if (availSpace != -1L && availSpace < MIN_DISK_SPACE) {
|
||||
download.status = AnimeDownload.State.ERROR
|
||||
notifier.onError(download, context.getString(R.string.download_insufficient_space), download.episode.name, download.anime.title)
|
||||
notifier.onError(context.getString(R.string.download_insufficient_space), download.episode.name, download.anime.title)
|
||||
return@defer Observable.just(download)
|
||||
}
|
||||
|
||||
|
@ -399,15 +389,12 @@ class AnimeDownloader(
|
|||
// Do after download completes
|
||||
.doOnNext {
|
||||
ensureSuccessfulAnimeDownload(download, animeDir, tmpDir, episodeDirname)
|
||||
|
||||
queueState.value.forEach {
|
||||
if (download.status == AnimeDownload.State.DOWNLOADED) notifier.dismissProgress(it)
|
||||
}
|
||||
if (download.status == AnimeDownload.State.DOWNLOADED) notifier.dismissProgress()
|
||||
}
|
||||
// If the video list threw, it will resume here
|
||||
.onErrorReturn { error ->
|
||||
download.status = AnimeDownload.State.ERROR
|
||||
notifier.onError(download, error.message, download.episode.name, download.anime.title)
|
||||
notifier.onError(error.message, download.episode.name, download.anime.title)
|
||||
download
|
||||
}
|
||||
}
|
||||
|
@ -465,7 +452,7 @@ class AnimeDownloader(
|
|||
.onErrorReturn {
|
||||
video.progress = 0
|
||||
video.status = Video.State.ERROR
|
||||
notifier.onError(download, it.message, download.episode.name, download.anime.title)
|
||||
notifier.onError(it.message, download.episode.name, download.anime.title)
|
||||
video
|
||||
}
|
||||
}
|
||||
|
@ -845,8 +832,8 @@ class AnimeDownloader(
|
|||
companion object {
|
||||
const val TMP_DIR_SUFFIX = "_tmp"
|
||||
const val WARNING_NOTIF_TIMEOUT_MS = 30_000L
|
||||
const val EPISODES_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 15
|
||||
private const val DOWNLOADS_QUEUED_WARNING_THRESHOLD = 30
|
||||
const val EPISODES_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 10
|
||||
private const val DOWNLOADS_QUEUED_WARNING_THRESHOLD = 20
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,10 @@ object Notifications {
|
|||
private const val GROUP_DOWNLOADER = "group_downloader"
|
||||
const val CHANNEL_DOWNLOADER_PROGRESS = "downloader_progress_channel"
|
||||
const val ID_DOWNLOAD_CHAPTER_PROGRESS = -201
|
||||
const val ID_DOWNLOAD_EPISODE_PROGRESS = -205
|
||||
const val ID_DOWNLOAD_EPISODE_PROGRESS = -203
|
||||
const val CHANNEL_DOWNLOADER_ERROR = "downloader_error_channel"
|
||||
const val ID_DOWNLOAD_CHAPTER_ERROR = -202
|
||||
const val ID_DOWNLOAD_EPISODE_ERROR = -204
|
||||
|
||||
/**
|
||||
* Notification channel and ids used by the library updater.
|
||||
|
|
Loading…
Reference in a new issue