Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 110 additions & 66 deletions DEVELOPMENT_ROADMAP.md

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<application
android:name=".core.App"
android:icon="@drawable/ic_launcher"
android:multiArch="true"
tools:ignore="UnusedAttribute,GoogleAppIndexingWarning"
tools:remove="android:appComponentFactory">

Expand Down
23 changes: 18 additions & 5 deletions app/src/main/java/com/topjohnwu/magisk/core/su/TestHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.topjohnwu.magisk.core.di.ServiceLocator
import com.topjohnwu.magisk.core.tasks.MagiskInstaller
import com.topjohnwu.magisk.core.utils.RootUtils
import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.internal.NOPList
import kotlinx.coroutines.runBlocking

object TestHandler {
Expand All @@ -16,10 +15,24 @@ object TestHandler {
val r = Bundle()

fun setup(): Boolean {
val nop = NOPList.getInstance()
return runBlocking {
MagiskInstaller.Emulator(nop, nop).exec()
val console = mutableListOf<String>()
val logs = mutableListOf<String>()
val success = runBlocking {
MagiskInstaller.Emulator(console, logs).exec()
}
if (!success) {
val output = (console.asSequence() + logs.asSequence())
.map { it.trim() }
.filter { it.isNotEmpty() }
.joinToString("\n")
.takeLast(4096)
r.putString(
"reason",
"setup failed (root=${Shell.getShell().isRoot})" +
if (output.isEmpty()) " without installer output" else "\n$output"
)
}
return success
}

fun test(): Boolean {
Expand Down Expand Up @@ -62,4 +75,4 @@ object TestHandler {
r.putBoolean("result", b)
return r
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.topjohnwu.magisk.core.tasks

import android.net.Uri
import android.os.Process
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
Expand Down Expand Up @@ -123,25 +124,37 @@ abstract class MagiskInstallImpl protected constructor(
zf.close()
} else {
val info = context.applicationInfo
var libs = File(info.nativeLibraryDir).listFiles { _, name ->
val libs = File(info.nativeLibraryDir).listFiles { _, name ->
name.startsWith("lib") && name.endsWith(".so")
} ?: emptyArray()

// Also symlink magisk32 on non 64-bit only 64-bit devices
val lib32 = info.javaClass.getDeclaredField("secondaryNativeLibraryDir")
.get(info) as String?
if (lib32 != null) {
libs += File(lib32, "libmagisk32.so")
}

for (lib in libs) {
val name = lib.name.substring(3, lib.name.length - 3)
Os.symlink(lib.path, "$installDir/$name")
}

// Do not depend on the hidden secondaryNativeLibraryDir field.
// Android's multi-arch extraction is unstable across package
// replacement on legacy releases; read the one 32-bit applet
// directly from the installed APK, matching current upstream.
val abi32 = Const.CPU_ABI_32
if (Process.is64Bit() && abi32 != null) {
val name = "lib/$abi32/libmagisk32.so"
javaClass.classLoader!!.getResourceAsStream(name)?.use {
it.writeTo(File(installDir, "magisk32"))
}
}
}

// Extract scripts
for (script in listOf("util_functions.sh", "boot_patch.sh", "addon.d.sh", "stub.apk")) {
for (script in listOf(
"util_functions.sh",
"boot_patch.sh",
"addon.d.sh",
"system_mode_transaction.sh",
"system_mode_verify.sh",
"stub.apk",
)) {
val dest = File(installDir, script)
context.assets.open(script).writeTo(dest)
}
Expand All @@ -157,7 +170,8 @@ abstract class MagiskInstallImpl protected constructor(
context.assets.open(name).writeTo(dest)
}
} catch (e: Exception) {
console.add("! Unable to extract files")
console.add("! Unable to extract files: ${e.javaClass.simpleName}: ${e.message}")
logs.add(e.stackTraceToString())
Timber.e(e)
return false
}
Expand Down Expand Up @@ -557,9 +571,12 @@ abstract class MagiskInstallImpl protected constructor(
. "${'$'}1/system_mode_manager.sh" || exit 1
rm -f "${'$'}1/system_mode_manager.sh" || exit 1
. "${'$'}1/util_functions.sh" || exit 1
[ "${'$'}KITSUNE_SOURCE_COMMIT" = "${'$'}3" ] || exit 1
[ "${'$'}KITSUNE_UPSTREAM_BASE" = "${'$'}4" ] || exit 1
app_init
xdirect_install_system "${'$'}1" "${'$'}2"
' system-mode "$installDir" "$AppApkPath"
' system-mode "$installDir" "$AppApkPath" \
"${BuildConfig.SOURCE_COMMIT}" "${BuildConfig.UPSTREAM_BASE}"
_system_mode_rc=${'$'}?
rm -f "$manager"
(exit "${'$'}_system_mode_rc")
Expand All @@ -572,7 +589,8 @@ abstract class MagiskInstallImpl protected constructor(

protected suspend fun fixEnv() = extractFiles() && "fix_env $installDir".sh().isSuccess

protected fun uninstall() = "run_uninstaller $AppApkPath".sh().isSuccess
protected fun uninstall() =
"run_uninstaller \"$AppApkPath\" \"${context.packageName}\"".sh().isSuccess

protected fun cleanupInstallDir() {
if (::installDir.isInitialized) {
Expand Down Expand Up @@ -664,15 +682,7 @@ abstract class MagiskInstaller(
) : MagiskInstallImpl(console, logs) {
override suspend fun operations() = uninstall()

override suspend fun exec(): Boolean {
val success = super.exec()
if (success) {
UiThreadHandler.handler.postDelayed(3000) {
Shell.cmd("pm uninstall ${context.packageName}").exec()
}
}
return success
}
override suspend fun exec() = super.exec()
}

class FixEnv(private val callback: () -> Unit) : MagiskInstallImpl() {
Expand Down
Loading