diff options
7 files changed, 108 insertions, 77 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java index 5cd4f0f123..434531a670 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java @@ -187,12 +187,13 @@ public class AarImport implements RuleConfiguredTargetFactory { common.addTransitiveInfoProviders( ruleBuilder, javaInfoBuilder, filesToBuild, /*classJar=*/ null); + resourceApk.addToConfiguredTargetBuilder(ruleBuilder, ruleContext.getLabel()); + ruleBuilder .setFilesToBuild(filesToBuild) .addSkylarkTransitiveInfo( JavaSkylarkApiProvider.NAME, JavaSkylarkApiProvider.fromRuleContext()) .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY) - .addNativeDeclaredProvider(resourceApk.toResourceInfo(ruleContext.getLabel())) .addNativeDeclaredProvider( new AndroidNativeLibsInfo( AndroidCommon.collectTransitiveNativeLibs(ruleContext).add(nativeLibs).build())) diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java index b306d69fa8..30f20c3aaa 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java @@ -781,7 +781,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP)) .withShrunkJar(proguardOutput.getOutputJar()) .withProguardMapping(proguardOutput.getMapping()) - .withPrimary(resourceApk.getPrimaryResource()) + .withPrimary(resourceApk.getPrimaryResources()) .withDependencies(resourceApk.getResourceDependencies()) .setTargetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)) .setResourceFilterFactory(ResourceFilterFactory.fromRuleContext(ruleContext)) @@ -790,15 +790,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory { .build(); filesBuilder.add( ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCE_SHRINKER_LOG)); - return new ResourceApk( - apk, - resourceApk.getResourceJavaSrcJar(), - resourceApk.getResourceJavaClassJar(), - resourceApk.getResourceDependencies(), - resourceApk.getPrimaryResource(), - resourceApk.getManifest(), - resourceApk.getResourceProguardConfig(), - resourceApk.getMainDexProguardConfig()); + return resourceApk.withApk(apk); } return resourceApk; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java index 68e9b1748d..c6292a623f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidCommon.java @@ -269,7 +269,7 @@ public class AndroidCommon { ideInfoProviderBuilder .setDefinesAndroidResources(true) // Sets the possibly merged manifest and the raw manifest. - .setGeneratedManifest(resourceApk.getPrimaryResource().getManifest()) + .setGeneratedManifest(resourceApk.getManifest()) .setManifest(ruleContext.getPrerequisiteArtifact("manifest", Mode.TARGET)) .setJavaPackage(getJavaPackage(ruleContext)) .setResourceApk(resourceApk.getArtifact()); @@ -437,7 +437,7 @@ public class AndroidCommon { if (useRClassGenerator) { new RClassGeneratorActionBuilder(ruleContext) .targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)) - .withPrimary(resourceApk.getPrimaryResource()) + .withPrimary(resourceApk.getPrimaryResources()) .withDependencies(resourceApk.getResourceDependencies()) .setClassJarOut(resourceClassJar) .build(); @@ -740,7 +740,7 @@ public class AndroidCommon { .setNeverlink(isNeverlink) .build(); - AndroidResourcesInfo resourceInfo = resourceApk.toResourceInfo(ruleContext.getLabel()); + resourceApk.addToConfiguredTargetBuilder(builder, ruleContext.getLabel()); return builder .setFilesToBuild(filesToBuild) @@ -748,7 +748,6 @@ public class AndroidCommon { JavaSkylarkApiProvider.NAME, JavaSkylarkApiProvider.fromRuleContext()) .addNativeDeclaredProvider(javaInfo) .addProvider(RunfilesProvider.class, RunfilesProvider.simple(getRunfiles())) - .addNativeDeclaredProvider(resourceInfo) .addProvider( AndroidIdeInfoProvider.class, createAndroidIdeInfoProvider( @@ -760,8 +759,6 @@ public class AndroidCommon { zipAlignedApk, apksUnderTest, nativeLibs)) - .addSkylarkTransitiveInfo( - AndroidSkylarkApiProvider.NAME, new AndroidSkylarkApiProvider(resourceInfo)) .addOutputGroup( OutputGroupInfo.HIDDEN_TOP_LEVEL, collectHiddenTopLevelArtifacts(ruleContext)) .addOutputGroup( diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java index bf14b5c3f9..9c899b1061 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java @@ -143,6 +143,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { && (definesLocalResources || ruleContext.getFragment(AndroidConfiguration.class).fixedResourceNeverlinking()); ResourceDependencies resourceDeps = ResourceDependencies.fromRuleDeps(ruleContext, isNeverLink); + AssetDependencies assetDeps = AssetDependencies.fromRuleDeps(ruleContext, isNeverLink); final ResourceApk resourceApk; if (definesLocalResources) { @@ -165,7 +166,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { return null; } } else { - resourceApk = ResourceApk.fromTransitiveResources(resourceDeps); + resourceApk = ResourceApk.fromTransitiveResources(resourceDeps, assetDeps); } JavaTargetAttributes javaTargetAttributes = @@ -189,7 +190,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory { final ResourceContainer primaryResources; final Aar aar; if (definesLocalResources) { - primaryResources = resourceApk.getPrimaryResource(); + primaryResources = resourceApk.getPrimaryResources(); // applicationManifest has already been checked for nullness above in this method ApplicationManifest applicationManifest = ApplicationManifest.fromExplicitManifest(ruleContext, resourceApk.getManifest()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java index 14279dc1bb..ca7f4b4943 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java @@ -142,7 +142,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor Substitution.of("%android_merged_assets%", "jar:file:" + resourcesLocation + "!/assets")); substitutions.add( Substitution.of( - "%android_custom_package%", resourceApk.getPrimaryResource().getJavaPackage())); + "%android_custom_package%", resourceApk.getPrimaryResources().getJavaPackage())); boolean generateBinaryResources = androidLocalTestConfiguration.useAndroidLocalTestBinaryResources(); @@ -371,7 +371,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor if (resourceApk.getResourceJavaClassJar() == null) { new RClassGeneratorActionBuilder(ruleContext) .targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)) - .withPrimary(resourceApk.getPrimaryResource()) + .withPrimary(resourceApk.getPrimaryResources()) .withDependencies(resourceApk.getResourceDependencies()) .setClassJarOut(resourceClassJar) .build(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java index 19113084da..9ce263170d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java @@ -348,15 +348,7 @@ public final class ApplicationManifest { } ResourceContainer processed = builder.build(ruleContext); - return new ResourceApk( - resourceContainer.getApk(), - processed.getJavaSourceJar(), - processed.getJavaClassJar(), - resourceDeps, - processed, - processed.getManifest(), - proguardCfg, - mainDexProguardCfg); + return ResourceApk.of(processed, resourceDeps, proguardCfg, mainDexProguardCfg); } /** Packages up the manifest with resource and assets from the LocalResourceContainer. */ @@ -419,15 +411,7 @@ public final class ApplicationManifest { .setStaticLibraryOut(merged.getStaticLibrary()) .build(ruleContext, merged); - return new ResourceApk( - resourceContainer.getApk(), - processed.getJavaSourceJar(), - processed.getJavaClassJar(), - resourceDeps, - processed, - processed.getManifest(), - null, - null); + return ResourceApk.of(processed, resourceDeps); } /* Creates an incremental apk from assets and data. */ @@ -483,15 +467,7 @@ public final class ApplicationManifest { .setPackageUnderTest(null) .build(ruleContext); - return new ResourceApk( - resourceContainer.getApk(), - processed.getJavaSourceJar(), - processed.getJavaClassJar(), - resourceDeps, - processed, - processed.getManifest(), - proguardCfg, - null); + return ResourceApk.of(processed, resourceDeps, proguardCfg, null); } /** Packages up the manifest with resource and assets from the rule and dependent resources. */ @@ -572,15 +548,7 @@ public final class ApplicationManifest { .setSourceJarOut(resourceContainer.getJavaSourceJar()) .build(ruleContext); - return new ResourceApk( - resourceContainer.getApk(), - processed.getJavaSourceJar(), - processed.getJavaClassJar(), - resourceDeps, - processed, - processed.getManifest(), - proguardCfg, - mainDexProguardCfg); + return ResourceApk.of(processed, resourceDeps, proguardCfg, mainDexProguardCfg); } public ResourceApk packLibraryWithDataAndResources( @@ -682,15 +650,7 @@ public final class ApplicationManifest { .setStaticLibraryOut(merged.getStaticLibrary()) .build(ruleContext, merged); - return new ResourceApk( - resourceContainer.getApk(), - processed.getJavaSourceJar(), - processed.getJavaClassJar(), - resourceDeps, - processed, - processed.getManifest(), - null, - null); + return ResourceApk.of(processed, resourceDeps); } public Artifact getManifest() { diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java index b2b73a2aa6..2a43b64fc5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java @@ -14,6 +14,8 @@ package com.google.devtools.build.lib.rules.android; import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.OutputGroupInfo; +import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import javax.annotation.Nullable; @@ -31,17 +33,44 @@ public final class ResourceApk { @Nullable private final Artifact resourceJavaSrcJar; // Source jar containing R.java and friends @Nullable private final Artifact resourceJavaClassJar; // Class jar containing R.class files private final ResourceDependencies resourceDeps; - @Nullable private final ResourceContainer primaryResource; + private final AssetDependencies assetDeps; + @Nullable private final ResourceContainer primaryResources; + @Nullable private final AndroidAssets primaryAssets; + @Nullable private final Artifact manifest; // The non-binary XML version of AndroidManifest.xml @Nullable private final Artifact resourceProguardConfig; @Nullable private final Artifact mainDexProguardConfig; - public ResourceApk( + static ResourceApk of(ResourceContainer resourceContainer, ResourceDependencies resourceDeps) { + return of(resourceContainer, resourceDeps, null, null); + } + + static ResourceApk of( + ResourceContainer resourceContainer, + ResourceDependencies resourceDeps, + @Nullable Artifact resourceProguardConfig, + @Nullable Artifact mainDexProguardConfig) { + return new ResourceApk( + resourceContainer.getApk(), + resourceContainer.getJavaSourceJar(), + resourceContainer.getJavaClassJar(), + resourceDeps, + AssetDependencies.empty(), + resourceContainer, + resourceContainer.getAndroidAssets(), + resourceContainer.getManifest(), + resourceProguardConfig, + mainDexProguardConfig); + } + + private ResourceApk( @Nullable Artifact resourceApk, @Nullable Artifact resourceJavaSrcJar, @Nullable Artifact resourceJavaClassJar, ResourceDependencies resourceDeps, - @Nullable ResourceContainer primaryResource, + AssetDependencies assetDeps, + @Nullable ResourceContainer primaryResources, + @Nullable AndroidAssets primaryAssets, @Nullable Artifact manifest, @Nullable Artifact resourceProguardConfig, @Nullable Artifact mainDexProguardConfig) { @@ -49,18 +78,42 @@ public final class ResourceApk { this.resourceJavaSrcJar = resourceJavaSrcJar; this.resourceJavaClassJar = resourceJavaClassJar; this.resourceDeps = resourceDeps; - this.primaryResource = primaryResource; + this.assetDeps = assetDeps; + this.primaryResources = primaryResources; + this.primaryAssets = primaryAssets; this.manifest = manifest; this.resourceProguardConfig = resourceProguardConfig; this.mainDexProguardConfig = mainDexProguardConfig; } + ResourceApk withApk(Artifact apk) { + return new ResourceApk( + apk, + resourceJavaSrcJar, + resourceJavaClassJar, + resourceDeps, + assetDeps, + primaryResources, + primaryAssets, + manifest, + resourceProguardConfig, + mainDexProguardConfig); + } + public Artifact getArtifact() { return resourceApk; } - public ResourceContainer getPrimaryResource() { - return primaryResource; + public ResourceContainer getPrimaryResources() { + return primaryResources; + } + + /** + * TODO(b/77574966): Use MergedAndroidAssets rather than the base class once we have completely + * decoupled assets and resources. + */ + public AndroidAssets getPrimaryAssets() { + return primaryAssets; } public Artifact getManifest() { @@ -75,8 +128,9 @@ public final class ResourceApk { return resourceJavaClassJar; } - public static ResourceApk fromTransitiveResources(ResourceDependencies resourceDeps) { - return new ResourceApk(null, null, null, resourceDeps, null, null, null, null); + public static ResourceApk fromTransitiveResources( + ResourceDependencies resourceDeps, AssetDependencies assetDeps) { + return new ResourceApk(null, null, null, resourceDeps, assetDeps, null, null, null, null, null); } public Artifact getResourceProguardConfig() { @@ -91,6 +145,10 @@ public final class ResourceApk { return resourceDeps; } + public AssetDependencies getAssetDependencies() { + return assetDeps; + } + /** * Creates an provider from the resources in the ResourceApk. * @@ -101,10 +159,32 @@ public final class ResourceApk { * <p>If the ResourceApk was generated from local resources, that will be the direct dependencies * and the rest will be transitive. */ - public AndroidResourcesInfo toResourceInfo(Label label) { - if (primaryResource == null) { + private AndroidResourcesInfo toResourceInfo(Label label) { + if (primaryResources == null) { return resourceDeps.toInfo(label); } - return resourceDeps.toInfo(primaryResource); + return resourceDeps.toInfo(primaryResources); + } + + public void addToConfiguredTargetBuilder(RuleConfiguredTargetBuilder builder, Label label) { + AndroidResourcesInfo resourceInfo = toResourceInfo(label); + builder.addNativeDeclaredProvider(resourceInfo); + + // TODO(b/77574966): Remove this cast once we get rid of ResourceContainer and can guarantee + // that only properly merged resources are passed into this object. + if (primaryAssets instanceof MergedAndroidAssets) { + MergedAndroidAssets merged = (MergedAndroidAssets) primaryAssets; + builder.addNativeDeclaredProvider(merged.toProvider()); + + // Asset merging output isn't consumed by anything. Require it to be run by top-level targets + // so we can validate there are no asset merging conflicts. + builder.addOutputGroup(OutputGroupInfo.HIDDEN_TOP_LEVEL, merged.getMergedAssets()); + + } else if (primaryAssets == null) { + builder.addNativeDeclaredProvider(assetDeps.toInfo(label)); + } + + builder.addSkylarkTransitiveInfo( + AndroidSkylarkApiProvider.NAME, new AndroidSkylarkApiProvider(resourceInfo)); } } |