Make emulator direct install env fix

This commit is contained in:
topjohnwu 2021-01-18 13:32:10 -08:00
parent d2bc2cfcf8
commit 9100186dce
5 changed files with 72 additions and 38 deletions

View File

@ -1,5 +1,6 @@
package com.topjohnwu.magisk.core
import android.os.Build
import androidx.databinding.ObservableBoolean
import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.core.model.UpdateInfo
@ -37,6 +38,26 @@ object Info {
@JvmStatic var isPixel = false
@JvmStatic val cryptoText get() = crypto.capitalize(Locale.US)
@JvmStatic
val isEmulator: Boolean get() {
return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
|| Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.HARDWARE.contains("goldfish")
|| Build.HARDWARE.contains("ranchu")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.PRODUCT.contains("sdk_google")
|| Build.PRODUCT.contains("google_sdk")
|| Build.PRODUCT.contains("sdk")
|| Build.PRODUCT.contains("sdk_x86")
|| Build.PRODUCT.contains("vbox86p")
|| Build.PRODUCT.contains("emulator")
|| Build.PRODUCT.contains("simulator"))
}
val isConnected by lazy {
ObservableBoolean(false).also { field ->
NetworkObserver.observe(get()) {

View File

@ -46,25 +46,21 @@ import java.security.SecureRandom
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import kotlin.collections.set
abstract class MagiskInstallImpl : KoinComponent {
abstract class MagiskInstallImpl protected constructor(
private var zipUri: Uri,
protected val console: MutableList<String> = NOPList.getInstance(),
private val logs: MutableList<String> = NOPList.getInstance()
) : KoinComponent {
protected lateinit var installDir: File
private lateinit var srcBoot: String
private lateinit var zipUri: Uri
protected val console: MutableList<String>
private val logs: MutableList<String>
private var tarOut: TarOutputStream? = null
private val service: NetworkService by inject()
protected val context: Context by inject()
protected constructor() {
console = NOPList.getInstance()
logs = NOPList.getInstance()
}
companion object {
private val ABI_MAP = TreeMap<String, String>()
init {
@ -75,15 +71,6 @@ abstract class MagiskInstallImpl : KoinComponent {
}
}
protected constructor(zip: Uri, out: MutableList<String>, err: MutableList<String>) {
console = out
logs = err
zipUri = zip
installDir = File(get<Context>(Protected).filesDir.parent, "install")
"rm -rf $installDir".sh()
installDir.mkdirs()
}
private fun findImage(): Boolean {
srcBoot = "find_boot_image; echo \"\$BOOTIMAGE\"".fsh()
if (srcBoot.isEmpty()) {
@ -416,7 +403,7 @@ abstract class MagiskInstallImpl : KoinComponent {
return true
}
private fun String.sh() = Shell.sh(this).to(console, logs).exec()
protected fun String.sh() = Shell.sh(this).to(console, logs).exec()
private fun Array<String>.sh() = Shell.sh(*this).to(console, logs).exec()
private fun String.fsh() = ShellUtils.fastCmd(this)
private fun Array<String>.fsh() = ShellUtils.fastCmd(*this)
@ -429,10 +416,9 @@ abstract class MagiskInstallImpl : KoinComponent {
protected suspend fun secondSlot() = findSecondaryImage() && extractZip() &&
patchBoot() && copySepolicyRules() && flashBoot() && postOTA()
protected fun fixEnv(zip: Uri): Boolean {
protected fun fixEnv(): Boolean {
installDir = SuFile("/data/adb/magisk")
Shell.su("rm -rf /data/adb/magisk/*").exec()
zipUri = zip
return extractZip() && Shell.su("fix_env").exec().isSuccess
}
@ -442,11 +428,17 @@ abstract class MagiskInstallImpl : KoinComponent {
open suspend fun exec() = withContext(Dispatchers.IO) { operations() }
}
sealed class MagiskInstaller(
file: Uri,
abstract class MagiskInstaller(
zip: Uri,
console: MutableList<String>,
logs: MutableList<String>
) : MagiskInstallImpl(file, console, logs) {
) : MagiskInstallImpl(zip, console, logs) {
init {
installDir = File(get<Context>(Protected).filesDir.parent, "install")
"rm -rf $installDir".sh()
installDir.mkdirs()
}
override suspend fun exec(): Boolean {
val success = super.exec()
@ -460,36 +452,52 @@ sealed class MagiskInstaller(
}
class Patch(
file: Uri,
zip: Uri,
private val uri: Uri,
console: MutableList<String>,
logs: MutableList<String>
) : MagiskInstaller(file, console, logs) {
) : MagiskInstaller(zip, console, logs) {
override suspend fun operations() = doPatchFile(uri)
}
class SecondSlot(
file: Uri,
zip: Uri,
console: MutableList<String>,
logs: MutableList<String>
) : MagiskInstaller(file, console, logs) {
) : MagiskInstaller(zip, console, logs) {
override suspend fun operations() = secondSlot()
}
class Direct(
file: Uri,
zip: Uri,
console: MutableList<String>,
logs: MutableList<String>
) : MagiskInstaller(file, console, logs) {
) : MagiskInstaller(zip, console, logs) {
override suspend fun operations() = direct()
}
class Emulator(
zip: Uri,
console: MutableList<String>,
logs: MutableList<String>
) : MagiskInstallImpl(zip, console, logs) {
override suspend fun operations() = fixEnv()
override suspend fun exec(): Boolean {
val success = super.exec()
if (success) {
console.add("- All done!")
} else {
console.add("! Installation failed")
}
return success
}
}
}
class EnvFixTask(
private val zip: Uri
) : MagiskInstallImpl() {
override suspend fun operations() = fixEnv(zip)
class EnvFixTask(zip: Uri) : MagiskInstallImpl(zip) {
override suspend fun operations() = fixEnv()
override suspend fun exec(): Boolean {
val success = super.exec()

View File

@ -12,6 +12,7 @@ import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.arch.diffListOf
import com.topjohnwu.magisk.arch.itemBindingOf
import com.topjohnwu.magisk.core.Const
import com.topjohnwu.magisk.core.Info
import com.topjohnwu.magisk.core.tasks.FlashZip
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
@ -69,6 +70,9 @@ class FlashViewModel(
FlashZip.Uninstall(installer, outItems, logItems).exec()
}
Const.Value.FLASH_MAGISK -> {
if (Info.isEmulator)
MagiskInstaller.Emulator(installer, outItems, logItems).exec()
else
MagiskInstaller.Direct(installer, outItems, logItems).exec()
}
Const.Value.FLASH_INACTIVE_SLOT -> {

View File

@ -27,7 +27,8 @@ class InstallViewModel(
) : BaseViewModel(State.LOADED) {
val isRooted = Shell.rootAccess()
val skipOptions = Info.ramdisk && !Info.isFDE && Info.isSAR
val skipOptions = Info.isEmulator || (Info.ramdisk && !Info.isFDE && Info.isSAR)
val noSecondSlot = !isRooted || Info.isPixel || !Info.isAB || Info.isEmulator
@get:Bindable
var step = if (skipOptions) 1 else 0

View File

@ -214,7 +214,7 @@
<RadioButton
android:id="@+id/method_inactive_slot"
style="@style/WidgetFoundation.RadioButton"
gone="@{!viewModel.isRooted || Info.isPixel || !Info.isAB}"
gone="@{viewModel.noSecondSlot}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/install_inactive_slot" />