@@ -27,11 +27,15 @@ import com.android.ide.common.symbols.parseManifest
2727import com.android.manifmerger.ManifestMerger2
2828import com.android.manifmerger.ManifestProvider
2929import com.android.utils.appendCapitalized
30+ import com.github.jengelman.gradle.plugins.shadow.ShadowStats
31+ import com.github.jengelman.gradle.plugins.shadow.relocation.RelocatePathContext
3032import com.github.jengelman.gradle.plugins.shadow.relocation.Relocator
3133import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
3234import org.gradle.api.Plugin
3335import org.gradle.api.Project
3436import org.gradle.api.artifacts.Configuration
37+ import org.gradle.api.attributes.Usage
38+ import org.gradle.api.file.Directory
3539import org.gradle.api.publish.maven.internal.publication.DefaultMavenPublication
3640import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
3741import org.gradle.kotlin.dsl.support.unzipTo
@@ -71,6 +75,7 @@ open class GreasePlugin : Plugin<Project> {
7175 fun configure (variant : Variant , vararg configurations : Configuration ) {
7276 configureVariantManifest(target, variant, configurations, log)
7377 configureVariantJniLibs(target, variant, configurations, log)
78+ configureVariantAidlParcelables(target, variant, configurations, log)
7479 configureVariantResources(target, variant, configurations, log)
7580 configureVariantSources(target, variant, configurations, greaseExtension, log)
7681 configureVariantAssets(target, variant, configurations, log)
@@ -121,7 +126,7 @@ open class GreasePlugin : Plugin<Project> {
121126 target.locateTask(componentConfig.resolveTaskName(" process" , " Manifest" ))?.configure {
122127 val processManifestTask = this as ProcessLibraryManifest
123128
124- val extraManifests = configurations.artifactsOf(AndroidArtifacts .ArtifactType .MANIFEST )
129+ val extraManifests = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .MANIFEST )
125130 dependsOn(extraManifests)
126131
127132 // After the file is copied we can go on with the actual manifest merging.
@@ -220,7 +225,7 @@ open class GreasePlugin : Plugin<Project> {
220225
221226 target.locateTask(creationConfig.resolveTaskName(" copy" , " JniLibsProjectAndLocalJars" ))?.configure {
222227 val copyJniTask = this as LibraryJniLibsTask
223- val extraJniLibs = configurations.artifactsOf(AndroidArtifacts .ArtifactType .JNI )
228+ val extraJniLibs = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .JNI )
224229 dependsOn(extraJniLibs)
225230
226231 fun injectJniLibs () {
@@ -248,6 +253,37 @@ open class GreasePlugin : Plugin<Project> {
248253 }
249254 }
250255
256+ private fun configureVariantAidlParcelables (
257+ target : Project ,
258+ variant : Variant ,
259+ configurations : Array <out Configuration >,
260+ logger : Logger
261+ ) {
262+ val log = logger.child(" configureVariantAidlParcelables" )
263+ log.d { " Configuring variant ${variant.name} ..." }
264+ val creationConfig = variant.componentCreationConfigOrThrow()
265+ creationConfig.taskContainer.aidlCompileTask?.configure {
266+ val extraAidlFiles = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .AIDL , Usage .JAVA_API )
267+ dependsOn(extraAidlFiles)
268+ fun injectAidlFiles () {
269+ log.d { " Executing for variant ${variant.name} and ${extraAidlFiles.files.size} roots..." }
270+ extraAidlFiles.files.forEach { inputRoot ->
271+ log.d { " Found aidl parcelables files root: $inputRoot " }
272+ val inputFiles = target.fileTree(inputRoot)
273+ target.copy {
274+ from(inputFiles)
275+ into(packagedDir.get())
276+ }
277+ }
278+ }
279+ if (sourceFiles.get().files.isNotEmpty()) {
280+ doLast { injectAidlFiles() }
281+ } else {
282+ injectAidlFiles()
283+ }
284+ }
285+ }
286+
251287 /* *
252288 * AARs ship with a file called R.txt which already includes all resource ids from dependencies,
253289 * so we shouldn't probably do nothing about it as it comes for free.
@@ -321,7 +357,7 @@ open class GreasePlugin : Plugin<Project> {
321357 val resourcesMergingWorkdir = target.greaseBuildDir.get().dir(variant.name).dir(" resources" )
322358 val mergedResourcesDir = resourcesMergingWorkdir.dir(" merged" )
323359 val blameDir = resourcesMergingWorkdir.dir(" blame" )
324- val extraAndroidRes = configurations.artifactsOf(AndroidArtifacts .ArtifactType .ANDROID_RES )
360+ val extraAndroidRes = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .ANDROID_RES )
325361 dependsOn(extraAndroidRes)
326362
327363 outputs.upToDateWhen { false } // always execute
@@ -386,6 +422,7 @@ open class GreasePlugin : Plugin<Project> {
386422 val creationConfig = variant.componentCreationConfigOrThrow()
387423
388424 val workdir = target.greaseBuildDir.get().dir(variant.name)
425+ workdir.asFile.deleteRecursively()
389426 val aarExtractWorkdir = workdir.dir(" extract" ).dir(" aar" )
390427 val jarExtractWorkdir = workdir.dir(" extract" ).dir(" jar" )
391428 val jarFileName = " classes.jar"
@@ -414,7 +451,7 @@ open class GreasePlugin : Plugin<Project> {
414451
415452 // There are many options here. PROCESSED_JAR, PROCESSED_AAR, CLASSES, CLASSES_JAR ...
416453 // CLASSES_JAR seems to be the best though it's not clear if it's jetified or not.
417- val extraJars = configurations.artifactsOf(AndroidArtifacts .ArtifactType .CLASSES_JAR )
454+ val extraJars = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .CLASSES_JAR )
418455 dependsOn(extraJars)
419456 dependsOn(greaseExpandTask)
420457
@@ -444,7 +481,7 @@ open class GreasePlugin : Plugin<Project> {
444481 ShadowJar ::class .java
445482 ) {
446483 val compileTask = creationConfig.taskContainer.javacTask
447- val extraManifests = configurations.artifactsOf(AndroidArtifacts .ArtifactType .MANIFEST )
484+ val extraManifests = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .MANIFEST )
448485 val greaseShadowDir = workdir.dir(" shadow" )
449486 val bundleAar = bundleLibraryTask?.get() as BundleAar
450487
@@ -475,8 +512,8 @@ open class GreasePlugin : Plugin<Project> {
475512
476513 val relocationPrefix = greaseExtension.prefix.get()
477514 if (relocationPrefix.isNotEmpty()) {
478- greaseProcessTask.get().outputs.files
479- .asSequence()
515+ val sequence = greaseProcessTask.get().outputs.files.asSequence() + aarExtractWorkdir.dir( " aidl " ).asFile
516+ sequence
480517 .flatMap { inputFile -> inputFile.packageNames }
481518 .distinct()
482519 .map { packageName -> packageName to " ${relocationPrefix} .$packageName " }
@@ -502,13 +539,20 @@ open class GreasePlugin : Plugin<Project> {
502539 into(aarExtractWorkdir)
503540 }
504541
505- replacePackagesInFile (
542+ replacePackagesInManifest (
506543 aarExtractWorkdir.file(" AndroidManifest.xml" ).asFile,
507544 greaseShadowDir.file(" AndroidManifest.xml" ).asFile,
508545 relocators,
509546 target,
510547 )
511548
549+ relocateAidlFiles(
550+ aarExtractWorkdir.dir(" aidl" ),
551+ greaseShadowDir.dir(" aidl" ),
552+ relocators,
553+ target,
554+ )
555+
512556 val oldArchive = bundleAar.archiveFile.get().asFile
513557 val archiveParent = oldArchive.parentFile
514558 val archiveName = oldArchive.name
@@ -544,7 +588,7 @@ open class GreasePlugin : Plugin<Project> {
544588 }
545589 }
546590
547- private fun replacePackagesInFile (
591+ private fun replacePackagesInManifest (
548592 input : File ,
549593 output : File ,
550594 relocators : List <Relocator >,
@@ -573,6 +617,48 @@ open class GreasePlugin : Plugin<Project> {
573617 }
574618 }
575619
620+
621+ private fun relocateAidlFiles (
622+ inputDir : Directory ,
623+ outputDir : Directory ,
624+ relocators : List <Relocator >,
625+ target : Project ,
626+ ) {
627+ if (inputDir.asFileTree.isEmpty) return
628+
629+ inputDir.asFileTree.forEach { file ->
630+ val relocatePathContext = RelocatePathContext ().apply {
631+ stats = ShadowStats ()
632+ }
633+ val reader = file.bufferedReader()
634+ val relocatedPath = relocators
635+ .filterNot { it is RClassRelocator }
636+ .fold(file.toRelativeString(inputDir.asFile)) { acc, relocator ->
637+ relocator.relocatePath(relocatePathContext.apply { path = acc })
638+ }
639+ val writer = outputDir.asFile.file(relocatedPath).bufferedWriter()
640+ reader.useLines { strings ->
641+ strings
642+ .map { string ->
643+ relocators
644+ .filterNot { it is RClassRelocator }
645+ .fold(string) { acc, relocator ->
646+ relocator.applyToSourceContent(acc)
647+ }
648+ }.forEach {
649+ writer.write(it)
650+ writer.newLine()
651+ }
652+ }
653+ writer.close()
654+ }
655+ inputDir.asFile.deleteRecursively()
656+ target.copy {
657+ from(outputDir)
658+ into(inputDir)
659+ }
660+ }
661+
576662 /* *
577663 * Interesting tasks:
578664 * 1. generate<>Assets: See [MutableTaskContainer].
@@ -592,7 +678,7 @@ open class GreasePlugin : Plugin<Project> {
592678 log.d { " Configuring variant ${variant.name} ..." }
593679 val creationConfig = variant.componentCreationConfigOrThrow()
594680 creationConfig.taskContainer.mergeAssetsTask.configure {
595- val extraAssets = configurations.artifactsOf(AndroidArtifacts .ArtifactType .ASSETS )
681+ val extraAssets = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .ASSETS )
596682 dependsOn(extraAssets)
597683 fun injectAssets () {
598684 log.d { " Executing for variant ${variant.name} and ${extraAssets.files.size} roots..." }
@@ -650,7 +736,7 @@ open class GreasePlugin : Plugin<Project> {
650736 // UNFILTERED_PROGUARD_RULES, FILTERED_PROGUARD_RULES, AAPT_PROGUARD_RULES, ...
651737 // UNFILTERED_PROGUARD_RULES is output of the AarTransform. FILTERED_PROGUARD_RULES
652738 // is processed by another transform and is probably what we want in the end.
653- val extraInputs = configurations.artifactsOf(AndroidArtifacts .ArtifactType .FILTERED_PROGUARD_RULES )
739+ val extraInputs = configurations.artifactsOf(target, AndroidArtifacts .ArtifactType .FILTERED_PROGUARD_RULES )
654740 dependsOn(extraInputs)
655741
656742 mergeFileTask.inputs.files(extraInputs + mergeFileTask.inputFiles.files)
0 commit comments