Commit 9100186d authored by topjohnwu's avatar topjohnwu

Make emulator direct install env fix

parent d2bc2cfc
package com.topjohnwu.magisk.core package com.topjohnwu.magisk.core
import android.os.Build
import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableBoolean
import com.topjohnwu.magisk.DynAPK import com.topjohnwu.magisk.DynAPK
import com.topjohnwu.magisk.core.model.UpdateInfo import com.topjohnwu.magisk.core.model.UpdateInfo
...@@ -37,6 +38,26 @@ object Info { ...@@ -37,6 +38,26 @@ object Info {
@JvmStatic var isPixel = false @JvmStatic var isPixel = false
@JvmStatic val cryptoText get() = crypto.capitalize(Locale.US) @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 { val isConnected by lazy {
ObservableBoolean(false).also { field -> ObservableBoolean(false).also { field ->
NetworkObserver.observe(get()) { NetworkObserver.observe(get()) {
......
...@@ -46,25 +46,21 @@ import java.security.SecureRandom ...@@ -46,25 +46,21 @@ import java.security.SecureRandom
import java.util.* import java.util.*
import java.util.zip.ZipEntry import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream 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 protected lateinit var installDir: File
private lateinit var srcBoot: String 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 var tarOut: TarOutputStream? = null
private val service: NetworkService by inject() private val service: NetworkService by inject()
protected val context: Context by inject() protected val context: Context by inject()
protected constructor() {
console = NOPList.getInstance()
logs = NOPList.getInstance()
}
companion object { companion object {
private val ABI_MAP = TreeMap<String, String>() private val ABI_MAP = TreeMap<String, String>()
init { init {
...@@ -75,15 +71,6 @@ abstract class MagiskInstallImpl : KoinComponent { ...@@ -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 { private fun findImage(): Boolean {
srcBoot = "find_boot_image; echo \"\$BOOTIMAGE\"".fsh() srcBoot = "find_boot_image; echo \"\$BOOTIMAGE\"".fsh()
if (srcBoot.isEmpty()) { if (srcBoot.isEmpty()) {
...@@ -416,7 +403,7 @@ abstract class MagiskInstallImpl : KoinComponent { ...@@ -416,7 +403,7 @@ abstract class MagiskInstallImpl : KoinComponent {
return true 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 Array<String>.sh() = Shell.sh(*this).to(console, logs).exec()
private fun String.fsh() = ShellUtils.fastCmd(this) private fun String.fsh() = ShellUtils.fastCmd(this)
private fun Array<String>.fsh() = ShellUtils.fastCmd(*this) private fun Array<String>.fsh() = ShellUtils.fastCmd(*this)
...@@ -429,10 +416,9 @@ abstract class MagiskInstallImpl : KoinComponent { ...@@ -429,10 +416,9 @@ abstract class MagiskInstallImpl : KoinComponent {
protected suspend fun secondSlot() = findSecondaryImage() && extractZip() && protected suspend fun secondSlot() = findSecondaryImage() && extractZip() &&
patchBoot() && copySepolicyRules() && flashBoot() && postOTA() patchBoot() && copySepolicyRules() && flashBoot() && postOTA()
protected fun fixEnv(zip: Uri): Boolean { protected fun fixEnv(): Boolean {
installDir = SuFile("/data/adb/magisk") installDir = SuFile("/data/adb/magisk")
Shell.su("rm -rf /data/adb/magisk/*").exec() Shell.su("rm -rf /data/adb/magisk/*").exec()
zipUri = zip
return extractZip() && Shell.su("fix_env").exec().isSuccess return extractZip() && Shell.su("fix_env").exec().isSuccess
} }
...@@ -442,11 +428,17 @@ abstract class MagiskInstallImpl : KoinComponent { ...@@ -442,11 +428,17 @@ abstract class MagiskInstallImpl : KoinComponent {
open suspend fun exec() = withContext(Dispatchers.IO) { operations() } open suspend fun exec() = withContext(Dispatchers.IO) { operations() }
} }
sealed class MagiskInstaller( abstract class MagiskInstaller(
file: Uri, zip: Uri,
console: MutableList<String>, console: MutableList<String>,
logs: 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 { override suspend fun exec(): Boolean {
val success = super.exec() val success = super.exec()
...@@ -460,36 +452,52 @@ sealed class MagiskInstaller( ...@@ -460,36 +452,52 @@ sealed class MagiskInstaller(
} }
class Patch( class Patch(
file: Uri, zip: Uri,
private val uri: Uri, private val uri: Uri,
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstaller(file, console, logs) { ) : MagiskInstaller(zip, console, logs) {
override suspend fun operations() = doPatchFile(uri) override suspend fun operations() = doPatchFile(uri)
} }
class SecondSlot( class SecondSlot(
file: Uri, zip: Uri,
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstaller(file, console, logs) { ) : MagiskInstaller(zip, console, logs) {
override suspend fun operations() = secondSlot() override suspend fun operations() = secondSlot()
} }
class Direct( class Direct(
file: Uri, zip: Uri,
console: MutableList<String>, console: MutableList<String>,
logs: MutableList<String> logs: MutableList<String>
) : MagiskInstaller(file, console, logs) { ) : MagiskInstaller(zip, console, logs) {
override suspend fun operations() = direct() 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( class EnvFixTask(zip: Uri) : MagiskInstallImpl(zip) {
private val zip: Uri
) : MagiskInstallImpl() { override suspend fun operations() = fixEnv()
override suspend fun operations() = fixEnv(zip)
override suspend fun exec(): Boolean { override suspend fun exec(): Boolean {
val success = super.exec() val success = super.exec()
......
...@@ -12,6 +12,7 @@ import com.topjohnwu.magisk.arch.BaseViewModel ...@@ -12,6 +12,7 @@ import com.topjohnwu.magisk.arch.BaseViewModel
import com.topjohnwu.magisk.arch.diffListOf import com.topjohnwu.magisk.arch.diffListOf
import com.topjohnwu.magisk.arch.itemBindingOf import com.topjohnwu.magisk.arch.itemBindingOf
import com.topjohnwu.magisk.core.Const 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.FlashZip
import com.topjohnwu.magisk.core.tasks.MagiskInstaller import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.core.utils.MediaStoreUtils import com.topjohnwu.magisk.core.utils.MediaStoreUtils
...@@ -69,7 +70,10 @@ class FlashViewModel( ...@@ -69,7 +70,10 @@ class FlashViewModel(
FlashZip.Uninstall(installer, outItems, logItems).exec() FlashZip.Uninstall(installer, outItems, logItems).exec()
} }
Const.Value.FLASH_MAGISK -> { 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 -> { Const.Value.FLASH_INACTIVE_SLOT -> {
MagiskInstaller.SecondSlot(installer, outItems, logItems).exec() MagiskInstaller.SecondSlot(installer, outItems, logItems).exec()
......
...@@ -27,7 +27,8 @@ class InstallViewModel( ...@@ -27,7 +27,8 @@ class InstallViewModel(
) : BaseViewModel(State.LOADED) { ) : BaseViewModel(State.LOADED) {
val isRooted = Shell.rootAccess() 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 @get:Bindable
var step = if (skipOptions) 1 else 0 var step = if (skipOptions) 1 else 0
......
...@@ -214,7 +214,7 @@ ...@@ -214,7 +214,7 @@
<RadioButton <RadioButton
android:id="@+id/method_inactive_slot" android:id="@+id/method_inactive_slot"
style="@style/WidgetFoundation.RadioButton" style="@style/WidgetFoundation.RadioButton"
gone="@{!viewModel.isRooted || Info.isPixel || !Info.isAB}" gone="@{viewModel.noSecondSlot}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/install_inactive_slot" /> android:text="@string/install_inactive_slot" />
......
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