diff --git a/buildSrc/src/main/java/Codegen.kt b/buildSrc/src/main/java/Codegen.kt index a151783c2..631d253ed 100644 --- a/buildSrc/src/main/java/Codegen.kt +++ b/buildSrc/src/main/java/Codegen.kt @@ -1,3 +1,7 @@ +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.* import java.io.ByteArrayOutputStream import java.io.File import java.io.InputStream @@ -72,23 +76,41 @@ fun genKeyData(keysDir: File, outSrc: File) { } } -fun genStubManifest(srcDir: File, outDir: File): String { - fun String.ind(level: Int) = replaceIndentByMargin(" ".repeat(level)) +@CacheableTask +abstract class ManifestUpdater: DefaultTask() { + @get:InputFile + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val mergedManifest: RegularFileProperty - val cmpList = mutableListOf() + @get:InputFiles + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val factoryClassDir: DirectoryProperty - cmpList.add( - """ + @get:InputFiles + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val appClassDir: DirectoryProperty + + @get:OutputFile + abstract val outputManifest: RegularFileProperty + + @TaskAction + fun taskAction() { + fun String.ind(level: Int) = replaceIndentByMargin(" ".repeat(level)) + + val cmpList = mutableListOf() + + cmpList.add( + """ |""".ind(2) - ) + ) - cmpList.add( - """ + cmpList.add( + """ | @@ -104,10 +126,10 @@ fun genStubManifest(srcDir: File, outDir: File): String { | | |""".ind(2) - ) + ) - cmpList.add( - """ + cmpList.add( + """ | @@ -116,37 +138,55 @@ fun genStubManifest(srcDir: File, outDir: File): String { | | |""".ind(2) - ) + ) - cmpList.add( - """ + cmpList.add( + """ | + | android:taskAffinity=""> | | | | |""".ind(2) - ) + ) - cmpList.add( - """ + cmpList.add( + """ |""".ind(2) - ) + ) - cmpList.add( - """ + cmpList.add( + """ |""".ind(2) - ) + ) + + // Shuffle the order of the components + cmpList.shuffle(RANDOM) + val (factoryPkg, factoryClass) = factoryClassDir.asFileTree.first().let { + it.parentFile.name to it.name.removeSuffix(".java") + } + val (appPkg, appClass) = appClassDir.asFileTree.first().let { + it.parentFile.name to it.name.removeSuffix(".java") + } + var manifest = mergedManifest.asFile.get().readText() + manifest = manifest.replace(" + + @get:Input + abstract val signingConfig: Property + + @get:InputFiles + abstract val apkFolder: DirectoryProperty + + @get:OutputDirectory + abstract val outFolder: DirectoryProperty + + @get:Internal + abstract val transformationRequest: Property> + + @TaskAction + fun taskAction() = transformationRequest.get().submit(this) { artifact -> + val inFile = File(artifact.outputFile) + val outFile = outFolder.file(inFile.name).get().asFile + addComment(inFile, outFile, signingConfig.get(), 0, comment.get()) + outFile + } +} + private fun Project.setupAppCommon() { setupCommon() @@ -146,15 +179,22 @@ private fun Project.setupAppCommon() { } } - android.applicationVariants.all { - val projectName = project.name.lowercase() - val variantCapped = name.replaceFirstChar { it.uppercase() } - tasks.getByPath(":$projectName:package$variantCapped").doLast { - val apk = outputs.files.asFileTree.filter { it.name.endsWith(".apk") }.singleFile - val comment = "version=${Config.version}\n" + + 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 = android.buildTypes.getByName(variant.buildType!!).signingConfig + commentTask.configure { + this.transformationRequest.set(transformationRequest) + this.signingConfig.set(signingConfig) + this.comment.set("version=${Config.version}\n" + "versionCode=${Config.versionCode}\n" + - "stubVersion=${Config.stubVersion}\n" - addComment(apk, signingConfig, android.defaultConfig.minSdk!!, comment) + "stubVersion=${Config.stubVersion}\n") + this.outFolder.set(File(buildDir, "outputs/apk/${variant.name}")) } } } @@ -265,33 +305,45 @@ fun Project.setupApp() { fun Project.setupStub() { setupAppCommon() + + androidComponents.onVariants { variant -> + val manifestUpdater = + project.tasks.register( + "${variant.name}ManifestProducer", + ManifestUpdater::class.java + ) { + dependsOn("generate${variant.name.replaceFirstChar { it.uppercase() }}ObfuscatedClass") + appClassDir.set(File(buildDir, "generated/source/app/${variant.name}")) + factoryClassDir.set(File(buildDir, "generated/source/factory/${variant.name}")) + } + variant.artifacts.use(manifestUpdater) + .wiredWithFiles( + ManifestUpdater::mergedManifest, + ManifestUpdater::outputManifest) + .toTransform(SingleArtifact.MERGED_MANIFEST) + } + android.applicationVariants.all { val variantCapped = name.replaceFirstChar { it.uppercase() } val variantLowered = name.lowercase() - val manifest = file("src/${variantLowered}/AndroidManifest.xml") - val outManifestDir = File(buildDir, "generated/source/manifest/${variantLowered}") + val outFactoryClassDir = File(buildDir, "generated/source/factory/${variantLowered}") + val outAppClassDir = File(buildDir, "generated/source/app/${variantLowered}") val outResDir = File(buildDir, "generated/source/res/${variantLowered}") - val templateDir = file("template") val aapt = File(android.sdkDirectory, "build-tools/${android.buildToolsVersion}/aapt2") val apk = File(buildDir, "intermediates/processed_res/" + "${variantLowered}/out/resources-${variantLowered}.ap_") val apkTmp = File("${apk}.tmp") - val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedManifest") { + val genManifestTask = tasks.register("generate${variantCapped}ObfuscatedClass") { inputs.property("seed", RAND_SEED) - inputs.dir(templateDir) - outputs.dir(outManifestDir) - outputs.file(manifest) + outputs.dirs(outFactoryClassDir, outAppClassDir) doLast { - val xml = genStubManifest(templateDir, outManifestDir) - manifest.parentFile.mkdirs() - PrintStream(manifest).use { - it.print(xml) - } + outFactoryClassDir.mkdirs() + outAppClassDir.mkdirs() + genStubClass(outFactoryClassDir, outAppClassDir) } } - preBuildProvider.configure { dependsOn(genManifestTask) } - registerJavaGeneratingTask(genManifestTask, outManifestDir) + registerJavaGeneratingTask(genManifestTask, outFactoryClassDir, outAppClassDir) val processResourcesTask = tasks.getByPath(":stub:process${variantCapped}Resources") processResourcesTask.doLast { diff --git a/stub/src/main/AndroidManifest.xml b/stub/src/main/AndroidManifest.xml index 9b65eb06c..386ed90bf 100644 --- a/stub/src/main/AndroidManifest.xml +++ b/stub/src/main/AndroidManifest.xml @@ -1 +1,14 @@ - + + + + + + + + + + + + diff --git a/stub/template/AndroidManifest.xml b/stub/template/AndroidManifest.xml deleted file mode 100644 index a9fc41040..000000000 --- a/stub/template/AndroidManifest.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - -%s - - - -