Update to AGP 9.0

This commit is contained in:
topjohnwu
2026-01-19 03:50:43 +08:00
committed by John Wu
parent 0bbc736051
commit 18c1347bd3
17 changed files with 242 additions and 228 deletions

2
app/.gitignore vendored
View File

@@ -3,5 +3,5 @@
# Gradle
.gradle
.kotlin
build
/local.properties
/build

1
app/apk/.gitignore vendored
View File

@@ -1 +0,0 @@
/build

View File

@@ -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

3
app/apk/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,3 @@
# Excessive obfuscation
-flattenpackagehierarchy
-allowaccessmodification

View File

@@ -1 +0,0 @@
/build

View File

@@ -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)

View File

@@ -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<BaseExtension>) =
private fun Project.android(configure: Action<CommonExtension>) =
extensions.configure("android", configure)
private fun Project.android(configure: Action<BaseAppModuleExtension>) =
private fun Project.androidApp(configure: Action<ApplicationExtension>) =
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<AndroidComponentsExtension<*, *, *>>) =
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<ApplicationAndroidComponentsExtension>) =
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<FixCrLfFilter>("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<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
variant.sources.assets?.let {
it.addGeneratedSourceDirectory(syncAssets, SyncWithDir::outputFolder)
}
}
mergeAssetsProvider.configure { dependsOn(syncAssets) }
}
tasks.named<Delete>("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) }
}
}

View File

@@ -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<String>
@get:Input
abstract val factoryClass: Property<String>
@get:Input
abstract val appClass: Property<String>
@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(".*\\<application"), """
|<application
| android:appComponentFactory="$factoryPkg.$factoryClass"
| android:name="$appPkg.$appClass"""".ind(1)
| android:appComponentFactory="${factoryClass.get()}"
| android:name="${appClass.get()}"""".ind(1)
).replace(Regex(".*\\<\\/application"), "$components\n </application")
outputManifest.get().asFile.writeText(manifest)
}
}
private fun genStubClasses(factoryOutDir: File, appOutDir: File) {
private fun genStubClasses(outDir: File): Pair<String, String> {
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

3
app/core/.gitignore vendored
View File

@@ -1,3 +0,0 @@
/build
src/debug
src/release

View File

@@ -1,6 +1,5 @@
plugins {
id("com.android.library")
kotlin("android")
kotlin("plugin.parcelize")
id("dev.zacsweers.moshix")
id("com.google.devtools.ksp")

View File

@@ -33,9 +33,5 @@
# is used.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
# Excessive obfuscation
-flattenpackagehierarchy
-allowaccessmodification
-dontwarn org.junit.**
-dontwarn org.apache.**

View File

@@ -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

View File

@@ -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]

View File

@@ -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

View File

@@ -1 +0,0 @@
/build

View File

@@ -6,4 +6,5 @@ setupCommon()
android {
namespace = "com.topjohnwu.shared"
enableKotlin = false
}

View File

@@ -1,6 +1,5 @@
plugins {
id("com.android.application")
kotlin("android")
}
android {