Dismiss notification after flashing

This commit is contained in:
topjohnwu 2019-07-25 01:05:06 -07:00
parent 55aaa421e8
commit 1947860d61
5 changed files with 57 additions and 35 deletions

View File

@ -83,6 +83,7 @@ object Const {
const val INTENT_SET_LINK = "link" const val INTENT_SET_LINK = "link"
const val FLASH_ACTION = "action" const val FLASH_ACTION = "action"
const val FLASH_DATA = "additional_data" const val FLASH_DATA = "additional_data"
const val DISMISS_ID = "dismiss_id"
const val BROADCAST_MANAGER_UPDATE = "manager_update" const val BROADCAST_MANAGER_UPDATE = "manager_update"
const val BROADCAST_REBOOT = "reboot" const val BROADCAST_REBOOT = "reboot"
} }

View File

@ -32,26 +32,28 @@ open class DownloadService : RemoteFileService() {
.getMimeTypeFromExtension(extension) .getMimeTypeFromExtension(extension)
?: "resource/folder" ?: "resource/folder"
override fun onFinished(file: File, subject: DownloadSubject) = when (subject) { override fun onFinished(file: File, subject: DownloadSubject, id: Int) = when (subject) {
is Magisk -> onFinishedInternal(file, subject) is Magisk -> onFinishedInternal(file, subject, id)
is Module -> onFinishedInternal(file, subject) is Module -> onFinishedInternal(file, subject, id)
} }
private fun onFinishedInternal( private fun onFinishedInternal(
file: File, file: File,
subject: Magisk subject: Magisk,
id: Int
) = when (val conf = subject.configuration) { ) = when (val conf = subject.configuration) {
Uninstall -> FlashActivity.uninstall(this, file) Uninstall -> FlashActivity.uninstall(this, file, id)
is Patch -> FlashActivity.patch(this, file, conf.fileUri) is Patch -> FlashActivity.patch(this, file, conf.fileUri, id)
is Flash -> FlashActivity.flash(this, file, conf is Secondary) is Flash -> FlashActivity.flash(this, file, conf is Secondary, id)
else -> Unit else -> Unit
} }
private fun onFinishedInternal( private fun onFinishedInternal(
file: File, file: File,
subject: Module subject: Module,
id: Int
) = when (subject.configuration) { ) = when (subject.configuration) {
is Flash -> FlashActivity.install(this, file) is Flash -> FlashActivity.install(this, file, id)
else -> Unit else -> Unit
} }

View File

@ -1,12 +1,11 @@
package com.topjohnwu.magisk.model.download package com.topjohnwu.magisk.model.download
import android.app.Notification import android.app.Notification
import android.app.NotificationManager
import android.app.Service import android.app.Service
import android.content.Intent import android.content.Intent
import android.os.IBinder import android.os.IBinder
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.content.getSystemService import androidx.core.app.NotificationManagerCompat
import java.util.* import java.util.*
import kotlin.random.Random.Default.nextInt import kotlin.random.Random.Default.nextInt
@ -14,7 +13,7 @@ abstract class NotificationService : Service() {
abstract val defaultNotification: NotificationCompat.Builder abstract val defaultNotification: NotificationCompat.Builder
private val manager get() = getSystemService<NotificationManager>() private val manager by lazy { NotificationManagerCompat.from(this) }
private val hasNotifications get() = notifications.isNotEmpty() private val hasNotifications get() = notifications.isNotEmpty()
private val notifications = private val notifications =
@ -44,37 +43,41 @@ abstract class NotificationService : Service() {
protected fun finishWork( protected fun finishWork(
id: Int, id: Int,
editBody: (NotificationCompat.Builder) -> NotificationCompat.Builder? = { null } editBody: (NotificationCompat.Builder) -> NotificationCompat.Builder? = { null }
) { ) : Int {
val currentNotification = remove(id)?.run(editBody) val currentNotification = remove(id)?.run(editBody)
updateForeground() updateForeground()
cancel(id) cancel(id)
currentNotification?.let { notify(nextInt(), it.build()) } var newId = -1
currentNotification?.let {
newId = nextInt(Int.MAX_VALUE)
notify(newId, it.build())
}
if (!hasNotifications) { if (!hasNotifications) {
stopForeground(true) stopForeground(true)
stopSelf() stopSelf()
} }
return newId
} }
// --- // ---
private fun notify(id: Int, notification: Notification) { private fun notify(id: Int, notification: Notification) {
manager?.notify(id, notification) manager.notify(id, notification)
} }
private fun cancel(id: Int) { private fun cancel(id: Int) {
manager?.cancel(id) manager.cancel(id)
} }
private fun remove(id: Int) = notifications.remove(id) private fun remove(id: Int) = notifications.remove(id)
.also { updateForeground() } .also { updateForeground() }
private fun updateForeground() { private fun updateForeground() {
runCatching { notifications.keys.first() to notifications.values.first() } if (notifications.isNotEmpty())
.getOrNull() startForeground(notifications.keys.first(), notifications.values.first().build())
?.let { startForeground(it.first, it.second.build()) }
} }
// -- // --

View File

@ -50,8 +50,8 @@ abstract class RemoteFileService : NotificationService() {
.doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.title) } } .doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.title) } }
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.doOnSuccess { .doOnSuccess {
runCatching { onFinished(it, subject) }.onFailure { Timber.e(it) } val id = finish(it, subject)
finish(it, subject) runCatching { onFinished(it, subject, id) }.onFailure { Timber.e(it) }
}.subscribeK() }.subscribeK()
private fun search(subject: DownloadSubject) = Single.fromCallable { private fun search(subject: DownloadSubject) = Single.fromCallable {
@ -92,7 +92,6 @@ abstract class RemoteFileService : NotificationService() {
return ProgInputStream(byteStream()) { return ProgInputStream(byteStream()) {
val progress = it / 1_000_000f val progress = it / 1_000_000f
update(id) { notification -> update(id) { notification ->
notification notification
.setProgress(maxRaw.toInt(), it.toInt(), false) .setProgress(maxRaw.toInt(), it.toInt(), false)
@ -114,7 +113,7 @@ abstract class RemoteFileService : NotificationService() {
@Throws(Throwable::class) @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( protected abstract fun NotificationCompat.Builder.addActions(
file: File, file: File,

View File

@ -3,6 +3,8 @@ package com.topjohnwu.magisk.ui.flash
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle
import androidx.core.app.NotificationManagerCompat
import androidx.core.net.toUri import androidx.core.net.toUri
import com.topjohnwu.magisk.ClassMap import com.topjohnwu.magisk.ClassMap
import com.topjohnwu.magisk.Const import com.topjohnwu.magisk.Const
@ -23,6 +25,13 @@ open class FlashActivity : MagiskActivity<FlashViewModel, ActivityFlashBinding>(
parametersOf(action, uri, additionalUri) 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() { override fun onBackPressed() {
if (viewModel.loading) return if (viewModel.loading) return
super.onBackPressed() super.onBackPressed()
@ -39,36 +48,44 @@ open class FlashActivity : MagiskActivity<FlashViewModel, ActivityFlashBinding>(
/* Flashing is understood as installing / flashing magisk itself */ /* 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.FLASH_ACTION, flashType(isSecondSlot))
.putExtra(Const.Key.DISMISS_ID, id)
fun flash(context: Context, file: File, isSecondSlot: Boolean) = fun flash(context: Context, file: File, isSecondSlot: Boolean, id: Int) =
context.startActivity(flashIntent(context, file, isSecondSlot)) context.startActivity(flashIntent(context, file, isSecondSlot, id))
/* Patching is understood as injecting img files with magisk */ /* 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_DATA, uri)
.putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_FILE) .putExtra(Const.Key.FLASH_ACTION, Const.Value.PATCH_FILE)
.putExtra(Const.Key.DISMISS_ID, id)
fun patch(context: Context, file: File, uri: Uri) = fun patch(context: Context, file: File, uri: Uri, id: Int) =
context.startActivity(patchIntent(context, file, uri)) context.startActivity(patchIntent(context, file, uri, id))
/* Uninstalling is understood as removing magisk entirely */ /* 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.FLASH_ACTION, Const.Value.UNINSTALL)
.putExtra(Const.Key.DISMISS_ID, id)
fun uninstall(context: Context, file: File) = fun uninstall(context: Context, file: File, id: Int) =
context.startActivity(uninstallIntent(context, file)) context.startActivity(uninstallIntent(context, file, id))
/* Installing is understood as flashing modules / zips */ /* 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.FLASH_ACTION, Const.Value.FLASH_ZIP)
.putExtra(Const.Key.DISMISS_ID, id)
fun install(context: Context, file: File) = fun install(context: Context, file: File, id: Int) =
context.startActivity(installIntent(context, file)) context.startActivity(installIntent(context, file, id))
} }