import java.security.MessageDigest import org.apache.tools.ant.filters.ReplaceTokens import org.apache.tools.ant.filters.FixCrLfFilter plugins { id("com.android.library") } val moduleId: String by rootProject.extra val moduleName: String by rootProject.extra val verCode: Int by rootProject.extra val verName: String by rootProject.extra android.buildFeatures { androidResources = false buildConfig = false } androidComponents.onVariants { variant -> val variantLowered = variant.name.toLowerCase() val variantCapped = variant.name.capitalize() val buildTypeLowered = variant.buildType?.toLowerCase() val moduleDir = "$buildDir/outputs/module/$variantLowered" val zipFileName = "$moduleName-$verName-$buildTypeLowered.zip".replace(' ', '-') val prepareModuleFilesTask = task("prepareModuleFiles$variantCapped") { group = "module" dependsOn( ":loader:assemble$variantCapped", ":zygiskd:cargoBuild", ) into(moduleDir) from("${rootProject.projectDir}/README.md") from("$projectDir/src") { exclude("module.prop", "customize.sh", "daemon.sh") filter("eol" to FixCrLfFilter.CrLf.newInstance("lf")) } from("$projectDir/src") { include("module.prop") expand( "moduleId" to moduleId, "moduleName" to moduleName, "versionName" to verName, "versionCode" to verCode, ) } from("$projectDir/src") { include("customize.sh", "daemon.sh") val tokens = mapOf( "ZYGISK_API" to (verCode / 1000).toString(), "DEBUG" to if (buildTypeLowered == "debug") "true" else "false" ) filter("tokens" to tokens) filter("eol" to FixCrLfFilter.CrLf.newInstance("lf")) } into("bin") { from(project(":zygiskd").buildDir.path + "/rustJniLibs/android") } into("lib") { from("${project(":loader").buildDir}/intermediates/stripped_native_libs/$variantLowered/out/lib") } doLast { fileTree(moduleDir).visit { if (isDirectory) return@visit val md = MessageDigest.getInstance("SHA-256") file.forEachBlock(4096) { bytes, size -> md.update(bytes, 0, size) } file(file.path + ".sha256").writeText(org.apache.commons.codec.binary.Hex.encodeHexString(md.digest())) } } } val zipTask = task("zip$variantCapped") { group = "module" dependsOn(prepareModuleFilesTask) archiveFileName.set(zipFileName) destinationDirectory.set(file("$buildDir/outputs/release")) from(moduleDir) } val pushTask = task("push$variantCapped") { group = "module" dependsOn(zipTask) commandLine("adb", "push", zipTask.outputs.files.singleFile.path, "/data/local/tmp") } val installKsuTask = task("installKsu$variantCapped") { group = "module" dependsOn(pushTask) doLast { exec { commandLine( "adb", "shell", "echo", """su -c \"/data/adb/ksud module install /data/local/tmp/$zipFileName\"""", "> /data/local/tmp/install.sh" ) } exec { commandLine("adb", "shell", "chmod", "755", "/data/local/tmp/install.sh") } exec { commandLine("adb", "shell", "su", "-c", "/data/local/tmp/install.sh") } } } val installMagiskTask = task("installMagisk$variantCapped") { group = "module" dependsOn(pushTask) commandLine("adb", "shell", "su", "-c", "KSU=true magisk --install-module /data/local/tmp/$zipFileName") } task("installKsuAndReboot$variantCapped") { group = "module" dependsOn(installKsuTask) commandLine("adb", "reboot") } task("installMagiskAndReboot$variantCapped") { group = "module" dependsOn(installMagiskTask) commandLine("adb", "reboot") } }