Make emulator direct install env fix
This commit is contained in:
parent
d2bc2cfcf8
commit
9100186dce
@ -1,5 +1,6 @@
|
|||||||
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 {
|
|||||||
@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
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
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,6 +70,9 @@ class FlashViewModel(
|
|||||||
FlashZip.Uninstall(installer, outItems, logItems).exec()
|
FlashZip.Uninstall(installer, outItems, logItems).exec()
|
||||||
}
|
}
|
||||||
Const.Value.FLASH_MAGISK -> {
|
Const.Value.FLASH_MAGISK -> {
|
||||||
|
if (Info.isEmulator)
|
||||||
|
MagiskInstaller.Emulator(installer, outItems, logItems).exec()
|
||||||
|
else
|
||||||
MagiskInstaller.Direct(installer, outItems, logItems).exec()
|
MagiskInstaller.Direct(installer, outItems, logItems).exec()
|
||||||
}
|
}
|
||||||
Const.Value.FLASH_INACTIVE_SLOT -> {
|
Const.Value.FLASH_INACTIVE_SLOT -> {
|
||||||
|
@ -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 @@
|
|||||||
<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" />
|
||||||
|
Loading…
Reference in New Issue
Block a user