mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-24 02:25:28 +00:00
Update libsu
This commit is contained in:
parent
ff340ce3d8
commit
cc79a96fa3
@ -86,10 +86,10 @@ dependencies {
|
|||||||
implementation("${bindingAdapter}:${vBAdapt}")
|
implementation("${bindingAdapter}:${vBAdapt}")
|
||||||
implementation("${bindingAdapter}-recyclerview:${vBAdapt}")
|
implementation("${bindingAdapter}-recyclerview:${vBAdapt}")
|
||||||
|
|
||||||
val vLibsu = "4.0.3"
|
val vLibsu = "5.0.0"
|
||||||
implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
|
implementation("com.github.topjohnwu.libsu:core:${vLibsu}")
|
||||||
implementation("com.github.topjohnwu.libsu:io:${vLibsu}")
|
|
||||||
implementation("com.github.topjohnwu.libsu:service:${vLibsu}")
|
implementation("com.github.topjohnwu.libsu:service:${vLibsu}")
|
||||||
|
implementation("com.github.topjohnwu.libsu:nio:${vLibsu}")
|
||||||
|
|
||||||
val vRetrofit = "2.9.0"
|
val vRetrofit = "2.9.0"
|
||||||
implementation("com.squareup.retrofit2:retrofit:${vRetrofit}")
|
implementation("com.squareup.retrofit2:retrofit:${vRetrofit}")
|
||||||
|
@ -5,4 +5,5 @@ package com.topjohnwu.magisk.core.utils;
|
|||||||
|
|
||||||
interface IRootUtils {
|
interface IRootUtils {
|
||||||
android.app.ActivityManager.RunningAppProcessInfo getAppProcess(int pid);
|
android.app.ActivityManager.RunningAppProcessInfo getAppProcess(int pid);
|
||||||
|
IBinder getFileSystem();
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ abstract class BaseMainActivity<Binding : ViewDataBinding> : NavigationActivity<
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (doPreload) {
|
if (doPreload) {
|
||||||
Shell.getShell(null) {
|
Shell.getShell(Shell.EXECUTOR) {
|
||||||
if (isRunningAsStub && !it.isRoot) {
|
if (isRunningAsStub && !it.isRoot) {
|
||||||
showInvalidStateMessage()
|
showInvalidStateMessage()
|
||||||
return@getShell
|
return@getShell
|
||||||
|
@ -8,7 +8,6 @@ import android.content.res.Configuration
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.topjohnwu.magisk.StubApk
|
import com.topjohnwu.magisk.StubApk
|
||||||
import com.topjohnwu.magisk.core.utils.*
|
import com.topjohnwu.magisk.core.utils.*
|
||||||
import com.topjohnwu.magisk.di.AppContext
|
|
||||||
import com.topjohnwu.magisk.di.ServiceLocator
|
import com.topjohnwu.magisk.di.ServiceLocator
|
||||||
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
import com.topjohnwu.magisk.ui.surequest.SuRequestActivity
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
@ -54,13 +53,11 @@ open class App() : Application() {
|
|||||||
super.attachBaseContext(base)
|
super.attachBaseContext(base)
|
||||||
ServiceLocator.context = base
|
ServiceLocator.context = base
|
||||||
app.registerActivityLifecycleCallbacks(ActivityTracker)
|
app.registerActivityLifecycleCallbacks(ActivityTracker)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
Shell.setDefaultBuilder(Shell.Builder.create()
|
Shell.setDefaultBuilder(Shell.Builder.create()
|
||||||
.setFlags(Shell.FLAG_MOUNT_MASTER)
|
.setFlags(Shell.FLAG_MOUNT_MASTER)
|
||||||
.setInitializers(ShellInit::class.java)
|
.setInitializers(ShellInit::class.java)
|
||||||
|
.setContext(base)
|
||||||
.setTimeout(2))
|
.setTimeout(2))
|
||||||
Shell.EXECUTOR = DispatcherExecutor(Dispatchers.IO)
|
Shell.EXECUTOR = DispatcherExecutor(Dispatchers.IO)
|
||||||
RootUtils.bindTask = RootService.bindOrTask(
|
RootUtils.bindTask = RootService.bindOrTask(
|
||||||
@ -72,7 +69,7 @@ open class App() : Application() {
|
|||||||
Shell.getShell(null) {}
|
Shell.getShell(null) {}
|
||||||
|
|
||||||
refreshLocale()
|
refreshLocale()
|
||||||
AppContext.resources.patch()
|
resources.patch()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
|
@ -8,7 +8,6 @@ import com.topjohnwu.magisk.core.utils.net.NetworkObserver
|
|||||||
import com.topjohnwu.magisk.data.repository.NetworkService
|
import com.topjohnwu.magisk.data.repository.NetworkService
|
||||||
import com.topjohnwu.magisk.di.AppContext
|
import com.topjohnwu.magisk.di.AppContext
|
||||||
import com.topjohnwu.magisk.ktx.getProperty
|
import com.topjohnwu.magisk.ktx.getProperty
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import com.topjohnwu.superuser.ShellUtils.fastCmd
|
import com.topjohnwu.superuser.ShellUtils.fastCmd
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||||
|
|
||||||
@ -36,6 +35,7 @@ object Info {
|
|||||||
@JvmField var vbmeta = false
|
@JvmField var vbmeta = false
|
||||||
var crypto = ""
|
var crypto = ""
|
||||||
var noDataExec = false
|
var noDataExec = false
|
||||||
|
var isRooted = false
|
||||||
|
|
||||||
@JvmField var hasGMS = true
|
@JvmField var hasGMS = true
|
||||||
val isSamsung = Build.MANUFACTURER.equals("samsung", ignoreCase = true)
|
val isSamsung = Build.MANUFACTURER.equals("samsung", ignoreCase = true)
|
||||||
@ -62,7 +62,7 @@ object Info {
|
|||||||
) {
|
) {
|
||||||
val versionCode = when {
|
val versionCode = when {
|
||||||
code < Const.Version.MIN_VERCODE -> -1
|
code < Const.Version.MIN_VERCODE -> -1
|
||||||
else -> if (Shell.rootAccess()) code else -1
|
else -> if (isRooted) code else -1
|
||||||
}
|
}
|
||||||
val isUnsupported = code > 0 && code < Const.Version.MIN_VERCODE
|
val isUnsupported = code > 0 && code < Const.Version.MIN_VERCODE
|
||||||
val isActive = versionCode >= 0
|
val isActive = versionCode >= 0
|
||||||
|
@ -2,9 +2,9 @@ package com.topjohnwu.magisk.core.model.module
|
|||||||
|
|
||||||
import com.squareup.moshi.JsonDataException
|
import com.squareup.moshi.JsonDataException
|
||||||
import com.topjohnwu.magisk.core.Const
|
import com.topjohnwu.magisk.core.Const
|
||||||
|
import com.topjohnwu.magisk.core.utils.RootUtils
|
||||||
import com.topjohnwu.magisk.di.ServiceLocator
|
import com.topjohnwu.magisk.di.ServiceLocator
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import com.topjohnwu.superuser.io.SuFile
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -26,13 +26,13 @@ data class LocalModule(
|
|||||||
var outdated = false
|
var outdated = false
|
||||||
|
|
||||||
private var updateUrl: String = ""
|
private var updateUrl: String = ""
|
||||||
private val removeFile = SuFile(path, "remove")
|
private val removeFile = RootUtils.fs.getFile(path, "remove")
|
||||||
private val disableFile = SuFile(path, "disable")
|
private val disableFile = RootUtils.fs.getFile(path, "disable")
|
||||||
private val updateFile = SuFile(path, "update")
|
private val updateFile = RootUtils.fs.getFile(path, "update")
|
||||||
private val ruleFile = SuFile(path, "sepolicy.rule")
|
private val ruleFile = RootUtils.fs.getFile(path, "sepolicy.rule")
|
||||||
private val riruFolder = SuFile(path, "riru")
|
private val riruFolder = RootUtils.fs.getFile(path, "riru")
|
||||||
private val zygiskFolder = SuFile(path, "zygisk")
|
private val zygiskFolder = RootUtils.fs.getFile(path, "zygisk")
|
||||||
private val unloaded = SuFile(zygiskFolder, "unloaded")
|
private val unloaded = RootUtils.fs.getFile(zygiskFolder, "unloaded")
|
||||||
|
|
||||||
val updated: Boolean get() = updateFile.exists()
|
val updated: Boolean get() = updateFile.exists()
|
||||||
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
|
val isRiru: Boolean get() = (id == "riru-core") || riruFolder.exists()
|
||||||
@ -139,7 +139,7 @@ data class LocalModule(
|
|||||||
private val PERSIST get() = "${Const.MAGISKTMP}/mirror/persist/magisk"
|
private val PERSIST get() = "${Const.MAGISKTMP}/mirror/persist/magisk"
|
||||||
|
|
||||||
suspend fun installed() = withContext(Dispatchers.IO) {
|
suspend fun installed() = withContext(Dispatchers.IO) {
|
||||||
SuFile(Const.MAGISK_PATH)
|
RootUtils.fs.getFile(Const.MAGISK_PATH)
|
||||||
.listFiles()
|
.listFiles()
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.filter { !it.isFile }
|
.filter { !it.isFile }
|
||||||
|
@ -12,6 +12,7 @@ import com.topjohnwu.magisk.core.*
|
|||||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
||||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.inputStream
|
||||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils.outputStream
|
||||||
|
import com.topjohnwu.magisk.core.utils.RootUtils
|
||||||
import com.topjohnwu.magisk.di.ServiceLocator
|
import com.topjohnwu.magisk.di.ServiceLocator
|
||||||
import com.topjohnwu.magisk.ktx.reboot
|
import com.topjohnwu.magisk.ktx.reboot
|
||||||
import com.topjohnwu.magisk.ktx.withStreams
|
import com.topjohnwu.magisk.ktx.withStreams
|
||||||
@ -22,9 +23,8 @@ import com.topjohnwu.superuser.Shell
|
|||||||
import com.topjohnwu.superuser.ShellUtils
|
import com.topjohnwu.superuser.ShellUtils
|
||||||
import com.topjohnwu.superuser.internal.NOPList
|
import com.topjohnwu.superuser.internal.NOPList
|
||||||
import com.topjohnwu.superuser.internal.UiThreadHandler
|
import com.topjohnwu.superuser.internal.UiThreadHandler
|
||||||
import com.topjohnwu.superuser.io.SuFile
|
import com.topjohnwu.superuser.nio.ExtendedFile
|
||||||
import com.topjohnwu.superuser.io.SuFileInputStream
|
import com.topjohnwu.superuser.nio.FileSystemManager
|
||||||
import com.topjohnwu.superuser.io.SuFileOutputStream
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import net.jpountz.lz4.LZ4FrameInputStream
|
import net.jpountz.lz4.LZ4FrameInputStream
|
||||||
@ -45,21 +45,24 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
private val logs: MutableList<String> = NOPList.getInstance()
|
private val logs: MutableList<String> = NOPList.getInstance()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
protected var installDir = File("xxx")
|
protected lateinit var installDir: ExtendedFile
|
||||||
private lateinit var srcBoot: File
|
private lateinit var srcBoot: ExtendedFile
|
||||||
|
|
||||||
private val shell = Shell.getShell()
|
private val shell = Shell.getShell()
|
||||||
private val service get() = ServiceLocator.networkService
|
private val service get() = ServiceLocator.networkService
|
||||||
protected val context get() = ServiceLocator.deContext
|
protected val context get() = ServiceLocator.deContext
|
||||||
private val useRootDir = shell.isRoot && Info.noDataExec
|
private val useRootDir = shell.isRoot && Info.noDataExec
|
||||||
|
|
||||||
|
private val rootFS get() = RootUtils.fs
|
||||||
|
private val localFS get() = FileSystemManager.getLocal()
|
||||||
|
|
||||||
private fun findImage(): Boolean {
|
private fun findImage(): Boolean {
|
||||||
val bootPath = "find_boot_image; echo \"\$BOOTIMAGE\"".fsh()
|
val bootPath = "find_boot_image; echo \"\$BOOTIMAGE\"".fsh()
|
||||||
if (bootPath.isEmpty()) {
|
if (bootPath.isEmpty()) {
|
||||||
console.add("! Unable to detect target image")
|
console.add("! Unable to detect target image")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
srcBoot = SuFile(bootPath)
|
srcBoot = rootFS.getFile(bootPath)
|
||||||
console.add("- Target image: $bootPath")
|
console.add("- Target image: $bootPath")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -77,7 +80,7 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
console.add("! Unable to detect target image")
|
console.add("! Unable to detect target image")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
srcBoot = SuFile(bootPath)
|
srcBoot = rootFS.getFile(bootPath)
|
||||||
console.add("- Target image: $bootPath")
|
console.add("- Target image: $bootPath")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -86,7 +89,7 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
console.add("- Device platform: ${Const.CPU_ABI}")
|
console.add("- Device platform: ${Const.CPU_ABI}")
|
||||||
console.add("- Installing: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
|
console.add("- Installing: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})")
|
||||||
|
|
||||||
installDir = File(context.filesDir.parent, "install")
|
installDir = localFS.getFile(context.filesDir.parent, "install")
|
||||||
installDir.deleteRecursively()
|
installDir.deleteRecursively()
|
||||||
installDir.mkdirs()
|
installDir.mkdirs()
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
|
|
||||||
if (useRootDir) {
|
if (useRootDir) {
|
||||||
// Move everything to tmpfs to workaround Samsung bullshit
|
// Move everything to tmpfs to workaround Samsung bullshit
|
||||||
SuFile(Const.TMPDIR).also {
|
rootFS.getFile(Const.TMPDIR).also {
|
||||||
arrayOf(
|
arrayOf(
|
||||||
"rm -rf $it",
|
"rm -rf $it",
|
||||||
"mkdir -p $it",
|
"mkdir -p $it",
|
||||||
@ -160,14 +163,6 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimization for SuFile I/O streams to skip an internal trial and error
|
|
||||||
private fun installDirFile(name: String): File {
|
|
||||||
return if (useRootDir)
|
|
||||||
SuFile(installDir, name)
|
|
||||||
else
|
|
||||||
File(installDir, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun InputStream.cleanPump(out: OutputStream) = withStreams(this, out) { src, _ ->
|
private fun InputStream.cleanPump(out: OutputStream) = withStreams(this, out) { src, _ ->
|
||||||
src.copyTo(out)
|
src.copyTo(out)
|
||||||
}
|
}
|
||||||
@ -198,8 +193,8 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
val name = entry.name.replace(".lz4", "")
|
val name = entry.name.replace(".lz4", "")
|
||||||
console.add("-- Extracting: $name")
|
console.add("-- Extracting: $name")
|
||||||
|
|
||||||
val extract = installDirFile(name)
|
val extract = installDir.getChildFile(name)
|
||||||
decompressedStream().cleanPump(SuFileOutputStream.open(extract))
|
decompressedStream().cleanPump(extract.newOutputStream())
|
||||||
} else if (entry.name.contains("vbmeta.img")) {
|
} else if (entry.name.contains("vbmeta.img")) {
|
||||||
val rawData = decompressedStream().readBytes()
|
val rawData = decompressedStream().readBytes()
|
||||||
// Valid vbmeta.img should be at least 256 bytes
|
// Valid vbmeta.img should be at least 256 bytes
|
||||||
@ -219,8 +214,8 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val boot = installDirFile("boot.img")
|
val boot = installDir.getChildFile("boot.img")
|
||||||
val recovery = installDirFile("recovery.img")
|
val recovery = installDir.getChildFile("recovery.img")
|
||||||
if (Config.recovery && recovery.exists() && boot.exists()) {
|
if (Config.recovery && recovery.exists() && boot.exists()) {
|
||||||
// Install to recovery
|
// Install to recovery
|
||||||
srcBoot = recovery
|
srcBoot = recovery
|
||||||
@ -234,7 +229,7 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
"./magiskboot cleanup",
|
"./magiskboot cleanup",
|
||||||
"rm -f new-boot.img",
|
"rm -f new-boot.img",
|
||||||
"cd /").sh()
|
"cd /").sh()
|
||||||
SuFileInputStream.open(boot).use {
|
boot.newInputStream().use {
|
||||||
tarOut.putNextEntry(newTarEntry("boot.img", boot.length()))
|
tarOut.putNextEntry(newTarEntry("boot.img", boot.length()))
|
||||||
it.copyTo(tarOut)
|
it.copyTo(tarOut)
|
||||||
}
|
}
|
||||||
@ -280,9 +275,9 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
processTar(src, outFile!!.uri.outputStream())
|
processTar(src, outFile!!.uri.outputStream())
|
||||||
} else {
|
} else {
|
||||||
// raw image
|
// raw image
|
||||||
srcBoot = installDirFile("boot.img")
|
srcBoot = installDir.getChildFile("boot.img")
|
||||||
console.add("- Copying image to cache")
|
console.add("- Copying image to cache")
|
||||||
src.cleanPump(SuFileOutputStream.open(srcBoot))
|
src.cleanPump(srcBoot.newOutputStream())
|
||||||
outFile = MediaStoreUtils.getFile("$filename.img", true)
|
outFile = MediaStoreUtils.getFile("$filename.img", true)
|
||||||
outFile!!.uri.outputStream()
|
outFile!!.uri.outputStream()
|
||||||
}
|
}
|
||||||
@ -302,12 +297,12 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
|
|
||||||
// Output file
|
// Output file
|
||||||
try {
|
try {
|
||||||
val newBoot = installDirFile("new-boot.img")
|
val newBoot = installDir.getChildFile("new-boot.img")
|
||||||
if (outStream is TarOutputStream) {
|
if (outStream is TarOutputStream) {
|
||||||
val name = if (srcBoot.path.contains("recovery")) "recovery.img" else "boot.img"
|
val name = if (srcBoot.path.contains("recovery")) "recovery.img" else "boot.img"
|
||||||
outStream.putNextEntry(newTarEntry(name, newBoot.length()))
|
outStream.putNextEntry(newTarEntry(name, newBoot.length()))
|
||||||
}
|
}
|
||||||
SuFileInputStream.open(newBoot).cleanPump(outStream)
|
newBoot.newInputStream().cleanPump(outStream)
|
||||||
newBoot.delete()
|
newBoot.delete()
|
||||||
|
|
||||||
console.add("")
|
console.add("")
|
||||||
@ -331,9 +326,9 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
|
|
||||||
private fun patchBoot(): Boolean {
|
private fun patchBoot(): Boolean {
|
||||||
var isSigned = false
|
var isSigned = false
|
||||||
if (srcBoot.let { it !is SuFile || !it.isCharacter }) {
|
if (!srcBoot.isCharacter) {
|
||||||
try {
|
try {
|
||||||
SuFileInputStream.open(srcBoot).use {
|
srcBoot.newInputStream().use {
|
||||||
if (SignBoot.verifySignature(it, null)) {
|
if (SignBoot.verifySignature(it, null)) {
|
||||||
isSigned = true
|
isSigned = true
|
||||||
console.add("- Boot image is signed with AVB 1.0")
|
console.add("- Boot image is signed with AVB 1.0")
|
||||||
@ -346,7 +341,7 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val newBoot = installDirFile("new-boot.img")
|
val newBoot = installDir.getChildFile("new-boot.img")
|
||||||
if (!useRootDir) {
|
if (!useRootDir) {
|
||||||
// Create output files before hand
|
// Create output files before hand
|
||||||
newBoot.createNewFile()
|
newBoot.createNewFile()
|
||||||
@ -370,7 +365,7 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
console.add("- Signing boot image with verity keys")
|
console.add("- Signing boot image with verity keys")
|
||||||
val signed = File.createTempFile("signed", ".img", context.cacheDir)
|
val signed = File.createTempFile("signed", ".img", context.cacheDir)
|
||||||
try {
|
try {
|
||||||
val src = SuFileInputStream.open(newBoot).buffered()
|
val src = newBoot.newInputStream().buffered()
|
||||||
val out = signed.outputStream().buffered()
|
val out = signed.outputStream().buffered()
|
||||||
withStreams(src, out) { _, _ ->
|
withStreams(src, out) { _, _ ->
|
||||||
SignBoot.doSignature(null, null, src, out, "/boot")
|
SignBoot.doSignature(null, null, src, out, "/boot")
|
||||||
@ -410,11 +405,11 @@ abstract class MagiskInstallImpl protected constructor(
|
|||||||
private fun String.fsh() = ShellUtils.fastCmd(shell, this)
|
private fun String.fsh() = ShellUtils.fastCmd(shell, this)
|
||||||
private fun Array<String>.fsh() = ShellUtils.fastCmd(shell, *this)
|
private fun Array<String>.fsh() = ShellUtils.fastCmd(shell, *this)
|
||||||
|
|
||||||
protected fun doPatchFile(patchFile: Uri) = extractFiles() && handleFile(patchFile)
|
protected fun patchFile(file: Uri) = extractFiles() && handleFile(file)
|
||||||
|
|
||||||
protected fun direct() = findImage() && extractFiles() && patchBoot() && flashBoot()
|
protected fun direct() = findImage() && extractFiles() && patchBoot() && flashBoot()
|
||||||
|
|
||||||
protected suspend fun secondSlot() =
|
protected fun secondSlot() =
|
||||||
findSecondary() && extractFiles() && patchBoot() && flashBoot() && postOTA()
|
findSecondary() && extractFiles() && patchBoot() && flashBoot() && postOTA()
|
||||||
|
|
||||||
protected fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess
|
protected fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess
|
||||||
@ -463,7 +458,7 @@ abstract class MagiskInstaller(
|
|||||||
console: MutableList<String>,
|
console: MutableList<String>,
|
||||||
logs: MutableList<String>
|
logs: MutableList<String>
|
||||||
) : MagiskInstaller(console, logs) {
|
) : MagiskInstaller(console, logs) {
|
||||||
override suspend fun operations() = doPatchFile(uri)
|
override suspend fun operations() = patchFile(uri)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SecondSlot(
|
class SecondSlot(
|
||||||
|
@ -9,6 +9,7 @@ import androidx.core.content.getSystemService
|
|||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import com.topjohnwu.superuser.ShellUtils
|
import com.topjohnwu.superuser.ShellUtils
|
||||||
import com.topjohnwu.superuser.ipc.RootService
|
import com.topjohnwu.superuser.ipc.RootService
|
||||||
|
import com.topjohnwu.superuser.nio.FileSystemManager
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.locks.AbstractQueuedSynchronizer
|
import java.util.concurrent.locks.AbstractQueuedSynchronizer
|
||||||
@ -33,6 +34,7 @@ class RootUtils(stub: Any?) : RootService() {
|
|||||||
override fun onBind(intent: Intent): IBinder {
|
override fun onBind(intent: Intent): IBinder {
|
||||||
return object : IRootUtils.Stub() {
|
return object : IRootUtils.Stub() {
|
||||||
override fun getAppProcess(pid: Int) = safe(null) { getAppProcessImpl(pid) }
|
override fun getAppProcess(pid: Int) = safe(null) { getAppProcessImpl(pid) }
|
||||||
|
override fun getFileSystem(): IBinder = FileSystemManager.getService()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +70,10 @@ class RootUtils(stub: Any?) : RootService() {
|
|||||||
|
|
||||||
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
override fun onServiceConnected(name: ComponentName, service: IBinder) {
|
||||||
Timber.d("onServiceConnected")
|
Timber.d("onServiceConnected")
|
||||||
obj = IRootUtils.Stub.asInterface(service)
|
IRootUtils.Stub.asInterface(service).let {
|
||||||
|
obj = it
|
||||||
|
fs = FileSystemManager.getRemote(it.fileSystem)
|
||||||
|
}
|
||||||
releaseShared(1)
|
releaseShared(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +106,8 @@ class RootUtils(stub: Any?) : RootService() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var bindTask: Shell.Task? = null
|
var bindTask: Shell.Task? = null
|
||||||
|
var fs = FileSystemManager.getLocal()
|
||||||
|
private set
|
||||||
var obj: IRootUtils? = null
|
var obj: IRootUtils? = null
|
||||||
get() {
|
get() {
|
||||||
Connection.await()
|
Connection.await()
|
||||||
|
@ -19,6 +19,7 @@ import java.util.jar.JarFile
|
|||||||
class ShellInit : Shell.Initializer() {
|
class ShellInit : Shell.Initializer() {
|
||||||
override fun onInit(context: Context, shell: Shell): Boolean {
|
override fun onInit(context: Context, shell: Shell): Boolean {
|
||||||
if (shell.isRoot) {
|
if (shell.isRoot) {
|
||||||
|
Info.isRooted = true
|
||||||
RootUtils.bindTask?.let { shell.execTask(it) }
|
RootUtils.bindTask?.let { shell.execTask(it) }
|
||||||
RootUtils.bindTask = null
|
RootUtils.bindTask = null
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.topjohnwu.magisk.core.utils
|
package com.topjohnwu.magisk.core.utils
|
||||||
|
|
||||||
import com.topjohnwu.superuser.io.SuFile
|
|
||||||
import com.topjohnwu.superuser.io.SuFileOutputStream
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
@ -31,12 +29,12 @@ fun InputStream.unzip(folder: File, path: String, junkPath: Boolean) {
|
|||||||
else
|
else
|
||||||
entry.name
|
entry.name
|
||||||
|
|
||||||
var dest = File(folder, name)
|
val dest = File(folder, name)
|
||||||
if (!dest.parentFile!!.exists() && !dest.parentFile!!.mkdirs()) {
|
dest.parentFile!!.let {
|
||||||
dest = SuFile(folder, name)
|
if (!it.exists())
|
||||||
dest.parentFile!!.mkdirs()
|
it.mkdirs()
|
||||||
}
|
}
|
||||||
SuFileOutputStream.open(dest).use { out -> zin.copyTo(out) }
|
dest.outputStream().use { out -> zin.copyTo(out) }
|
||||||
}
|
}
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
throw IOException(e)
|
throw IOException(e)
|
||||||
|
@ -21,14 +21,13 @@ import com.topjohnwu.magisk.databinding.set
|
|||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.magisk.ktx.*
|
import com.topjohnwu.magisk.ktx.*
|
||||||
import com.topjohnwu.superuser.CallbackList
|
import com.topjohnwu.superuser.CallbackList
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class FlashViewModel : BaseViewModel() {
|
class FlashViewModel : BaseViewModel() {
|
||||||
|
|
||||||
@get:Bindable
|
@get:Bindable
|
||||||
var showReboot = Shell.rootAccess()
|
var showReboot = Info.isRooted
|
||||||
set(value) = set(value, field, { field = it }, BR.showReboot)
|
set(value) = set(value, field, { field = it }, BR.showReboot)
|
||||||
|
|
||||||
private val _subtitle = MutableLiveData(R.string.flashing)
|
private val _subtitle = MutableLiveData(R.string.flashing)
|
||||||
|
@ -6,11 +6,11 @@ import android.widget.ImageView
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.arch.BaseFragment
|
import com.topjohnwu.magisk.arch.BaseFragment
|
||||||
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.download.DownloadService
|
import com.topjohnwu.magisk.core.download.DownloadService
|
||||||
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
import com.topjohnwu.magisk.databinding.FragmentHomeMd2Binding
|
||||||
import com.topjohnwu.magisk.di.viewModel
|
import com.topjohnwu.magisk.di.viewModel
|
||||||
import com.topjohnwu.magisk.events.RebootEvent
|
import com.topjohnwu.magisk.events.RebootEvent
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
|
|
||||||
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
|
class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class HomeFragment : BaseFragment<FragmentHomeMd2Binding>() {
|
|||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
inflater.inflate(R.menu.menu_home_md2, menu)
|
inflater.inflate(R.menu.menu_home_md2, menu)
|
||||||
if (!Shell.rootAccess())
|
if (!Info.isRooted)
|
||||||
menu.removeItem(R.id.action_reboot)
|
menu.removeItem(R.id.action_reboot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ import com.topjohnwu.magisk.di.ServiceLocator
|
|||||||
import com.topjohnwu.magisk.events.MagiskInstallFileEvent
|
import com.topjohnwu.magisk.events.MagiskInstallFileEvent
|
||||||
import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog
|
import com.topjohnwu.magisk.events.dialog.SecondSlotWarningDialog
|
||||||
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
import com.topjohnwu.magisk.ui.flash.FlashFragment
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -29,7 +28,7 @@ class InstallViewModel(
|
|||||||
svc: NetworkService
|
svc: NetworkService
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
|
|
||||||
val isRooted = Shell.rootAccess()
|
val isRooted get() = Info.isRooted
|
||||||
val hideVbmeta = Info.vbmeta || Info.isSamsung || Info.isAB
|
val hideVbmeta = Info.vbmeta || Info.isSamsung || Info.isAB
|
||||||
val skipOptions = Info.isEmulator || (Info.isSAR && !Info.isFDE && hideVbmeta && Info.ramdisk)
|
val skipOptions = Info.isEmulator || (Info.isSAR && !Info.isFDE && hideVbmeta && Info.ramdisk)
|
||||||
val noSecondSlot = !isRooted || !Info.isAB || Info.isEmulator
|
val noSecondSlot = !isRooted || !Info.isAB || Info.isEmulator
|
||||||
|
Loading…
Reference in New Issue
Block a user