From 9100186dcefebfcb97fc879db7255f4e8b76e9a9 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Mon, 18 Jan 2021 13:32:10 -0800 Subject: [PATCH] Make emulator direct install env fix --- .../java/com/topjohnwu/magisk/core/Info.kt | 21 +++++ .../magisk/core/tasks/MagiskInstaller.kt | 78 ++++++++++--------- .../magisk/ui/flash/FlashViewModel.kt | 6 +- .../magisk/ui/install/InstallViewModel.kt | 3 +- .../main/res/layout/fragment_install_md2.xml | 2 +- 5 files changed, 72 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Info.kt b/app/src/main/java/com/topjohnwu/magisk/core/Info.kt index 1e1753c4a..ee9b8bf02 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Info.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Info.kt @@ -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()) { diff --git a/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt b/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt index e3a31a4bc..eebb6ddf9 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/tasks/MagiskInstaller.kt @@ -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 = NOPList.getInstance(), + private val logs: MutableList = NOPList.getInstance() +) : KoinComponent { protected lateinit var installDir: File private lateinit var srcBoot: String - private lateinit var zipUri: Uri - protected val console: MutableList - private val logs: MutableList 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() init { @@ -75,15 +71,6 @@ abstract class MagiskInstallImpl : KoinComponent { } } - protected constructor(zip: Uri, out: MutableList, err: MutableList) { - console = out - logs = err - zipUri = zip - installDir = File(get(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.sh() = Shell.sh(*this).to(console, logs).exec() private fun String.fsh() = ShellUtils.fastCmd(this) private fun Array.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, logs: MutableList -) : MagiskInstallImpl(file, console, logs) { +) : MagiskInstallImpl(zip, console, logs) { + + init { + installDir = File(get(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, logs: MutableList - ) : MagiskInstaller(file, console, logs) { + ) : MagiskInstaller(zip, console, logs) { override suspend fun operations() = doPatchFile(uri) } class SecondSlot( - file: Uri, + zip: Uri, console: MutableList, logs: MutableList - ) : MagiskInstaller(file, console, logs) { + ) : MagiskInstaller(zip, console, logs) { override suspend fun operations() = secondSlot() } class Direct( - file: Uri, + zip: Uri, console: MutableList, logs: MutableList - ) : MagiskInstaller(file, console, logs) { + ) : MagiskInstaller(zip, console, logs) { override suspend fun operations() = direct() } + class Emulator( + zip: Uri, + console: MutableList, + logs: MutableList + ) : 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() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashViewModel.kt index 35fd8a6a7..ca97e0be5 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/flash/FlashViewModel.kt @@ -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,7 +70,10 @@ class FlashViewModel( FlashZip.Uninstall(installer, outItems, logItems).exec() } Const.Value.FLASH_MAGISK -> { - MagiskInstaller.Direct(installer, outItems, logItems).exec() + if (Info.isEmulator) + MagiskInstaller.Emulator(installer, outItems, logItems).exec() + else + MagiskInstaller.Direct(installer, outItems, logItems).exec() } Const.Value.FLASH_INACTIVE_SLOT -> { MagiskInstaller.SecondSlot(installer, outItems, logItems).exec() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt index 010725a27..ad5e72149 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/install/InstallViewModel.kt @@ -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 diff --git a/app/src/main/res/layout/fragment_install_md2.xml b/app/src/main/res/layout/fragment_install_md2.xml index 6e3235372..1555928a6 100644 --- a/app/src/main/res/layout/fragment_install_md2.xml +++ b/app/src/main/res/layout/fragment_install_md2.xml @@ -214,7 +214,7 @@