From 6b3da4f07e564659a42dd0d2f5ae53f28d685203 Mon Sep 17 00:00:00 2001 From: Enova <17408285+Enovale@users.noreply.github.com> Date: Sun, 16 Jun 2024 18:43:36 -0500 Subject: [PATCH] fix(ManifestPatcher): add `vmSafeMode` manifest attribute (#73) On certain ROMs like GrapheneOS with agressive dexopt settings, the current method of deleting ART profiles upon startup does not work as dexopt runs right after app installation. This code cache would then be deletable only via ADB or root. --- .../manager/installer/util/ManifestPatcher.kt | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt b/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt index 5b5cf6a..d33101d 100644 --- a/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt +++ b/app/src/main/kotlin/com/aliucord/manager/installer/util/ManifestPatcher.kt @@ -13,6 +13,7 @@ object ManifestPatcher { private const val ANDROID_NAMESPACE = "http://schemas.android.com/apk/res/android" private const val USES_CLEARTEXT_TRAFFIC = "usesCleartextTraffic" private const val DEBUGGABLE = "debuggable" + private const val VM_SAFE_MODE = "vmSafeMode" private const val REQUEST_LEGACY_EXTERNAL_STORAGE = "requestLegacyExternalStorage" private const val NETWORK_SECURITY_CONFIG = "networkSecurityConfig" private const val LABEL = "label" @@ -30,6 +31,13 @@ object ManifestPatcher { val writer = AxmlWriter() reader.accept(object : AxmlVisitor(writer) { + // Without this, decompiling the finished manifest has the android namespace + // under an autogenerated name like axml_00 or something. + override fun ns(prefix: String?, uri: String?, ln: Int) { + val realUri = uri ?: ANDROID_NAMESPACE + super.ns(prefix, realUri, ln) + } + override fun child(ns: String?, name: String?) = object : ReplaceAttrsVisitor( super.child(ns, name), @@ -88,14 +96,16 @@ object ManifestPatcher { ) { private var addDebuggable = debuggable private var addLegacyStorage = true + private var useVmSafeMode = true private var addUseClearTextTraffic = true override fun attr(ns: String?, name: String, resourceId: Int, type: Int, value: Any?) { if (name == NETWORK_SECURITY_CONFIG) return - super.attr(ns, name, resourceId, type, value) if (name == REQUEST_LEGACY_EXTERNAL_STORAGE) addLegacyStorage = false + if (name == VM_SAFE_MODE) useVmSafeMode = false if (name == DEBUGGABLE) addDebuggable = false if (name == USES_CLEARTEXT_TRAFFIC) addUseClearTextTraffic = false + super.attr(ns, name, resourceId, type, value) } override fun child(ns: String?, name: String): NodeVisitor { @@ -124,9 +134,10 @@ object ManifestPatcher { } override fun end() { - if (addLegacyStorage) super.attr(ANDROID_NAMESPACE, REQUEST_LEGACY_EXTERNAL_STORAGE, -1, TYPE_INT_BOOLEAN, 1) - if (addDebuggable) super.attr(ANDROID_NAMESPACE, DEBUGGABLE, -1, TYPE_INT_BOOLEAN, 1) - if (addUseClearTextTraffic) super.attr(ANDROID_NAMESPACE, USES_CLEARTEXT_TRAFFIC, -1, TYPE_INT_BOOLEAN, 1) + if (addLegacyStorage && Build.VERSION.SDK_INT >= 29) super.attr(ANDROID_NAMESPACE, REQUEST_LEGACY_EXTERNAL_STORAGE, android.R.attr.requestLegacyExternalStorage, TYPE_INT_BOOLEAN, 1) + if (useVmSafeMode) super.attr(ANDROID_NAMESPACE, VM_SAFE_MODE, android.R.attr.vmSafeMode, TYPE_INT_BOOLEAN, 1) + if (addDebuggable) super.attr(ANDROID_NAMESPACE, DEBUGGABLE, android.R.attr.debuggable, TYPE_INT_BOOLEAN, 1) + if (addUseClearTextTraffic) super.attr(ANDROID_NAMESPACE, USES_CLEARTEXT_TRAFFIC, android.R.attr.usesCleartextTraffic, TYPE_INT_BOOLEAN, 1) super.end() } }