diff --git a/app/.gitignore b/app/.gitignore index 39b258fe4..abb5fdfad 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -3,5 +3,5 @@ # Gradle .gradle .kotlin +build /local.properties -/build diff --git a/app/apk/.gitignore b/app/apk/.gitignore deleted file mode 100644 index 796b96d1c..000000000 --- a/app/apk/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/app/apk/build.gradle.kts b/app/apk/build.gradle.kts index 3e6b329f6..f3301097c 100644 --- a/app/apk/build.gradle.kts +++ b/app/apk/build.gradle.kts @@ -1,8 +1,7 @@ plugins { id("com.android.application") - kotlin("android") kotlin("plugin.parcelize") - kotlin("kapt") + id("com.android.legacy-kapt") id("androidx.navigation.safeargs.kotlin") } @@ -26,6 +25,10 @@ android { isCoreLibraryDesugaringEnabled = true } + defaultConfig { + proguardFile("proguard-rules.pro") + } + buildTypes { release { isMinifyEnabled = true diff --git a/app/apk/proguard-rules.pro b/app/apk/proguard-rules.pro new file mode 100644 index 000000000..105abd009 --- /dev/null +++ b/app/apk/proguard-rules.pro @@ -0,0 +1,3 @@ +# Excessive obfuscation +-flattenpackagehierarchy +-allowaccessmodification diff --git a/app/buildSrc/.gitignore b/app/buildSrc/.gitignore deleted file mode 100644 index 796b96d1c..000000000 --- a/app/buildSrc/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/app/buildSrc/build.gradle.kts b/app/buildSrc/build.gradle.kts index ee451efa2..80cae8093 100644 --- a/app/buildSrc/build.gradle.kts +++ b/app/buildSrc/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.kotlin.gradle.dsl.KotlinVersion - plugins { `kotlin-dsl` } @@ -21,6 +19,7 @@ gradlePlugin { dependencies { implementation(kotlin("gradle-plugin", libs.versions.kotlin.get())) implementation(libs.android.gradle.plugin) + implementation(libs.android.kapt.plugin) implementation(libs.ksp.plugin) implementation(libs.navigation.safe.args.plugin) implementation(libs.lsparanoid.plugin) diff --git a/app/buildSrc/src/main/java/Setup.kt b/app/buildSrc/src/main/java/Setup.kt index 4a16ecf5a..c5aaebdec 100644 --- a/app/buildSrc/src/main/java/Setup.kt +++ b/app/buildSrc/src/main/java/Setup.kt @@ -1,72 +1,68 @@ import com.android.build.api.artifact.SingleArtifact +import com.android.build.api.dsl.ApplicationExtension +import com.android.build.api.dsl.CommonExtension import com.android.build.api.instrumentation.FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS import com.android.build.api.instrumentation.InstrumentationScope +import com.android.build.api.variant.AndroidComponentsExtension import com.android.build.api.variant.ApplicationAndroidComponentsExtension -import com.android.build.gradle.BaseExtension -import com.android.build.gradle.LibraryExtension -import com.android.build.gradle.internal.dsl.BaseAppModuleExtension import org.apache.tools.ant.filters.FixCrLfFilter import org.gradle.api.Action import org.gradle.api.JavaVersion import org.gradle.api.Project -import org.gradle.api.tasks.Copy -import org.gradle.api.tasks.Delete +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.StopExecutionException import org.gradle.api.tasks.Sync import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.exclude import org.gradle.kotlin.dsl.filter import org.gradle.kotlin.dsl.get -import org.gradle.kotlin.dsl.getValue -import org.gradle.kotlin.dsl.named -import org.gradle.kotlin.dsl.provideDelegate import org.gradle.kotlin.dsl.register import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import java.io.ByteArrayOutputStream import java.io.File import java.net.URI import java.security.MessageDigest import java.util.HexFormat -import java.util.zip.Deflater -import java.util.zip.DeflaterOutputStream -import java.util.zip.ZipEntry -import java.util.zip.ZipFile -import java.util.zip.ZipOutputStream -private fun Project.androidBase(configure: Action) = +private fun Project.android(configure: Action) = extensions.configure("android", configure) -private fun Project.android(configure: Action) = +private fun Project.androidApp(configure: Action) = extensions.configure("android", configure) -internal val Project.androidApp: BaseAppModuleExtension - get() = extensions["android"] as BaseAppModuleExtension +internal val Project.androidApp: ApplicationExtension + get() = extensions["android"] as ApplicationExtension -private val Project.androidLib: LibraryExtension - get() = extensions["android"] as LibraryExtension +private fun Project.androidComponents(configure: Action>) = + extensions.configure(AndroidComponentsExtension::class.java, configure) -internal val Project.androidComponents - get() = extensions.getByType(ApplicationAndroidComponentsExtension::class.java) +private val Project.androidComponents: AndroidComponentsExtension<*, *, *> + get() = extensions["androidComponents"] as AndroidComponentsExtension<*, *, *> + +internal fun Project.androidAppComponents(configure: Action) = + extensions.configure(ApplicationAndroidComponentsExtension::class.java, configure) fun Project.setupCommon() { - androidBase { - compileSdkVersion(36) + android { + compileSdk { + version = release(36) + } buildToolsVersion = "36.0.0" - ndkPath = "$sdkDirectory/ndk/magisk" + ndkPath = "${androidComponents.sdkComponents.sdkDirectory.get().asFile}/ndk/magisk" ndkVersion = "29.0.14206865" - defaultConfig { + defaultConfig.apply { minSdk = 23 } - compileOptions { + compileOptions.apply { sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } - packagingOptions { + packaging.apply { resources { excludes += arrayOf( "/META-INF/*", @@ -123,93 +119,108 @@ const val BUSYBOX_DOWNLOAD_URL = const val BUSYBOX_ZIP_CHECKSUM = "b4d0551feabaf314e53c79316c980e8f66432e9fb91a69dbbf10a93564b40951" +private abstract class SyncWithDir : Sync() { + @get:OutputDirectory + abstract val outputFolder: DirectoryProperty +} + fun Project.setupCoreLib() { setupCommon() - androidLib.libraryVariants.all { - val variant = name - val variantCapped = name.replaceFirstChar { it.uppercase() } - val abiList = Config.abiList + val abiList = Config.abiList - val syncLibs = tasks.register("sync${variantCapped}JniLibs", Sync::class) { - into("src/$variant/jniLibs") - for (abi in abiList) { - into(abi) { - from(rootFile("native/out/$abi")) { - include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so") - rename { if (it.endsWith(".so")) it else "lib$it.so" } + androidComponents { + onVariants { variant -> + val variantName = variant.name + val variantCapped = variantName.replaceFirstChar { it.uppercase() } + + val syncLibs = tasks.register("sync${variantCapped}JniLibs", SyncWithDir::class) { + outputFolder.set(layout.buildDirectory.dir("$variantName/jniLibs")) + into(outputFolder) + + for (abi in abiList) { + into(abi) { + from(rootFile("native/out/$abi")) { + include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so") + rename { if (it.endsWith(".so")) it else "lib$it.so" } + } + } + } + from(zipTree(downloadFile(BUSYBOX_DOWNLOAD_URL, BUSYBOX_ZIP_CHECKSUM))) + include(abiList.map { "$it/libbusybox.so" }) + onlyIf { + if (inputs.sourceFiles.files.size != abiList.size * 6) + throw StopExecutionException("Please build binaries first! (./build.py binary)") + true + } + } + + variant.sources.jniLibs?.let { + it.addGeneratedSourceDirectory(syncLibs, SyncWithDir::outputFolder) + } + + val syncResources = tasks.register("sync${variantCapped}Resources", SyncWithDir::class) { + outputFolder.set(layout.buildDirectory.dir("$variantName/resources")) + into(outputFolder) + + into("META-INF/com/google/android") { + from(rootFile("scripts/update_binary.sh")) { + rename { "update-binary" } + } + from(rootFile("scripts/flash_script.sh")) { + rename { "updater-script" } } } } - from(zipTree(downloadFile(BUSYBOX_DOWNLOAD_URL, BUSYBOX_ZIP_CHECKSUM))) - include(abiList.map { "$it/libbusybox.so" }) - onlyIf { - if (inputs.sourceFiles.files.size != abiList.size * 6) - throw StopExecutionException("Please build binaries first! (./build.py binary)") - true + + variant.sources.resources?.let { + it.addGeneratedSourceDirectory(syncResources, SyncWithDir::outputFolder) } - } - tasks.getByPath("merge${variantCapped}JniLibFolders").dependsOn(syncLibs) + val stubTask = tasks.getByPath(":stub:comment$variantCapped") + val syncAssets = tasks.register("sync${variantCapped}Assets", SyncWithDir::class) { + outputFolder.set(layout.buildDirectory.dir("$variantName/assets")) + into(outputFolder) - val syncResources = tasks.register("sync${variantCapped}Resources", Sync::class) { - into("src/$variant/resources/META-INF/com/google/android") - from(rootFile("scripts/update_binary.sh")) { - rename { "update-binary" } - } - from(rootFile("scripts/flash_script.sh")) { - rename { "updater-script" } - } - } - - processJavaResourcesProvider.configure { dependsOn(syncResources) } - - val stubTask = tasks.getByPath(":stub:comment$variantCapped") - val stubApk = stubTask.outputs.files.asFileTree.filter { - it.name.endsWith(".apk") - } - - val syncAssets = tasks.register("sync${variantCapped}Assets", Sync::class) { - dependsOn(stubTask) - inputs.property("version", Config.version) - inputs.property("versionCode", Config.versionCode) - into("src/$variant/assets") - from(rootFile("scripts")) { - include("util_functions.sh", "boot_patch.sh", "addon.d.sh", - "app_functions.sh", "uninstaller.sh", "module_installer.sh") - } - from(rootFile("tools/bootctl")) - into("chromeos") { - from(rootFile("tools/futility")) - from(rootFile("tools/keys")) { - include("kernel_data_key.vbprivk", "kernel.keyblock") + inputs.property("version", Config.version) + inputs.property("versionCode", Config.versionCode) + from(rootFile("scripts")) { + include("util_functions.sh", "boot_patch.sh", "addon.d.sh", + "app_functions.sh", "uninstaller.sh", "module_installer.sh") + } + from(rootFile("tools/bootctl")) + into("chromeos") { + from(rootFile("tools/futility")) + from(rootFile("tools/keys")) { + include("kernel_data_key.vbprivk", "kernel.keyblock") + } + } + from(stubTask) { + include { it.name.endsWith(".apk") } + rename { "stub.apk" } + } + filesMatching("**/util_functions.sh") { + filter { + it.replace( + "#MAGISK_VERSION_STUB", + "MAGISK_VER='${Config.version}'\nMAGISK_VER_CODE=${Config.versionCode}" + ) + } + filter("eol" to FixCrLfFilter.CrLf.newInstance("lf")) } } - from(stubApk) { - rename { "stub.apk" } - } - filesMatching("**/util_functions.sh") { - filter { - it.replace( - "#MAGISK_VERSION_STUB", - "MAGISK_VER='${Config.version}'\nMAGISK_VER_CODE=${Config.versionCode}" - ) - } - filter("eol" to FixCrLfFilter.CrLf.newInstance("lf")) + + variant.sources.assets?.let { + it.addGeneratedSourceDirectory(syncAssets, SyncWithDir::outputFolder) } } - mergeAssetsProvider.configure { dependsOn(syncAssets) } - } - - tasks.named("clean") { - delete.addAll(listOf("src/main/jniLibs", "src/main/resources", "src/debug", "src/release")) } } fun Project.setupAppCommon() { setupCommon() - android { + androidApp { signingConfigs { Config["keyStore"]?.also { create("config") { @@ -254,22 +265,25 @@ fun Project.setupAppCommon() { } } - androidComponents.onVariants { variant -> - val commentTask = tasks.register( - "comment${variant.name.replaceFirstChar { it.uppercase() }}", - AddCommentTask::class.java - ) - val transformationRequest = variant.artifacts.use(commentTask) - .wiredWithDirectories(AddCommentTask::apkFolder, AddCommentTask::outFolder) - .toTransformMany(SingleArtifact.APK) - val signingConfig = androidApp.buildTypes.getByName(variant.buildType!!).signingConfig - commentTask.configure { - this.transformationRequest = transformationRequest - this.signingConfig = signingConfig - this.comment = "version=${Config.version}\n" + - "versionCode=${Config.versionCode}\n" + - "stubVersion=${Config.stubVersion}\n" - this.outFolder.set(layout.buildDirectory.dir("outputs/apk/${variant.name}")) + androidAppComponents { + onVariants { variant -> + val commentTask = tasks.register( + "comment${variant.name.replaceFirstChar { it.uppercase() }}", + AddCommentTask::class.java + ) + val transformationRequest = variant.artifacts.use(commentTask) + .wiredWithDirectories(AddCommentTask::apkFolder, AddCommentTask::outFolder) + .toTransformMany(SingleArtifact.APK) + val signingConfig = androidApp.buildTypes.getByName(variant.buildType!!).signingConfig + commentTask.configure { + this.transformationRequest = transformationRequest + this.signingConfig = signingConfig + this.comment = "version=${Config.version}\n" + + "versionCode=${Config.versionCode}\n" + + "stubVersion=${Config.stubVersion}\n" + this.outFolder.set(layout.buildDirectory.dir("outputs/apk/${variant.name}")) + } + } } } @@ -277,7 +291,7 @@ fun Project.setupAppCommon() { fun Project.setupMainApk() { setupAppCommon() - android { + androidApp { namespace = "com.topjohnwu.magisk" defaultConfig { @@ -290,8 +304,10 @@ fun Project.setupMainApk() { debugSymbolLevel = "FULL" } } + } - androidComponents.onVariants { variant -> + androidComponents { + onVariants { variant -> variant.instrumentation.apply { setAsmFramesComputationMode(COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS) transformClassesWith( @@ -314,17 +330,26 @@ const val SHAMIKO_CHECKSUM = fun Project.setupTestApk() { setupAppCommon() - androidApp.applicationVariants.all { - val variantCapped = name.replaceFirstChar { it.uppercase() } - val dlTask by tasks.register("download${variantCapped}Lsposed", Sync::class) { - from(downloadFile(LSPOSED_DOWNLOAD_URL, LSPOSED_CHECKSUM)) { - rename { "lsposed.zip" } + androidComponents { + onVariants { variant -> + val variantName = variant.name + val variantCapped = variantName.replaceFirstChar { it.uppercase() } + + val dlTask = tasks.register("download${variantCapped}Lsposed", SyncWithDir::class) { + outputFolder.set(layout.buildDirectory.dir("$variantName/lsposed")) + into(outputFolder) + + from(downloadFile(LSPOSED_DOWNLOAD_URL, LSPOSED_CHECKSUM)) { + rename { "lsposed.zip" } + } + from(downloadFile(SHAMIKO_DOWNLOAD_URL, SHAMIKO_CHECKSUM)) { + rename { "shamiko.zip" } + } } - from(downloadFile(SHAMIKO_DOWNLOAD_URL, SHAMIKO_CHECKSUM)) { - rename { "shamiko.zip" } + + variant.sources.assets?.let { + it.addGeneratedSourceDirectory(dlTask, SyncWithDir::outputFolder) } - into("src/${this@all.name}/assets") } - mergeAssetsProvider.configure { dependsOn(dlTask) } } } diff --git a/app/buildSrc/src/main/java/Stub.kt b/app/buildSrc/src/main/java/Stub.kt index f229afe44..61ceb9fb2 100644 --- a/app/buildSrc/src/main/java/Stub.kt +++ b/app/buildSrc/src/main/java/Stub.kt @@ -8,13 +8,14 @@ import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Delete import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File @@ -82,18 +83,16 @@ private abstract class ManifestUpdater: DefaultTask() { @get:Input abstract val applicationId: Property + @get:Input + abstract val factoryClass: Property + + @get:Input + abstract val appClass: Property + @get:InputFile @get:PathSensitive(PathSensitivity.RELATIVE) abstract val mergedManifest: RegularFileProperty - @get:InputFiles - @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val factoryClassDir: DirectoryProperty - - @get:InputFiles - @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val appClassDir: DirectoryProperty - @get:OutputFile abstract val outputManifest: RegularFileProperty @@ -170,25 +169,18 @@ private abstract class ManifestUpdater: DefaultTask() { // Shuffle the order of the components cmpList.shuffle(RANDOM) - val (factoryPkg, factoryClass) = factoryClassDir.asFileTree.firstNotNullOf { - it.parentFile!!.name to it.name.removeSuffix(".java") - } - val (appPkg, appClass) = appClassDir.asFileTree.firstNotNullOf { - it.parentFile!!.name to it.name.removeSuffix(".java") - } val components = cmpList.joinToString("\n\n") .replace("\${applicationId}", applicationId.get()) val manifest = mergedManifest.asFile.get().readText().replace(Regex(".*\\ { val classNameGenerator = sequence { fun notJavaKeyword(name: String) = when (name) { "do", "if", "for", "int", "new", "try" -> false @@ -217,7 +209,7 @@ private fun genStubClasses(factoryOutDir: File, appOutDir: File) { } }.distinct().iterator() - fun genClass(type: String, outDir: File) { + fun genClass(type: String, outDir: File): String { val clzName = classNameGenerator.next() val (pkg, name) = clzName.split('.') val pkgDir = File(outDir, pkg) @@ -226,10 +218,12 @@ private fun genStubClasses(factoryOutDir: File, appOutDir: File) { it.println("package $pkg;") it.println("public class $name extends com.topjohnwu.magisk.$type {}") } + return clzName } - genClass("DelegateComponentFactory", factoryOutDir) - genClass("StubApplication", appOutDir) + val factory = genClass("DelegateComponentFactory", outDir) + val app = genClass("StubApplication", outDir) + return Pair(factory, app) } private fun genEncryptedResources(res: ByteArray, outDir: File) { @@ -264,74 +258,76 @@ private fun genEncryptedResources(res: ByteArray, outDir: File) { } } +private abstract class TaskWithDir : DefaultTask() { + @get:OutputDirectory + abstract val outputFolder: DirectoryProperty +} + fun Project.setupStubApk() { setupAppCommon() - androidComponents.onVariants { variant -> - val variantName = variant.name - val variantCapped = variantName.replaceFirstChar { it.uppercase() } - val manifestUpdater = - project.tasks.register("${variantName}ManifestProducer", ManifestUpdater::class.java) { - dependsOn("generate${variantCapped}ObfuscatedClass") - applicationId = variant.applicationId - appClassDir.set(layout.buildDirectory.dir("generated/source/app/$variantName")) - factoryClassDir.set(layout.buildDirectory.dir("generated/source/factory/$variantName")) - } - variant.artifacts.use(manifestUpdater) - .wiredWithFiles( - ManifestUpdater::mergedManifest, - ManifestUpdater::outputManifest) - .toTransform(SingleArtifact.MERGED_MANIFEST) - } + androidAppComponents { + onVariants { variant -> + val variantName = variant.name + val variantCapped = variantName.replaceFirstChar { it.uppercase() } + val variantLowered = variantName.lowercase() - androidApp.applicationVariants.all { - val variantCapped = name.replaceFirstChar { it.uppercase() } - val variantLowered = name.lowercase() - val outFactoryClassDir = layout.buildDirectory.file("generated/source/factory/${variantLowered}").get().asFile - val outAppClassDir = layout.buildDirectory.file("generated/source/app/${variantLowered}").get().asFile - val outResDir = layout.buildDirectory.dir("generated/source/res/${variantLowered}").get().asFile - val aapt = File(androidApp.sdkDirectory, "build-tools/${androidApp.buildToolsVersion}/aapt2") - val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" + - "${variantLowered}/process${variantCapped}Resources/linked-resources-binary-format-${variantLowered}.ap_").get().asFile + val componentJavaOutDir = layout.buildDirectory + .dir("generated/${variantLowered}/components").get().asFile - val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") { - inputs.property("seed", RAND_SEED) - outputs.dirs(outFactoryClassDir, outAppClassDir) - doLast { - outFactoryClassDir.mkdirs() - outAppClassDir.mkdirs() - genStubClasses(outFactoryClassDir, outAppClassDir) - } - } - registerJavaGeneratingTask(genManifestTask, outFactoryClassDir, outAppClassDir) + val (factory, app) = genStubClasses(componentJavaOutDir) - val processResourcesTask = tasks.named("process${variantCapped}Resources") { - outputs.dir(outResDir) - doLast { - val apkTmp = File("${apk}.tmp") - providers.exec { - commandLine(aapt, "optimize", "-o", apkTmp, "--collapse-resource-names", apk) - }.result.get() - - val bos = ByteArrayOutputStream() - ZipFile(apkTmp).use { src -> - ZipOutputStream(apk.outputStream()).use { - it.setLevel(Deflater.BEST_COMPRESSION) - it.putNextEntry(ZipEntry("AndroidManifest.xml")) - src.getInputStream(src.getEntry("AndroidManifest.xml")).transferTo(it) - it.closeEntry() - } - DeflaterOutputStream(bos, Deflater(Deflater.BEST_COMPRESSION)).use { - src.getInputStream(src.getEntry("resources.arsc")).transferTo(it) - } + val manifestUpdater = + project.tasks.register("${variantName}ManifestProducer", ManifestUpdater::class.java) { + applicationId = variant.applicationId + factoryClass.set(factory) + appClass.set(app) } - apkTmp.delete() - genEncryptedResources(bos.toByteArray(), outResDir) + variant.artifacts.use(manifestUpdater) + .wiredWithFiles( + ManifestUpdater::mergedManifest, + ManifestUpdater::outputManifest) + .toTransform(SingleArtifact.MERGED_MANIFEST) + + val aapt = sdkComponents.aapt2.get().executable.get().asFile + val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" + + "${variantLowered}/process${variantCapped}Resources/" + + "linked-resources-binary-format-${variantLowered}.ap_").get().asFile + + val genResourcesTask = tasks.register("generate${variantCapped}BundledResources", TaskWithDir::class) { + dependsOn("process${variantCapped}Resources") + outputFolder.set(layout.buildDirectory.dir("generated/${variantLowered}/resources")) + + doLast { + val apkTmp = File("${apk}.tmp") + providers.exec { + commandLine(aapt, "optimize", "-o", apkTmp, "--collapse-resource-names", apk) + }.result.get() + + val bos = ByteArrayOutputStream() + ZipFile(apkTmp).use { src -> + ZipOutputStream(apk.outputStream()).use { + it.setLevel(Deflater.BEST_COMPRESSION) + it.putNextEntry(ZipEntry("AndroidManifest.xml")) + src.getInputStream(src.getEntry("AndroidManifest.xml")).transferTo(it) + it.closeEntry() + } + DeflaterOutputStream(bos, Deflater(Deflater.BEST_COMPRESSION)).use { + src.getInputStream(src.getEntry("resources.arsc")).transferTo(it) + } + } + apkTmp.delete() + genEncryptedResources(bos.toByteArray(), outputFolder.get().asFile) + } + } + + variant.sources.java?.let { + it.addStaticSourceDirectory(componentJavaOutDir.path) + it.addGeneratedSourceDirectory(genResourcesTask, TaskWithDir::outputFolder) } } - - registerJavaGeneratingTask(processResourcesTask, outResDir) } + // Override optimizeReleaseResources task val apk = layout.buildDirectory.file("intermediates/linked_resources_binary_format/" + "release/processReleaseResources/linked-resources-binary-format-release.ap_").get().asFile diff --git a/app/core/.gitignore b/app/core/.gitignore deleted file mode 100644 index e2350c9f8..000000000 --- a/app/core/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/build -src/debug -src/release diff --git a/app/core/build.gradle.kts b/app/core/build.gradle.kts index 4df731211..3e47b9208 100644 --- a/app/core/build.gradle.kts +++ b/app/core/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("com.android.library") - kotlin("android") kotlin("plugin.parcelize") id("dev.zacsweers.moshix") id("com.google.devtools.ksp") diff --git a/app/core/proguard-rules.pro b/app/core/proguard-rules.pro index 854ec7bb3..9fde52bc6 100644 --- a/app/core/proguard-rules.pro +++ b/app/core/proguard-rules.pro @@ -33,9 +33,5 @@ # is used. -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation -# Excessive obfuscation --flattenpackagehierarchy --allowaccessmodification - -dontwarn org.junit.** -dontwarn org.apache.** diff --git a/app/gradle.properties b/app/gradle.properties index 7229b7476..d7cef38a1 100644 --- a/app/gradle.properties +++ b/app/gradle.properties @@ -24,9 +24,7 @@ org.gradle.caching=true kapt.use.k2=true # Android -android.useAndroidX=true android.injected.testOnly=false -android.nonFinalResIds=false # Magisk magisk.stubVersion=40 diff --git a/app/gradle/libs.versions.toml b/app/gradle/libs.versions.toml index 7ea321c40..1947d50f4 100644 --- a/app/gradle/libs.versions.toml +++ b/app/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] -kotlin = "2.2.21" -android = "8.13.2" -ksp = "2.3.3" +kotlin = "2.3.0" +android = "9.0.0" +ksp = "2.3.4" rikka = "1.3.0" navigation = "2.9.6" libsu = "6.0.0" @@ -23,7 +23,7 @@ timber = { module = "com.jakewharton.timber:timber", version = "5.0.1" } jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version = "7.1.0.202411261347-r" } # AndroidX -activity = { module = "androidx.activity:activity", version = "1.12.1" } +activity = { module = "androidx.activity:activity", version = "1.12.2" } appcompat = { module = "androidx.appcompat:appcompat", version = "1.7.1" } core-ktx = { module = "androidx.core:core-ktx", version = "1.17.0" } core-splashscreen = { module = "androidx.core:core-splashscreen", version = "1.2.0" } @@ -37,7 +37,7 @@ room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version = "1.2.0" } -transition = { module = "androidx.transition:transition", version = "1.6.0" } +transition = { module = "androidx.transition:transition", version = "1.7.0" } collection-ktx = { module = "androidx.collection:collection-ktx", version = "1.5.0" } material = { module = "com.google.android.material:material", version = "1.13.0" } jdk-libs = { module = "com.android.tools:desugar_jdk_libs_nio", version = "2.1.5" } @@ -59,9 +59,10 @@ rikka-insets = { module = "dev.rikka.rikkax.insets:insets", version.ref = "rikka # Build plugins android-gradle-plugin = { module = "com.android.tools.build:gradle", version.ref = "android" } +android-kapt-plugin = { module = "com.android.legacy-kapt:com.android.legacy-kapt.gradle.plugin", version.ref = "android" } ksp-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } navigation-safe-args-plugin = { module = "androidx.navigation:navigation-safe-args-gradle-plugin", version.ref = "navigation" } lsparanoid-plugin = { module = "org.lsposed.lsparanoid:gradle-plugin", version = "0.6.0" } -moshi-plugin = { module = "dev.zacsweers.moshix:dev.zacsweers.moshix.gradle.plugin", version = "0.34.1" } +moshi-plugin = { module = "dev.zacsweers.moshix:dev.zacsweers.moshix.gradle.plugin", version = "0.34.2" } [plugins] diff --git a/app/gradle/wrapper/gradle-wrapper.properties b/app/gradle/wrapper/gradle-wrapper.properties index 2a84e188b..19a6bdeb8 100644 --- a/app/gradle/wrapper/gradle-wrapper.properties +++ b/app/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/app/shared/.gitignore b/app/shared/.gitignore deleted file mode 100644 index 796b96d1c..000000000 --- a/app/shared/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/app/shared/build.gradle.kts b/app/shared/build.gradle.kts index d794c75fa..ce36bed08 100644 --- a/app/shared/build.gradle.kts +++ b/app/shared/build.gradle.kts @@ -6,4 +6,5 @@ setupCommon() android { namespace = "com.topjohnwu.shared" + enableKotlin = false } diff --git a/app/test/build.gradle.kts b/app/test/build.gradle.kts index f07eaf206..03202db95 100644 --- a/app/test/build.gradle.kts +++ b/app/test/build.gradle.kts @@ -1,6 +1,5 @@ plugins { id("com.android.application") - kotlin("android") } android {