diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/android')
4 files changed, 228 insertions, 26 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java index fea9610f6d..41abe2f7a3 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java @@ -41,7 +41,7 @@ public class AndroidResourceValidatorActionBuilder { private final AndroidSdkProvider sdk; // Inputs - private ResourceContainer primary; + private CompiledMergableAndroidData primary; private Artifact mergedResources; // Outputs @@ -70,7 +70,7 @@ public class AndroidResourceValidatorActionBuilder { } /** The primary resource container. We mostly propagate its values, but update the R.txt. */ - public AndroidResourceValidatorActionBuilder withPrimary(ResourceContainer primary) { + private AndroidResourceValidatorActionBuilder withPrimary(CompiledMergableAndroidData primary) { this.primary = primary; return this; } @@ -116,15 +116,47 @@ public class AndroidResourceValidatorActionBuilder { return this; } - public ResourceContainer build(ActionConstructionContext context) { - ResourceContainer container = primary; + private void build(ActionConstructionContext context) { if (rTxtOut != null) { - container = createValidateAction(container, context); + createValidateAction(context); } + if (compiledSymbols != null) { - container = createLinkStaticLibraryAction(container, context); + createLinkStaticLibraryAction(context); } - return container; + } + + public ResourceContainer build( + ActionConstructionContext context, ResourceContainer resourceContainer) { + withPrimary(resourceContainer).build(context); + ResourceContainer.Builder builder = resourceContainer.toBuilder(); + + if (rTxtOut != null) { + builder.setJavaSourceJar(sourceJarOut).setRTxt(rTxtOut); + } + + if (compiledSymbols != null) { + builder + .setAapt2JavaSourceJar(aapt2SourceJarOut) + .setAapt2RTxt(aapt2RTxtOut) + .setStaticLibrary(staticLibraryOut); + } + + return builder.build(); + } + + public ValidatedAndroidResources build( + ActionConstructionContext context, MergedAndroidResources merged) { + withPrimary(merged).build(context); + + return ValidatedAndroidResources.of( + merged, + rTxtOut, + sourceJarOut, + apkOut, + aapt2RTxtOut, + aapt2SourceJarOut, + staticLibraryOut); } public AndroidResourceValidatorActionBuilder setCompiledSymbols(Artifact compiledSymbols) { @@ -143,8 +175,7 @@ public class AndroidResourceValidatorActionBuilder { * <p>This allows the link action to replace the validate action for builds that use aapt2, as * opposed to executing both actions. */ - private ResourceContainer createLinkStaticLibraryAction( - ResourceContainer validated, ActionConstructionContext context) { + private void createLinkStaticLibraryAction(ActionConstructionContext context) { Preconditions.checkNotNull(staticLibraryOut); Preconditions.checkNotNull(aapt2SourceJarOut); Preconditions.checkNotNull(aapt2RTxtOut); @@ -166,7 +197,7 @@ public class AndroidResourceValidatorActionBuilder { inputs.add(compiledSymbols); builder.addExecPath("--manifest", primary.getManifest()); - inputs.add(validated.getManifest()); + inputs.add(primary.getManifest()); if (!Strings.isNullOrEmpty(customJavaPackage)) { // Sets an alternative java package for the generated R.java @@ -205,17 +236,9 @@ public class AndroidResourceValidatorActionBuilder { "Linking static android resource library for %s", ruleContext.getLabel()) .setMnemonic("AndroidResourceLink") .build(context)); - - return validated - .toBuilder() - .setAapt2JavaSourceJar(aapt2SourceJarOut) - .setAapt2RTxt(aapt2RTxtOut) - .setStaticLibrary(staticLibraryOut) - .build(); } - private ResourceContainer createValidateAction( - ResourceContainer primary, ActionConstructionContext context) { + private void createValidateAction(ActionConstructionContext context) { CustomCommandLine.Builder builder = new CustomCommandLine.Builder(); // Set the busybox tool. @@ -277,8 +300,5 @@ public class AndroidResourceValidatorActionBuilder { .setProgressMessage("Validating Android resources for %s", ruleContext.getLabel()) .setMnemonic("AndroidResourceValidator") .build(context)); - - // Return the full set of validated transitive dependencies. - return primary.toBuilder().setJavaSourceJar(sourceJarOut).setRTxt(rTxtOut).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 62eb612a15..bcac5b4d14 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 @@ -408,7 +408,6 @@ public final class ApplicationManifest { .setJavaPackage(merged.getJavaPackage()) .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT) .setMergedResources(mergedResources) - .withPrimary(merged) .setRTxtOut(merged.getRTxt()) .setSourceJarOut(merged.getJavaSourceJar()) .setApkOut(resourceContainer.getApk()) @@ -418,7 +417,7 @@ public final class ApplicationManifest { .setAapt2RTxtOut(merged.getAapt2RTxt()) .setAapt2SourceJarOut(merged.getAapt2JavaSourceJar()) .setStaticLibraryOut(merged.getStaticLibrary()) - .build(ruleContext); + .build(ruleContext, merged); return new ResourceApk( resourceContainer.getApk(), @@ -672,7 +671,6 @@ public final class ApplicationManifest { .setJavaPackage(merged.getJavaPackage()) .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT) .setMergedResources(mergedResources) - .withPrimary(merged) .setRTxtOut(merged.getRTxt()) .setSourceJarOut(merged.getJavaSourceJar()) .setApkOut(resourceContainer.getApk()) @@ -682,7 +680,7 @@ public final class ApplicationManifest { .setAapt2RTxtOut(merged.getAapt2RTxt()) .setAapt2SourceJarOut(merged.getAapt2JavaSourceJar()) .setStaticLibraryOut(merged.getStaticLibrary()) - .build(ruleContext); + .build(ruleContext, merged); return new ResourceApk( resourceContainer.getApk(), diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java index e6cf1791d7..c9b6ca69a4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java @@ -123,6 +123,20 @@ public class MergedAndroidResources extends ParsedAndroidResources { return manifest; } + public ResourceDependencies getResourceDependencies() { + return resourceDependencies; + } + + /** + * Validates and packages this rule's resources. + * + * <p>See {@link ValidatedAndroidResources#validateFrom(RuleContext, MergedAndroidResources)}. + * This method is a convenience method for calling that one. + */ + public ValidatedAndroidResources validate(RuleContext ruleContext) throws InterruptedException { + return ValidatedAndroidResources.validateFrom(ruleContext, this); + } + @Override public boolean equals(Object object) { if (!super.equals(object)) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java new file mode 100644 index 0000000000..bfb6863a6e --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java @@ -0,0 +1,170 @@ +// Copyright 2018 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.rules.android; + +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; +import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; +import java.util.Objects; +import javax.annotation.Nullable; + +/** Wraps {@link AndroidResources} that have been validated, processed, and packaged. */ +public class ValidatedAndroidResources extends MergedAndroidResources { + private final Artifact rTxt; + private final Artifact sourceJar; + private final Artifact apk; + + // aapt2 outputs. Will be null if and only if aapt2 is not used for validation. + @Nullable private final Artifact aapt2RTxt; + @Nullable private final Artifact aapt2SourceJar; + @Nullable private final Artifact staticLibrary; + + /** + * Validates and packages merged resources. + * + * <p>Specifically, validates that: + * + * <ul> + * <li>there are no conflicts between resources (though currently we just warn) + * <li>each reference to a resource in resources and manifest are satisfied + * </ul> + * + * <p>And packs resources into: + * + * <ul> + * <li>R.java and R.txt files + * <li>A resource-only APK (deprecated) + * <li>When building with aapt2, aapt2 equivalents of the above + * <li>When building with aapt2, a compiled symbols zip + * </ul> + */ + public static ValidatedAndroidResources validateFrom( + RuleContext ruleContext, MergedAndroidResources merged) throws InterruptedException { + AndroidConfiguration config = AndroidCommon.getAndroidConfig(ruleContext); + AndroidResourceValidatorActionBuilder builder = + new AndroidResourceValidatorActionBuilder(ruleContext) + .setJavaPackage(merged.getJavaPackage()) + .setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT) + .setMergedResources(merged.getMergedResources()) + .setRTxtOut(ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT)) + .setSourceJarOut( + ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR)) + // Request an APK so it can be inherited when a library is used in a binary's + // resources attr. + // TODO(b/30307842): Remove this once it is no longer needed for resources migration. + .setApkOut( + ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_LIBRARY_APK)) + .withDependencies(merged.getResourceDependencies()); + + if (config.getAndroidAaptVersion() == AndroidAaptVersion.AAPT2) { + builder + .setCompiledSymbols(merged.getCompiledSymbols()) + .setAapt2RTxtOut( + ruleContext.getImplicitOutputArtifact( + AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_R_TXT)) + .setAapt2SourceJarOut( + ruleContext.getImplicitOutputArtifact( + AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_SOURCE_JAR)) + .setStaticLibraryOut( + ruleContext.getImplicitOutputArtifact( + AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_LIBRARY_APK)); + } + + return builder.build(ruleContext, merged); + } + + static ValidatedAndroidResources of( + MergedAndroidResources merged, + Artifact rTxt, + Artifact sourceJar, + Artifact apk, + Artifact aapt2RTxt, + Artifact aapt2SourceJar, + Artifact staticLibrary) { + return new ValidatedAndroidResources( + merged, rTxt, sourceJar, apk, aapt2RTxt, aapt2SourceJar, staticLibrary); + } + + private ValidatedAndroidResources( + MergedAndroidResources merged, + Artifact rTxt, + Artifact sourceJar, + Artifact apk, + @Nullable Artifact aapt2RTxt, + @Nullable Artifact aapt2SourceJar, + @Nullable Artifact staticLibrary) { + super(merged); + this.rTxt = rTxt; + this.sourceJar = sourceJar; + this.apk = apk; + this.aapt2RTxt = aapt2RTxt; + this.aapt2SourceJar = aapt2SourceJar; + this.staticLibrary = staticLibrary; + } + + public Artifact getRTxt() { + return rTxt; + } + + public Artifact getSourceJar() { + return sourceJar; + } + + public Artifact getApk() { + return apk; + } + + @Nullable + public Artifact getAapt2RTxt() { + return aapt2RTxt; + } + + @Nullable + public Artifact getAapt2SourceJar() { + return aapt2SourceJar; + } + + @Nullable + public Artifact getStaticLibrary() { + return staticLibrary; + } + + @Override + public boolean equals(Object object) { + if (!super.equals(object)) { + return false; + } + + ValidatedAndroidResources other = (ValidatedAndroidResources) object; + return rTxt.equals(other.rTxt) + && sourceJar.equals(other.sourceJar) + && apk.equals(other.apk) + && Objects.equals(aapt2RTxt, other.aapt2RTxt) + && Objects.equals(aapt2SourceJar, other.aapt2SourceJar) + && Objects.equals(staticLibrary, other.staticLibrary); + } + + @Override + public int hashCode() { + return Objects.hash( + super.hashCode(), + rTxt, + sourceJar, + apk, + aapt2RTxt, + aapt2SourceJar, + staticLibrary); + } +} |