Commit fc05f377 authored by topjohnwu's avatar topjohnwu

Update env fix handling logic

parent 5c0e8638
...@@ -9,15 +9,18 @@ import android.os.Build ...@@ -9,15 +9,18 @@ import android.os.Build
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.intent import com.topjohnwu.magisk.core.intent
import com.topjohnwu.magisk.core.tasks.EnvFixTask
import com.topjohnwu.magisk.extensions.chooser import com.topjohnwu.magisk.extensions.chooser
import com.topjohnwu.magisk.extensions.exists import com.topjohnwu.magisk.extensions.exists
import com.topjohnwu.magisk.extensions.provide import com.topjohnwu.magisk.extensions.provide
import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.legacy.flash.FlashActivity import com.topjohnwu.magisk.legacy.flash.FlashActivity
import com.topjohnwu.magisk.model.entity.internal.Configuration.* import com.topjohnwu.magisk.model.entity.internal.Configuration.*
import com.topjohnwu.magisk.model.entity.internal.Configuration.Flash.Secondary import com.topjohnwu.magisk.model.entity.internal.Configuration.Flash.Secondary
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.* import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.*
import com.topjohnwu.magisk.utils.APKInstall import com.topjohnwu.magisk.utils.APKInstall
import io.reactivex.Completable
import org.koin.core.get import org.koin.core.get
import java.io.File import java.io.File
import kotlin.random.Random.Default.nextInt import kotlin.random.Random.Default.nextInt
...@@ -43,6 +46,7 @@ open class DownloadService : RemoteFileService() { ...@@ -43,6 +46,7 @@ open class DownloadService : RemoteFileService() {
id: Int id: Int
) = when (val conf = subject.configuration) { ) = when (val conf = subject.configuration) {
Uninstall -> FlashActivity.uninstall(this, subject.file, id) Uninstall -> FlashActivity.uninstall(this, subject.file, id)
EnvFix -> { remove(id); EnvFixTask(subject.file).exec() }
is Patch -> FlashActivity.patch(this, subject.file, conf.fileUri, id) is Patch -> FlashActivity.patch(this, subject.file, conf.fileUri, id)
is Flash -> FlashActivity.flash(this, subject.file, conf is Secondary, id) is Flash -> FlashActivity.flash(this, subject.file, conf is Secondary, id)
else -> Unit else -> Unit
...@@ -60,10 +64,14 @@ open class DownloadService : RemoteFileService() { ...@@ -60,10 +64,14 @@ open class DownloadService : RemoteFileService() {
subject: Manager, subject: Manager,
id: Int id: Int
) { ) {
remove(id) Completable.fromAction {
when (subject.configuration) { handleAPK(subject)
is APK.Upgrade -> APKInstall.install(this, subject.file) }.subscribeK {
is APK.Restore -> Unit remove(id)
when (subject.configuration) {
is APK.Upgrade -> APKInstall.install(this, subject.file)
is APK.Restore -> Unit
}
} }
} }
......
...@@ -20,8 +20,8 @@ private fun RemoteFileService.patch(apk: File, id: Int) { ...@@ -20,8 +20,8 @@ private fun RemoteFileService.patch(apk: File, id: Int) {
if (packageName == BuildConfig.APPLICATION_ID) if (packageName == BuildConfig.APPLICATION_ID)
return return
update(id) { notification -> update(id) {
notification.setProgress(0, 0, true) it.setProgress(0, 0, true)
.setProgress(0, 0, true) .setProgress(0, 0, true)
.setContentTitle(getString(R.string.hide_manager_title)) .setContentTitle(getString(R.string.hide_manager_title))
.setContentText("") .setContentText("")
...@@ -53,11 +53,11 @@ private fun RemoteFileService.upgrade(apk: File, id: Int) { ...@@ -53,11 +53,11 @@ private fun RemoteFileService.upgrade(apk: File, id: Int) {
} }
private fun RemoteFileService.restore(apk: File, id: Int) { private fun RemoteFileService.restore(apk: File, id: Int) {
update(id) { notification -> update(id) {
notification.setProgress(0, 0, true) it.setProgress(0, 0, true)
.setProgress(0, 0, true) .setProgress(0, 0, true)
.setContentTitle(getString(R.string.restore_img_msg)) .setContentTitle(getString(R.string.restore_img_msg))
.setContentText("") .setContentText("")
} }
Config.export() Config.export()
// Make it world readable // Make it world readable
...@@ -65,8 +65,8 @@ private fun RemoteFileService.restore(apk: File, id: Int) { ...@@ -65,8 +65,8 @@ private fun RemoteFileService.restore(apk: File, id: Int) {
Shell.su("pm install $apk && pm uninstall $packageName").exec() Shell.su("pm install $apk && pm uninstall $packageName").exec()
} }
fun RemoteFileService.handleAPK(subject: DownloadSubject.Manager) fun RemoteFileService.handleAPK(subject: DownloadSubject.Manager) =
= when (subject.configuration) { when (subject.configuration) {
is Upgrade -> upgrade(subject.file, subject.hashCode()) is Upgrade -> upgrade(subject.file, subject.hashCode())
is Restore -> restore(subject.file, subject.hashCode()) is Restore -> restore(subject.file, subject.hashCode())
} }
...@@ -7,16 +7,14 @@ import com.topjohnwu.magisk.core.base.BaseService ...@@ -7,16 +7,14 @@ import com.topjohnwu.magisk.core.base.BaseService
import com.topjohnwu.magisk.core.view.Notifications import com.topjohnwu.magisk.core.view.Notifications
import org.koin.core.KoinComponent import org.koin.core.KoinComponent
import java.util.* import java.util.*
import kotlin.collections.HashMap
import kotlin.random.Random.Default.nextInt import kotlin.random.Random.Default.nextInt
abstract class NotificationService : BaseService(), KoinComponent { abstract class NotificationService : BaseService(), KoinComponent {
abstract val defaultNotification: Notification.Builder
private val hasNotifications get() = notifications.isNotEmpty() private val hasNotifications get() = notifications.isNotEmpty()
private val notifications = private val notifications = Collections.synchronizedMap(HashMap<Int, Notification.Builder>())
Collections.synchronizedMap(mutableMapOf<Int, Notification.Builder>())
override fun onTaskRemoved(rootIntent: Intent?) { override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent) super.onTaskRemoved(rootIntent)
...@@ -24,22 +22,23 @@ abstract class NotificationService : BaseService(), KoinComponent { ...@@ -24,22 +22,23 @@ abstract class NotificationService : BaseService(), KoinComponent {
notifications.clear() notifications.clear()
} }
abstract fun createNotification(): Notification.Builder
// -- // --
fun update( fun update(
id: Int, id: Int,
body: (Notification.Builder) -> Unit = {} body: (Notification.Builder) -> Unit = {}
) { ) {
val notification = notifications.getOrPut(id) { defaultNotification } val wasEmpty = notifications.isEmpty()
val notification = notifications.getOrPut(id, ::createNotification).also(body)
notify(id, notification.also(body).build()) if (wasEmpty)
if (notifications.size == 1) {
updateForeground() updateForeground()
} else
notify(id, notification.build())
} }
protected fun finishNotify( protected fun lastNotify(
id: Int, id: Int,
editBody: (Notification.Builder) -> Notification.Builder? = { null } editBody: (Notification.Builder) -> Notification.Builder? = { null }
) : Int { ) : Int {
...@@ -57,6 +56,11 @@ abstract class NotificationService : BaseService(), KoinComponent { ...@@ -57,6 +56,11 @@ abstract class NotificationService : BaseService(), KoinComponent {
return newId return newId
} }
protected fun remove(id: Int) = notifications.remove(id).also {
cancel(id)
updateForeground()
}
// --- // ---
private fun notify(id: Int, notification: Notification) { private fun notify(id: Int, notification: Notification) {
...@@ -67,16 +71,13 @@ abstract class NotificationService : BaseService(), KoinComponent { ...@@ -67,16 +71,13 @@ abstract class NotificationService : BaseService(), KoinComponent {
Notifications.mgr.cancel(id) Notifications.mgr.cancel(id)
} }
protected fun remove(id: Int) = notifications.remove(id).also {
cancel(id)
updateForeground()
}
private fun updateForeground() { private fun updateForeground() {
if (hasNotifications) if (hasNotifications) {
startForeground(notifications.keys.first(), notifications.values.first().build()) val first = notifications.entries.first()
else startForeground(first.key, first.value.build())
} else {
stopForeground(true) stopForeground(true)
}
} }
// -- // --
......
...@@ -14,7 +14,8 @@ import com.topjohnwu.magisk.extensions.get ...@@ -14,7 +14,8 @@ import com.topjohnwu.magisk.extensions.get
import com.topjohnwu.magisk.extensions.subscribeK import com.topjohnwu.magisk.extensions.subscribeK
import com.topjohnwu.magisk.extensions.writeTo import com.topjohnwu.magisk.extensions.writeTo
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.* import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Module
import com.topjohnwu.superuser.ShellUtils import com.topjohnwu.superuser.ShellUtils
import io.reactivex.Completable import io.reactivex.Completable
import okhttp3.ResponseBody import okhttp3.ResponseBody
...@@ -27,19 +28,17 @@ abstract class RemoteFileService : NotificationService() { ...@@ -27,19 +28,17 @@ abstract class RemoteFileService : NotificationService() {
val service: GithubRawServices by inject() val service: GithubRawServices by inject()
override val defaultNotification
get() = Notifications.progress(this, "")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
intent?.getParcelableExtra<DownloadSubject>(ARG_URL)?.let { start(it) } intent?.getParcelableExtra<DownloadSubject>(ARG_URL)?.let { start(it) }
return START_REDELIVER_INTENT return START_REDELIVER_INTENT
} }
override fun createNotification() = Notifications.progress(this, "")
// --- // ---
private fun start(subject: DownloadSubject) = checkExisting(subject) private fun start(subject: DownloadSubject) = checkExisting(subject)
.onErrorResumeNext { download(subject) } .onErrorResumeNext { download(subject) }
.doOnSubscribe { update(subject.hashCode()) { it.setContentTitle(subject.title) } }
.subscribeK(onError = { .subscribeK(onError = {
Timber.e(it) Timber.e(it)
failNotify(subject) failNotify(subject)
...@@ -52,16 +51,14 @@ abstract class RemoteFileService : NotificationService() { ...@@ -52,16 +51,14 @@ abstract class RemoteFileService : NotificationService() {
private fun checkExisting(subject: DownloadSubject) = Completable.fromAction { private fun checkExisting(subject: DownloadSubject) = Completable.fromAction {
check(subject is Magisk) { "Download cache is disabled" } check(subject is Magisk) { "Download cache is disabled" }
check(subject.file.exists() &&
subject.file.also { ShellUtils.checkSum("MD5", subject.file, subject.magisk.md5)) {
check(it.exists() && ShellUtils.checkSum("MD5", it, subject.magisk.md5)) { "The given file does not match checksum"
"The given file does not match checksum"
}
} }
} }
private fun download(subject: DownloadSubject) = service.fetchFile(subject.url) private fun download(subject: DownloadSubject) = service.fetchFile(subject.url)
.map { it.toStream(subject.hashCode(), subject) } .map { it.toProgressStream(subject) }
.flatMapCompletable { stream -> .flatMapCompletable { stream ->
when (subject) { when (subject) {
is Module -> service.fetchInstaller() is Module -> service.fetchInstaller()
...@@ -69,14 +66,14 @@ abstract class RemoteFileService : NotificationService() { ...@@ -69,14 +66,14 @@ abstract class RemoteFileService : NotificationService() {
.ignoreElement() .ignoreElement()
else -> Completable.fromAction { stream.writeTo(subject.file) } else -> Completable.fromAction { stream.writeTo(subject.file) }
} }
}.doOnComplete {
if (subject is Manager)
handleAPK(subject)
} }
private fun ResponseBody.toStream(id: Int, subject: DownloadSubject): InputStream { private fun ResponseBody.toProgressStream(subject: DownloadSubject): InputStream {
val maxRaw = contentLength() val maxRaw = contentLength()
val max = maxRaw / 1_000_000f val max = maxRaw / 1_000_000f
val id = subject.hashCode()
update(id) { it.setContentTitle(subject.title) }
return ProgressInputStream(byteStream()) { return ProgressInputStream(byteStream()) {
val progress = it / 1_000_000f val progress = it / 1_000_000f
...@@ -94,14 +91,14 @@ abstract class RemoteFileService : NotificationService() { ...@@ -94,14 +91,14 @@ abstract class RemoteFileService : NotificationService() {
} }
} }
private fun failNotify(subject: DownloadSubject) = finishNotify(subject.hashCode()) { private fun failNotify(subject: DownloadSubject) = lastNotify(subject.hashCode()) {
send(0f, subject) send(0f, subject)
it.setContentText(getString(R.string.download_file_error)) it.setContentText(getString(R.string.download_file_error))
.setSmallIcon(android.R.drawable.stat_notify_error) .setSmallIcon(android.R.drawable.stat_notify_error)
.setOngoing(false) .setOngoing(false)
} }
private fun finishNotify(subject: DownloadSubject) = finishNotify(subject.hashCode()) { private fun finishNotify(subject: DownloadSubject) = lastNotify(subject.hashCode()) {
send(1f, subject) send(1f, subject)
it.addActions(subject) it.addActions(subject)
.setContentText(getString(R.string.download_complete)) .setContentText(getString(R.string.download_complete))
......
package com.topjohnwu.magisk.core.tasks
import androidx.annotation.MainThread
interface FlashResultListener {
@MainThread
fun onResult(success: Boolean)
}
...@@ -18,7 +18,7 @@ abstract class FlashZip( ...@@ -18,7 +18,7 @@ abstract class FlashZip(
private val mUri: Uri, private val mUri: Uri,
private val console: MutableList<String>, private val console: MutableList<String>,
private val logs: MutableList<String> private val logs: MutableList<String>
) { ) : FlashResultListener {
private val context: Context by inject() private val context: Context by inject()
private val installFolder = File(context.cacheDir, "flash").apply { private val installFolder = File(context.cacheDir, "flash").apply {
...@@ -94,6 +94,4 @@ abstract class FlashZip( ...@@ -94,6 +94,4 @@ abstract class FlashZip(
.subscribeK(onError = { onResult(false) }) { onResult(it) } .subscribeK(onError = { onResult(false) }) { onResult(it) }
.let { Unit } // ignores result disposable .let { Unit } // ignores result disposable
protected abstract fun onResult(success: Boolean)
} }
package com.topjohnwu.magisk.model.flash package com.topjohnwu.magisk.core.tasks
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import androidx.core.os.postDelayed import androidx.core.os.postDelayed
import com.topjohnwu.magisk.core.tasks.FlashZip
import com.topjohnwu.magisk.extensions.inject import com.topjohnwu.magisk.extensions.inject
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.UiThreadHandler import com.topjohnwu.superuser.internal.UiThreadHandler
...@@ -28,16 +27,7 @@ sealed class Flashing( ...@@ -28,16 +27,7 @@ sealed class Flashing(
console: MutableList<String>, console: MutableList<String>,
log: MutableList<String>, log: MutableList<String>,
resultListener: FlashResultListener resultListener: FlashResultListener
) : Flashing(uri, console, log, resultListener) { ) : Flashing(uri, console, log, resultListener)
override fun onResult(success: Boolean) {
if (success) {
//Utils.loadModules()
}
super.onResult(success)
}
}
class Uninstall( class Uninstall(
uri: Uri, uri: Uri,
......
...@@ -12,13 +12,13 @@ import androidx.databinding.ObservableArrayList ...@@ -12,13 +12,13 @@ import androidx.databinding.ObservableArrayList
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Config
import com.topjohnwu.magisk.core.Const import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.tasks.FlashResultListener
import com.topjohnwu.magisk.core.tasks.Flashing
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.extensions.* import com.topjohnwu.magisk.extensions.*
import com.topjohnwu.magisk.model.binding.BindingAdapter import com.topjohnwu.magisk.model.binding.BindingAdapter
import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem import com.topjohnwu.magisk.model.entity.recycler.ConsoleItem
import com.topjohnwu.magisk.model.events.SnackbarEvent import com.topjohnwu.magisk.model.events.SnackbarEvent
import com.topjohnwu.magisk.model.flash.FlashResultListener
import com.topjohnwu.magisk.model.flash.Flashing
import com.topjohnwu.magisk.model.flash.Patching
import com.topjohnwu.magisk.ui.base.BaseViewModel import com.topjohnwu.magisk.ui.base.BaseViewModel
import com.topjohnwu.magisk.ui.base.diffListOf import com.topjohnwu.magisk.ui.base.diffListOf
import com.topjohnwu.magisk.ui.base.itemBindingOf import com.topjohnwu.magisk.ui.base.itemBindingOf
...@@ -60,26 +60,26 @@ class FlashViewModel( ...@@ -60,26 +60,26 @@ class FlashViewModel(
Const.Value.UNINSTALL -> Flashing Const.Value.UNINSTALL -> Flashing
.Uninstall(installer, outItems, logItems, this) .Uninstall(installer, outItems, logItems, this)
.exec() .exec()
Const.Value.FLASH_MAGISK -> Patching Const.Value.FLASH_MAGISK -> MagiskInstaller
.Direct(installer, outItems, logItems, this) .Direct(installer, outItems, logItems, this)
.exec() .exec()
Const.Value.FLASH_INACTIVE_SLOT -> Patching Const.Value.FLASH_INACTIVE_SLOT -> MagiskInstaller
.SecondSlot(installer, outItems, logItems, this) .SecondSlot(installer, outItems, logItems, this)
.exec() .exec()
Const.Value.PATCH_FILE -> Patching Const.Value.PATCH_FILE -> MagiskInstaller
.File(installer, uri ?: return, outItems, logItems, this) .Patch(installer, uri ?: return, outItems, logItems, this)
.exec() .exec()
} }
} }
override fun onResult(isSuccess: Boolean) { override fun onResult(success: Boolean) {
state = if (isSuccess) State.LOADED else State.LOADING_FAILED state = if (success) State.LOADED else State.LOADING_FAILED
behaviorText.value = when { behaviorText.value = when {
isSuccess -> resources.getString(R.string.done) success -> resources.getString(R.string.done)
else -> resources.getString(R.string.failure) else -> resources.getString(R.string.failure)
} }
if (isSuccess) { if (success) {
Handler().postDelayed(500) { Handler().postDelayed(500) {
showRestartTitle.value = true showRestartTitle.value = true
} }
......
...@@ -31,7 +31,10 @@ sealed class Configuration : Parcelable { ...@@ -31,7 +31,10 @@ sealed class Configuration : Parcelable {
@Parcelize @Parcelize
object Uninstall : Configuration() object Uninstall : Configuration()
@Parcelize
object EnvFix : Configuration()
@Parcelize @Parcelize
data class Patch(val fileUri: Uri) : Configuration() data class Patch(val fileUri: Uri) : Configuration()
} }
\ No newline at end of file
...@@ -20,7 +20,7 @@ sealed class DownloadSubject : Parcelable { ...@@ -20,7 +20,7 @@ sealed class DownloadSubject : Parcelable {
open val title: String get() = file.name open val title: String get() = file.name
@Parcelize @Parcelize
data class Module( class Module(
val module: Repo, val module: Repo,
val configuration: Configuration val configuration: Configuration
) : DownloadSubject() { ) : DownloadSubject() {
...@@ -33,7 +33,7 @@ sealed class DownloadSubject : Parcelable { ...@@ -33,7 +33,7 @@ sealed class DownloadSubject : Parcelable {
} }
@Parcelize @Parcelize
data class Manager( class Manager(
val configuration: Configuration.APK val configuration: Configuration.APK
) : DownloadSubject() { ) : DownloadSubject() {
...@@ -53,13 +53,13 @@ sealed class DownloadSubject : Parcelable { ...@@ -53,13 +53,13 @@ sealed class DownloadSubject : Parcelable {
} }
sealed class Magisk : DownloadSubject() { abstract class Magisk : DownloadSubject() {
abstract val configuration: Configuration abstract val configuration: Configuration
val magisk: MagiskJson = Info.remote.magisk val magisk: MagiskJson = Info.remote.magisk
@Parcelize @Parcelize
data class Flash( private class DownloadInternal(
override val configuration: Configuration override val configuration: Configuration
) : Magisk() { ) : Magisk() {
override val url: String get() = magisk.link override val url: String get() = magisk.link
...@@ -72,8 +72,8 @@ sealed class DownloadSubject : Parcelable { ...@@ -72,8 +72,8 @@ sealed class DownloadSubject : Parcelable {
} }
@Parcelize @Parcelize
class Uninstall : Magisk() { private class Uninstall : Magisk() {
override val configuration: Configuration get() = Configuration.Uninstall override val configuration get() = Configuration.Uninstall
override val url: String get() = Info.remote.uninstaller.link override val url: String get() = Info.remote.uninstaller.link
@IgnoredOnParcel @IgnoredOnParcel
...@@ -83,8 +83,8 @@ sealed class DownloadSubject : Parcelable { ...@@ -83,8 +83,8 @@ sealed class DownloadSubject : Parcelable {
} }
@Parcelize @Parcelize
class Download : Magisk() { private class Download : Magisk() {
override val configuration: Configuration get() = Configuration.Download override val configuration get() = Configuration.Download
override val url: String get() = magisk.link override val url: String get() = magisk.link
@IgnoredOnParcel @IgnoredOnParcel
...@@ -97,7 +97,8 @@ sealed class DownloadSubject : Parcelable { ...@@ -97,7 +97,8 @@ sealed class DownloadSubject : Parcelable {
operator fun invoke(configuration: Configuration) = when (configuration) { operator fun invoke(configuration: Configuration) = when (configuration) {
Configuration.Download -> Download() Configuration.Download -> Download()
Configuration.Uninstall -> Uninstall() Configuration.Uninstall -> Uninstall()
else -> Flash(configuration) Configuration.EnvFix, is Configuration.Flash -> DownloadInternal(configuration)
else -> throw IllegalArgumentException()
} }
} }
......
package com.topjohnwu.magisk.model.events.dialog package com.topjohnwu.magisk.model.events.dialog
import android.content.DialogInterface import android.content.BroadcastReceiver
import android.widget.Toast import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.core.tasks.MagiskInstaller import com.topjohnwu.magisk.core.download.DownloadService
import com.topjohnwu.magisk.core.utils.Utils import com.topjohnwu.magisk.model.entity.internal.Configuration.EnvFix
import com.topjohnwu.magisk.extensions.reboot import com.topjohnwu.magisk.model.entity.internal.DownloadSubject.Magisk
import com.topjohnwu.magisk.view.MagiskDialog import com.topjohnwu.magisk.view.MagiskDialog
import com.topjohnwu.superuser.internal.UiThreadHandler
import org.koin.core.KoinComponent
class EnvFixDialog : DialogEvent() { class EnvFixDialog : DialogEvent() {
...@@ -21,14 +22,16 @@ class EnvFixDialog : DialogEvent() { ...@@ -21,14 +22,16 @@ class EnvFixDialog : DialogEvent() {
onClick { onClick {
dialog.applyTitle(R.string.setup_title) dialog.applyTitle(R.string.setup_title)
.applyMessage(R.string.setup_msg) .applyMessage(R.string.setup_msg)
.applyButton(MagiskDialog.ButtonType.POSITIVE) { .resetButtons()
title = ""
}
.applyButton(MagiskDialog.ButtonType.NEGATIVE) {
title = ""
}
.cancellable(false) .cancellable(false)
fixEnv(it) val lbm = LocalBroadcastManager.getInstance(dialog.context)
lbm.registerReceiver(object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
dialog.dismiss()
lbm.unregisterReceiver(this)
}
}, IntentFilter(DISMISS))
DownloadService(dialog.context) { subject = Magisk(EnvFix) }
} }
} }
.applyButton(MagiskDialog.ButtonType.NEGATIVE) { .applyButton(MagiskDialog.ButtonType.NEGATIVE) {
...@@ -36,20 +39,7 @@ class EnvFixDialog : DialogEvent() { ...@@ -36,20 +39,7 @@ class EnvFixDialog : DialogEvent() {
} }
.let { Unit } .let { Unit }
private fun fixEnv(dialog: DialogInterface) { companion object {
object : MagiskInstaller(), KoinComponent { const val DISMISS = "com.topjohnwu.magisk.ENV_DONE"
override fun operations() = fixEnv()
override fun onResult(success: Boolean) {
dialog.dismiss()
Utils.toast(
if (success) R.string.reboot_delay_toast else R.string.setup_fail,
Toast.LENGTH_LONG
)
if (success)
UiThreadHandler.handler.postDelayed({ reboot() }, 5000)
}
}.exec()
} }
} }
package com.topjohnwu.magisk.model.flash
interface FlashResultListener {
fun onResult(isSuccess: Boolean)
}
\ No newline at end of file
package com.topjohnwu.magisk.model.flash
import android.net.Uri
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.superuser.Shell
sealed class Patching(
file: Uri,
private val console: MutableList<String>,
logs: MutableList<String>,
private val resultListener: FlashResultListener
) : MagiskInstaller(file, console, logs) {
override fun onResult(success: Boolean) {
if (success) {
console.add("- All done!")
} else {
Shell.sh("rm -rf $installDir").submit()
console.add("! Installation failed")
}
resultListener.onResult(success)
}
class File(
file: Uri,
private val uri: Uri,
console: MutableList<String>,
logs: MutableList<String>,
resultListener: FlashResultListener
) : Patching(file, console, logs, resultListener) {
override fun operations() = doPatchFile(uri)
}
class SecondSlot(
file: Uri,
console: MutableList<String>,
logs: MutableList<String>,
resultListener: FlashResultListener
) : Patching(file, console, logs, resultListener) {
override fun operations() = secondSlot()
}
class Direct(
file: Uri,
console: MutableList<String>,
logs: MutableList<String>,
resultListener: FlashResultListener
) : Patching(file, console, logs, resultListener) {
override fun operations() = direct()
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment