aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java36
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java81
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java79
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java57
11 files changed, 219 insertions, 118 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java
index 32c5989cf1..11ddc1bd61 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidAssets.java
@@ -61,12 +61,13 @@ public class AndroidAssets {
}
}
- /** Collects this rule's android assets. */
+ /** Collects this rule's android assets, based on rule attributes. */
public static AndroidAssets from(RuleContext ruleContext) throws RuleErrorException {
return from(ruleContext, getAssetTargets(ruleContext), getAssetDir(ruleContext));
}
- static AndroidAssets from(
+ /** Collects Android assets from the specified values */
+ public static AndroidAssets from(
RuleErrorConsumer errorConsumer,
@Nullable Iterable<? extends TransitiveInfoCollection> assetTargets,
@Nullable PathFragment assetsDir)
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 eed11af544..46198628f7 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
@@ -202,13 +202,16 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
applicationManifest =
ApplicationManifest.fromExplicitManifest(ruleContext, manifest.getManifest());
+ AndroidAaptVersion aaptVersion = AndroidAaptVersion.chooseTargetAaptVersion(ruleContext);
resourceApk =
ProcessedAndroidData.processBinaryDataFrom(
ruleContext,
manifest,
/* conditionalKeepRules = */ shouldShrinkResourceCycles(
- ruleContext, shrinkResources))
- .generateRClass(ruleContext);
+ ruleContext, shrinkResources),
+ applicationManifest.getManifestValues(),
+ aaptVersion)
+ .generateRClass(ruleContext, aaptVersion);
} else {
applicationManifest =
androidSemantics.getManifestForRule(ruleContext).mergeWith(ruleContext, resourceDeps);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java
index 64d0cd7bf2..1042e2c161 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java
@@ -76,7 +76,8 @@ public final class AndroidBinaryMobileInstall {
manifest.addMobileInstallStubApplication(ruleContext),
ruleContext.getImplicitOutputArtifact(
AndroidRuleClasses.ANDROID_INCREMENTAL_RESOURCES_APK),
- "incremental")
+ "incremental",
+ applicationManifest.getManifestValues())
// Intentionally skip building an R class JAR - incremental binaries handle this
// separately.
.withValidatedResources(null);
@@ -86,7 +87,8 @@ public final class AndroidBinaryMobileInstall {
ruleContext,
manifest.createSplitManifest(ruleContext, "android_resources", false),
getMobileInstallArtifact(ruleContext, "android_resources.ap_"),
- "incremental_split")
+ "incremental_split",
+ applicationManifest.getManifestValues())
// Intentionally skip building an R class JAR - incremental binaries handle this
// separately.
.withValidatedResources(null);
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 d9f1feeaeb..c88e36990b 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
@@ -36,6 +36,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
import com.google.devtools.build.lib.rules.java.ClasspathConfiguredFragment;
import com.google.devtools.build.lib.rules.java.DeployArchiveBuilder;
import com.google.devtools.build.lib.rules.java.JavaCommon;
@@ -93,9 +94,14 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
StampedAndroidManifest manifest =
AndroidManifest.from(ruleContext).mergeWithDeps(ruleContext);
+ AndroidAaptVersion aaptVersion = AndroidAaptVersion.chooseTargetAaptVersion(ruleContext);
resourceApk =
- ProcessedAndroidData.processLocalTestDataFrom(ruleContext, manifest)
- .generateRClass(ruleContext);
+ ProcessedAndroidData.processLocalTestDataFrom(
+ ruleContext,
+ manifest,
+ ApplicationManifest.getManifestValues(ruleContext),
+ aaptVersion)
+ .generateRClass(ruleContext, aaptVersion);
} else {
// Create the final merged manifest
ResourceDependencies resourceDependencies =
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java
index dfe7a014d0..b90d28b03d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifest.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.android;
-import com.google.common.annotations.VisibleForTesting;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
@@ -21,6 +20,7 @@ import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.
import com.google.devtools.build.lib.rules.java.JavaUtil;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
@@ -91,8 +91,11 @@ public class AndroidManifest {
this(manifest, other.pkg, other.exported);
}
- @VisibleForTesting
- AndroidManifest(Artifact manifest, @Nullable String pkg, boolean exported) {
+ /**
+ * Creates a manifest wrapper without doing any processing. From within a rule, use {@link
+ * #from(RuleContext, AndroidSemantics)} instead.
+ */
+ public AndroidManifest(Artifact manifest, @Nullable String pkg, boolean exported) {
this.manifest = manifest;
this.pkg = pkg;
this.exported = exported;
@@ -112,11 +115,15 @@ public class AndroidManifest {
* <p>If no manifest values are specified, the manifest will remain unstamped.
*/
public StampedAndroidManifest stampWithManifestValues(RuleContext ruleContext) {
- return mergeWithDeps(ruleContext, ResourceDependencies.empty());
+ return mergeWithDeps(
+ ruleContext,
+ ResourceDependencies.empty(),
+ ApplicationManifest.getManifestValues(ruleContext),
+ ApplicationManifest.useLegacyMerging(ruleContext));
}
/**
- * Merges the manifest with any dependent manifests.
+ * Merges the manifest with any dependent manifests, extracted from rule attributes.
*
* <p>The manifest will also be stamped with any manifest values specified in the target's
* attributes
@@ -126,17 +133,20 @@ public class AndroidManifest {
*/
public StampedAndroidManifest mergeWithDeps(RuleContext ruleContext) {
return mergeWithDeps(
- ruleContext, ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false));
+ ruleContext,
+ ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false),
+ ApplicationManifest.getManifestValues(ruleContext),
+ ApplicationManifest.useLegacyMerging(ruleContext));
}
- private StampedAndroidManifest mergeWithDeps(
- RuleContext ruleContext, ResourceDependencies resourceDeps) {
+ public StampedAndroidManifest mergeWithDeps(
+ RuleContext ruleContext,
+ ResourceDependencies resourceDeps,
+ Map<String, String> manifestValues,
+ boolean useLegacyMerger) {
Artifact newManifest =
ApplicationManifest.maybeMergeWith(
- ruleContext,
- manifest,
- resourceDeps,
- ApplicationManifest.getManifestValues(ruleContext))
+ ruleContext, manifest, resourceDeps, manifestValues, useLegacyMerger, pkg)
.orElse(manifest);
return new StampedAndroidManifest(newManifest, pkg, exported);
@@ -165,7 +175,7 @@ public class AndroidManifest {
}
/** Gets the default Java package */
- static String getDefaultPackage(RuleContext ruleContext) {
+ public static String getDefaultPackage(RuleContext ruleContext) {
PathFragment dummyJar = ruleContext.getPackageDirectory().getChild("Dummy.jar");
return getJavaPackageFromPath(ruleContext, dummyJar);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java
index 7858091b3d..842b4ed5ab 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResources.java
@@ -138,7 +138,7 @@ public class AndroidResources {
resourcesAttr);
}
- static AndroidResources from(
+ public static AndroidResources from(
RuleErrorConsumer errorConsumer,
Iterable<FileProvider> resourcesTargets,
String resourcesAttr)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
index cb13f6a559..389115afd1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidSkylarkData.java
@@ -19,6 +19,7 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.skylark.SkylarkRuleContext;
+import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Location;
@@ -396,16 +397,7 @@ public abstract class AndroidSkylarkData {
aaptVersion)
.validate(ctx.getRuleContext(), aaptVersion);
- JavaInfo javaInfo =
- JavaInfo.Builder.create()
- .setNeverlink(true)
- .addProvider(
- JavaCompilationInfoProvider.class,
- new JavaCompilationInfoProvider.Builder()
- .setCompilationClasspath(
- NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, validated.getClassJar()))
- .build())
- .build();
+ JavaInfo javaInfo = getJavaInfoForRClassJar(validated.getClassJar());
return SkylarkDict.of(
/* env = */ null,
@@ -742,8 +734,35 @@ public abstract class AndroidSkylarkData {
.build());
}
+ public static SkylarkDict<NativeProvider<?>, NativeInfo> getNativeInfosFrom(
+ ResourceApk resourceApk, Label label) {
+ ImmutableMap.Builder<NativeProvider<?>, NativeInfo> builder = ImmutableMap.builder();
+
+ builder.put(AndroidResourcesInfo.PROVIDER, resourceApk.toResourceInfo(label));
+
+ resourceApk
+ .toAssetsInfo(label)
+ .ifPresent(info -> builder.put(AndroidAssetsInfo.PROVIDER, info));
+ resourceApk.toManifestInfo().ifPresent(info -> builder.put(AndroidManifestInfo.PROVIDER, info));
+
+ builder.put(JavaInfo.PROVIDER, getJavaInfoForRClassJar(resourceApk.getResourceJavaClassJar()));
+
+ return SkylarkDict.copyOf(/* env = */ null, builder.build());
+ }
+
+ private static JavaInfo getJavaInfoForRClassJar(Artifact rClassJar) {
+ return JavaInfo.Builder.create()
+ .setNeverlink(true)
+ .addProvider(
+ JavaCompilationInfoProvider.class,
+ new JavaCompilationInfoProvider.Builder()
+ .setCompilationClasspath(NestedSetBuilder.create(Order.NAIVE_LINK_ORDER, rClassJar))
+ .build())
+ .build();
+ }
+
/** Checks if a "Noneable" object passed by Skylark is "None", which Java should treat as null. */
- private static boolean isNone(Object object) {
+ public static boolean isNone(Object object) {
return object == Runtime.NONE;
}
@@ -760,7 +779,7 @@ public abstract class AndroidSkylarkData {
* @return {@code null}, if the noneable argument was None, or the cast object, otherwise.
*/
@Nullable
- private static <T> T fromNoneable(Object object, Class<T> clazz) {
+ public static <T> T fromNoneable(Object object, Class<T> clazz) {
if (isNone(object)) {
return null;
}
@@ -768,7 +787,7 @@ public abstract class AndroidSkylarkData {
return clazz.cast(object);
}
- private static <T> T fromNoneableOrDefault(Object object, Class<T> clazz, T defaultValue) {
+ public static <T> T fromNoneableOrDefault(Object object, Class<T> clazz, T defaultValue) {
T value = fromNoneable(object, clazz);
if (value == null) {
return defaultValue;
@@ -784,7 +803,7 @@ public abstract class AndroidSkylarkData {
* casts it to a list with the appropriate generic.
*/
@Nullable
- private static <T> List<T> listFromNoneable(Object object, Class<T> clazz) throws EvalException {
+ public static <T> List<T> listFromNoneable(Object object, Class<T> clazz) throws EvalException {
SkylarkList<?> asList = fromNoneable(object, SkylarkList.class);
if (asList == null) {
return null;
@@ -803,7 +822,7 @@ public abstract class AndroidSkylarkData {
return SkylarkList.createImmutable(value);
}
- private static <T extends NativeInfo> SkylarkList<T> getProviders(
+ public static <T extends NativeInfo> SkylarkList<T> getProviders(
SkylarkList<ConfiguredTarget> targets, NativeProvider<T> provider) {
return SkylarkList.createImmutable(
targets
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 783f0f284c..deb2cb530e 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
@@ -192,7 +192,7 @@ public final class ApplicationManifest {
*
* @return an artifact for the generated manifest
*/
- static Artifact generateManifest(RuleContext ruleContext, String manifestPackage) {
+ public static Artifact generateManifest(RuleContext ruleContext, String manifestPackage) {
Artifact generatedManifest =
ruleContext.getUniqueDirectoryArtifact(
ruleContext.getRule().getName() + "_generated",
@@ -216,19 +216,35 @@ public final class ApplicationManifest {
return generatedManifest;
}
+ /** Gets a map of manifest values from this rule's 'manifest_values' attribute */
static ImmutableMap<String, String> getManifestValues(RuleContext context) {
+ return getManifestValues(
+ context,
+ context.attributes().isAttributeValueExplicitlySpecified("manifest_values")
+ ? context.attributes().get("manifest_values", Type.STRING_DICT)
+ : null);
+ }
+
+ /** Gets and expands an expanded map of manifest values from some raw map of manifest values. */
+ static ImmutableMap<String, String> getManifestValues(
+ RuleContext ruleContext, @Nullable Map<String, String> rawMap) {
Map<String, String> manifestValues = new TreeMap<>();
- if (context.attributes().isAttributeValueExplicitlySpecified("manifest_values")) {
- manifestValues.putAll(context.attributes().get("manifest_values", Type.STRING_DICT));
+ if (rawMap != null) {
+ manifestValues.putAll(rawMap);
}
for (String variable : manifestValues.keySet()) {
manifestValues.put(
- variable, context.getExpander().expand("manifest_values", manifestValues.get(variable)));
+ variable,
+ ruleContext.getExpander().expand("manifest_values", manifestValues.get(variable)));
}
return ImmutableMap.copyOf(manifestValues);
}
+ public ImmutableMap<String, String> getManifestValues() {
+ return manifestValues;
+ }
+
private final Artifact manifest;
private final ImmutableMap<String, String> manifestValues;
private final AndroidAaptVersion targetAaptVersion;
@@ -241,7 +257,13 @@ public final class ApplicationManifest {
}
public ApplicationManifest mergeWith(RuleContext ruleContext, ResourceDependencies resourceDeps) {
- return maybeMergeWith(ruleContext, manifest, resourceDeps, manifestValues)
+ return maybeMergeWith(
+ ruleContext,
+ manifest,
+ resourceDeps,
+ manifestValues,
+ useLegacyMerging(ruleContext),
+ AndroidCommon.getJavaPackage(ruleContext))
.map(merged -> new ApplicationManifest(ruleContext, merged, targetAaptVersion))
.orElse(this);
}
@@ -250,11 +272,14 @@ public final class ApplicationManifest {
RuleContext ruleContext,
Artifact primaryManifest,
ResourceDependencies resourceDeps,
- Map<String, String> manifestValues) {
+ Map<String, String> manifestValues,
+ boolean useLegacyMerging,
+ String customPackage) {
Map<Artifact, Label> mergeeManifests = getMergeeManifests(resourceDeps.getResourceContainers());
- if (useLegacyMerging(ruleContext)) {
+ if (useLegacyMerging) {
if (!mergeeManifests.isEmpty()) {
+
Artifact outputManifest =
ruleContext.getUniqueDirectoryArtifact(
ruleContext.getRule().getName() + "_merged",
@@ -285,7 +310,7 @@ public final class ApplicationManifest {
.setMergeeManifests(mergeeManifests)
.setLibrary(false)
.setManifestValues(manifestValues)
- .setCustomPackage(AndroidCommon.getJavaPackage(ruleContext))
+ .setCustomPackage(customPackage)
.setManifestOutput(outputManifest)
.setLogOut(mergeLog)
.build(ruleContext);
@@ -295,24 +320,30 @@ public final class ApplicationManifest {
return Optional.empty();
}
- private static boolean useLegacyMerging(RuleContext ruleContext) {
- boolean legacy = false;
- if (ruleContext.isLegalFragment(AndroidConfiguration.class)
- && ruleContext.getRule().isAttrDefined("manifest_merger", STRING)) {
- AndroidManifestMerger merger =
- AndroidManifestMerger.fromString(ruleContext.attributes().get("manifest_merger", STRING));
- if (merger == null) {
- merger = ruleContext.getFragment(AndroidConfiguration.class).getManifestMerger();
- }
- if (merger == AndroidManifestMerger.LEGACY) {
- ruleContext.ruleWarning(
- "manifest_merger 'legacy' is deprecated. Please update to 'android'.\n"
- + "See https://developer.android.com/studio/build/manifest-merge.html for more "
- + "information about the manifest merger.");
- }
- legacy = merger == AndroidManifestMerger.LEGACY;
+ /** Checks if the legacy manifest merger should be used, based on a rule attribute */
+ static boolean useLegacyMerging(RuleContext ruleContext) {
+ return ruleContext.isLegalFragment(AndroidConfiguration.class)
+ && ruleContext.getRule().isAttrDefined("manifest_merger", STRING)
+ && useLegacyMerging(ruleContext, ruleContext.attributes().get("manifest_merger", STRING));
+ }
+
+ /**
+ * Checks if the legacy manifest merger should be used, based on an optional string specifying the
+ * merger to use.
+ */
+ public static boolean useLegacyMerging(RuleContext ruleContext, @Nullable String mergerString) {
+ AndroidManifestMerger merger = AndroidManifestMerger.fromString(mergerString);
+ if (merger == null) {
+ merger = ruleContext.getFragment(AndroidConfiguration.class).getManifestMerger();
+ }
+ if (merger == AndroidManifestMerger.LEGACY) {
+ ruleContext.ruleWarning(
+ "manifest_merger 'legacy' is deprecated. Please update to 'android'.\n"
+ + "See https://developer.android.com/studio/build/manifest-merge.html for more "
+ + "information about the manifest merger.");
}
- return legacy;
+
+ return merger == AndroidManifestMerger.LEGACY;
}
private static Map<Artifact, Label> getMergeeManifests(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java b/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java
index cc9c8dc5ae..1cfe929fc6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AssetDependencies.java
@@ -38,14 +38,15 @@ public class AssetDependencies {
private final NestedSet<Artifact> transitiveAssets;
private final NestedSet<Artifact> transitiveSymbols;
- static AssetDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) {
+ public static AssetDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) {
return fromProviders(
AndroidCommon.getTransitivePrerequisites(
ruleContext, Mode.TARGET, AndroidAssetsInfo.PROVIDER),
neverlink);
}
- static AssetDependencies fromProviders(Iterable<AndroidAssetsInfo> providers, boolean neverlink) {
+ public static AssetDependencies fromProviders(
+ Iterable<AndroidAssetsInfo> providers, boolean neverlink) {
NestedSetBuilder<ParsedAndroidAssets> direct = NestedSetBuilder.naiveLinkOrder();
NestedSetBuilder<ParsedAndroidAssets> transitive = NestedSetBuilder.naiveLinkOrder();
NestedSetBuilder<Artifact> assets = NestedSetBuilder.naiveLinkOrder();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java b/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
index 8a0d0e66ab..438f12cbc0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.android;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
@@ -52,7 +53,11 @@ public class ProcessedAndroidData {
/** Processes Android data (assets, resources, and manifest) for android_binary targets. */
public static ProcessedAndroidData processBinaryDataFrom(
- RuleContext ruleContext, StampedAndroidManifest manifest, boolean conditionalKeepRules)
+ RuleContext ruleContext,
+ StampedAndroidManifest manifest,
+ boolean conditionalKeepRules,
+ Map<String, String> manifestValues,
+ AndroidAaptVersion aaptVersion)
throws RuleErrorException, InterruptedException {
if (conditionalKeepRules
&& AndroidAaptVersion.chooseTargetAaptVersion(ruleContext) != AndroidAaptVersion.AAPT2) {
@@ -61,7 +66,7 @@ public class ProcessedAndroidData {
}
AndroidResourcesProcessorBuilder builder =
- builderForNonIncrementalTopLevelTarget(ruleContext, manifest)
+ builderForNonIncrementalTopLevelTarget(ruleContext, manifest, manifestValues, aaptVersion)
.setUseCompiledResourcesForMerge(
AndroidAaptVersion.chooseTargetAaptVersion(ruleContext) == AndroidAaptVersion.AAPT2
&& AndroidCommon.getAndroidConfig(ruleContext).skipParsingAction())
@@ -95,11 +100,13 @@ public class ProcessedAndroidData {
RuleContext ruleContext,
StampedAndroidManifest manifest,
Artifact apkOut,
- String proguardPrefix)
+ String proguardPrefix,
+ Map<String, String> manifestValues)
throws RuleErrorException {
AndroidResourcesProcessorBuilder builder =
- builderForTopLevelTarget(ruleContext, manifest, proguardPrefix).setApkOut(apkOut);
+ builderForTopLevelTarget(ruleContext, manifest, proguardPrefix, manifestValues)
+ .setApkOut(apkOut);
return buildActionForBinary(ruleContext, builder, manifest);
}
@@ -135,10 +142,14 @@ public class ProcessedAndroidData {
/** Processes Android data (assets, resources, and manifest) for android_local_test targets. */
public static ProcessedAndroidData processLocalTestDataFrom(
- RuleContext ruleContext, StampedAndroidManifest manifest)
+ RuleContext ruleContext,
+ StampedAndroidManifest manifest,
+ Map<String, String> manifestValues,
+ AndroidAaptVersion aaptVersion)
throws RuleErrorException, InterruptedException {
- return builderForNonIncrementalTopLevelTarget(ruleContext, manifest)
+ return builderForNonIncrementalTopLevelTarget(
+ ruleContext, manifest, manifestValues, aaptVersion)
.setUseCompiledResourcesForMerge(
AndroidAaptVersion.chooseTargetAaptVersion(ruleContext) == AndroidAaptVersion.AAPT2
&& AndroidCommon.getAndroidConfig(ruleContext).skipParsingAction())
@@ -161,27 +172,24 @@ public class ProcessedAndroidData {
RuleContext ruleContext,
StampedAndroidManifest manifest,
String packageUnderTest,
- boolean hasLocalResourceFiles)
- throws InterruptedException, RuleErrorException {
+ boolean hasLocalResourceFiles,
+ AndroidAaptVersion aaptVersion,
+ AndroidResources resources,
+ ResourceDependencies resourceDeps,
+ AndroidAssets assets,
+ AssetDependencies assetDeps)
+ throws InterruptedException {
AndroidResourcesProcessorBuilder builder =
- builderForNonIncrementalTopLevelTarget(ruleContext, manifest)
+ builderForNonIncrementalTopLevelTarget(
+ ruleContext, manifest, ImmutableMap.of(), aaptVersion)
.setMainDexProguardOut(AndroidBinary.createMainDexProguardSpec(ruleContext))
.setPackageUnderTest(packageUnderTest)
- .setIsTestWithResources(hasLocalResourceFiles);
-
- if (hasLocalResourceFiles) {
- builder
- .withResourceDependencies(
- ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false))
- .withAssetDependencies(
- AssetDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false));
- }
+ .setIsTestWithResources(hasLocalResourceFiles)
+ .withResourceDependencies(resourceDeps)
+ .withAssetDependencies(assetDeps);
- return builder.build(
- AndroidResources.from(ruleContext, "local_resource_files"),
- AndroidAssets.from(ruleContext),
- manifest);
+ return builder.build(resources, assets, manifest);
}
/**
@@ -190,18 +198,22 @@ public class ProcessedAndroidData {
* <p>The builder will be populated with commonly-used settings and outputs.
*/
private static AndroidResourcesProcessorBuilder builderForNonIncrementalTopLevelTarget(
- RuleContext ruleContext, StampedAndroidManifest manifest)
- throws InterruptedException, RuleErrorException {
+ RuleContext ruleContext,
+ StampedAndroidManifest manifest,
+ Map<String, String> manifestValues,
+ AndroidAaptVersion aaptVersion)
+ throws InterruptedException {
- return builderForTopLevelTarget(ruleContext, manifest, "")
- .targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
+ return builderForTopLevelTarget(ruleContext, manifest, "", manifestValues)
+ .targetAaptVersion(aaptVersion)
// Outputs
.setApkOut(ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK))
.setRTxtOut(ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT))
.setSourceJarOut(
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR))
- .setSymbols(ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_MERGED_SYMBOLS));
+ .setSymbols(
+ ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_MERGED_SYMBOLS));
}
/**
@@ -210,9 +222,10 @@ public class ProcessedAndroidData {
* <p>The builder will be populated with commonly-used settings and outputs.
*/
private static AndroidResourcesProcessorBuilder builderForTopLevelTarget(
- RuleContext ruleContext, StampedAndroidManifest manifest, String proguardPrefix) {
- Map<String, String> manifestValues = ApplicationManifest.getManifestValues(ruleContext);
-
+ RuleContext ruleContext,
+ StampedAndroidManifest manifest,
+ String proguardPrefix,
+ Map<String, String> manifestValues) {
return new AndroidResourcesProcessorBuilder(ruleContext)
// Settings
.setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
@@ -272,10 +285,10 @@ public class ProcessedAndroidData {
* <p>Registers an action to run R class generation, the last step needed in resource processing.
* Returns the fully processed data, including validated resources, wrapped in a ResourceApk.
*/
- public ResourceApk generateRClass(RuleContext ruleContext)
- throws RuleErrorException, InterruptedException {
+ public ResourceApk generateRClass(RuleContext ruleContext, AndroidAaptVersion aaptVersion)
+ throws InterruptedException {
return new RClassGeneratorActionBuilder(ruleContext)
- .targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
+ .targetAaptVersion(aaptVersion)
.withDependencies(resourceDeps)
.setClassJarOut(
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
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 324766d323..7b128596eb 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
@@ -20,6 +20,7 @@ import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.CompilationMode;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import java.util.Optional;
import javax.annotation.Nullable;
/**
@@ -228,35 +229,49 @@ public final class ResourceApk {
return resourceDeps.toInfo(validatedResources);
}
- public void addToConfiguredTargetBuilder(
- RuleConfiguredTargetBuilder builder, Label label, boolean includeSkylarkApiProvider) {
- AndroidResourcesInfo resourceInfo = toResourceInfo(label);
- builder.addNativeDeclaredProvider(resourceInfo);
+ // TODO(b/77574966): Stop returning an Optional once we get rid of ResourceContainer and can
+ // guarantee that only properly merged assets are passed into this object.
+ Optional<AndroidAssetsInfo> toAssetsInfo(Label label) {
+ if (primaryAssets instanceof MergedAndroidAssets) {
+ MergedAndroidAssets merged = (MergedAndroidAssets) primaryAssets;
+ AndroidAssetsInfo assetsInfo = merged.toProvider();
+ return Optional.of(assetsInfo);
+ } else if (primaryAssets == null) {
+ return Optional.of(assetDeps.toInfo(label));
+ } else {
+ return Optional.empty();
+ }
+ }
- // 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.
+ // 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.
+ Optional<AndroidManifestInfo> toManifestInfo() {
if (validatedResources instanceof ValidatedAndroidResources) {
ValidatedAndroidResources validated = (ValidatedAndroidResources) validatedResources;
- builder.addNativeDeclaredProvider(validated.getStampedManifest().toProvider());
+ return Optional.of(validated.getStampedManifest().toProvider());
}
- // 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;
- AndroidAssetsInfo assetsInfo = merged.toProvider();
- builder.addNativeDeclaredProvider(assetsInfo);
+ return Optional.empty();
+ }
- if (assetsInfo.getValidationResult() != null) {
- // 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, assetsInfo.getValidationResult());
- }
+ public void addToConfiguredTargetBuilder(
+ RuleConfiguredTargetBuilder builder, Label label, boolean includeSkylarkApiProvider) {
+ AndroidResourcesInfo resourceInfo = toResourceInfo(label);
+ builder.addNativeDeclaredProvider(resourceInfo);
- } else if (primaryAssets == null) {
- builder.addNativeDeclaredProvider(assetDeps.toInfo(label));
+ Optional<AndroidManifestInfo> manifestInfo = toManifestInfo();
+ manifestInfo.ifPresent(builder::addNativeDeclaredProvider);
+
+ Optional<AndroidAssetsInfo> assetsInfo = toAssetsInfo(label);
+ if (assetsInfo.isPresent()) {
+ builder.addNativeDeclaredProvider(assetsInfo.get());
+ if (assetsInfo.get().getValidationResult() != null) {
+ // 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, assetsInfo.get().getValidationResult());
+ }
}
if (includeSkylarkApiProvider) {