| // Copyright 2017 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 static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.Iterables; |
| import com.google.devtools.build.lib.actions.Artifact; |
| import com.google.devtools.build.lib.analysis.ConfiguredTarget; |
| import com.google.devtools.build.lib.analysis.RuleContext; |
| import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException; |
| import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion; |
| import com.google.devtools.build.lib.rules.android.databinding.DataBinding; |
| import com.google.devtools.build.lib.rules.android.databinding.DataBindingContext; |
| import com.google.devtools.build.lib.vfs.PathFragment; |
| import java.util.Optional; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** Tests {@link AndroidResources} */ |
| @RunWith(JUnit4.class) |
| public class AndroidResourcesTest extends ResourceTestBase { |
| private static final PathFragment DEFAULT_RESOURCE_ROOT = PathFragment.create(RESOURCE_ROOT); |
| private static final ImmutableList<PathFragment> RESOURCES_ROOTS = |
| ImmutableList.of(DEFAULT_RESOURCE_ROOT); |
| |
| @Before |
| public void setupCcToolchain() throws Exception { |
| getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a"); |
| } |
| |
| @Before |
| @Test |
| public void testGetResourceRootsNoResources() throws Exception { |
| assertThat(getResourceRoots()).isEmpty(); |
| } |
| |
| @Test |
| public void testGetResourceRootsInvalidResourceDirectory() throws Exception { |
| try { |
| getResourceRoots("is-this-drawable-or-values/foo.xml"); |
| assertWithMessage("Expected exception not thrown!").fail(); |
| } catch (RuleErrorException e) { |
| // expected |
| } |
| |
| errorConsumer.assertAttributeError( |
| "resource_files", "is not in the expected resource directory structure"); |
| } |
| |
| @Test |
| public void testGetResourceRootsMultipleRoots() throws Exception { |
| try { |
| getResourceRoots("subdir/values/foo.xml", "otherdir/values/bar.xml"); |
| assertWithMessage("Expected exception not thrown!").fail(); |
| } catch (RuleErrorException e) { |
| // expected |
| } |
| |
| errorConsumer.assertAttributeError( |
| "resource_files", "All resources must share a common directory"); |
| } |
| |
| @Test |
| public void testGetResourceRoots() throws Exception { |
| assertThat(getResourceRoots("values-hdpi/foo.xml", "values-mdpi/bar.xml")) |
| .isEqualTo(RESOURCES_ROOTS); |
| } |
| |
| @Test |
| public void testGetResourceRootsCommonSubdirectory() throws Exception { |
| assertThat(getResourceRoots("subdir/values-hdpi/foo.xml", "subdir/values-mdpi/bar.xml")) |
| .containsExactly(DEFAULT_RESOURCE_ROOT.getRelative("subdir")); |
| } |
| |
| private ImmutableList<PathFragment> getResourceRoots(String... pathResourceStrings) |
| throws Exception { |
| return getResourceRoots(getResources(pathResourceStrings)); |
| } |
| |
| private ImmutableList<PathFragment> getResourceRoots(ImmutableList<Artifact> artifacts) |
| throws Exception { |
| return AndroidResources.getResourceRoots(errorConsumer, artifacts, "resource_files"); |
| } |
| |
| @Test |
| public void testFilterEmpty() throws Exception { |
| assertFilter(ImmutableList.of(), ImmutableList.of()); |
| } |
| |
| @Test |
| public void testFilterNoop() throws Exception { |
| ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "values-es/bar.xml"); |
| assertFilter(resources, resources); |
| } |
| |
| @Test |
| public void testFilterToEmpty() throws Exception { |
| assertFilter(getResources("values-en/foo.xml", "values-es/bar.xml"), ImmutableList.of()); |
| } |
| |
| @Test |
| public void testPartiallyFilter() throws Exception { |
| Artifact keptResource = getResource("values-en/foo.xml"); |
| assertFilter( |
| ImmutableList.of(keptResource, getResource("values-es/bar.xml")), |
| ImmutableList.of(keptResource)); |
| } |
| |
| @Test |
| public void testFilterIsDependency() throws Exception { |
| Artifact keptResource = getResource("values-en/foo.xml"); |
| assertFilter( |
| ImmutableList.of(keptResource, getResource("drawable/bar.png")), |
| ImmutableList.of(keptResource), |
| /* isDependency = */ true); |
| } |
| |
| @Test |
| public void testFilterValidatedNoop() throws Exception { |
| ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "values-es/bar.xml"); |
| assertFilterValidated(resources, resources); |
| } |
| |
| @Test |
| public void testFilterValidated() throws Exception { |
| Artifact keptResource = getResource("values-en/foo.xml"); |
| assertFilterValidated( |
| ImmutableList.of(keptResource, getResource("drawable/bar.png")), |
| ImmutableList.of(keptResource)); |
| } |
| |
| private void assertFilterValidated( |
| ImmutableList<Artifact> unfilteredResources, ImmutableList<Artifact> filteredResources) |
| throws Exception { |
| RuleContext ruleContext = getRuleContext(); |
| final AndroidDataContext dataContext = AndroidDataContext.forNative(ruleContext); |
| ValidatedAndroidResources unfiltered = |
| new AndroidResources(unfilteredResources, getResourceRoots(unfilteredResources)) |
| .process( |
| ruleContext, |
| dataContext, |
| getManifest(), |
| DataBinding.contextFrom(ruleContext, dataContext.getAndroidConfig()), |
| /* neverlink = */ false); |
| Optional<? extends AndroidResources> maybeFiltered = |
| assertFilter(unfiltered, filteredResources, /* isDependency = */ true); |
| |
| if (maybeFiltered.isPresent()) { |
| AndroidResources filtered = maybeFiltered.get(); |
| assertThat(filtered instanceof ValidatedAndroidResources).isTrue(); |
| ValidatedAndroidResources validated = (ValidatedAndroidResources) filtered; |
| |
| // Validate fields related to validation are unchanged |
| assertThat(validated.getRTxt()).isEqualTo(unfiltered.getRTxt()); |
| assertThat(validated.getAapt2RTxt()).isEqualTo(unfiltered.getAapt2RTxt()); |
| } |
| } |
| |
| private void assertFilter( |
| ImmutableList<Artifact> unfilteredResources, ImmutableList<Artifact> filteredResources) |
| throws Exception { |
| assertFilter(unfilteredResources, filteredResources, /* isDependency = */ false); |
| } |
| |
| private void assertFilter( |
| ImmutableList<Artifact> unfilteredResources, |
| ImmutableList<Artifact> filteredResources, |
| boolean isDependency) |
| throws Exception { |
| AndroidResources unfiltered = |
| new AndroidResources(unfilteredResources, getResourceRoots(unfilteredResources)); |
| assertFilter(unfiltered, filteredResources, isDependency); |
| } |
| |
| private Optional<? extends AndroidResources> assertFilter( |
| AndroidResources unfiltered, ImmutableList<Artifact> filteredResources, boolean isDependency) |
| throws Exception { |
| |
| ImmutableList.Builder<Artifact> filteredDepsBuilder = ImmutableList.builder(); |
| |
| ResourceFilter fakeFilter = |
| ResourceFilter.of(ImmutableSet.copyOf(filteredResources), filteredDepsBuilder::add); |
| |
| Optional<? extends AndroidResources> filtered = |
| unfiltered.maybeFilter(errorConsumer, fakeFilter, isDependency); |
| |
| if (filteredResources.equals(unfiltered.getResources())) { |
| // We expect filtering to have been a no-op |
| assertThat(filtered.isPresent()).isFalse(); |
| } else { |
| // The resources and their roots should be filtered |
| assertThat(filtered.get().getResources()) |
| .containsExactlyElementsIn(filteredResources) |
| .inOrder(); |
| assertThat(filtered.get().getResourceRoots()) |
| .containsExactlyElementsIn(getResourceRoots(filteredResources)) |
| .inOrder(); |
| } |
| |
| if (!isDependency) { |
| // The filter should not record any filtered dependencies |
| assertThat(filteredDepsBuilder.build()).isEmpty(); |
| } else { |
| // The filtered dependencies should be exactly the list of filtered resources |
| assertThat(unfiltered.getResources()) |
| .containsExactlyElementsIn( |
| Iterables.concat(filteredDepsBuilder.build(), filteredResources)); |
| } |
| |
| return filtered; |
| } |
| |
| @Test |
| public void testParseNoCompile() throws Exception { |
| useConfiguration("--android_aapt=aapt"); |
| |
| RuleContext ruleContext = getRuleContext(); |
| ParsedAndroidResources parsed = |
| assertParse( |
| ruleContext, |
| DataBinding.contextFrom( |
| ruleContext, |
| ruleContext.getConfiguration().getFragment(AndroidConfiguration.class))); |
| |
| // Since we are not using aapt2, there should be no compiled symbols |
| assertThat(parsed.getCompiledSymbols()).isNull(); |
| |
| // The parse action should take resources in and output symbols |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ parsed.getResources(), |
| /* outputs = */ ImmutableList.of(parsed.getSymbols())); |
| } |
| |
| @Test |
| public void testParseAndCompile() throws Exception { |
| mockAndroidSdkWithAapt2(); |
| useConfiguration("--android_sdk=//sdk:sdk", "--android_aapt=aapt2"); |
| |
| RuleContext ruleContext = getRuleContext(); |
| ParsedAndroidResources parsed = assertParse(ruleContext); |
| |
| assertThat(parsed.getCompiledSymbols()).isNotNull(); |
| |
| // The parse action should take resources in and output symbols |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ parsed.getResources(), |
| /* outputs = */ ImmutableList.of(parsed.getSymbols())); |
| |
| // Since there was no data binding, the compile action should just take in resources and output |
| // compiled symbols. |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ parsed.getResources(), |
| /* outputs = */ ImmutableList.of(parsed.getCompiledSymbols())); |
| } |
| |
| @Test |
| public void testParseWithDataBinding() throws Exception { |
| mockAndroidSdkWithAapt2(); |
| useConfiguration("--android_sdk=//sdk:sdk", "--android_aapt=aapt2"); |
| |
| RuleContext ruleContext = getRuleContextWithDataBinding(); |
| |
| ParsedAndroidResources parsed = assertParse(ruleContext); |
| |
| // The parse action should take resources and busybox artifacts in and output symbols |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ parsed.getResources(), |
| /* outputs = */ ImmutableList.of(parsed.getSymbols())); |
| |
| // The compile action should take in resources and manifest in and output compiled symbols and |
| // an unused data binding zip. |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.<Artifact>builder() |
| .addAll(parsed.getResources()) |
| .add(parsed.getManifest()) |
| .build(), |
| /* outputs = */ ImmutableList.of( |
| parsed.getCompiledSymbols(), |
| ParsedAndroidResources.getDummyDataBindingArtifact(ruleContext))); |
| } |
| |
| @Test |
| public void testMergeDataBinding() throws Exception { |
| useConfiguration("--android_aapt=aapt"); |
| |
| RuleContext ruleContext = getRuleContextWithDataBinding(); |
| ParsedAndroidResources parsed = assertParse(ruleContext); |
| MergedAndroidResources merged = |
| parsed.merge( |
| AndroidDataContext.forNative(ruleContext), |
| ResourceDependencies.empty(), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)); |
| |
| // Besides processed manifest, inherited values should be equal |
| assertThat(parsed).isEqualTo(new ParsedAndroidResources(merged, parsed.getStampedManifest())); |
| |
| // There should be a new processed manifest |
| assertThat(merged.getManifest()).isNotEqualTo(parsed.getManifest()); |
| |
| assertThat(merged.getDataBindingInfoZip()).isNotNull(); |
| |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.<Artifact>builder() |
| .addAll(merged.getResources()) |
| .add(merged.getSymbols()) |
| .add(parsed.getManifest()) |
| .build(), |
| /* outputs = */ ImmutableList.of( |
| merged.getMergedResources(), |
| merged.getClassJar(), |
| merged.getDataBindingInfoZip(), |
| merged.getManifest())); |
| } |
| |
| @Test |
| public void testMergeCompiled() throws Exception { |
| mockAndroidSdkWithAapt2(); |
| useConfiguration( |
| "--android_sdk=//sdk:sdk", "--android_aapt=aapt2", "--experimental_skip_parsing_action"); |
| |
| RuleContext ruleContext = getRuleContext(); |
| ParsedAndroidResources parsed = assertParse(ruleContext); |
| MergedAndroidResources merged = |
| parsed.merge( |
| AndroidDataContext.forNative(ruleContext), |
| ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)); |
| |
| // Besides processed manifest, inherited values should be equal |
| assertThat(parsed).isEqualTo(new ParsedAndroidResources(merged, parsed.getStampedManifest())); |
| |
| // There should be a new processed manifest |
| assertThat(merged.getManifest()).isNotEqualTo(parsed.getManifest()); |
| |
| assertThat(merged.getDataBindingInfoZip()).isNull(); |
| assertThat(merged.getCompiledSymbols()).isNotNull(); |
| |
| // We use the compiled symbols file to build the resource class jar |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.<Artifact>builder() |
| .addAll(merged.getResources()) |
| .add(merged.getCompiledSymbols()) |
| .add(parsed.getManifest()) |
| .build(), |
| /* outputs = */ ImmutableList.of(merged.getClassJar(), merged.getManifest())); |
| |
| // The old symbols file is still needed to build the merged resources zip |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.<Artifact>builder() |
| .addAll(merged.getResources()) |
| .add(merged.getSymbols()) |
| .add(parsed.getManifest()) |
| .build(), |
| /* outputs = */ ImmutableList.of(merged.getMergedResources())); |
| } |
| |
| @Test |
| public void testValidateAapt() throws Exception { |
| useConfiguration("--android_aapt=aapt"); |
| RuleContext ruleContext = getRuleContext(); |
| |
| MergedAndroidResources merged = makeMergedResources(ruleContext); |
| ValidatedAndroidResources validated = |
| merged.validate( |
| AndroidDataContext.forNative(ruleContext), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)); |
| |
| // Inherited values should be equal |
| assertThat(merged).isEqualTo(new MergedAndroidResources(validated)); |
| |
| // aapt artifacts should be generated |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.of(validated.getMergedResources(), validated.getManifest()), |
| /* outputs = */ ImmutableList.of( |
| validated.getRTxt(), validated.getJavaSourceJar(), validated.getApk())); |
| |
| // aapt2 artifacts should not be generated |
| assertThat(validated.getCompiledSymbols()).isNull(); |
| assertThat(validated.getAapt2RTxt()).isNull(); |
| assertThat(validated.getAapt2SourceJar()).isNull(); |
| assertThat(validated.getStaticLibrary()).isNull(); |
| } |
| |
| @Test |
| public void testValidateAapt2() throws Exception { |
| mockAndroidSdkWithAapt2(); |
| useConfiguration("--android_sdk=//sdk:sdk", "--android_aapt=aapt2"); |
| RuleContext ruleContext = getRuleContext(); |
| |
| MergedAndroidResources merged = makeMergedResources(ruleContext); |
| ValidatedAndroidResources validated = |
| merged.validate( |
| AndroidDataContext.forNative(ruleContext), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)); |
| |
| // Inherited values should be equal |
| assertThat(merged).isEqualTo(new MergedAndroidResources(validated)); |
| |
| // aapt artifacts should be generated |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.of(validated.getMergedResources(), validated.getManifest()), |
| /* outputs = */ ImmutableList.of( |
| validated.getRTxt(), validated.getJavaSourceJar(), validated.getApk())); |
| |
| // aapt2 artifacts should be recorded |
| assertThat(validated.getCompiledSymbols()).isNotNull(); |
| assertThat(validated.getAapt2RTxt()).isNotNull(); |
| assertThat(validated.getAapt2SourceJar()).isNotNull(); |
| assertThat(validated.getStaticLibrary()).isNotNull(); |
| |
| // Compile the resources into compiled symbols files |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ validated.getResources(), |
| /* outputs = */ ImmutableList.of(validated.getCompiledSymbols())); |
| |
| // Use the compiled symbols and manifest to build aapt2 packaging outputs |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.of(validated.getCompiledSymbols(), validated.getManifest()), |
| /* outputs = */ ImmutableList.of( |
| validated.getAapt2RTxt(), validated.getAapt2SourceJar(), validated.getStaticLibrary())); |
| } |
| |
| @Test |
| public void testGenerateRClass() throws Exception { |
| RuleContext ruleContext = getRuleContext(); |
| Artifact rTxt = ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT); |
| ProcessedAndroidManifest manifest = getManifest(); |
| |
| ProcessedAndroidData processedData = |
| ProcessedAndroidData.of( |
| makeParsedResources(ruleContext), |
| AndroidAssets.from(ruleContext) |
| .process( |
| AndroidDataContext.forNative(ruleContext), |
| AssetDependencies.empty(), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)), |
| manifest, |
| rTxt, |
| ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_JAVA_SOURCE_JAR), |
| ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK), |
| /* dataBindingInfoZip = */ null, |
| ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false), |
| null, |
| null); |
| |
| ValidatedAndroidResources validated = |
| processedData |
| .generateRClass( |
| AndroidDataContext.forNative(ruleContext), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)) |
| .getValidatedResources(); |
| |
| // An action to generate the R.class file should be registered. |
| assertActionArtifacts( |
| ruleContext, |
| /* inputs = */ ImmutableList.of(rTxt, manifest.getManifest()), |
| /* outputs = */ ImmutableList.of(validated.getJavaClassJar())); |
| } |
| |
| @Test |
| public void testProcessBinaryDataGeneratesProguardOutput() throws Exception { |
| RuleContext ruleContext = getRuleContext("android_binary", "manifest='AndroidManifest.xml',"); |
| AndroidDataContext dataContext = AndroidDataContext.forNative(ruleContext); |
| |
| ResourceApk resourceApk = |
| ProcessedAndroidData.processBinaryDataFrom( |
| dataContext, |
| ruleContext, |
| getManifest(), |
| false, |
| ImmutableMap.of(), |
| AndroidAaptVersion.AUTO, |
| AndroidResources.empty(), |
| AndroidAssets.empty(), |
| ResourceDependencies.empty(), |
| AssetDependencies.empty(), |
| ResourceFilterFactory.empty(), |
| ImmutableList.of(), |
| false, |
| null, |
| null, |
| DataBinding.contextFrom(ruleContext, dataContext.getAndroidConfig())) |
| .generateRClass(dataContext, AndroidAaptVersion.AUTO); |
| |
| assertThat(resourceApk.getResourceProguardConfig()).isNotNull(); |
| assertThat(resourceApk.getMainDexProguardConfig()).isNotNull(); |
| } |
| |
| @Test |
| public void test_incompatibleUseAapt2ByDefaultEnabled_targetsAapt2() throws Exception { |
| mockAndroidSdkWithAapt2(); |
| useConfiguration("--android_sdk=//sdk:sdk", "--incompatible_use_aapt2_by_default"); |
| RuleContext ruleContext = |
| getRuleContext( |
| "android_binary", "aapt_version = 'auto',", "manifest = 'AndroidManifest.xml',"); |
| assertThat(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)) |
| .isEqualTo(AndroidAaptVersion.AAPT2); |
| } |
| |
| @Test |
| public void test_incompatibleUseAapt2ByDefaultDisabled_targetsAapt() throws Exception { |
| mockAndroidSdkWithAapt2(); |
| useConfiguration("--android_sdk=//sdk:sdk", "--noincompatible_use_aapt2_by_default"); |
| RuleContext ruleContext = |
| getRuleContext( |
| "android_binary", "aapt_version = 'auto',", "manifest = 'AndroidManifest.xml',"); |
| assertThat(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)) |
| .isEqualTo(AndroidAaptVersion.AAPT); |
| } |
| |
| /** |
| * Validates that a parse action was invoked correctly. Returns the {@link ParsedAndroidResources} |
| * for further validation. |
| */ |
| private ParsedAndroidResources assertParse(RuleContext ruleContext) throws Exception { |
| return assertParse( |
| ruleContext, |
| DataBinding.contextFrom( |
| ruleContext, ruleContext.getConfiguration().getFragment(AndroidConfiguration.class))); |
| } |
| |
| private ParsedAndroidResources assertParse( |
| RuleContext ruleContext, DataBindingContext dataBindingContext) throws Exception { |
| ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "drawable-hdpi/bar.png"); |
| AndroidResources raw = |
| new AndroidResources( |
| resources, AndroidResources.getResourceRoots(ruleContext, resources, "resource_files")); |
| StampedAndroidManifest manifest = getManifest(); |
| |
| ParsedAndroidResources parsed = |
| raw.parse( |
| AndroidDataContext.forNative(ruleContext), |
| manifest, |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext), |
| dataBindingContext); |
| |
| // Inherited values should be equal |
| assertThat(raw).isEqualTo(new AndroidResources(parsed)); |
| |
| // Label should be set from RuleContext |
| assertThat(parsed.getLabel()).isEqualTo(ruleContext.getLabel()); |
| |
| return parsed; |
| } |
| |
| private MergedAndroidResources makeMergedResources(RuleContext ruleContext) |
| throws RuleErrorException, InterruptedException { |
| return makeParsedResources(ruleContext) |
| .merge( |
| AndroidDataContext.forNative(ruleContext), |
| ResourceDependencies.fromRuleDeps(ruleContext, /* neverlink = */ false), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext)); |
| } |
| |
| private ParsedAndroidResources makeParsedResources(RuleContext ruleContext) |
| throws RuleErrorException, InterruptedException { |
| DataBindingContext dataBindingContext = |
| DataBinding.contextFrom(ruleContext, |
| ruleContext.getConfiguration().getFragment(AndroidConfiguration.class)); |
| return makeParsedResources(ruleContext, dataBindingContext); |
| } |
| |
| private ParsedAndroidResources makeParsedResources( |
| RuleContext ruleContext, DataBindingContext dataBindingContext) |
| throws RuleErrorException, InterruptedException { |
| ImmutableList<Artifact> resources = getResources("values-en/foo.xml", "drawable-hdpi/bar.png"); |
| return new AndroidResources( |
| resources, AndroidResources.getResourceRoots(ruleContext, resources, "resource_files")) |
| .parse( |
| AndroidDataContext.forNative(ruleContext), |
| getManifest(), |
| AndroidAaptVersion.chooseTargetAaptVersion(ruleContext), |
| dataBindingContext); |
| } |
| |
| private ProcessedAndroidManifest getManifest() { |
| return new ProcessedAndroidManifest( |
| getResource("some/path/AndroidManifest.xml"), "some.java.pkg", /* exported = */ true); |
| } |
| |
| /** Gets a dummy rule context object by creating a dummy target. */ |
| private RuleContext getRuleContext() throws Exception { |
| return getRuleContext("android_library"); |
| } |
| |
| private RuleContext getRuleContextWithDataBinding() throws Exception { |
| return getRuleContext("android_library", "enable_data_binding = 1"); |
| } |
| |
| /** Gets a dummy rule context object by creating a dummy target. */ |
| private RuleContext getRuleContext(String kind, String... additionalLines) throws Exception { |
| ConfiguredTarget target = |
| scratchConfiguredTarget( |
| "java/foo", |
| "target", |
| ImmutableList.<String>builder() |
| .add(kind + "(name = 'target',") |
| .add(additionalLines) |
| .add(")") |
| .build() |
| .toArray(new String[0])); |
| return getRuleContextForActionTesting(target); |
| } |
| } |