diff --git a/app/src/main/java/com/topjohnwu/magisk/Const.kt b/app/src/main/java/com/topjohnwu/magisk/Const.kt index 99681169c..694ca87c2 100644 --- a/app/src/main/java/com/topjohnwu/magisk/Const.kt +++ b/app/src/main/java/com/topjohnwu/magisk/Const.kt @@ -83,6 +83,7 @@ object Const { const val INTENT_SET_LINK = "link" const val FLASH_ACTION = "action" const val FLASH_DATA = "additional_data" + const val DISMISS_ID = "dismiss_id" const val BROADCAST_MANAGER_UPDATE = "manager_update" const val BROADCAST_REBOOT = "reboot" } diff --git a/app/src/main/java/com/topjohnwu/magisk/model/download/DownloadService.kt b/app/src/main/java/com/topjohnwu/magisk/model/download/DownloadService.kt index a11a96b2b..fa0df28b9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/model/download/DownloadService.kt +++ b/app/src/main/java/com/topjohnwu/magisk/model/download/DownloadService.kt @@ -32,26 +32,28 @@ open class DownloadService : RemoteFileService() { .getMimeTypeFromExtension(extension) ?: "resource/folder" - override fun onFinished(file: File, subject: DownloadSubject) = when (subject) { - is Magisk -> onFinishedInternal(file, subject) - is Module -> onFinishedInternal(file, subject) + override fun onFinished(file: File, subject: DownloadSubject, id: Int) = when (subject) { + is Magisk -> onFinishedInternal(file, subject, id) + is Module -> onFinishedInternal(file, subject, id) } private fun onFinishedInternal( file: File, - subject: Magisk + subject: Magisk, + id: Int ) = when (val conf = subject.configuration) { - Uninstall -> FlashActivity.uninstall(this, file) - is Patch -> FlashActivity.patch(this, file, conf.fileUri) - is Flash -> FlashActivity.flash(this, file, conf is Secondary) + Uninstall -> FlashActivity.uninstall(this, file, id) + is Patch -> FlashActivity.patch(this, file, conf.fileUri, id) + is Flash -> FlashActivity.flash(this, file, conf is Secondary, id) else -> Unit } private fun onFinishedInternal( file: File, - subject: Module + subject: Module, + id: Int ) = when (subject.configuration) { - is Flash -> FlashActivity.install(this, file) + is Flash -> FlashActivity.install(this, file, id) else -> Unit } diff --git a/app/src/main/java/com/topjohnwu/magisk/model/download/NotificationService.kt b/app/src/main/java/com/topjohnwu/magisk/model/download/NotificationService.kt index 726022cd7..d1a1138da 100644 --- a/app/src/main/java/com/topjohnwu/magisk/model/download/NotificationService.kt +++ b/app/src/main/java/com/topjohnwu/magisk/model/download/NotificationService.kt @@ -1,12 +1,11 @@ package com.topjohnwu.magisk.model.download import android.app.Notification -import android.app.NotificationManager import android.app.Service import android.content.Intent import android.os.IBinder import androidx.core.app.NotificationCompat -import androidx.core.content.getSystemService +import androidx.core.app.NotificationManagerCompat import java.util.* import kotlin.random.Random.Default.nextInt @@ -14,7 +13,7 @@ abstract class NotificationService : Service() { abstract val defaultNotification: NotificationCompat.Builder - private val manager get() = getSystemService() + private val manager by lazy { NotificationManagerCompat.from(this) } private val hasNotifications get() = notifications.isNotEmpty() private val notifications = @@ -44,37 +43,41 @@ abstract class NotificationService : Service() { protected fun finishWork( id: Int, editBody: (NotificationCompat.Builder) -> NotificationCompat.Builder? = { null } - ) { + ) : Int { val currentNotification = remove(id)?.run(editBody) updateForeground() cancel(id) - currentNotification?.let { notify(nextInt(), it.build()) } + var newId = -1 + currentNotification?.let { + newId = nextInt(Int.MAX_VALUE) + notify(newId, it.build()) + } if (!hasNotifications) { stopForeground(true) stopSelf() } + return newId } // --- private fun notify(id: Int, notification: Notification) { - manager?.notify(id, notification) + manager.notify(id, notification) } private fun cancel(id: Int) { - manager?.cancel(id) + manager.cancel(id) } private fun remove(id: Int) = notifications.remove(id) .also { updateForeground() } private fun updateForeground() { - runCatching { notifications.keys.first() to notifications.values.first() } - .getOrNull() - ?.let { startForeground(it.first, it.second.build()) } + if (notifications.isNotEmpty()) + startForeground(notifications.keys.first(), notifications.values.first().build()) } // -- diff --git a/app/src/main/java/com/topjohnwu/magisk/model/download/RemoteFileService.kt b/app/src/main/java/com/topjohnwu/magisk/model/download/RemoteFileService.kt index a0e3eb22b..73a2f79ad 100644 --- a/app/src/main/java/com/topjohnwu/magisk/model/download/RemoteFileService.kt +++ b/app/src/main/java/com/topjohnwu/magisk/model/download/RemoteFileService.kt @@ -50,8 +50,8 @@ abstract class RemoteFileService : NotificationService() { .doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.title) } } .observeOn(AndroidSchedulers.mainThread()) .doOnSuccess { - runCatching { onFinished(it, subject) }.onFailure { Timber.e(it) } - finish(it, subject) + val id = finish(it, subject) + runCatching { onFinished(it, subject, id) }.onFailure { Timber.e(it) } }.subscribeK() private fun search(subject: DownloadSubject) = Single.fromCallable { @@ -92,7 +92,6 @@ abstract class RemoteFileService : NotificationService() { return ProgInputStream(byteStream()) { val progress = it / 1_000_000f - update(id) { notification -> notification .setProgress(maxRaw.toInt(), it.toInt(), false) @@ -114,7 +113,7 @@ abstract class RemoteFileService : NotificationService() { @Throws(Throwable::class) - protected abstract fun onFinished(file: File, subject: DownloadSubject) + protected abstract fun onFinished(file: File, subject: DownloadSubject, id: Int) protected abstract fun NotificationCompat.Builder.addActions( file: File, diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashActivity.kt b/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashActivity.kt index 26246efdb..d10deff8a 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashActivity.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashActivity.kt @@ -3,6 +3,8 @@ package com.topjohnwu.magisk.ui.flash import android.content.Context import android.content.Intent import android.net.Uri +import android.os.Bundle +import androidx.core.app.NotificationManagerCompat import androidx.core.net.toUri import com.topjohnwu.magisk.ClassMap import com.topjohnwu.magisk.Const @@ -23,6 +25,13 @@ open class FlashActivity : MagiskActivity( parametersOf(action, uri, additionalUri) } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val id = intent.getIntExtra(Const.Key.DISMISS_ID, -1) + if (id != -1) + NotificationManagerCompat.from(this).cancel(id) + } + override fun onBackPressed() { if (viewModel.loading) return super.onBackPressed() @@ -39,36 +48,44 @@ open class FlashActivity : MagiskActivity( /* Flashing is understood as installing / flashing magisk itself */ - fun flashIntent(context: Context, file: File, isSecondSlot: Boolean) = intent(context, file) + fun flashIntent(context: Context, file: File, isSecondSlot: Boolean, id : Int = -1) + = intent(context, file) .putExtra(Const.Key.FLASH_ACTION, flashType(isSecondSlot)) + .putExtra(Const.Key.DISMISS_ID, id) - fun flash(context: Context, file: File, isSecondSlot: Boolean) = - context.startActivity(flashIntent(context, file, isSecondSlot)) + fun flash(context: Context, file: File, isSecondSlot: Boolean, id: Int) = + context.startActivity(flashIntent(context, file, isSecondSlot, id)) /* Patching is understood as injecting img files with magisk */ - fun patchIntent(context: Context, file: File, uri: Uri) = intent(context, file) + fun patchIntent(context: Context, file: File, uri: Uri, id : Int = -1) + = intent(context, file) .putExtra(Const.Key.FLASH_DATA, uri) .putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_FILE) + .putExtra(Const.Key.DISMISS_ID, id) - fun patch(context: Context, file: File, uri: Uri) = - context.startActivity(patchIntent(context, file, uri)) + fun patch(context: Context, file: File, uri: Uri, id: Int) = + context.startActivity(patchIntent(context, file, uri, id)) /* Uninstalling is understood as removing magisk entirely */ - fun uninstallIntent(context: Context, file: File) = intent(context, file) + fun uninstallIntent(context: Context, file: File, id : Int = -1) + = intent(context, file) .putExtra(Const.Key.FLASH_ACTION, Const.Value.UNINSTALL) + .putExtra(Const.Key.DISMISS_ID, id) - fun uninstall(context: Context, file: File) = - context.startActivity(uninstallIntent(context, file)) + fun uninstall(context: Context, file: File, id: Int) = + context.startActivity(uninstallIntent(context, file, id)) /* Installing is understood as flashing modules / zips */ - fun installIntent(context: Context, file: File) = intent(context, file) + fun installIntent(context: Context, file: File, id : Int = -1) + = intent(context, file) .putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP) + .putExtra(Const.Key.DISMISS_ID, id) - fun install(context: Context, file: File) = - context.startActivity(installIntent(context, file)) + fun install(context: Context, file: File, id: Int) = + context.startActivity(installIntent(context, file, id)) }