diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt index a9dea6e342..cb465aef7b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/notification/Notifications.kt @@ -47,6 +47,8 @@ object Notifications { */ const val CHANNEL_UPDATES_TO_EXTS = "updates_ext_channel" const val ID_UPDATES_TO_EXTS = -401 + + const val CHANNEL_EXT_PROGRESS = "ext_update_progress_channel" const val ID_EXTENSION_PROGRESS = -402 private const val GROUP_BACKUP_RESTORE = "group_backup_restore" @@ -136,5 +138,16 @@ object Notifications { ) ) context.notificationManager.createNotificationChannels(channels) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + val channel = NotificationChannel( + CHANNEL_EXT_PROGRESS, + context.getString(R.string.updating_extensions), + NotificationManager.IMPORTANCE_LOW + ).apply { + setShowBadge(false) + setSound(null, null) + } + context.notificationManager.createNotificationChannel(channel) + } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallNotifier.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallNotifier.kt index cb85b0b8c9..f2109ff42e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallNotifier.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallNotifier.kt @@ -50,12 +50,12 @@ class ExtensionInstallNotifier(private val context: Context) { * @param current the current progress. * @param total the total progress. */ - fun showProgressNotification() { + fun showProgressNotification(progress: Int, max: Int) { context.notificationManager.notify( Notifications.ID_EXTENSION_PROGRESS, progressNotificationBuilder .setContentTitle(context.getString(R.string.updating_extensions)) - .setProgress(0, 0, true) + .setProgress(max, progress, progress == 0) .build() ) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallService.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallService.kt index 0c9918ed57..19a967b3c2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionInstallService.kt @@ -63,10 +63,19 @@ class ExtensionInstallService( val list = intent.getParcelableArrayListExtra(KEY_EXTENSION) ?: return START_NOT_STICKY + var installed = 0 job = serviceScope.launch { val results = list.map { async { - installExtension(it) + requestSemaphore.withPermit { + extensionManager.installExtension(it, serviceScope) + .collect { + if (it.first.isCompleted()) { + installed++ + } + notifier.showProgressNotification(installed, list.size) + } + } } } results.awaitAll() @@ -76,15 +85,6 @@ class ExtensionInstallService( return START_REDELIVER_INTENT } - suspend fun installExtension(extension: ExtensionInfo) { - requestSemaphore.withPermit { - extensionManager.installExtension(extension, serviceScope) - .collect { - notifier.showProgressNotification() - } - } - } - /** * Method called when the service is created. It injects dagger dependencies and acquire * the wake lock. diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionUpdateJob.kt index 7f546e0db2..cf7284d066 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionUpdateJob.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionUpdateJob.kt @@ -47,6 +47,7 @@ class ExtensionUpdateJob(private val context: Context, workerParams: WorkerParam private fun createUpdateNotification(extensions: List) { val preferences: PreferencesHelper by injectLazy() preferences.extensionUpdatesCount().set(extensions.size) + // Not doing this yet since users will get prompted while device is idle // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && preferences.autoUpdateExtensions()) { // val intent = ExtensionInstallService.jobIntent(context, extensions) // context.startForegroundService(intent) @@ -76,7 +77,7 @@ class ExtensionUpdateJob(private val context: Context, workerParams: WorkerParam if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val intent = ExtensionInstallService.jobIntent(context, extensions) val pendingIntent = - PendingIntent.getForegroundService(context, 0, intent, 0) + PendingIntent.getForegroundService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) addAction( R.drawable.ic_file_download_24dp, context.getString(R.string.update_all), diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/model/InstallStep.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/model/InstallStep.kt index c50188bb62..299555b6e8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/model/InstallStep.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/model/InstallStep.kt @@ -1,9 +1,9 @@ package eu.kanade.tachiyomi.extension.model enum class InstallStep { - Pending, Downloading, Loading, Installing, Installed, Error; + Pending, Downloading, Loading, Installing, Installed, Error, Done; fun isCompleted(): Boolean { - return this == Installed || this == Error + return this == Installed || this == Error || this == Done } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt index cc8966b858..df157ddb3b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/util/ExtensionInstaller.kt @@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.transformWhile import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.launch import timber.log.Timber import java.io.File @@ -188,9 +189,20 @@ internal class ExtensionInstaller(private val context: Context) { delay(500) } } + .takeWhile { + val sessionId = downloadInstallerMap[id] + if (sessionId != null) { + context.packageManager.packageInstaller.getSessionInfo(sessionId) != null + } else { + true + } + } .catch { Timber.e(it) } + .onCompletion { + emit(InstallStep.Done to null) + } } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt index da24759def..3706c5f04f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt @@ -68,6 +68,7 @@ class ExtensionHolder(view: View, val adapter: ExtensionAdapter) : @Suppress("ResourceType") fun bindButton(item: ExtensionItem) = with(binding.extButton) { + if (item.installStep == InstallStep.Done) return@with isEnabled = true isClickable = true isActivated = false @@ -87,6 +88,7 @@ class ExtensionHolder(view: View, val adapter: ExtensionAdapter) : InstallStep.Installing -> R.string.installing InstallStep.Installed -> R.string.installed InstallStep.Error -> R.string.retry + else -> return@with } ) if (installStep != InstallStep.Error) {