diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4646cf1bf..da67bfd11 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,4 +1,3 @@ -import com.android.build.gradle.internal.api.ApkVariantOutputImpl import org.apache.tools.ant.filters.FixCrLfFilter import java.io.PrintStream @@ -42,13 +41,6 @@ android { } } - splits { - abi { - isEnable = true - isUniversalApk = true - } - } - buildFeatures { dataBinding = true } @@ -81,40 +73,24 @@ val syncLibs by tasks.registering(Sync::class) { include("busybox", "magiskboot", "magiskinit", "magisk") rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" } } - from(rootProject.file("native/out/arm64-v8a")) { - include("magisk") - rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" } - } } into("x86") { from(rootProject.file("native/out/x86")) { include("busybox", "magiskboot", "magiskinit", "magisk") rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" } } - from(rootProject.file("native/out/x86_64")) { - include("magisk") - rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" } - } } into("arm64-v8a") { from(rootProject.file("native/out/arm64-v8a")) { include("busybox", "magiskboot", "magiskinit", "magisk") rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" } } - from(rootProject.file("native/out/armeabi-v7a")) { - include("magisk") - rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" } - } } into("x86_64") { from(rootProject.file("native/out/x86_64")) { include("busybox", "magiskboot", "magiskinit", "magisk") rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" } } - from(rootProject.file("native/out/x86")) { - include("magisk") - rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" } - } } onlyIf { if (inputs.sourceFiles.files.size != 16) @@ -139,10 +115,9 @@ val syncAssets by tasks.registering(Sync::class) { } filesMatching("**/util_functions.sh") { filter { - it.replace( - "#MAGISK_VERSION_STUB", + it.replace("#MAGISK_VERSION_STUB", "MAGISK_VER='${Config.version}'\n" + - "MAGISK_VER_CODE=${Config.versionCode}" + "MAGISK_VER_CODE=${Config.versionCode}" ) } filter("eol" to FixCrLfFilter.CrLf.newInstance("lf")) @@ -196,13 +171,6 @@ android.applicationVariants.all { } } registerJavaGeneratingTask(genSrcTask.get(), outSrcDir) - - outputs.all { - val output = this as ApkVariantOutputImpl - output.filters.forEach { - output.versionNameOverride += "-${it.identifier}" - } - } } dependencies { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 22361ca52..c94dad5c3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ android:name=".core.App" android:extractNativeLibs="true" android:icon="@drawable/ic_launcher" + android:multiArch="true" tools:ignore="UnusedAttribute,GoogleAppIndexingWarning"> diff --git a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt index 93e0ed474..69b6973d8 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Const.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Const.kt @@ -7,8 +7,12 @@ import com.topjohnwu.magisk.BuildConfig @Suppress("DEPRECATION") object Const { - val CPU_ABI: String = Build.SUPPORTED_ABIS[0] - val CPU_ABI_32: String = Build.SUPPORTED_32_BIT_ABIS.firstOrNull() ?: CPU_ABI + val CPU_ABI: String get() = Build.SUPPORTED_ABIS[0] + + // Null if 32-bit only or 64-bit only + val CPU_ABI_32 = + if (Build.SUPPORTED_64_BIT_ABIS.isEmpty()) null + else Build.SUPPORTED_32_BIT_ABIS.firstOrNull() // Paths lateinit var MAGISKTMP: String 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 3e0bb77a1..37e4ccca1 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/Info.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/Info.kt @@ -17,7 +17,6 @@ val isRunningAsStub get() = Info.stub != null object Info { var stub: DynAPK.Data? = null - var stubArch = "lib/${Const.CPU_ABI}" val EMPTY_REMOTE = UpdateInfo() var remote = EMPTY_REMOTE 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 0c7c50b00..35986f8d4 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 @@ -37,6 +37,7 @@ import java.io.* import java.nio.ByteBuffer import java.security.SecureRandom import java.util.* +import java.util.zip.ZipEntry import java.util.zip.ZipFile abstract class MagiskInstallImpl protected constructor( @@ -93,8 +94,14 @@ abstract class MagiskInstallImpl protected constructor( // Extract binaries if (isRunningAsStub) { val zf = ZipFile(DynAPK.current(context)) + + // Also extract magisk32 on non 64-bit only 64-bit devices + val is32lib = Const.CPU_ABI_32?.let { + { entry: ZipEntry -> entry.name == "lib/$it/libmagisk32.so" } + } ?: { false } + zf.entries().asSequence().filter { - !it.isDirectory && it.name.startsWith(Info.stubArch) + !it.isDirectory && (it.name.startsWith("lib/${Const.CPU_ABI}/") || is32lib(it)) }.forEach { val n = it.name.substring(it.name.lastIndexOf('/') + 1) val name = n.substring(3, n.length - 3) @@ -102,9 +109,17 @@ abstract class MagiskInstallImpl protected constructor( zf.getInputStream(it).writeTo(dest) } } else { - val libs = File(context.applicationInfo.nativeLibraryDir).listFiles { _, name -> + val info = context.applicationInfo + var 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") diff --git a/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt b/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt index ee9bd0516..dc4a8d59f 100644 --- a/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt +++ b/app/src/main/java/com/topjohnwu/magisk/core/utils/ShellInit.kt @@ -33,11 +33,7 @@ class BusyBoxInit : BaseShellInit() { if (!shell.isRoot) return true val jar = JarFile(DynAPK.current(context)) - var bb = jar.getJarEntry("${Info.stubArch}/libbusybox.so") - if (bb == null) { - Info.stubArch = "lib/${Const.CPU_ABI_32}" - bb = jar.getJarEntry("${Info.stubArch}/libbusybox.so") - } + val bb = jar.getJarEntry("lib/${Const.CPU_ABI}/libbusybox.so") localBB = context.deviceProtectedContext.cachedFile("busybox") localBB.delete() jar.getInputStream(bb).writeTo(localBB) diff --git a/build.py b/build.py index f55c1cdf0..d9578c17e 100755 --- a/build.py +++ b/build.py @@ -347,19 +347,11 @@ def build_apk(args, module): build_type = build_type.lower() - if module == 'app': - for arch in archs + ['universal']: - apk = f'{module}-{arch}-{build_type}.apk' - source = op.join(module, 'build', 'outputs', 'apk', build_type, apk) - target = op.join(config['outdir'], apk) - mv(source, target) - header('Output: ' + target) - else: - apk = f'{module}-{build_type}.apk' - source = op.join(module, 'build', 'outputs', 'apk', build_type, apk) - target = op.join(config['outdir'], apk) - mv(source, target) - header('Output: ' + target) + apk = f'{module}-{build_type}.apk' + source = op.join(module, 'build', 'outputs', 'apk', build_type, apk) + target = op.join(config['outdir'], apk) + mv(source, target) + header('Output: ' + target) def build_app(args): diff --git a/native/jni/Application.mk b/native/jni/Application.mk index b9767d52f..28d7a7835 100644 --- a/native/jni/Application.mk +++ b/native/jni/Application.mk @@ -1,4 +1,4 @@ -APP_ABI := armeabi-v7a x86 arm64-v8a x86_64 +APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto \ -D__MVSTR=${MAGISK_VERSION} -D__MCODE=${MAGISK_VER_CODE} APP_LDFLAGS := -flto diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index aab52a3b8..bce2c742e 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -147,15 +147,22 @@ echo "RECOVERYMODE=$RECOVERYMODE" >> config [ ! -z $SHA1 ] && echo "SHA1=$SHA1" >> config # Compress to save precious ramdisk space -./magiskboot compress=xz magisk32 magisk32.xz -./magiskboot compress=xz magisk64 magisk64.xz -$IS64BIT && SKIP64="" || SKIP64="#" +SKIP32="#" +SKIP64="#" +if [ -f magisk32 ]; then + ./magiskboot compress=xz magisk32 magisk32.xz + unset SKIP32 +fi +if [ -f magisk64 ]; then + ./magiskboot compress=xz magisk64 magisk64.xz + unset SKIP64 +fi ./magiskboot cpio ramdisk.cpio \ "add 0750 init magiskinit" \ "mkdir 0750 overlay.d" \ "mkdir 0750 overlay.d/sbin" \ -"add 0644 overlay.d/sbin/magisk32.xz magisk32.xz" \ +"$SKIP32 add 0644 overlay.d/sbin/magisk32.xz magisk32.xz" \ "$SKIP64 add 0644 overlay.d/sbin/magisk64.xz magisk64.xz" \ "patch" \ "backup ramdisk.cpio.orig" \ diff --git a/scripts/flash_script.sh b/scripts/flash_script.sh index 8ba48002f..b6e8275ef 100644 --- a/scripts/flash_script.sh +++ b/scripts/flash_script.sh @@ -50,16 +50,15 @@ api_level_arch_detect [ $API -lt 21 ] && abort "! Magisk only support Android 5.0 and above" -ui_print "- Device platform: $ARCH" +ui_print "- Device platform: $ABI" -BINDIR=$INSTALLER/lib/$ABILONG -[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/$ARCH32 -[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/armeabi-v7a +BINDIR=$INSTALLER/lib/$ABI cd $BINDIR for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done cd / -chmod -R 755 $CHROMEDIR $BINDIR +cp -af $INSTALLER/lib/$ABI32/libmagisk32.so $BINDIR/magisk32 2>/dev/null cp -af $CHROMEDIR/. $BINDIR/chromeos +chmod -R 755 $BINDIR # Check if system root is installed and remove $BOOTMODE || remove_system_su diff --git a/scripts/uninstaller.sh b/scripts/uninstaller.sh index 9b4561f9e..ed5309c95 100644 --- a/scripts/uninstaller.sh +++ b/scripts/uninstaller.sh @@ -55,16 +55,14 @@ ui_print "- Target image: $BOOTIMAGE" # Detect version and architecture api_level_arch_detect -ui_print "- Device platform: $ARCH" +ui_print "- Device platform: $ABI" -BINDIR=$INSTALLER/lib/$ABILONG -[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/$ARCH32 -[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/armeabi-v7a +BINDIR=$INSTALLER/lib/$ABI cd $BINDIR for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done cd / -chmod -R 755 $CHROMEDIR $BINDIR cp -af $CHROMEDIR/. $BINDIR/chromeos +chmod -R 755 $BINDIR ############ # Uninstall diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index d2e7eb2e4..cd39b6a2c 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -519,17 +519,25 @@ remove_system_su() { api_level_arch_detect() { API=$(grep_get_prop ro.build.version.sdk) - ABI=$(grep_get_prop ro.product.cpu.abi | cut -c-3) - ABI2=$(grep_get_prop ro.product.cpu.abi2 | cut -c-3) - ABILONG=$(grep_get_prop ro.product.cpu.abi) - - ARCH=arm - ARCH32=arm - IS64BIT=false - if [ "$ABI" = "x86" ]; then ARCH=x86; ARCH32=x86; fi; - if [ "$ABI2" = "x86" ]; then ARCH=x86; ARCH32=x86; fi; - if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; ARCH32=arm; IS64BIT=true; fi; - if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; ARCH32=x86; IS64BIT=true; fi; + ABI=$(grep_get_prop ro.product.cpu.abi) + if [ "$ABI" = "x86" ]; then + ARCH=x86 + ABI32=x86 + IS64BIT=false + elif [ "$ABI" = "arm64-v8a" ]; then + ARCH=arm64 + ABI32=armeabi-v7a + IS64BIT=true + elif [ "$ABI" = "x86_64" ]; then + ARCH=x64 + ABI32=x86 + IS64BIT=true + else + ARCH=arm + ABI=armeabi-v7a + ABI32=armeabi-v7a + IS64BIT=false + fi } check_data() {