You've already forked Magisk
mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-09-06 06:36:58 +00:00
Redesign is now the new norm
This commit is contained in:
@@ -1,115 +0,0 @@
|
||||
package com.topjohnwu.magisk.ui.flash
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.core.net.toUri
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.BaseActivity
|
||||
import com.topjohnwu.magisk.databinding.ActivityFlashBinding
|
||||
import com.topjohnwu.magisk.extensions.snackbar
|
||||
import com.topjohnwu.magisk.intent
|
||||
import com.topjohnwu.magisk.model.events.BackPressEvent
|
||||
import com.topjohnwu.magisk.model.events.PermissionEvent
|
||||
import com.topjohnwu.magisk.model.events.SnackbarEvent
|
||||
import com.topjohnwu.magisk.model.events.ViewEvent
|
||||
import com.topjohnwu.magisk.view.Notifications
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koin.core.parameter.parametersOf
|
||||
import java.io.File
|
||||
|
||||
open class FlashActivity : BaseActivity<FlashViewModel, ActivityFlashBinding>() {
|
||||
|
||||
override val layoutRes: Int = R.layout.activity_flash
|
||||
override val themeRes: Int = R.style.MagiskTheme_Flashing
|
||||
override val viewModel: FlashViewModel by viewModel {
|
||||
val uri = intent.data ?: let { finish(); Uri.EMPTY }
|
||||
val additionalUri = intent.getParcelableExtra(Const.Key.FLASH_DATA) ?: uri
|
||||
val action = intent.getStringExtra(Const.Key.FLASH_ACTION) ?: let { finish();"" }
|
||||
parametersOf(action, uri, additionalUri)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
|
||||
super.onCreate(savedInstanceState)
|
||||
val id = intent.getIntExtra(Const.Key.DISMISS_ID, -1)
|
||||
if (id != -1)
|
||||
Notifications.mgr.cancel(id)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (viewModel.loading) return
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is SnackbarEvent -> snackbar(snackbarView, event.message(this), event.length, event.f)
|
||||
is BackPressEvent -> onBackPressed()
|
||||
is PermissionEvent -> withPermissions(*event.permissions.toTypedArray()) {
|
||||
onSuccess { event.callback.onNext(true) }
|
||||
onFailure {
|
||||
event.callback.onNext(false)
|
||||
event.callback.onError(SecurityException("User refused permissions"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private fun intent(context: Context) = context.intent<FlashActivity>()
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
private fun intent(context: Context, file: File) = intent(context).setData(file.toUri())
|
||||
|
||||
private fun flashType(isSecondSlot: Boolean) =
|
||||
if (isSecondSlot) Const.Value.FLASH_INACTIVE_SLOT else Const.Value.FLASH_MAGISK
|
||||
|
||||
/* Flashing is understood as installing / flashing magisk itself */
|
||||
|
||||
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, 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, 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, id: Int) =
|
||||
context.startActivity(patchIntent(context, file, uri, id))
|
||||
|
||||
/* Uninstalling is understood as removing magisk entirely */
|
||||
|
||||
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, id: Int) =
|
||||
context.startActivity(uninstallIntent(context, file, id))
|
||||
|
||||
/* Installing is understood as flashing modules / zips */
|
||||
|
||||
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, id: Int) =
|
||||
context.startActivity(installIntent(context, file, id))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.topjohnwu.magisk.ui.flash
|
||||
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.databinding.FragmentFlashMd2Binding
|
||||
import com.topjohnwu.magisk.ui.compat.CompatFragment
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
class FlashFragment : CompatFragment<FlashViewModel, FragmentFlashMd2Binding>() {
|
||||
|
||||
override val layoutRes = R.layout.fragment_flash_md2
|
||||
override val viewModel by viewModel<FlashViewModel>()
|
||||
|
||||
}
|
||||
@@ -1,110 +1,5 @@
|
||||
package com.topjohnwu.magisk.ui.flash
|
||||
|
||||
import android.Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
import android.content.res.Resources
|
||||
import android.net.Uri
|
||||
import android.os.Handler
|
||||
import androidx.core.os.postDelayed
|
||||
import androidx.databinding.ObservableArrayList
|
||||
import com.topjohnwu.magisk.BR
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.base.viewmodel.BaseViewModel
|
||||
import com.topjohnwu.magisk.databinding.ComparableRvItem
|
||||
import com.topjohnwu.magisk.extensions.*
|
||||
import com.topjohnwu.magisk.model.entity.recycler.ConsoleRvItem
|
||||
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.utils.DiffObservableList
|
||||
import com.topjohnwu.magisk.utils.KObservableField
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import me.tatarka.bindingcollectionadapter2.ItemBinding
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import com.topjohnwu.magisk.ui.compat.CompatViewModel
|
||||
|
||||
class FlashViewModel(
|
||||
action: String,
|
||||
installer: Uri,
|
||||
uri: Uri,
|
||||
private val resources: Resources
|
||||
) : BaseViewModel(), FlashResultListener {
|
||||
|
||||
val canShowReboot = Shell.rootAccess()
|
||||
val showRestartTitle = KObservableField(false)
|
||||
|
||||
val behaviorText = KObservableField(resources.getString(R.string.flashing))
|
||||
|
||||
val items = DiffObservableList(ComparableRvItem.callback)
|
||||
val itemBinding = ItemBinding.of<ComparableRvItem<*>> { itemBinding, _, item ->
|
||||
item.bind(itemBinding)
|
||||
itemBinding.bindExtra(BR.viewModel, this@FlashViewModel)
|
||||
}
|
||||
|
||||
private val outItems = ObservableArrayList<String>()
|
||||
private val logItems = Collections.synchronizedList(mutableListOf<String>())
|
||||
|
||||
init {
|
||||
outItems.sendUpdatesTo(items) { it.map { ConsoleRvItem(it) } }
|
||||
outItems.copyNewInputInto(logItems)
|
||||
|
||||
state = State.LOADING
|
||||
|
||||
when (action) {
|
||||
Const.Value.FLASH_ZIP -> Flashing
|
||||
.Install(installer, outItems, logItems, this)
|
||||
.exec()
|
||||
Const.Value.UNINSTALL -> Flashing
|
||||
.Uninstall(installer, outItems, logItems, this)
|
||||
.exec()
|
||||
Const.Value.FLASH_MAGISK -> Patching
|
||||
.Direct(installer, outItems, logItems, this)
|
||||
.exec()
|
||||
Const.Value.FLASH_INACTIVE_SLOT -> Patching
|
||||
.SecondSlot(installer, outItems, logItems, this)
|
||||
.exec()
|
||||
Const.Value.PATCH_FILE -> Patching
|
||||
.File(installer, uri, outItems, logItems, this)
|
||||
.exec()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResult(isSuccess: Boolean) {
|
||||
state = if (isSuccess) State.LOADED else State.LOADING_FAILED
|
||||
behaviorText.value = when {
|
||||
isSuccess -> resources.getString(R.string.done)
|
||||
else -> resources.getString(R.string.failure)
|
||||
}
|
||||
|
||||
if (isSuccess) {
|
||||
Handler().postDelayed(500) {
|
||||
showRestartTitle.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun savePressed() = withPermissions(READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE)
|
||||
.map { now }
|
||||
.map { it.toTime(timeFormatStandard) }
|
||||
.map { Const.MAGISK_INSTALL_LOG_FILENAME.format(it) }
|
||||
.map { File(Config.downloadDirectory, it) }
|
||||
.map { file ->
|
||||
file.bufferedWriter().use { writer ->
|
||||
logItems.forEach {
|
||||
writer.write(it)
|
||||
writer.newLine()
|
||||
}
|
||||
}
|
||||
file.path
|
||||
}
|
||||
.subscribeK { SnackbarEvent(it).publish() }
|
||||
.add()
|
||||
|
||||
fun restartPressed() = reboot()
|
||||
|
||||
fun backPressed() = back()
|
||||
|
||||
}
|
||||
class FlashViewModel : CompatViewModel()
|
||||
|
||||
Reference in New Issue
Block a user