// 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.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.getFirstArtifactEndingWith;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.hasInput;
import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.prettyArtifactNames;
import static com.google.devtools.build.lib.rules.java.JavaCompileActionTestHelper.getJavacArguments;
import static com.google.devtools.build.lib.rules.java.JavaCompileActionTestHelper.getProcessorpath;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Ascii;
import com.google.common.base.Joiner;
import com.google.common.base.Predicates;
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.common.truth.Truth;
import com.google.devtools.build.lib.actions.Action;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.FailAction;
import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.analysis.AnalysisResult;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.OutputGroupInfo;
import com.google.devtools.build.lib.analysis.RequiredConfigFragmentsProvider;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
import com.google.devtools.build.lib.analysis.util.DummyTestFragment;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.FileTarget;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.util.BazelMockAndroidSupport;
import com.google.devtools.build.lib.rules.android.AndroidBinaryTest.WithPlatforms;
import com.google.devtools.build.lib.rules.android.AndroidBinaryTest.WithoutPlatforms;
import com.google.devtools.build.lib.rules.android.AndroidRuleClasses.MultidexMode;
import com.google.devtools.build.lib.rules.android.deployinfo.AndroidDeployInfoOuterClass.AndroidDeployInfo;
import com.google.devtools.build.lib.rules.cpp.CppFileTypes;
import com.google.devtools.build.lib.rules.cpp.CppLinkAction;
import com.google.devtools.build.lib.rules.java.JavaCompilationArgsProvider;
import com.google.devtools.build.lib.rules.java.JavaCompileAction;
import com.google.devtools.build.lib.rules.java.JavaInfo;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

/** A test for {@link com.google.devtools.build.lib.rules.android.AndroidBinary}. */
@RunWith(Suite.class)
@SuiteClasses({WithoutPlatforms.class, WithPlatforms.class})
public abstract class AndroidBinaryTest extends AndroidBuildViewTestCase {

  /** Allow use of --foo as a dummy flag */
  @Override
  protected ConfiguredRuleClassProvider createRuleClassProvider() {
    ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
    TestRuleClassProvider.addStandardRules(builder);
    builder.addConfigurationFragment(DummyTestFragment.class);
    return builder.build();
  }

  /** Use legacy toolchain resolution. */
  @RunWith(JUnit4.class)
  public static class WithoutPlatforms extends AndroidBinaryTest {

    @Test
    public void testAndroidSplitTransitionWithInvalidCpu() throws Exception {
      scratch.file(
          "test/starlark/my_rule.bzl",
          "def impl(ctx): ",
          "  return []",
          "my_rule = rule(",
          "  implementation = impl,",
          "  attrs = {",
          "    'deps': attr.label_list(cfg = android_common.multi_cpu_configuration),",
          "    'dep':  attr.label(cfg = android_common.multi_cpu_configuration),",
          "  })");

      scratch.file(
          "test/starlark/BUILD",
          "load('//test/starlark:my_rule.bzl', 'my_rule')",
          "my_rule(name = 'test', deps = [':main'], dep = ':main')",
          "cc_binary(name = 'main', srcs = ['main.c'])");
      BazelMockAndroidSupport.setupNdk(mockToolsConfig);

      // --android_cpu with --android_crosstool_top also triggers the split transition.
      useConfiguration(
          "--fat_apk_cpu=doesnotexist", "--android_crosstool_top=//android/crosstool:everything");

      AssertionError noToolchainError =
          assertThrows(AssertionError.class, () -> getConfiguredTarget("//test/starlark:test"));
      assertThat(noToolchainError)
          .hasMessageThat()
          .contains("does not contain a toolchain for cpu 'doesnotexist'");
    }
  }

  /** Use platform-based toolchain resolution. */
  @RunWith(JUnit4.class)
  public static class WithPlatforms extends AndroidBinaryTest {
    @Override
    protected boolean platformBasedToolchains() {
      return true;
    }

    @Override
    protected String defaultPlatformFlag() {
      return String.format(
          "--android_platforms=%sandroid:armeabi-v7a", TestConstants.CONSTRAINTS_PACKAGE_ROOT);
    }

    @Test
    public void testFatApk_androidPlatformsFlag() throws Exception {
      BazelMockAndroidSupport.setupNdk(mockToolsConfig);
      scratch.file(
          "java/foo/BUILD",
          "config_setting(",
          "    name = 'is_x86',",
          "    constraint_values = ['" + TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:x86_32'],",
          ")",
          "config_setting(",
          "    name = 'is_arm',",
          "    constraint_values = ['" + TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:armv7'],",
          ")",
          "android_library(",
          "    name = 'lib',",
          "    srcs = ['MyLibrary.java'])",
          "cc_library(",
          "    name = 'arm-native-lib',",
          "    srcs = ['armnative.so'])",
          "cc_library(",
          "    name = 'x86-native-lib',",
          "    srcs = ['x86native.so'])",
          "cc_library(",
          "    name = 'native-lib',",
          "    deps = select({",
          "        ':is_x86': [':x86-native-lib'],",
          "        ':is_arm': [':arm-native-lib'],",
          "        '//conditions:default': [],",
          "    }))",
          "android_binary(",
          "    name = 'abin',",
          "    srcs = ['a.java'],",
          "    proguard_specs = [],",
          "    deps = ['lib', 'native-lib'],",
          "    manifest = 'AndroidManifest.xml',",
          ")");
      useConfiguration(
          "--android_platforms=//java/android/platforms:x86,//java/android/platforms:armeabi-v7a",
          "--dynamic_mode=off");
      ConfiguredTarget apk = getConfiguredTarget("//java/foo:abin");
      List<String> args = getGeneratingSpawnActionArgs(getCompressedUnsignedApk(apk));
      assertContainsSublist(
          args,
          ImmutableList.of("--resources", "java/foo/armnative.so:lib/armeabi-v7a/armnative.so"));
      assertContainsSublist(
          args, ImmutableList.of("--resources", "java/foo/x86native.so:lib/x86/x86native.so"));
    }
  }

  @Before
  public void setupCcToolchain() throws Exception {
    getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a");
  }

  @Before
  public void setup() throws Exception {
    scratch.file(
        "java/android/BUILD",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "              )");
    scratch.file(
        "java/android/res/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    scratch.file("java/android/A.java", "package android; public class A {};");
    if (platformBasedToolchains()) {
      scratch.file(
          "java/android/platforms/BUILD",
          "platform(",
          "    name = 'x86',",
          "    parents = ['" + TestConstants.CONSTRAINTS_PACKAGE_ROOT + "android:armeabi-v7a'],",
          "    constraint_values = ['" + TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:x86_32'],",
          ")",
          "platform(",
          "    name = 'armeabi-v7a',",
          "    parents = ['" + TestConstants.CONSTRAINTS_PACKAGE_ROOT + "android:armeabi-v7a'],",
          "    constraint_values = ['" + TestConstants.CONSTRAINTS_PACKAGE_ROOT + "cpu:armv7'],",
          ")");
      scratch.file(
          "/workspace/platform_mappings",
          "platforms:",
          "  //java/android/platforms:armeabi-v7a",
          "    --cpu=armeabi-v7a",
          "    --android_cpu=armeabi-v7a",
          "    --crosstool_top=//android/crosstool:everything",
          "  //java/android/platforms:x86",
          "    --cpu=x86",
          "    --android_cpu=x86",
          "    --crosstool_top=//android/crosstool:everything",
          "flags:",
          "  --crosstool_top=//android/crosstool:everything",
          "  --cpu=armeabi-v7a",
          "    //java/android/platforms:armv7",
          "  --crosstool_top=//android/crosstool:everything",
          "  --cpu=x86",
          "    //java/android/platforms:x86");
      invalidatePackages(false);
    }
    setBuildLanguageOptions("--experimental_google_legacy_api");
  }

  @Test
  public void testAssetsInExternalRepository() throws Exception {
    FileSystemUtils.appendIsoLatin1(
        scratch.resolve("WORKSPACE"), "local_repository(name='r', path='/r')");
    scratch.file("/r/WORKSPACE");
    scratch.file("/r/p/BUILD", "filegroup(name='assets', srcs=['a/b'])");
    scratch.file("/r/p/a/b");
    invalidatePackages();
    scratchConfiguredTarget(
        "java/a",
        "a",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    assets = ['@r//p:assets'],",
        "    assets_dir = '')");
  }

  @Test
  public void testMultidexModeAndMainDexProguardSpecs() throws Exception {
    checkError(
        "java/a",
        "a",
        "only allowed if 'multidex' is set to 'legacy'",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    main_dex_proguard_specs = ['foo'])");
  }

  @Test
  public void testAndroidManifestWithCustomName() throws Exception {
    scratchConfiguredTarget(
        "java/a",
        "a",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'SomeOtherAndroidManifest.xml')");
    assertNoEvents();
  }

  @Test
  public void testMainDexProguardSpecs() throws Exception {
    useConfiguration("--noincremental_dexing");
    ConfiguredTarget ct =
        scratchConfiguredTarget(
            "java/a",
            "a",
            "android_binary(",
            "    name = 'a',",
            "    srcs = ['A.java'],",
            "    manifest = 'AndroidManifest.xml',",
            "    multidex = 'legacy',",
            "    main_dex_proguard_specs = ['a.spec'])");

    Artifact intermediateJar =
        artifactByPath(
            ImmutableList.of(getCompressedUnsignedApk(ct)),
            ".apk",
            ".dex.zip",
            ".dex.zip",
            "main_dex_list.txt",
            "_intermediate.jar");
    List<String> args = getGeneratingSpawnActionArgs(intermediateJar);
    MoreAsserts.assertContainsSublist(args, "-include", "java/a/a.spec");
    assertThat(Joiner.on(" ").join(args)).doesNotContain("mainDexClasses.rules");
  }

  @Test
  public void testLegacyMainDexListGenerator() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'legacy')");
    scratch.file(
        "tools/fake/BUILD",
        "cc_binary(",
        "    name = 'generate_main_dex_list',",
        "    srcs = ['main.cc'])");
    useConfiguration("--legacy_main_dex_list_generator=//tools/fake:generate_main_dex_list");

    ConfiguredTarget binary = getConfiguredTarget("//java/a:a");
    Artifact mainDexList =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "main_dex_list.txt");
    List<String> args = getGeneratingSpawnActionArgs(mainDexList);
    NestedSet<Artifact> mainDexInputs = getGeneratingAction(mainDexList).getInputs();

    MoreAsserts.assertContainsSublist(args, "--lib", getAndroidJarPath());
    MoreAsserts.assertContainsSublist(args, "--main-dex-rules", getMainDexClassesPath());

    assertThat(ActionsTestUtil.baseArtifactNames(mainDexInputs)).contains("generate_main_dex_list");
    assertThat(ActionsTestUtil.baseArtifactNames(mainDexInputs)).contains("a_deploy.jar");
    assertThat(ActionsTestUtil.baseArtifactNames(mainDexInputs)).contains(getAndroidJarFilename());
    assertThat(ActionsTestUtil.baseArtifactNames(mainDexInputs))
        .contains(getMainDexClassesFilename());
    assertThat(ActionsTestUtil.baseArtifactNames(mainDexInputs))
        .contains("main_dex_a_proguard.cfg");
    assertThat(getFirstArtifactEndingWith(mainDexInputs, "main_dex_list_creator")).isNull();
  }

  @Test
  public void testMainDexListObfuscation() throws Exception {
    useConfiguration("--noincremental_dexing");
    scratch.file("/java/a/list.txt");
    ConfiguredTarget ct =
        scratchConfiguredTarget(
            "java/a",
            "a",
            "android_binary(",
            "    name = 'a',",
            "    srcs = ['A.java'],",
            "    manifest = 'AndroidManifest.xml',",
            "    multidex = 'manual_main_dex',",
            "    proguard_generate_mapping = 1,",
            "    main_dex_list = 'list.txt')");

    Artifact obfuscatedDexList =
        artifactByPath(
            ImmutableList.of(getCompressedUnsignedApk(ct)),
            ".apk",
            ".dex.zip",
            ".dex.zip",
            "main_dex_list_obfuscated.txt");
    List<String> args = getGeneratingSpawnActionArgs(obfuscatedDexList);
    assertThat(args.get(0)).contains("dex_list_obfuscator");
    MoreAsserts.assertContainsSublist(args, "--input", "java/a/list.txt");
  }

  @Test
  public void testNonLegacyNativeDepsDoesNotPolluteDexSharding() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "android_binary(name = 'a',",
        "               manifest = 'AndroidManifest.xml',",
        "               multidex = 'native',",
        "               deps = [':cc'],",
        "               dex_shards = 2)",
        "cc_library(name = 'cc',",
        "           srcs = ['cc.cc'])");

    Artifact jarShard =
        artifactByPath(
            ImmutableList.of(getCompressedUnsignedApk(getConfiguredTarget("//java/a:a"))),
            ".apk",
            "classes.dex.zip",
            "shard1.dex.zip",
            "shard1.jar.dex.zip");
    NestedSet<Artifact> shardInputs = getGeneratingAction(jarShard).getInputs();
    assertThat(getFirstArtifactEndingWith(shardInputs, ".txt")).isNull();
  }

  @Test
  public void testCcInfoDeps() throws Exception {
    scratch.file(
        "java/a/cc_info.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = cc_toolchain,",
        "    requested_features = ctx.features,",
        "    unsupported_features = ctx.disabled_features,",
        "  )",
        "  library_to_link = cc_common.create_library_to_link(",
        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
        "    cc_toolchain = cc_toolchain, ",
        "    static_library=ctx.file.static_library)",
        "  linker_input = cc_common.create_linker_input(",
        "    libraries = depset([library_to_link]),",
        "    user_link_flags=depset(ctx.attr.user_link_flags),",
        "    owner = ctx.label,",
        "  )",
        "  linking_context = cc_common.create_linking_context(",
        "    linker_inputs=depset([linker_input]))",
        "  return [CcInfo(linking_context=linking_context)]",
        "cc_info = rule(",
        "  implementation=_impl,",
        "  fragments = [\"cpp\"],",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=True),",
        "    'user_link_flags' : attr.string_list(),",
        "    'static_library': attr.label(allow_single_file=True),",
        "    '_cc_toolchain': attr.label(default=Label('//java/a:alias'))",
        "  },",
        ");");
    scratch.file(
        "java/a/BUILD",
        "load('//java/a:cc_info.bzl', 'cc_info')",
        "cc_toolchain_alias(name='alias')",
        "android_binary(",
        "    name = 'a',",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'native',",
        "    deps = [':cc_info'],",
        ")",
        "cc_info(",
        "    name = 'cc_info',",
        "    user_link_flags = ['-first_flag', '-second_flag'],",
        "    static_library = 'cc_info.a',",
        ")");

    ConfiguredTarget app = getConfiguredTarget("//java/a:a");
    assertNoEvents();

    Artifact copiedLib = getOnlyElement(getNativeLibrariesInApk(app));
    Artifact linkedLib = getGeneratingAction(copiedLib).getInputs().getSingleton();
    CppLinkAction action = (CppLinkAction) getGeneratingAction(linkedLib);

    assertThat(action.getArguments()).containsAtLeast("-first_flag", "-second_flag");

    NestedSet<Artifact> linkInputs = action.getInputs();
    assertThat(ActionsTestUtil.baseArtifactNames(linkInputs)).contains("cc_info.a");
  }

  @Test
  public void testCcInfoDepsViaAndroidLibrary() throws Exception {
    scratch.file(
        "java/a/cc_info.bzl",
        "def _impl(ctx):",
        "  cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]",
        "  feature_configuration = cc_common.configure_features(",
        "    ctx = ctx,",
        "    cc_toolchain = cc_toolchain,",
        "    requested_features = ctx.features,",
        "    unsupported_features = ctx.disabled_features,",
        "  )",
        "  library_to_link = cc_common.create_library_to_link(",
        "    actions=ctx.actions, feature_configuration=feature_configuration, ",
        "    cc_toolchain = cc_toolchain, ",
        "    static_library=ctx.file.static_library)",
        "  linker_input = cc_common.create_linker_input(",
        "    libraries = depset([library_to_link]),",
        "    user_link_flags=depset(ctx.attr.user_link_flags),",
        "    owner = ctx.label,",
        "  )",
        "  linking_context = cc_common.create_linking_context(",
        "    linker_inputs=depset([linker_input]))",
        "  return [CcInfo(linking_context=linking_context)]",
        "cc_info = rule(",
        "  implementation=_impl,",
        "  fragments = [\"cpp\"],",
        "  attrs = {",
        "    'srcs': attr.label_list(allow_files=True),",
        "    'user_link_flags' : attr.string_list(),",
        "    'static_library': attr.label(allow_single_file=True),",
        "    '_cc_toolchain': attr.label(default=Label('//java/a:alias'))",
        "  },",
        ");");
    scratch.file(
        "java/a/BUILD",
        "load('//java/a:cc_info.bzl', 'cc_info')",
        "cc_toolchain_alias(name='alias')",
        "android_binary(",
        "    name = 'a',",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'native',",
        "    deps = [':liba'],",
        ")",
        "android_library(",
        "    name = 'liba',",
        "    srcs = ['a.java'],",
        "    deps = [':cc_info'],",
        ")",
        "cc_info(",
        "    name = 'cc_info',",
        "    user_link_flags = ['-first_flag', '-second_flag'],",
        "    static_library = 'cc_info.a',",
        ")");

    ConfiguredTarget app = getConfiguredTarget("//java/a:a");

    Artifact copiedLib = getOnlyElement(getNativeLibrariesInApk(app));
    Artifact linkedLib = getGeneratingAction(copiedLib).getInputs().getSingleton();
    CppLinkAction action = (CppLinkAction) getGeneratingAction(linkedLib);

    assertThat(action.getArguments()).containsAtLeast("-first_flag", "-second_flag");

    NestedSet<Artifact> linkInputs = action.getInputs();
    assertThat(ActionsTestUtil.baseArtifactNames(linkInputs)).contains("cc_info.a");
  }

  @Test
  public void testJavaPluginProcessorPath() throws Exception {
    scratch.file(
        "java/test/BUILD",
        "java_library(name = 'plugin_dep',",
        "    srcs = [ 'ProcessorDep.java'])",
        "java_plugin(name = 'plugin',",
        "    srcs = ['AnnotationProcessor.java'],",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [ ':plugin_dep' ])",
        "android_binary(name = 'to_be_processed',",
        "    manifest = 'AndroidManifest.xml',",
        "    plugins = [':plugin'],",
        "    srcs = ['ToBeProcessed.java'])");
    ConfiguredTarget target = getConfiguredTarget("//java/test:to_be_processed");
    JavaCompileAction javacAction =
        (JavaCompileAction) getGeneratingAction(getBinArtifact("libto_be_processed.jar", target));

    assertThat(getProcessorNames(javacAction)).contains("com.google.process.stuff");
    assertThat(getProcessorNames(javacAction)).hasSize(1);

    assertThat(
            ActionsTestUtil.baseArtifactNames(
                getInputs(javacAction, getProcessorpath(javacAction))))
        .containsExactly("libplugin.jar", "libplugin_dep.jar");
    assertThat(
            actionsTestUtil()
                .predecessorClosureOf(getFilesToBuild(target), JavaSemantics.JAVA_SOURCE))
        .isEqualTo("ToBeProcessed.java AnnotationProcessor.java ProcessorDep.java");
  }

  // Same test as above, enabling the plugin through the command line.
  @Test
  public void testPluginCommandLine() throws Exception {
    scratch.file(
        "java/test/BUILD",
        "java_library(name = 'plugin_dep',",
        "    srcs = [ 'ProcessorDep.java'])",
        "java_plugin(name = 'plugin',",
        "    srcs = ['AnnotationProcessor.java'],",
        "    processor_class = 'com.google.process.stuff',",
        "    deps = [ ':plugin_dep' ])",
        "android_binary(name = 'to_be_processed',",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['ToBeProcessed.java'])");

    useConfiguration("--plugin=//java/test:plugin");
    ConfiguredTarget target = getConfiguredTarget("//java/test:to_be_processed");
    JavaCompileAction javacAction =
        (JavaCompileAction) getGeneratingAction(getBinArtifact("libto_be_processed.jar", target));

    assertThat(getProcessorNames(javacAction)).contains("com.google.process.stuff");
    assertThat(getProcessorNames(javacAction)).hasSize(1);
    assertThat(
            ActionsTestUtil.baseArtifactNames(
                getInputs(javacAction, getProcessorpath(javacAction))))
        .containsExactly("libplugin.jar", "libplugin_dep.jar");
    assertThat(
            actionsTestUtil()
                .predecessorClosureOf(getFilesToBuild(target), JavaSemantics.JAVA_SOURCE))
        .isEqualTo("ToBeProcessed.java AnnotationProcessor.java ProcessorDep.java");
  }

  @Test
  public void testInvalidPlugin() throws Exception {
    checkError(
        "java/test",
        "lib",
        // error:
        getErrorMsgMandatoryProviderMissing("//java/test:not_a_plugin", "JavaPluginInfo"),
        // BUILD file:
        "java_library(name = 'not_a_plugin',",
        "    srcs = [ 'NotAPlugin.java'])",
        "android_binary(name = 'lib',",
        "    plugins = [':not_a_plugin'],",
        "    manifest = 'AndroidManifest.xml',",
        "    srcs = ['Lib.java'])");
  }

  @Test
  public void testBaselineCoverageArtifacts() throws Exception {
    useConfiguration("--collect_code_coverage");
    ConfiguredTarget target =
        scratchConfiguredTarget(
            "java/com/google/a",
            "bin",
            "android_binary(name='bin', srcs=['Main.java'], manifest='AndroidManifest.xml')");

    assertThat(baselineCoverageArtifactBasenames(target)).containsExactly("Main.java");
  }

  @Test
  public void testSameSoFromMultipleDeps() throws Exception {
    scratch.file(
        "java/d/BUILD",
        "genrule(name='genrule', srcs=[], outs=['genrule.so'], cmd='')",
        "cc_library(name='cc1', srcs=[':genrule.so'])",
        "cc_library(name='cc2', srcs=[':genrule.so'])",
        "android_binary(name='ab', deps=[':cc1', ':cc2'], manifest='AndroidManifest.xml')");
    getConfiguredTarget("//java/d:ab");
  }

  @Test
  public void testSimpleBinary_desugarJava8() throws Exception {
    useConfiguration("--experimental_desugar_for_android");
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(
                    actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "_deploy.jar");
    assertThat(ActionsTestUtil.baseArtifactNames(action.getInputs()))
        .contains("libapp.jar_desugared.jar");
    assertThat(ActionsTestUtil.baseArtifactNames(action.getInputs())).doesNotContain("libapp.jar");
  }

  /**
   * Tests that --experimental_check_desugar_deps causes the relevant flags to be set on desugaring
   * and singlejar actions, and makes sure the deploy jar is built even when just building an APK.
   */
  @Test
  public void testSimpleBinary_checkDesugarDepsAlwaysHappens() throws Exception {
    useConfiguration("--experimental_check_desugar_deps");
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");
    assertNoEvents();

    // 1. Find app's deploy jar and make sure checking flags are set for it and its inputs
    SpawnAction singlejar =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(getFilesToBuild(binary), "/app_deploy.jar");
    assertThat(getGeneratingSpawnActionArgs(singlejar.getPrimaryOutput()))
        .contains("--check_desugar_deps");

    SpawnAction desugar =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(singlejar.getInputs(), "/libapp.jar_desugared.jar");
    assertThat(desugar).isNotNull();
    assertThat(getGeneratingSpawnActionArgs(desugar.getPrimaryOutput()))
        .contains("--emit_dependency_metadata_as_needed");

    // 2. Make sure all APK outputs depend on the deploy Jar.
    int found = 0;
    for (Artifact built : getFilesToBuild(binary).toList()) {
      if (built.getExtension().equals("apk")) {
        // If this assertion breaks then APK artifacts have stopped depending on deploy jars.
        // If that's desired then we'll need to make sure dependency checking is done in another
        // action that APK artifacts depend on, in addition to the check that happens when building
        // deploy.jars, which we assert above.
        assertWithMessage("%s dependency on deploy.jar", built.getFilename())
            .that(actionsTestUtil().artifactClosureOf(built))
            .contains(singlejar.getPrimaryOutput());
        ++found;
      }
    }
    assertThat(found).isEqualTo(2 /* signed and unsigned apks */);
  }

  @Test
  public void testSimpleBinary_dexNoMinSdkVersion() throws Exception {
    scratch.overwriteFile(
        "java/android/BUILD",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               multidex = 'legacy',",
        "              )");
    useConfiguration("--experimental_desugar_java8_libs");
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    List<String> args =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)),
                "/libapp.jar.dex.zip"));
    assertThat(args).doesNotContain("--min_sdk_version");
  }

  @Test
  public void testSimpleBinary_dexMinSdkVersion() throws Exception {
    scratch.overwriteFile(
        "java/android/BUILD",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               min_sdk_version = 28,",
        "               multidex = 'legacy',",
        "              )");
    useConfiguration("--experimental_desugar_java8_libs");
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    List<String> args =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)),
                "/libapp.jar.dex.zip"));
    assertThat(args).contains("--min_sdk_version");
    assertThat(args).contains("28");
  }

  @Test
  public void testSimpleBinary_desugarNoMinSdkVersion() throws Exception {
    scratch.overwriteFile(
        "java/android/BUILD",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               multidex = 'legacy',",
        "              )");
    useConfiguration("--experimental_desugar_java8_libs");
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    List<String> args =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)),
                "/libapp.jar_desugared.jar"));
    assertThat(args).doesNotContain("--min_sdk_version");
  }

  @Test
  public void testSimpleBinary_desugarMinSdkVersion() throws Exception {
    scratch.overwriteFile(
        "java/android/BUILD",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               min_sdk_version = 28,",
        "               multidex = 'legacy',",
        "              )");
    useConfiguration("--experimental_desugar_java8_libs");
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    List<String> args =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)),
                "/libapp.jar_desugared.jar"));
    assertThat(args).contains("--min_sdk_version");
    assertThat(args).contains("28");
  }

  @Test
  public void testSimpleAndroidBinary_multipleMinSdkVersionOnSameLibrary() throws Exception {
    scratch.overwriteFile(
        "java/android/BUILD",
        "android_binary(name = 'app1',",
        "               srcs = ['A.java'],",
        "               deps = ['lib'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "              )",
        "android_binary(name = 'app2',",
        "               srcs = ['B.java'],",
        "               deps = ['lib'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               min_sdk_version = 28,",
        "              )",
        "android_library(name = 'lib',",
        "                srcs = ['C.java'])");
    AnalysisResult result =
        update(
            ImmutableList.of("//java/android:app1", "//java/android:app2"),
            /* keepGoing= */ true,
            /* loadingPhaseThreads= */ 1,
            /* doAnalysis= */ true,
            eventBus);

    ImmutableMap<String, ConfiguredTarget> targets =
        result.getTargetsToBuild().stream()
            .collect(toImmutableMap(ct -> ct.getLabel().toString(), Function.identity()));

    ConfiguredTarget app1 = targets.get("//java/android:app1");
    ConfiguredTarget app2 = targets.get("//java/android:app2");

    // The "lib" target is built twice: once with the default minsdk from app1, and again with
    // min_sdk_version = 28 from app2.

    List<String> libDesugarNoMinSdkArgs =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(app1)),
                "/liblib.jar_desugared.jar"));
    assertThat(libDesugarNoMinSdkArgs).doesNotContain("--min_sdk_version");

    List<String> libDexNoMinSdkArgs =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(app1)), "/liblib.jar.dex.zip"));
    assertThat(libDexNoMinSdkArgs).doesNotContain("--min_sdk_version");

    List<String> libDesugarWithMinSdkArgs =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(app2)),
                "/liblib.jar_minsdk=28_desugared.jar"));
    assertThat(libDesugarWithMinSdkArgs).containsAtLeast("--min_sdk_version", "28").inOrder();

    List<String> libDexWithMinSdkArgs =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(app2)),
                "liblib.jar--min_sdk_version=28.dex.zip"));
    assertThat(libDexWithMinSdkArgs).containsAtLeast("--min_sdk_version", "28").inOrder();
  }

  // regression test for #3169099
  @Test
  public void testBinarySrcs() throws Exception {
    scratch.file("java/srcs/a.foo", "foo");
    scratch.file(
        "java/srcs/BUILD",
        "android_binary(name = 'valid', manifest = 'AndroidManifest.xml', "
            + "srcs = ['a.java', 'b.srcjar', ':gvalid', ':gmix'])",
        "android_binary(name = 'invalid', manifest = 'AndroidManifest.xml', "
            + "srcs = ['a.foo', ':ginvalid'])",
        "android_binary(name = 'mix', manifest = 'AndroidManifest.xml', "
            + "srcs = ['a.java', 'a.foo'])",
        "genrule(name = 'gvalid', srcs = ['a.java'], outs = ['b.java'], cmd = '')",
        "genrule(name = 'ginvalid', srcs = ['a.java'], outs = ['b.foo'], cmd = '')",
        "genrule(name = 'gmix', srcs = ['a.java'], outs = ['c.java', 'c.foo'], cmd = '')");
    assertSrcsValidityForRuleType("//java/srcs", "android_binary", ".java or .srcjar");
  }

  // regression test for #3169095
  @Test
  public void testXmbInSrcs_notPermittedButDoesNotThrow() throws Exception {
    reporter.removeHandler(failFastHandler);
    scratchConfiguredTarget(
        "java/xmb",
        "a",
        "android_binary(name = 'a', manifest = 'AndroidManifest.xml', srcs = ['a.xmb'])");
    // We expect there to be an error here because a.xmb is not a valid src,
    // and more importantly, no exception to have been thrown.
    assertContainsEvent(
        "in srcs attribute of android_binary rule //java/xmb:a: "
            + "target '//java/xmb:a.xmb' does not exist");
  }

  @Test
  public void testNativeLibraryBasenameCollision() throws Exception {
    reporter.removeHandler(failFastHandler); // expect errors
    scratch.file(
        "java/android/common/BUILD",
        "cc_library(name = 'libcommon_armeabi',",
        "           srcs = ['armeabi/native.so'],)");
    scratch.file(
        "java/android/app/BUILD",
        "cc_library(name = 'libnative',",
        "           srcs = ['native.so'],)",
        "android_binary(name = 'b',",
        "               srcs = ['A.java'],",
        "               deps = [':libnative', '//java/android/common:libcommon_armeabi'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )");
    getConfiguredTarget("//java/android/app:b");
    assertContainsEvent(
        "Each library in the transitive closure must have a unique basename to avoid name"
            + " collisions when packaged into an apk, but two libraries have the basename"
            + " 'native.so': java/android/common/armeabi/native.so and"
            + " java/android/app/native.so");
  }

  private void setupNativeLibrariesForLinking() throws Exception {
    scratch.file(
        "java/android/common/BUILD",
        "cc_library(name = 'common_native',",
        "           srcs = ['common.cc'],)",
        "android_library(name = 'common',",
        "                exports = [':common_native'],)");
    scratch.file(
        "java/android/app/BUILD",
        "cc_library(name = 'native',",
        "           srcs = ['native.cc'],)",
        "android_binary(name = 'auto',",
        "               srcs = ['A.java'],",
        "               deps = [':native', '//java/android/common:common'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )",
        "android_binary(name = 'off',",
        "               srcs = ['A.java'],",
        "               deps = [':native', '//java/android/common:common'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )");
  }

  private void assertNativeLibraryLinked(ConfiguredTarget target, String... srcNames) {
    Artifact linkedLib = getOnlyElement(getNativeLibrariesInApk(target));
    assertThat(linkedLib.getFilename())
        .isEqualTo("lib" + target.getLabel().toPathFragment().getBaseName() + ".so");
    assertThat(linkedLib.isSourceArtifact()).isFalse();
    assertWithMessage("Native libraries were not linked to produce " + linkedLib)
        .that(getGeneratingLabelForArtifact(linkedLib))
        .isEqualTo(target.getLabel());
    assertThat(artifactsToStrings(actionsTestUtil().artifactClosureOf(linkedLib)))
        .containsAtLeastElementsIn(ImmutableSet.copyOf(Arrays.asList(srcNames)));
  }

  @Test
  public void testNativeLibrary_linksLibrariesWhenCodeIsPresent() throws Exception {
    setupNativeLibrariesForLinking();
    assertNativeLibraryLinked(
        getConfiguredTarget("//java/android/app:auto"),
        "src java/android/common/common.cc",
        "src java/android/app/native.cc");
    assertNativeLibraryLinked(
        getConfiguredTarget("//java/android/app:off"),
        "src java/android/common/common.cc",
        "src java/android/app/native.cc");
  }

  @Test
  public void testNativeLibrary_copiesLibrariesDespiteExtraLayersOfIndirection() throws Exception {
    setBuildLanguageOptions(
        "--experimental_builtins_injection_override=+cc_library",
        "--experimental_google_legacy_api");
    scratch.file(
        "java/android/app/BUILD",
        "cc_library(name = 'native_dep',",
        "           srcs = ['dep.so'])",
        "cc_library(name = 'native',",
        "           srcs = ['native_prebuilt.so'],",
        "           deps = [':native_dep'])",
        "cc_library(name = 'native_wrapper',",
        "           deps = [':native'])",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               deps = [':native_wrapper'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )");
    ConfiguredTarget app = getConfiguredTarget("//java/android/app:app");
    assertNativeLibrariesCopiedNotLinked(
        app,
        getConfiguration(getDirectPrerequisite(app, "//java/android/app:native_wrapper")),
        "src java/android/app/dep.so",
        "src java/android/app/native_prebuilt.so");
  }

  @Test
  public void testNativeLibrary_copiesLibrariesWrappedInCcLibraryWithSameName() throws Exception {
    scratch.file(
        "java/android/app/BUILD",
        "cc_library(name = 'native',",
        "           srcs = ['libnative.so'])",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               deps = [':native'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )");
    ConfiguredTarget app = getConfiguredTarget("//java/android/app:app");
    assertNativeLibrariesCopiedNotLinked(
        app,
        getConfiguration(getDirectPrerequisite(app, "//java/android/app:native")),
        "src java/android/app/libnative.so");
  }

  @Test
  public void testNativeLibrary_linksWhenPrebuiltArchiveIsSupplied() throws Exception {
    scratch.file(
        "java/android/app/BUILD",
        "cc_library(name = 'native_dep',",
        "           srcs = ['dep.lo'])",
        "cc_library(name = 'native',",
        "           srcs = ['native_prebuilt.a'],",
        "           deps = [':native_dep'])",
        "cc_library(name = 'native_wrapper',",
        "           deps = [':native'])",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               deps = [':native_wrapper'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )");
    assertNativeLibraryLinked(
        getConfiguredTarget("//java/android/app:app"), "src java/android/app/native_prebuilt.a");
  }

  @Test
  public void testNativeLibrary_copiesFullLibrariesInIfsoMode() throws Exception {
    useConfiguration("--interface_shared_objects");
    scratch.file(
        "java/android/app/BUILD",
        "cc_library(name = 'native_dep',",
        "           srcs = ['dep.so'])",
        "cc_library(name = 'native',",
        "           srcs = ['native.cc', 'native_prebuilt.so'],",
        "           deps = [':native_dep'])",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               deps = [':native'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )");
    ConfiguredTarget app = getConfiguredTarget("//java/android/app:app");
    Iterable<Artifact> nativeLibraries = getNativeLibrariesInApk(app);
    assertThat(artifactsToStrings(nativeLibraries))
        .containsAtLeast("src java/android/app/native_prebuilt.so", "src java/android/app/dep.so");
    assertThat(FileType.filter(nativeLibraries, CppFileTypes.INTERFACE_SHARED_LIBRARY)).isEmpty();
  }

  @Test
  public void testNativeLibrary_providesLinkerScriptToLinkAction() throws Exception {
    scratch.file(
        "java/android/app/BUILD",
        "cc_library(name = 'native',",
        "           srcs = ['native.cc'],",
        "           linkopts = ['-Wl,-version-script', '$(location jni.lds)'],",
        "           deps = ['jni.lds'],)",
        "android_binary(name = 'app',",
        "               srcs = ['A.java'],",
        "               deps = [':native'],",
        "               manifest = 'AndroidManifest.xml',",
        "              )");

    ConfiguredTarget app = getConfiguredTarget("//java/android/app:app");
    Artifact copiedLib = getOnlyElement(getNativeLibrariesInApk(app));
    Artifact linkedLib = getGeneratingAction(copiedLib).getInputs().getSingleton();
    NestedSet<Artifact> linkInputs = getGeneratingAction(linkedLib).getInputs();
    assertThat(ActionsTestUtil.baseArtifactNames(linkInputs)).contains("jni.lds");
  }

  /** Regression test for http://b/33173461. */
  @Test
  public void testIncrementalDexingUsesDexArchives_binaryDependingOnAliasTarget() throws Exception {
    useConfiguration(
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "java/com/google/android/BUILD",
        "android_library(",
        "  name = 'dep',",
        "  srcs = ['dep.java'],",
        "  manifest = 'AndroidManifest.xml',",
        ")",
        "alias(",
        "  name = 'alt',",
        "  actual = ':dep',",
        ")",
        "android_binary(",
        "  name = 'top',",
        "  srcs = ['foo.java', 'bar.srcjar'],",
        "  multidex = 'native',",
        "  manifest = 'AndroidManifest.xml',",
        "  deps = [':alt',],",
        ")");

    ConfiguredTarget topTarget = getConfiguredTarget("//java/com/google/android:top");
    assertNoEvents();

    Action shardAction = getGeneratingAction(getBinArtifact("_dx/top/classes.jar", topTarget));
    for (Artifact input : getNonToolInputs(shardAction)) {
      String basename = input.getFilename();
      // all jars are converted to dex archives
      assertWithMessage(basename)
          .that(!basename.contains(".jar") || basename.endsWith(".jar.dex.zip"))
          .isTrue();
      // all jars are desugared before being converted
      if (basename.endsWith(".jar.dex.zip")) {
        assertThat(getGeneratingAction(input).getPrimaryInput().getFilename())
            .isEqualTo(
                basename.substring(0, basename.length() - ".jar.dex.zip".length())
                    + ".jar_desugared.jar");
      }
    }
    // Make sure exactly the dex archives generated for top and dependents appear.  We also *don't*
    // want neverlink and unused_dep to appear, and to be safe we do so by explicitly enumerating
    // *all* expected input dex archives.
    assertThat(
            Iterables.filter(
                ActionsTestUtil.baseArtifactNames(getNonToolInputs(shardAction)),
                Predicates.containsPattern("\\.jar")))
        .containsExactly(
            // top's dex archives
            "libtop.jar.dex.zip",
            "top_resources.jar.dex.zip",
            // dep's dex archives
            "libdep.jar.dex.zip");
  }

  @Test
  public void testIncrementalDexingDisabledWithBlacklistedDexopts() throws Exception {
    // Even if we mark a dx flag as supported, incremental dexing isn't used with disallowlisted
    // dexopts (unless incremental_dexing attribute is set, which a different test covers)
    useConfiguration(
        "--incremental_dexing",
        "--non_incremental_per_target_dexopts=--no-locals",
        "--dexopts_supported_in_incremental_dexing=--no-locals");
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'top',",
        "  srcs = ['foo.java', 'bar.srcjar'],",
        "  manifest = 'AndroidManifest.xml',",
        "  dexopts = ['--no-locals'],",
        "  dex_shards = 2,",
        "  multidex = 'native',",
        ")");

    ConfiguredTarget topTarget = getConfiguredTarget("//java/com/google/android:top");
    assertNoEvents();
    Action shardAction = getGeneratingAction(getBinArtifact("_dx/top/shard1.jar", topTarget));
    assertThat(
            Iterables.filter(
                ActionsTestUtil.baseArtifactNames(getNonToolInputs(shardAction)),
                Predicates.containsPattern("\\.jar\\.dex\\.zip")))
        .isEmpty(); // no dex archives are used
  }

  @Test
  public void testIncrementalDexingDisabledWithProguard() throws Exception {
    useConfiguration(
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'top',",
        "  srcs = ['foo.java', 'bar.srcjar'],",
        "  manifest = 'AndroidManifest.xml',",
        "  proguard_specs = ['proguard.cfg'],",
        ")");

    ConfiguredTarget topTarget = getConfiguredTarget("//java/com/google/android:top");
    assertNoEvents();
    Action dexAction =
        getGeneratingAction(getBinArtifact("_dx/top/intermediate_classes.dex.zip", topTarget));
    assertThat(
            Iterables.filter(
                ActionsTestUtil.baseArtifactNames(dexAction.getInputs()),
                Predicates.containsPattern("\\.jar")))
        .containsExactly("top_proguard.jar", "dx_binary.jar"); // proguard output is used directly
  }

  @Test
  public void testIncrementalDexing_incompatibleWithProguardWhenDisabled() throws Exception {
    useConfiguration(
        "--experimental_incremental_dexing_after_proguard=0", // disable with Proguard
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false");
    checkError(
        "java/com/google/android",
        "top",
        "target cannot be incrementally dexed",
        "android_binary(",
        "  name = 'top',",
        "  srcs = ['foo.java', 'bar.srcjar'],",
        "  manifest = 'AndroidManifest.xml',",
        "  proguard_specs = ['proguard.cfg'],",
        "  incremental_dexing = 1,",
        ")");
  }

  @Test
  public void testIncrementalDexingAfterProguard_unsharded() throws Exception {
    useConfiguration("--experimental_incremental_dexing_after_proguard=1");
    // Use "legacy" multidex mode so we get a main dex list file and can test that it's passed to
    // the splitter action (similar to _withDexShards below), unlike without the dex splitter where
    // the main dex list goes to the merging action.
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'top',",
        "  srcs = ['foo.java', 'bar.srcjar'],",
        "  manifest = 'AndroidManifest.xml',",
        "  incremental_dexing = 1,",
        "  multidex = 'legacy',",
        "  dexopts = ['--minimal-main-dex', '--positions=none'],",
        "  proguard_specs = ['b.pro'],",
        ")");

    ConfiguredTarget topTarget = getConfiguredTarget("//java/com/google/android:top");
    assertNoEvents();

    SpawnAction shardAction =
        getGeneratingSpawnAction(getBinArtifact("_dx/top/classes.dex.zip", topTarget));
    assertThat(shardAction.getArguments()).contains("--main-dex-list");
    assertThat(shardAction.getArguments()).contains("--minimal-main-dex");
    assertThat(ActionsTestUtil.baseArtifactNames(getNonToolInputs(shardAction)))
        .containsExactly("classes.jar", "main_dex_list.txt");

    // --positions dexopt is supported after Proguard, even though not normally otherwise
    assertThat(
            paramFileArgsForAction(
                getGeneratingSpawnAction(getBinArtifact("_dx/top/classes.jar", topTarget))))
        .contains("--positions=none");
  }

  @Test
  public void testIncrementalDexingAfterProguard_autoShardedMultidexAutoOptIn() throws Exception {
    useConfiguration(
        "--experimental_incremental_dexing_after_proguard=3",
        "--experimental_incremental_dexing_after_proguard_by_default");
    // Use "legacy" multidex mode so we get a main dex list file and can test that it's passed to
    // the splitter action (similar to _withDexShards below), unlike without the dex splitter where
    // the main dex list goes to the merging action.
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'top',",
        "  srcs = ['foo.java', 'bar.srcjar'],",
        "  manifest = 'AndroidManifest.xml',",
        "  multidex = 'legacy',",
        "  dexopts = ['--minimal-main-dex', '--positions=none'],",
        "  proguard_specs = ['b.pro'],",
        ")"); // incremental_dexing = 1 attribute not needed

    ConfiguredTarget topTarget = getConfiguredTarget("//java/com/google/android:top");
    assertNoEvents();

    SpawnAction splitAction = getGeneratingSpawnAction(getTreeArtifact("dexsplits/top", topTarget));
    assertThat(splitAction.getArguments()).contains("--main-dex-list");
    assertThat(splitAction.getArguments()).contains("--minimal-main-dex");
    assertThat(ActionsTestUtil.baseArtifactNames(getNonToolInputs(splitAction)))
        .containsExactly(
            "shard1.jar.dex.zip", "shard2.jar.dex.zip", "shard3.jar.dex.zip", "main_dex_list.txt");

    SpawnAction shuffleAction =
        getGeneratingSpawnAction(getBinArtifact("_dx/top/shard1.jar", topTarget));
    assertThat(shuffleAction.getArguments()).doesNotContain("--main-dex-list");
    assertThat(ActionsTestUtil.baseArtifactNames(getNonToolInputs(shuffleAction)))
        .containsExactly("top_proguard.jar");

    // --positions dexopt is supported after Proguard, even though not normally otherwise
    assertThat(
            paramFileArgsForAction(
                getGeneratingSpawnAction(getBinArtifact("_dx/top/shard3.jar.dex.zip", topTarget))))
        .contains("--positions=none");
  }

  @Test
  public void testIncrementalDexingAfterProguard_explicitDexShards() throws Exception {
    useConfiguration("--experimental_incremental_dexing_after_proguard=2");
    // Use "legacy" multidex mode so we get a main dex list file and can test that it's passed to
    // the shardAction, not to the subsequent dexMerger action.  Without dex_shards, main dex list
    // file goes to the dexMerger instead (see _multidex test).
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'top',",
        "  srcs = ['foo.java', 'bar.srcjar'],",
        "  manifest = 'AndroidManifest.xml',",
        "  dex_shards = 25,",
        "  incremental_dexing = 1,",
        "  multidex = 'legacy',",
        "  proguard_specs = ['b.pro'],",
        ")");

    ConfiguredTarget topTarget = getConfiguredTarget("//java/com/google/android:top");
    assertNoEvents();
    SpawnAction shardAction =
        getGeneratingSpawnAction(getBinArtifact("_dx/top/shard25.jar", topTarget));
    assertThat(shardAction.getArguments()).contains("--main_dex_filter");
    assertThat(ActionsTestUtil.baseArtifactNames(getNonToolInputs(shardAction)))
        .containsExactly("top_proguard.jar", "main_dex_list.txt");
    SpawnAction mergeAction =
        getGeneratingSpawnAction(getBinArtifact("_dx/top/shard1.jar.dex.zip", topTarget));
    assertThat(mergeAction.getArguments()).doesNotContain("--main-dex-list");
    assertThat(ActionsTestUtil.baseArtifactNames(getNonToolInputs(mergeAction)))
        .contains("shard1.jar");
  }

  @Test
  public void testV1SigningMethod() throws Exception {
    actualSignerToolTests("v1", "true", "false", null);
  }

  @Test
  public void testV2SigningMethod() throws Exception {
    actualSignerToolTests("v2", "false", "true", null);
  }

  @Test
  public void testV1V2SigningMethod() throws Exception {
    actualSignerToolTests("v1_v2", "true", "true", null);
  }

  @Test
  public void testV4SigningMethod() throws Exception {
    actualSignerToolTests("v4", "false", "false", "true");
  }

  private void actualSignerToolTests(
      String apkSigningMethod, String signV1, String signV2, String signV4) throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',)");
    useConfiguration("--apk_signing_method=" + apkSigningMethod);
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:hello");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));
    assertThat(getFirstArtifactEndingWith(artifacts, "signed_hello.apk")).isNull();
    SpawnAction unsignedApkAction =
        (SpawnAction)
            actionsTestUtil().getActionForArtifactEndingWith(artifacts, "/hello_unsigned.apk");
    assertThat(
            unsignedApkAction.getInputs().toList().stream()
                .map(Artifact::getFilename)
                .anyMatch(filename -> Ascii.toLowerCase(filename).contains("singlejar")))
        .isTrue();
    SpawnAction compressedUnsignedApkAction =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(artifacts, "compressed_hello_unsigned.apk");
    assertThat(
            compressedUnsignedApkAction.getInputs().toList().stream()
                .map(Artifact::getFilename)
                .anyMatch(filename -> Ascii.toLowerCase(filename).contains("singlejar")))
        .isTrue();
    SpawnAction zipalignAction =
        (SpawnAction)
            actionsTestUtil().getActionForArtifactEndingWith(artifacts, "zipaligned_hello.apk");
    assertThat(zipalignAction.getCommandFilename()).endsWith("zipalign");
    Artifact a = ActionsTestUtil.getFirstArtifactEndingWith(artifacts, "hello.apk");
    assertThat(getGeneratingSpawnAction(a).getCommandFilename()).endsWith("ApkSignerBinary");
    List<String> args = getGeneratingSpawnActionArgs(a);

    assertThat(flagValue("--v1-signing-enabled", args)).isEqualTo(signV1);
    assertThat(flagValue("--v2-signing-enabled", args)).isEqualTo(signV2);
    if (signV4 != null) {
      assertThat(flagValue("--v4-signing-enabled", args)).isEqualTo(signV4);
      if (signV4.equals("true")) {
        assertThat(getFirstArtifactEndingWith(artifacts, "hello.apk.idsig")).isNotNull();
      }
    } else {
      assertThat(args).doesNotContain("--v4-signing-enabled");
    }
  }

  @Test
  public void testResourcePathShortening_flagEnabledAndCOpt_optimizedApkIsInputToApkBuilderAction()
      throws Exception {
    useConfiguration("--experimental_android_resource_path_shortening", "-c", "opt");

    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    SpawnAction optimizeAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "app_optimized.ap_"));
    assertThat(optimizeAction.getMnemonic()).isEqualTo("Aapt2Optimize");
    assertThat(getGeneratingAction(getFirstArtifactEndingWith(artifacts, "app_resource_paths.map")))
        .isEqualTo(optimizeAction);

    List<String> processingArgs = optimizeAction.getArguments();
    assertThat(processingArgs).contains("--shorten-resource-paths");
    assertThat(flagValue("--resource-path-shortening-map", processingArgs))
        .endsWith("app_resource_paths.map");

    // Verify that the optimized APK is an input to build the unsigned APK.
    SpawnAction apkAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "app_unsigned.apk"));
    assertThat(apkAction.getMnemonic()).isEqualTo("ApkBuilder");
    assertThat(hasInput(apkAction, "app_optimized.ap_")).isTrue();
  }

  @Test
  public void testResourcePathShortening_flagEnabledAndCDefault_optimizeArtifactsAbsent()
      throws Exception {
    useConfiguration("--experimental_android_resource_path_shortening");

    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    Artifact resourcePathShorteningMapArtifact =
        getFirstArtifactEndingWith(artifacts, "app_resource_paths.map");
    assertThat(resourcePathShorteningMapArtifact).isNull();

    Artifact optimizedResourceApk = getFirstArtifactEndingWith(artifacts, "app_optimized.ap_");
    assertThat(optimizedResourceApk).isNull();

    // Verify that the optimized APK is not an input to build the unsigned APK.
    SpawnAction apkAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "app_unsigned.apk"));
    assertThat(apkAction.getMnemonic()).isEqualTo("ApkBuilder");
    assertThat(hasInput(apkAction, "app_optimized.ap_")).isFalse();
  }

  @Test
  public void testResourcePathShortening_flagNotEnabledAndCOpt_optimizeArtifactsAbsent()
      throws Exception {
    useConfiguration("-c", "opt");

    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    Artifact resourcePathShorteningMapArtifact =
        getFirstArtifactEndingWith(artifacts, "app_resource_paths.map");
    assertThat(resourcePathShorteningMapArtifact).isNull();

    Artifact optimizedResourceApk = getFirstArtifactEndingWith(artifacts, "app_optimized.ap_");
    assertThat(optimizedResourceApk).isNull();

    // Verify that the optimized APK is not an input to build the unsigned APK.
    SpawnAction apkAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "app_unsigned.apk"));
    assertThat(apkAction.getMnemonic()).isEqualTo("ApkBuilder");
    assertThat(hasInput(apkAction, "app_optimized.ap_")).isFalse();
  }

  @Test
  public void resourceNameCollapse_flagAndProguardSpecsPresent_optimizedApkIsInputToApkBuilder()
      throws Exception {
    useConfiguration("--experimental_android_resource_name_obfuscation");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               shrink_resources = 1,",
        "               proguard_specs = ['proguard-spec.pro'],)");

    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:hello");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    SpawnAction shrinkerAction =
        getGeneratingSpawnAction(
            getFirstArtifactEndingWith(artifacts, "resource_optimization.cfg"));
    assertThat(shrinkerAction.getMnemonic()).isEqualTo("ResourceShrinker");
    SpawnAction optimizeAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "hello_optimized.ap_"));
    assertThat(optimizeAction.getMnemonic()).isEqualTo("Aapt2Optimize");

    List<String> processingArgs = optimizeAction.getArguments();
    assertThat(processingArgs).contains("--collapse-resource-names");
    assertThat(flagValue("--resources-config-path", processingArgs))
        .endsWith("resource_optimization.cfg");

    // Verify that the optimized APK is an input to build the unsigned APK.
    SpawnAction apkAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "hello_unsigned.apk"));
    assertThat(apkAction.getMnemonic()).isEqualTo("ApkBuilder");
    assertThat(hasInput(apkAction, "hello_optimized.ap_")).isTrue();
  }

  @Test
  public void resourceNameCollapse_featureAndProguardSpecsPresent_optimizedApkIsInputToApkBuilder()
      throws Exception {
    useConfiguration("--features=resource_name_obfuscation");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               shrink_resources = 1,",
        "               proguard_specs = ['proguard-spec.pro'],)");

    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:hello");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    SpawnAction shrinkerAction =
        getGeneratingSpawnAction(
            getFirstArtifactEndingWith(artifacts, "resource_optimization.cfg"));
    assertThat(shrinkerAction.getMnemonic()).isEqualTo("ResourceShrinker");
    SpawnAction optimizeAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "hello_optimized.ap_"));
    assertThat(optimizeAction.getMnemonic()).isEqualTo("Aapt2Optimize");

    List<String> processingArgs = optimizeAction.getArguments();
    assertThat(processingArgs).contains("--collapse-resource-names");
    assertThat(flagValue("--resources-config-path", processingArgs))
        .endsWith("resource_optimization.cfg");

    // Verify that the optimized APK is an input to build the unsigned APK.
    SpawnAction apkAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "hello_unsigned.apk"));
    assertThat(apkAction.getMnemonic()).isEqualTo("ApkBuilder");
    assertThat(hasInput(apkAction, "hello_optimized.ap_")).isTrue();
  }

  @Test
  public void resourceNameCollapse_flagPresentProguardSpecsAbsent_optimizeArtifactsAbsent()
      throws Exception {
    useConfiguration("--experimental_android_resource_name_obfuscation");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               shrink_resources = 1,)");

    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:hello");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    Artifact optimizedResourceApk = getFirstArtifactEndingWith(artifacts, "hello_optimized.ap_");
    assertThat(optimizedResourceApk).isNull();

    // Verify that the optimized APK is not an input to build the unsigned APK.
    SpawnAction apkAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "hello_unsigned.apk"));
    assertThat(apkAction.getMnemonic()).isEqualTo("ApkBuilder");
    assertThat(hasInput(apkAction, "hello_optimized.ap_")).isFalse();
  }

  @Test
  public void resourceNameCollapse_flagAbsentProguardSpecsPresent_optimizeArtifactsAbsent()
      throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               shrink_resources = 1,",
        "               proguard_specs = ['proguard-spec.pro'],)");

    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:hello");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    Artifact optimizedResourceApk = getFirstArtifactEndingWith(artifacts, "hello_optimized.ap_");
    assertThat(optimizedResourceApk).isNull();

    // Verify that the optimized APK is not an input to build the unsigned APK.
    SpawnAction apkAction =
        getGeneratingSpawnAction(getFirstArtifactEndingWith(artifacts, "hello_unsigned.apk"));
    assertThat(apkAction.getMnemonic()).isEqualTo("ApkBuilder");
    assertThat(hasInput(apkAction, "hello_optimized.ap_")).isFalse();
  }

  @Test
  public void testResourceShrinking_requiresProguard() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               shrink_resources = 1,)");

    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:hello");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    assertThat(artifacts)
        .containsNoneOf(
            getFirstArtifactEndingWith(artifacts, "shrunk.jar"),
            getFirstArtifactEndingWith(artifacts, "shrunk.ap_"));
  }

  @Test
  public void testProguardExtraOutputs() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro'])");
    ConfiguredTarget output = getConfiguredTarget("//java/com/google/android/hello:b");

    // Checks that ProGuard is called with the appropriate options.
    Artifact a = getFirstArtifactEndingWith(getFilesToBuild(output), "_proguard.jar");
    SpawnAction action = getGeneratingSpawnAction(a);
    List<String> args = getGeneratingSpawnActionArgs(a);

    // Assert that the ProGuard executable set in the android_sdk rule appeared in the command-line
    // of the SpawnAction that generated the _proguard.jar.
    assertThat(args)
        .containsAtLeast(
            getProguardBinary().getExecPathString(),
            "-injars",
            execPathEndingWith(action.getInputs(), "b_deploy.jar"),
            "-printseeds",
            execPathEndingWith(action.getOutputs(), "b_proguard.seeds"),
            "-printusage",
            execPathEndingWith(action.getOutputs(), "b_proguard.usage"))
        .inOrder();

    // Checks that the output files are produced.
    assertProguardUsed(output);
    assertThat(getBinArtifact("b_proguard.usage", output)).isNotNull();
    assertThat(getBinArtifact("b_proguard.seeds", output)).isNotNull();
  }

  @Test
  public void testProGuardExecutableMatchesConfiguration() throws Exception {
    scratch.file(
        "java/com/google/devtools/build/jkrunchy/BUILD",
        "package(default_visibility=['//visibility:public'])",
        "java_binary(name = 'jkrunchy',",
        "            main_class = 'com.google.devtools.build.jkrunchy.JKrunchyMain')");

    useConfiguration("--proguard_top=//java/com/google/devtools/build/jkrunchy:jkrunchy");

    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro'])");

    ConfiguredTarget output = getConfiguredTarget("//java/com/google/android/hello:b_proguard.jar");
    assertProguardUsed(output);

    SpawnAction proguardAction =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(getFilesToBuild(output), "_proguard.jar");
    Artifact jkrunchyExecutable =
        getHostConfiguredTarget("//java/com/google/devtools/build/jkrunchy")
            .getProvider(FilesToRunProvider.class)
            .getExecutable();
    assertWithMessage("ProGuard implementation was not correctly taken from the configuration")
        .that(proguardAction.getCommandFilename())
        .endsWith(jkrunchyExecutable.getRepositoryRelativePathString());
  }

  @Test
  public void enforceProguardFileExtension_disabled_allowsOtherExtensions() throws Exception {
    useConfiguration("--noenforce_proguard_file_extension");
    scratch.file(
        "java/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro'])");

    ConfiguredTarget unused = getConfiguredTarget("//java/android/hello:b");
  }

  @Test
  public void enforceProguardFileExtension_enabled_disallowsOtherExtensions() throws Exception {
    useConfiguration("--enforce_proguard_file_extension");
    scratch.file(
        "java/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro'])");

    AssertionError assertionError =
        assertThrows(AssertionError.class, () -> getConfiguredTarget("//java/android/hello:b"));

    assertThat(assertionError).hasMessageThat().contains("These files do not end in .pgcfg");
  }

  @Test
  public void enforceProguardFileExtension_enabled_allowsPgcfg() throws Exception {
    useConfiguration("--enforce_proguard_file_extension");
    scratch.file(
        "java/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = [':proguard.pgcfg'])");

    ConfiguredTarget unused = getConfiguredTarget("//java/android/hello:b");
  }

  @Test
  public void enforceProguardFileExtension_enabled_ignoresThirdParty() throws Exception {
    useConfiguration("--enforce_proguard_file_extension");
    scratch.file(
        "third_party/bar/BUILD", "licenses(['unencumbered'])", "exports_files(['proguard.pro'])");
    scratch.file(
        "java/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['//third_party/bar:proguard.pro'])");

    ConfiguredTarget unused = getConfiguredTarget("//java/android/hello:b");
  }

  @Test
  public void testNeverlinkTransitivity() throws Exception {
    useConfiguration("--android_fixed_resource_neverlinking");

    scratch.file(
        "java/com/google/android/neversayneveragain/BUILD",
        "android_library(name = 'l1',",
        "                srcs = ['l1.java'],",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['res/values/resource.xml'])",
        "android_library(name = 'l2',",
        "                srcs = ['l2.java'],",
        "                deps = [':l1'],",
        "                neverlink = 1)",
        "android_library(name = 'l3',",
        "                srcs = ['l3.java'],",
        "                deps = [':l2'])",
        "android_library(name = 'l4',",
        "                srcs = ['l4.java'],",
        "                deps = [':l1'])",
        "android_binary(name = 'b1',",
        "               srcs = ['b1.java'],",
        "               deps = [':l2'],",
        "               manifest = 'AndroidManifest.xml')",
        "android_binary(name = 'b2',",
        "               srcs = ['b2.java'],",
        "               deps = [':l3'],",
        "               manifest = 'AndroidManifest.xml')",
        "android_binary(name = 'b3',",
        "               srcs = ['b3.java'],",
        "               deps = [':l3', ':l4'],",
        "               manifest = 'AndroidManifest.xml')");
    ConfiguredTarget b1 = getConfiguredTarget("//java/com/google/android/neversayneveragain:b1");
    Action b1DeployAction =
        actionsTestUtil()
            .getActionForArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(b1)), "b1_deploy.jar");
    List<String> b1Inputs = prettyArtifactNames(b1DeployAction.getInputs());

    assertThat(b1Inputs)
        .containsNoneOf(
            "java/com/google/android/neversayneveragain/libl1.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/libl2.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/libl3.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/libl4.jar_desugared.jar");
    assertThat(b1Inputs)
        .contains("java/com/google/android/neversayneveragain/libb1.jar_desugared.jar");
    assertThat(
            resourceInputPaths(
                "java/com/google/android/neversayneveragain", getValidatedResources(b1)))
        .doesNotContain("res/values/resource.xml");

    ConfiguredTarget b2 = getConfiguredTarget("//java/com/google/android/neversayneveragain:b2");
    Action b2DeployAction =
        actionsTestUtil()
            .getActionForArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(b2)), "b2_deploy.jar");
    List<String> b2Inputs = prettyArtifactNames(b2DeployAction.getInputs());

    assertThat(b2Inputs)
        .containsNoneOf(
            "java/com/google/android/neversayneveragain/libl1.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/libl2.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/libl4.jar_desugared.jar");
    assertThat(b2Inputs)
        .containsAtLeast(
            "java/com/google/android/neversayneveragain/_dx/l3/libl3.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/libb2.jar_desugared.jar");
    assertThat(
            resourceInputPaths(
                "java/com/google/android/neversayneveragain", getValidatedResources(b2)))
        .doesNotContain("res/values/resource.xml");

    ConfiguredTarget b3 = getConfiguredTarget("//java/com/google/android/neversayneveragain:b3");
    Action b3DeployAction =
        actionsTestUtil()
            .getActionForArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(b3)), "b3_deploy.jar");
    List<String> b3Inputs = prettyArtifactNames(b3DeployAction.getInputs());

    assertThat(b3Inputs)
        .containsAtLeast(
            "java/com/google/android/neversayneveragain/_dx/l1/libl1.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/_dx/l3/libl3.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/_dx/l4/libl4.jar_desugared.jar",
            "java/com/google/android/neversayneveragain/libb3.jar_desugared.jar");
    assertThat(b3Inputs)
        .doesNotContain("java/com/google/android/neversayneveragain/libl2.jar_desugared.jar");
    assertThat(
            resourceInputPaths(
                "java/com/google/android/neversayneveragain", getValidatedResources(b3)))
        .contains("res/values/resource.xml");
  }

  @Test
  public void testDexopts() throws Exception {
    useConfiguration("--noincremental_dexing");
    checkDexopts("[ '--opt1', '--opt2' ]", ImmutableList.of("--opt1", "--opt2"));
  }

  @Test
  public void testDexoptsTokenization() throws Exception {
    useConfiguration("--noincremental_dexing");
    checkDexopts(
        "[ '--opt1', '--opt2 tokenized' ]", ImmutableList.of("--opt1", "--opt2", "tokenized"));
  }

  @Test
  public void testDexoptsMakeVariableSubstitution() throws Exception {
    useConfiguration("--noincremental_dexing");
    checkDexopts("[ '--opt1', '$(COMPILATION_MODE)' ]", ImmutableList.of("--opt1", "fastbuild"));
  }

  private void checkDexopts(String dexopts, List<String> expectedArgs) throws Exception {
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(name = 'b',",
        "    srcs = ['dummy1.java'],",
        "    dexopts = " + dexopts + ",",
        "    manifest = 'AndroidManifest.xml')");

    // Include arguments that are always included.
    ImmutableList<String> fixedArgs = ImmutableList.of("--multi-dex");
    expectedArgs =
        new ImmutableList.Builder<String>().addAll(expectedArgs).addAll(fixedArgs).build();

    // Ensure that the args that immediately follow "--dex" match the expectation.
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android:b");
    List<String> args =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)),
                "intermediate_classes.dex.zip"));
    int start = args.indexOf("--dex") + 1;
    assertThat(start).isNotEqualTo(0);
    int end = Math.min(args.size(), start + expectedArgs.size());
    assertThat(args.subList(start, end)).isEqualTo(expectedArgs);
  }

  @Test
  public void testDexMainListOpts() throws Exception {
    checkDexMainListOpts("[ '--opt1', '--opt2' ]", "--opt1", "--opt2");
  }

  @Test
  public void testDexMainListOptsTokenization() throws Exception {
    checkDexMainListOpts("[ '--opt1', '--opt2 tokenized' ]", "--opt1", "--opt2", "tokenized");
  }

  @Test
  public void testDexMainListOptsMakeVariableSubstitution() throws Exception {
    checkDexMainListOpts("[ '--opt1', '$(COMPILATION_MODE)' ]", "--opt1", "fastbuild");
  }

  private void checkDexMainListOpts(String mainDexListOpts, String... expectedArgs)
      throws Exception {
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(name = 'b',",
        "    srcs = ['dummy1.java'],",
        "    multidex = \"legacy\",",
        "    main_dex_list_opts = " + mainDexListOpts + ",",
        "    manifest = 'AndroidManifest.xml')");

    // Ensure that the args that immediately follow the main class in the shell command
    // match the expectation.
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android:b");
    List<String> args =
        getGeneratingSpawnActionArgs(
            ActionsTestUtil.getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "main_dex_list.txt"));

    // args: [ "bash", "-c", "java -cp dx.jar main opts other" ]
    MoreAsserts.assertContainsSublist(args, expectedArgs);
  }

  @Test
  public void omitResourcesInfoProviderFromAndroidBinary_enabled() throws Exception {
    useConfiguration("--experimental_omit_resources_info_provider_from_android_binary");
    ConfiguredTarget binary =
        scratchConfiguredTarget(
            "java/com/pkg/myapp",
            "myapp",
            "android_binary(",
            "  name = 'myapp',",
            "  manifest = 'AndroidManifest.xml',",
            ")");

    assertThat(binary.get(AndroidResourcesInfo.PROVIDER)).isNull();
  }

  @Test
  public void omitResourcesInfoProviderFromAndroidBinary_disabled() throws Exception {
    useConfiguration("--noexperimental_omit_resources_info_provider_from_android_binary");
    ConfiguredTarget binary =
        scratchConfiguredTarget(
            "java/com/pkg/myapp",
            "myapp",
            "android_binary(",
            "  name = 'myapp',",
            "  manifest = 'AndroidManifest.xml',",
            ")");

    assertThat(binary.get(AndroidResourcesInfo.PROVIDER)).isNotNull();
  }

  @Test
  public void testResourceConfigurationFilters() throws Exception {
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(name = 'b',",
        "    srcs = ['dummy1.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    resource_configuration_filters = [ 'en', 'fr'],)");

    // Ensure that the args are present
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android:b");
    List<String> args = resourceArguments(getValidatedResources(binary));
    assertThat(flagValue("--resourceConfigs", args)).contains("en,fr");
  }

  /** Test that resources are not filtered in analysis under aapt2. */
  @Test
  public void testFilteredResourcesFilteringAapt2() throws Exception {
    List<String> resources =
        ImmutableList.of("res/values/foo.xml", "res/values-en/foo.xml", "res/values-fr/foo.xml");
    String dir = "java/r/android";

    ConfiguredTarget binary =
        scratchConfiguredTarget(
            dir,
            "r",
            "android_binary(name = 'r',",
            "  manifest = 'AndroidManifest.xml',",
            "  resource_configuration_filters = ['', 'en, es, '],",
            "  densities = ['hdpi, , ', 'xhdpi'],",
            "  resource_files = ['" + Joiner.on("', '").join(resources) + "'])");
    ValidatedAndroidResources directResources =
        getValidatedResources(binary, /* transitive= */ false);

    // Validate that the AndroidResourceProvider for this binary contains all values.
    assertThat(resourceContentsPaths(dir, directResources)).containsExactlyElementsIn(resources);

    // Validate that the input to resource processing contains all values.
    assertThat(resourceInputPaths(dir, directResources)).containsAtLeastElementsIn(resources);

    // Validate that the filters are correctly passed to the resource processing action
    // This includes trimming whitespace and ignoring empty filters.
    assertThat(resourceArguments(directResources)).contains("en,es");
    assertThat(resourceArguments(directResources)).contains("hdpi,xhdpi");
  }

  @Test
  public void testFilterResourcesPseudolocalesPropagated() throws Exception {
    String dir = "java/r/android";
    ConfiguredTarget binary =
        scratchConfiguredTarget(
            dir,
            "bin",
            "android_binary(name = 'bin',",
            "  resource_configuration_filters = ['en', 'en-rXA', 'ar-rXB'],",
            "  manifest = 'AndroidManifest.xml')");

    List<String> resourceProcessingArgs =
        getGeneratingSpawnActionArgs(getValidatedResources(binary).getRTxt());

    assertThat(resourceProcessingArgs).containsAtLeast("--resourceConfigs", "ar-rXB,en,en-rXA");
  }

  /**
   * Gets the paths of matching artifacts contained within a resource container
   *
   * @param dir the directory to look for artifacts in
   * @param resource the container that contains eligible artifacts
   * @return the paths to all artifacts from the input that are contained within the given
   *     directory, relative to that directory.
   */
  private List<String> resourceContentsPaths(String dir, ValidatedAndroidResources resource) {
    return pathsToArtifacts(dir, resource.getArtifacts());
  }

  /**
   * Gets the paths of matching artifacts that are used as input to resource processing
   *
   * @param dir the directory to look for artifacts in
   * @param resource the output from the resource processing that uses these artifacts as inputs
   * @return the paths to all artifacts used as inputs to resource processing that are contained
   *     within the given directory, relative to that directory.
   */
  private List<String> resourceInputPaths(String dir, ValidatedAndroidResources resource) {
    return pathsToArtifacts(dir, resourceGeneratingAction(resource).getInputs().toList());
  }

  /**
   * Gets the paths of matching artifacts from an iterable
   *
   * @param dir the directory to look for artifacts in
   * @param artifacts all available artifacts
   * @return the paths to all artifacts from the input that are contained within the given
   *     directory, relative to that directory.
   */
  private List<String> pathsToArtifacts(String dir, Iterable<Artifact> artifacts) {
    List<String> paths = new ArrayList<>();

    Path containingDir = rootDirectory;
    for (String part : dir.split("/")) {
      containingDir = containingDir.getChild(part);
    }

    for (Artifact a : artifacts) {
      if (a.getPath().startsWith(containingDir)) {
        paths.add(a.getPath().relativeTo(containingDir).toString());
      }
    }

    return paths;
  }

  @Test
  public void testInheritedRNotInRuntimeJars() throws Exception {
    String dir = "java/r/android/";
    scratch.file(
        dir + "BUILD",
        "android_library(name = 'sublib',",
        "                manifest = 'AndroidManifest.xml',",
        "                srcs =['sublib.java'],",
        "                )",
        "android_library(name = 'lib',",
        "                manifest = 'AndroidManifest.xml',",
        "                deps = [':sublib'],",
        "                srcs =['lib.java'],",
        "                )",
        "android_binary(name = 'bin',",
        "               manifest = 'AndroidManifest.xml',",
        "               deps = [':lib'],",
        "               srcs =['bin.java'],",
        "               )");

    Action deployJarAction =
        getGeneratingAction(
            getFileConfiguredTarget("//java/r/android:bin_deploy.jar").getArtifact());
    List<String> inputs = ActionsTestUtil.baseArtifactNames(deployJarAction.getInputs());

    assertThat(inputs)
        .containsAtLeast(
            "libsublib.jar_desugared.jar",
            "liblib.jar_desugared.jar",
            "libbin.jar_desugared.jar",
            "bin_resources.jar_desugared.jar");
    assertThat(inputs)
        .containsNoneOf("lib_resources.jar_desugared.jar", "sublib_resources.jar_desugared.jar");
  }

  @Test
  public void testLocalResourcesUseRClassGenerator() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_library(name = 'lib',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = glob(['res2/**']),",
        "                )",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               deps = [':lib'],",
        "               )");
    scratch.file(
        "java/r/android/res2/values/strings.xml",
        "<resources><string name = 'lib_string'>Libs!</string></resources>");
    scratch.file(
        "java/r/android/res/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    Artifact jar = getResourceClassJar(getConfiguredTargetAndData("//java/r/android:r"));
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    assertThat(getGeneratingSpawnActionArgs(jar))
        .containsAtLeast("--primaryRTxt", "--primaryManifest", "--library", "--classJarOutput");
  }

  @Test
  public void testLocalResourcesUseRClassGeneratorNoLibraries() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               )");
    scratch.file(
        "java/r/android/res/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    Artifact jar = getResourceClassJar(getConfiguredTargetAndData("//java/r/android:r"));
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    List<String> args = getGeneratingSpawnActionArgs(jar);
    assertThat(args).containsAtLeast("--primaryRTxt", "--primaryManifest", "--classJarOutput");
    assertThat(args).doesNotContain("--libraries");
  }

  @Test
  public void testUseRClassGeneratorCustomPackage() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_library(name = 'lib',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = glob(['res2/**']),",
        "                custom_package = 'com.lib.custom',",
        "                )",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = glob(['res/**']),",
        "               custom_package = 'com.binary.custom',",
        "               deps = [':lib'],",
        "               )");
    scratch.file(
        "java/r/android/res2/values/strings.xml",
        "<resources><string name = 'lib_string'>Libs!</string></resources>");
    scratch.file(
        "java/r/android/res/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    ConfiguredTargetAndData binary = getConfiguredTargetAndData("//java/r/android:r");
    Artifact jar = getResourceClassJar(binary);
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    List<String> args = getGeneratingSpawnActionArgs(jar);
    assertThat(args)
        .containsAtLeast(
            "--primaryRTxt",
            "--primaryManifest",
            "--library",
            "--classJarOutput",
            "--packageForR",
            "com.binary.custom");
  }

  @Test
  public void testUseRClassGeneratorMultipleDeps() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_library(name = 'lib1',",
        "                manifest = 'AndroidManifest.xml',",
        "                )",
        "android_library(name = 'lib2',",
        "                manifest = 'AndroidManifest.xml',",
        "                )",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               deps = [':lib1', ':lib2'],",
        "               )");
    ConfiguredTargetAndData binary = getConfiguredTargetAndData("//java/r/android:r");
    Artifact jar = getResourceClassJar(binary);
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    List<String> args = getGeneratingSpawnActionArgs(jar);

    AndroidResourcesInfo resourcesInfo =
        binary.getConfiguredTarget().get(AndroidResourcesInfo.PROVIDER);
    assertThat(resourcesInfo.getTransitiveAndroidResources().toList()).hasSize(2);
    ValidatedAndroidResources firstDep =
        resourcesInfo.getTransitiveAndroidResources().toList().get(0);
    ValidatedAndroidResources secondDep =
        resourcesInfo.getTransitiveAndroidResources().toList().get(1);

    assertThat(args)
        .containsAtLeast(
            "--primaryRTxt",
            "--primaryManifest",
            "--library",
            firstDep.getAapt2RTxt().getExecPathString()
                + ","
                + firstDep.getManifest().getExecPathString(),
            "--library",
            secondDep.getAapt2RTxt().getExecPathString()
                + ","
                + secondDep.getManifest().getExecPathString(),
            "--classJarOutput")
        .inOrder();
  }

  @Test
  public void useRTxtFromMergedResourcesForFinalRClasses() throws Exception {
    useConfiguration("--experimental_use_rtxt_from_merged_resources");
    scratch.file(
        "java/pkg/BUILD",
        "android_library(",
        "    name = 'lib',",
        "    srcs = ['B.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    resource_files = [ 'res/values/values.xml' ], ",
        ")",
        "android_binary(",
        "    name = 'bin',",
        "    manifest = 'AndroidManifest.xml',",
        "    deps = [ ':lib' ],",
        ")");

    ConfiguredTargetAndData bin = getConfiguredTargetAndData("//java/pkg:bin");
    ConfiguredTarget lib = getDirectPrerequisite(bin.getConfiguredTarget(), "//java/pkg:lib");
    ValidatedAndroidResources libResources =
        lib.get(AndroidResourcesInfo.PROVIDER).getDirectAndroidResources().toList().get(0);
    SpawnAction topLevelResourceClassAction = getGeneratingSpawnAction(getResourceClassJar(bin));

    // verify that the R.txt from creating the library-level resources.jar is also used for creating
    // the top-level resources.jar
    assertThat(getGeneratingSpawnAction(libResources.getClassJar()).getOutputs())
        .contains(libResources.getAapt2RTxt());
    MoreAsserts.assertContainsSublist(
        topLevelResourceClassAction.getArguments(),
        "--library",
        libResources.getAapt2RTxt().getExecPathString()
            + ","
            + libResources.getManifest().getExecPathString());

    // the "validation artifact" shouldn't be used for creating the top-level resources.jar,
    // but it's still fed as an pseudo-input to trigger validation.
    MoreAsserts.assertDoesNotContainSublist(
        topLevelResourceClassAction.getArguments(),
        "--library",
        libResources.getAapt2ValidationArtifact().getExecPathString()
            + ","
            + libResources.getManifest().getExecPathString());
    assertThat(topLevelResourceClassAction.getInputs().toList())
        .contains(libResources.getAapt2ValidationArtifact());
  }

  // (test for undesired legacy behavior)
  @Test
  public void doNotUseRTxtFromMergedResourcesForFinalRClasses() throws Exception {
    scratch.file(
        "java/pkg/BUILD",
        "android_library(",
        "    name = 'lib',",
        "    srcs = ['B.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    resource_files = [ 'res/values/values.xml' ], ",
        ")",
        "android_binary(",
        "    name = 'bin',",
        "    manifest = 'AndroidManifest.xml',",
        "    deps = [ ':lib' ],",
        ")");

    ConfiguredTargetAndData bin = getConfiguredTargetAndData("//java/pkg:bin");
    ConfiguredTarget lib = getDirectPrerequisite(bin.getConfiguredTarget(), "//java/pkg:lib");
    ValidatedAndroidResources libResources =
        lib.get(AndroidResourcesInfo.PROVIDER).getDirectAndroidResources().toList().get(0);

    // use the "validation artifact" for creating the top-level resources.jar
    MoreAsserts.assertContainsSublist(
        getGeneratingSpawnActionArgs(getResourceClassJar(bin)),
        "--library",
        libResources.getAapt2ValidationArtifact().getExecPathString()
            + ","
            + libResources.getManifest().getExecPathString());
  }

  @Test
  public void testNoCrunchBinaryOnly() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/drawable-hdpi-v4/foo.png',",
        "                                 'res/drawable-hdpi-v4/bar.9.png'],",
        "               crunch_png = 0,",
        "               )");
    ConfiguredTarget binary = getConfiguredTarget("//java/r/android:r");
    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(binary));
    assertThat(args).contains("--useAaptCruncher=no");
  }

  @Test
  public void testDoCrunch() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/drawable-hdpi-v4/foo.png',",
        "                                 'res/drawable-hdpi-v4/bar.9.png'],",
        "               crunch_png = 1,",
        "               )");
    ConfiguredTarget binary = getConfiguredTarget("//java/r/android:r");
    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(binary));
    assertThat(args).doesNotContain("--useAaptCruncher=no");
  }

  @Test
  public void testDoCrunchDefault() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/drawable-hdpi-v4/foo.png',",
        "                                 'res/drawable-hdpi-v4/bar.9.png'],",
        "               )");
    ConfiguredTarget binary = getConfiguredTarget("//java/r/android:r");
    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(binary));
    assertThat(args).doesNotContain("--useAaptCruncher=no");
  }

  @Test
  public void testNoCrunchWithAndroidLibraryNoBinaryResources() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_library(name = 'resources',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['res/values/strings.xml',",
        "                                  'res/drawable-hdpi-v4/foo.png',",
        "                                  'res/drawable-hdpi-v4/bar.9.png'],",
        "               )",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               deps = [':resources'],",
        "               crunch_png = 0,",
        "               )");
    ConfiguredTarget binary = getConfiguredTarget("//java/r/android:r");
    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(binary));
    assertThat(args).contains("--useAaptCruncher=no");
  }

  @Test
  public void testNoCrunchWithMultidexNative() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_library(name = 'resources',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['res/values/strings.xml',",
        "                                  'res/drawable-hdpi-v4/foo.png',",
        "                                  'res/drawable-hdpi-v4/bar.9.png'],",
        "               )",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               deps = [':resources'],",
        "               multidex = 'native',",
        "               crunch_png = 0,",
        "               )");
    ConfiguredTarget binary = getConfiguredTarget("//java/r/android:r");
    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(binary));
    assertThat(args).contains("--useAaptCruncher=no");
  }

  @Test
  public void testZipaligned() throws Exception {
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");
    Artifact a =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "zipaligned_app.apk");
    SpawnAction action = getGeneratingSpawnAction(a);

    assertThat(action.getMnemonic()).isEqualTo("AndroidZipAlign");

    List<String> arguments = getGeneratingSpawnActionArgs(a);
    assertThat(arguments).contains("-p");
    assertThat(arguments).contains("4");

    Artifact zipAlignTool = getFirstArtifactEndingWith(action.getInputs(), "/zipalign");
    assertThat(arguments).contains(zipAlignTool.getExecPathString());

    Artifact unsignedApk = getFirstArtifactEndingWith(action.getInputs(), "/app_unsigned.apk");
    assertThat(arguments).contains(unsignedApk.getExecPathString());

    Artifact zipalignedApk = getFirstArtifactEndingWith(action.getOutputs(), "/zipaligned_app.apk");
    assertThat(arguments).contains(zipalignedApk.getExecPathString());
  }

  @Test
  public void testDeployInfo() throws Exception {
    ConfiguredTarget binary = getConfiguredTarget("//java/android:app");
    NestedSet<Artifact> outputGroup = getOutputGroup(binary, "android_deploy_info");
    Artifact deployInfoArtifact =
        ActionsTestUtil.getFirstArtifactEndingWith(outputGroup, "/deploy_info.deployinfo.pb");
    assertThat(deployInfoArtifact).isNotNull();
    AndroidDeployInfo deployInfo = getAndroidDeployInfo(deployInfoArtifact);
    assertThat(deployInfo).isNotNull();
    assertThat(deployInfo.getMergedManifest().getExecRootPath()).endsWith("/AndroidManifest.xml");
    assertThat(deployInfo.getAdditionalMergedManifestsList()).isEmpty();
    assertThat(deployInfo.getApksToDeploy(0).getExecRootPath()).endsWith("/app.apk");
    Artifact mergedManifest =
        ActionsTestUtil.getFirstArtifactEndingWith(outputGroup, "/AndroidManifest.xml");
    assertThat(mergedManifest).isNotNull();
  }

  /**
   * Internal helper method: checks that dex sharding input and output is correct for different
   * combinations of multidex mode and build with and without proguard.
   */
  private void internalTestDexShardStructure(
      MultidexMode multidexMode, boolean proguard, String nonProguardSuffix) throws Exception {
    ConfiguredTarget target = getConfiguredTarget("//java/a:a");
    assertNoEvents();
    Action shardAction = getGeneratingAction(getBinArtifact("_dx/a/shard1.jar", target));

    // Verify command line arguments
    List<String> arguments = ((SpawnAction) shardAction).getRemainingArguments();
    List<String> expectedArguments = new ArrayList<>();
    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(target));
    Artifact shard1 = getFirstArtifactEndingWith(artifacts, "shard1.jar");
    Artifact shard2 = getFirstArtifactEndingWith(artifacts, "shard2.jar");
    Artifact resourceJar = getFirstArtifactEndingWith(artifacts, "/java_resources.jar");
    expectedArguments.add("--output_jar");
    expectedArguments.add(shard1.getExecPathString());
    expectedArguments.add("--output_jar");
    expectedArguments.add(shard2.getExecPathString());
    expectedArguments.add("--output_resources");
    expectedArguments.add(resourceJar.getExecPathString());
    if (multidexMode == MultidexMode.LEGACY) {
      Artifact mainDexList = getFirstArtifactEndingWith(artifacts, "main_dex_list.txt");
      expectedArguments.add("--main_dex_filter");
      expectedArguments.add(mainDexList.getExecPathString());
    }
    if (!proguard) {
      expectedArguments.add("--input_jar");
      expectedArguments.add(
          getFirstArtifactEndingWith(artifacts, "a_resources.jar" + nonProguardSuffix)
              .getExecPathString());
    }
    Artifact inputJar;
    if (proguard) {
      inputJar = getFirstArtifactEndingWith(artifacts, "a_proguard.jar");
    } else {
      inputJar = getFirstArtifactEndingWith(artifacts, "liba.jar" + nonProguardSuffix);
    }
    expectedArguments.add("--input_jar");
    expectedArguments.add(inputJar.getExecPathString());
    assertThat(arguments).containsExactlyElementsIn(expectedArguments).inOrder();

    // Verify input and output artifacts
    List<String> shardOutputs = ActionsTestUtil.baseArtifactNames(shardAction.getOutputs());
    List<String> shardInputs = ActionsTestUtil.baseArtifactNames(shardAction.getInputs());
    assertThat(shardOutputs).containsExactly("shard1.jar", "shard2.jar", "java_resources.jar");
    if (multidexMode == MultidexMode.LEGACY) {
      assertThat(shardInputs).contains("main_dex_list.txt");
    } else {
      assertThat(shardInputs).doesNotContain("main_dex_list.txt");
    }
    if (proguard) {
      assertThat(shardInputs).contains("a_proguard.jar");
      assertThat(shardInputs).doesNotContain("liba.jar" + nonProguardSuffix);
    } else {
      assertThat(shardInputs).contains("liba.jar" + nonProguardSuffix);
      assertThat(shardInputs).doesNotContain("a_proguard.jar");
    }
    assertThat(shardInputs).doesNotContain("a_deploy.jar");

    // Verify that dex compilation is followed by the correct merge operation
    Action apkAction =
        getGeneratingAction(
            getFirstArtifactEndingWith(
                actionsTestUtil().artifactClosureOf(getFilesToBuild(target)),
                "compressed_a_unsigned.apk"));
    Action mergeAction =
        getGeneratingAction(getFirstArtifactEndingWith(apkAction.getInputs(), "classes.dex.zip"));
    Iterable<Artifact> dexShards =
        Iterables.filter(
            mergeAction.getInputs().toList(), ActionsTestUtil.getArtifactSuffixMatcher(".dex.zip"));
    assertThat(ActionsTestUtil.baseArtifactNames(dexShards))
        .containsExactly("shard1.dex.zip", "shard2.dex.zip");
  }

  @Test
  public void testDexShardingDoesNotWorkWithManualMultidex() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='manual_main_dex',",
        "    main_dex_list='main_dex_list.txt',",
        "    manifest='AndroidManifest.xml')");
    reporter.removeHandler(failFastHandler);
    getConfiguredTarget("//java/a:a");
    assertContainsEvent(".dex sharding is not available in manual multidex mode");
  }

  @Test
  public void testDexShardingLegacyStructure() throws Exception {
    useConfiguration("--noincremental_dexing");
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='legacy',",
        "    manifest='AndroidManifest.xml')");

    internalTestDexShardStructure(MultidexMode.LEGACY, false, "_desugared.jar");
  }

  @Test
  public void testDexShardingNativeStructure_withNoDesugaring() throws Exception {
    useConfiguration("--noexperimental_desugar_for_android", "--noincremental_dexing");
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='native',",
        "    manifest='AndroidManifest.xml')");

    internalTestDexShardStructure(MultidexMode.NATIVE, false, "");
  }

  @Test
  public void testDexShardingNativeStructure() throws Exception {
    useConfiguration("--noincremental_dexing");
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='native',",
        "    manifest='AndroidManifest.xml')");

    internalTestDexShardStructure(MultidexMode.NATIVE, false, "_desugared.jar");
  }

  @Test
  public void testDexShardingLegacyAndProguardStructure_withNoDesugaring() throws Exception {
    useConfiguration(
        "--noexperimental_desugar_for_android",
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='legacy',",
        "    manifest='AndroidManifest.xml',",
        "    proguard_specs=['proguard.cfg'])");

    internalTestDexShardStructure(MultidexMode.LEGACY, true, "");
  }

  @Test
  public void testDexShardingLegacyAndProguardStructure() throws Exception {
    useConfiguration(
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='legacy',",
        "    manifest='AndroidManifest.xml',",
        "    proguard_specs=['proguard.cfg'])");

    internalTestDexShardStructure(MultidexMode.LEGACY, true, "_desugared.jar");
  }

  @Test
  public void testDexShardingNativeAndProguardStructure() throws Exception {
    useConfiguration(
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='native',",
        "    manifest='AndroidManifest.xml',",
        "    proguard_specs=['proguard.cfg'])");

    internalTestDexShardStructure(MultidexMode.NATIVE, true, "");
  }

  @Test
  public void testIncrementalApkAndProguardBuildStructure() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name='a',",
        "    srcs=['A.java'],",
        "    dex_shards=2,",
        "    multidex='native',",
        "    manifest='AndroidManifest.xml',",
        "    proguard_specs=['proguard.cfg'])");

    ConfiguredTarget target = getConfiguredTarget("//java/a:a");
    Action shardAction = getGeneratingAction(getBinArtifact("_dx/a/shard1.jar", target));
    List<String> shardOutputs = ActionsTestUtil.baseArtifactNames(shardAction.getOutputs());
    assertThat(shardOutputs).contains("java_resources.jar");
    assertThat(shardOutputs).doesNotContain("a_deploy.jar");
  }

  @Test
  public void testManualMainDexBuildStructure() throws Exception {
    checkError(
        "java/foo",
        "maindex_nomultidex",
        "Both \"main_dex_list\" and \"multidex='manual_main_dex'\" must be specified",
        "android_binary(",
        "    name = 'maindex_nomultidex',",
        "    srcs = ['a.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'manual_main_dex')");
  }

  @Test
  public void testMainDexListLegacyMultidex() throws Exception {
    checkError(
        "java/foo",
        "maindex_nomultidex",
        "Both \"main_dex_list\" and \"multidex='manual_main_dex'\" must be specified",
        "android_binary(",
        "    name = 'maindex_nomultidex',",
        "    srcs = ['a.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'legacy',",
        "    main_dex_list = 'main_dex_list.txt')");
  }

  @Test
  public void testMainDexListNativeMultidex() throws Exception {
    checkError(
        "java/foo",
        "maindex_nomultidex",
        "Both \"main_dex_list\" and \"multidex='manual_main_dex'\" must be specified",
        "android_binary(",
        "    name = 'maindex_nomultidex',",
        "    srcs = ['a.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'native',",
        "    main_dex_list = 'main_dex_list.txt')");
  }

  @Test
  public void testMainDexListNoMultidex() throws Exception {
    checkError(
        "java/foo",
        "maindex_nomultidex",
        "Both \"main_dex_list\" and \"multidex='manual_main_dex'\" must be specified",
        "android_binary(",
        "    name = 'maindex_nomultidex',",
        "    srcs = ['a.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    main_dex_list = 'main_dex_list.txt')");
  }

  @Test
  public void testMainDexListWithAndroidSdk() throws Exception {
    scratch.file(
        "sdk/BUILD",
        "android_sdk(",
        "    name = 'sdk',",
        "    aapt = 'aapt',",
        "    aapt2 = 'aapt2',",
        "    adb = 'adb',",
        "    aidl = 'aidl',",
        "    android_jar = 'android.jar',",
        "    apksigner = 'apksigner',",
        "    dx = 'dx',",
        "    framework_aidl = 'framework_aidl',",
        "    main_dex_classes = 'main_dex_classes',",
        "    main_dex_list_creator = 'main_dex_list_creator',",
        "    proguard = 'proguard',",
        "    shrinked_android_jar = 'shrinked_android_jar',",
        "    zipalign = 'zipalign',",
        "    tags = ['__ANDROID_RULES_MIGRATION__'])");

    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'legacy',",
        "    main_dex_list_opts = ['--hello', '--world'])");

    useConfiguration("--android_sdk=//sdk:sdk");
    ConfiguredTarget a = getConfiguredTarget("//java/a:a");
    Artifact mainDexList =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(a)), "main_dex_list.txt");
    List<String> args = getGeneratingSpawnActionArgs(mainDexList);
    assertThat(args).containsAtLeast("--hello", "--world");
  }

  @Test
  public void testLegacyMainDexListWithAndroidSdk() throws Exception {
    scratch.file(
        "tools/fake/BUILD",
        "cc_binary(",
        "    name = 'generate_main_dex_list',",
        "    srcs = ['main.cc'])");

    scratch.file(
        "sdk/BUILD",
        "android_sdk(",
        "    name = 'sdk',",
        "    aapt = 'aapt',",
        "    aapt2 = 'aapt2',",
        "    adb = 'adb',",
        "    aidl = 'aidl',",
        "    android_jar = 'android.jar',",
        "    apksigner = 'apksigner',",
        "    dx = 'dx',",
        "    framework_aidl = 'framework_aidl',",
        "    main_dex_classes = 'main_dex_classes',",
        "    main_dex_list_creator = 'main_dex_list_creator',",
        "    proguard = 'proguard',",
        "    shrinked_android_jar = 'shrinked_android_jar',",
        "    zipalign = 'zipalign',",
        "    legacy_main_dex_list_generator = '//tools/fake:generate_main_dex_list',",
        "    tags = ['__ANDROID_RULES_MIGRATION__'])");

    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'legacy')");

    useConfiguration("--android_sdk=//sdk:sdk");
    ConfiguredTarget a = getConfiguredTarget("//java/a:a");
    Artifact mainDexList =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(a)), "main_dex_list.txt");
    List<String> args = getGeneratingSpawnActionArgs(mainDexList);
    NestedSet<Artifact> mainDexInputs = getGeneratingAction(mainDexList).getInputs();

    MoreAsserts.assertContainsSublist(args, "--lib", "sdk/android.jar");
    assertThat(ActionsTestUtil.baseArtifactNames(mainDexInputs)).contains("generate_main_dex_list");
    assertThat(ActionsTestUtil.baseArtifactNames(mainDexInputs)).contains("a_deploy.jar");
    assertThat(getFirstArtifactEndingWith(mainDexInputs, "main_dex_list_creator")).isNull();
  }

  @Test
  public void testMainDexAaptGenerationSupported() throws Exception {
    useConfiguration("--android_sdk=//sdk:sdk", "--noincremental_dexing");
    scratch.file(
        "sdk/BUILD",
        "android_sdk(",
        "    name = 'sdk',",
        "    build_tools_version = '24.0.0',",
        "    aapt = 'aapt',",
        "    aapt2 = 'aapt2',",
        "    adb = 'adb',",
        "    aidl = 'aidl',",
        "    android_jar = 'android.jar',",
        "    apksigner = 'apksigner',",
        "    dx = 'dx',",
        "    framework_aidl = 'framework_aidl',",
        "    main_dex_classes = 'main_dex_classes',",
        "    main_dex_list_creator = 'main_dex_list_creator',",
        "    proguard = 'proguard',",
        "    shrinked_android_jar = 'shrinked_android_jar',",
        "    zipalign = 'zipalign',",
        "    tags = ['__ANDROID_RULES_MIGRATION__'])");

    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'legacy')");

    ConfiguredTargetAndData a = getConfiguredTargetAndData("//java/a:a");
    Artifact intermediateJar =
        artifactByPath(
            ImmutableList.of(getCompressedUnsignedApk(a.getConfiguredTarget())),
            ".apk",
            ".dex.zip",
            ".dex.zip",
            "main_dex_list.txt",
            "_intermediate.jar");
    List<String> args = getGeneratingSpawnActionArgs(intermediateJar);
    assertContainsSublist(
        args,
        ImmutableList.of(
            "-include",
            a.getConfiguration().getBinFragment(RepositoryName.MAIN)
                + "/java/a/proguard/a/main_dex_a_proguard.cfg"));
  }

  @Test
  public void testMainDexGenerationWithoutProguardMap() throws Exception {
    useConfiguration("--noincremental_dexing");
    scratchConfiguredTarget(
        "java/foo",
        "abin",
        "android_binary(",
        "    name = 'abin',",
        "    srcs = ['a.java'],",
        "    proguard_specs = [],",
        "    manifest = 'AndroidManifest.xml',",
        "    multidex = 'legacy',)");
    ConfiguredTarget a = getConfiguredTarget("//java/foo:abin");
    Artifact intermediateJar =
        artifactByPath(
            ImmutableList.of(getCompressedUnsignedApk(a)),
            ".apk",
            ".dex.zip",
            ".dex.zip",
            "main_dex_list.txt",
            "_intermediate.jar");
    List<String> args = getGeneratingSpawnActionArgs(intermediateJar);
    MoreAsserts.assertDoesNotContainSublist(args, "-previousobfuscationmap");
  }

  // regression test for b/14288948
  @Test
  public void testEmptyListAsProguardSpec() throws Exception {
    scratch.file(
        "java/foo/BUILD",
        "android_binary(",
        "    name = 'abin',",
        "    srcs = ['a.java'],",
        "    proguard_specs = [],",
        "    manifest = 'AndroidManifest.xml')");
    Rule rule = getTarget("//java/foo:abin").getAssociatedRule();
    assertNoEvents();
    ImmutableList<String> implicitOutputFilenames =
        rule.getOutputFiles().stream().map(FileTarget::getName).collect(toImmutableList());
    assertThat(implicitOutputFilenames).doesNotContain("abin_proguard.jar");
  }

  @Test
  public void testConfigurableProguardSpecsEmptyList() throws Exception {
    scratch.file(
        "java/foo/BUILD",
        "android_binary(",
        "    name = 'abin',",
        "    srcs = ['a.java'],",
        "    proguard_specs = select({",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [],",
        "    }),",
        "    manifest = 'AndroidManifest.xml')");
    Rule rule = getTarget("//java/foo:abin").getAssociatedRule();
    assertNoEvents();
    ImmutableList<String> implicitOutputFilenames =
        rule.getOutputFiles().stream().map(FileTarget::getName).collect(toImmutableList());
    assertThat(implicitOutputFilenames).contains("abin_proguard.jar");
  }

  @Test
  public void testConfigurableProguardSpecsEmptyListWithMapping() throws Exception {
    scratchConfiguredTarget(
        "java/foo",
        "abin",
        "android_binary(",
        "    name = 'abin',",
        "    srcs = ['a.java'],",
        "    proguard_specs = select({",
        "        '" + BuildType.Selector.DEFAULT_CONDITION_KEY + "': [],",
        "    }),",
        "    proguard_generate_mapping = 1,",
        "    manifest = 'AndroidManifest.xml')");
    assertNoEvents();
  }

  @Test
  public void testResourcesWithConfigurationQualifier_localResources() throws Exception {
    scratch.file(
        "java/android/resources/BUILD",
        "android_binary(name = 'r',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = glob(['res/**']),",
        "                )");
    scratch.file(
        "java/android/resources/res/values-en/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    scratch.file(
        "java/android/resources/res/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    ConfiguredTarget resource = getConfiguredTarget("//java/android/resources:r");

    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(resource));

    assertPrimaryResourceDirs(ImmutableList.of("java/android/resources/res"), args);
  }

  @Test
  public void testResourcesInOtherPackage_exported_localResources() throws Exception {
    scratch.file(
        "java/android/resources/BUILD",
        "android_binary(name = 'r',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['//java/resources/other:res/values/strings.xml'],",
        "                )");
    scratch.file("java/resources/other/BUILD", "exports_files(['res/values/strings.xml'])");
    ConfiguredTarget resource = getConfiguredTarget("//java/android/resources:r");

    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(resource));
    assertPrimaryResourceDirs(ImmutableList.of("java/resources/other/res"), args);
    assertNoEvents();
  }

  @Test
  public void testResourcesInOtherPackage_filegroup_localResources() throws Exception {
    scratch.file(
        "java/android/resources/BUILD",
        "android_binary(name = 'r',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['//java/other/resources:fg'],",
        "                )");
    scratch.file(
        "java/other/resources/BUILD",
        "filegroup(name = 'fg',",
        "          srcs = ['res/values/strings.xml'],",
        ")");
    ConfiguredTarget resource = getConfiguredTarget("//java/android/resources:r");

    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(resource));
    assertPrimaryResourceDirs(ImmutableList.of("java/other/resources/res"), args);
    assertNoEvents();
  }

  @Test
  public void testResourcesInOtherPackage_filegroupWithExternalSources_localResources()
      throws Exception {
    scratch.file(
        "java/android/resources/BUILD",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = [':fg'],",
        "               )",
        "filegroup(name = 'fg',",
        "          srcs = ['//java/other/resources:res/values/strings.xml'])");
    scratch.file("java/other/resources/BUILD", "exports_files(['res/values/strings.xml'])");
    ConfiguredTarget resource = getConfiguredTarget("//java/android/resources:r");

    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(resource));
    assertPrimaryResourceDirs(ImmutableList.of("java/other/resources/res"), args);
    assertNoEvents();
  }

  @Test
  public void testMultipleDependentResourceDirectories_localResources() throws Exception {
    scratch.file(
        "java/android/resources/d1/BUILD",
        "android_library(name = 'd1',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['d1-res/values/strings.xml'],",
        "                )");
    scratch.file(
        "java/android/resources/d2/BUILD",
        "android_library(name = 'd2',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['d2-res/values/strings.xml'],",
        "                )");
    scratch.file(
        "java/android/resources/BUILD",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['bin-res/values/strings.xml'],",
        "               deps = [",
        "                   '//java/android/resources/d1:d1','//java/android/resources/d2:d2'",
        "               ])");
    ConfiguredTarget resource = getConfiguredTarget("//java/android/resources:r");

    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(resource));
    assertPrimaryResourceDirs(ImmutableList.of("java/android/resources/bin-res"), args);
    assertThat(getDirectDependentResourceDirs(args))
        .containsAtLeast("java/android/resources/d1/d1-res", "java/android/resources/d2/d2-res");
    assertNoEvents();
  }

  // Regression test for b/11924769
  @Test
  public void testResourcesInOtherPackage_doubleFilegroup_localResources() throws Exception {
    scratch.file(
        "java/android/resources/BUILD",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = [':fg'],",
        "               )",
        "filegroup(name = 'fg',",
        "          srcs = ['//java/other/resources:fg'])");
    scratch.file(
        "java/other/resources/BUILD",
        "filegroup(name = 'fg',",
        "          srcs = ['res/values/strings.xml'],",
        ")");
    ConfiguredTarget resource = getConfiguredTarget("//java/android/resources:r");

    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(resource));
    assertPrimaryResourceDirs(ImmutableList.of("java/other/resources/res"), args);
    assertNoEvents();
  }

  @Test
  public void testResourcesDoesNotMatchDirectoryLayout_badFile_localResources() throws Exception {
    checkError(
        "java/android/resources",
        "r",
        "'java/android/resources/res/somefile.xml' is not in the expected resource directory "
            + "structure of <resource directory>/{"
            + Joiner.on(',').join(AndroidResources.RESOURCE_DIRECTORY_TYPES)
            + "}",
        "android_binary(name = 'r',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['res/somefile.xml', 'r/t/f/m/raw/fold']",
        "                )");
  }

  @Test
  public void testResourcesDoesNotMatchDirectoryLayout_badDirectory_localResources()
      throws Exception {
    checkError(
        "java/android/resources",
        "r",
        "'java/android/resources/res/other/somefile.xml' is not in the expected resource directory "
            + "structure of <resource directory>/{"
            + Joiner.on(',').join(AndroidResources.RESOURCE_DIRECTORY_TYPES)
            + "}",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/other/somefile.xml', 'r/t/f/m/raw/fold']",
        "               )");
  }

  @Test
  public void testResourcesNotUnderCommonDirectoryFails_localResources() throws Exception {
    checkError(
        "java/android/resources",
        "r",
        "'java/android/resources/r/t/f/m/raw/fold' (generated by '//java/android/resources:r/t/f/m/"
            + "raw/fold') is not in the same directory 'res' "
            + "(derived from java/android/resources/res/raw/speed). "
            + "All resources must share a common directory",
        "android_binary(name = 'r',",
        "                manifest = 'AndroidManifest.xml',",
        "                resource_files = ['res/raw/speed', 'r/t/f/m/raw/fold']",
        "                )");
  }

  @Test
  public void testAssetsAndNoAssetsDirFails_localResources() throws Exception {
    scratch.file(
        "java/android/resources/assets/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    checkError(
        "java/android/resources",
        "r",
        "'assets' and 'assets_dir' should be either both empty or both non-empty",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               assets = glob(['assets/**']),",
        "               )");
  }

  @Test
  public void testAssetsDirAndNoAssetsFails_localResources() throws Exception {
    checkError(
        "java/cpp/android",
        "r",
        "'assets' and 'assets_dir' should be either both empty or both non-empty",
        "android_binary(name = 'r',",
        "               manifest = 'AndroidManifest.xml',",
        "               assets_dir = 'assets',",
        "                )");
  }

  @Test
  public void testAssetsNotUnderAssetsDirFails_localResources() throws Exception {
    checkError(
        "java/android/resources",
        "r",
        "'java/android/resources/r/t/f/m' (generated by '//java/android/resources:r/t/f/m') "
            + "is not beneath 'assets'",
        "android_binary(name = 'r',",
        "                manifest = 'AndroidManifest.xml',",
        "                assets_dir = 'assets',",
        "                assets = ['assets/valuable', 'r/t/f/m']",
        "                )");
  }

  @Test
  public void testFileLocation_localResources() throws Exception {
    scratch.file(
        "java/android/resources/BUILD",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               )");
    ConfiguredTargetAndData r = getConfiguredTargetAndData("//java/android/resources:r");
    assertThat(
            getFirstArtifactEndingWith(getFilesToBuild(r.getConfiguredTarget()), ".apk").getRoot())
        .isEqualTo(r.getConfiguration().getBinDirectory(RepositoryName.MAIN));
  }

  @Test
  public void testCustomPackage_localResources() throws Exception {
    scratch.file(
        "a/r/BUILD",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               custom_package = 'com.google.android.bar',",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               )");
    ConfiguredTarget r = getConfiguredTarget("//a/r:r");
    assertNoEvents();
    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(r));
    assertContainsSublist(args, ImmutableList.of("--packageForR", "com.google.android.bar"));
  }

  @Test
  public void testCustomJavacopts() throws Exception {
    scratch.file("java/foo/A.java", "foo");
    scratch.file(
        "java/foo/BUILD",
        "android_binary(name = 'a', manifest = 'AndroidManifest.xml', ",
        "  srcs = ['A.java'], javacopts = ['-g:lines,source'])");

    Artifact deployJar = getFileConfiguredTarget("//java/foo:a_deploy.jar").getArtifact();
    Action deployAction = getGeneratingAction(deployJar);
    JavaCompileAction javacAction =
        (JavaCompileAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(
                    actionsTestUtil().artifactClosureOf(deployAction.getInputs()), "liba.jar");

    assertThat(getJavacArguments(javacAction)).contains("-g:lines,source");
  }

  @Test
  public void testFixDepsToolFlag() throws Exception {
    useConfiguration("--experimental_fix_deps_tool=autofixer");

    scratch.file("java/foo/A.java", "foo");
    scratch.file(
        "java/foo/BUILD",
        "android_binary(name = 'a', manifest = 'AndroidManifest.xml', ",
        "  srcs = ['A.java'])");

    Iterable<String> commandLine =
        getJavacArguments(
            ((JavaCompileAction)
                actionsTestUtil()
                    .getActionForArtifactEndingWith(
                        actionsTestUtil()
                            .artifactClosureOf(
                                getGeneratingAction(
                                        getFileConfiguredTarget("//java/foo:a_deploy.jar")
                                            .getArtifact())
                                    .getInputs()),
                        "liba.jar")));

    assertThat(commandLine).containsAtLeast("--experimental_fix_deps_tool", "autofixer").inOrder();
  }

  @Test
  public void testFixDepsToolFlagEmpty() throws Exception {
    scratch.file("java/foo/A.java", "foo");
    scratch.file(
        "java/foo/BUILD",
        "android_binary(name = 'a', manifest = 'AndroidManifest.xml', ",
        "  srcs = ['A.java'])");

    Iterable<String> commandLine =
        getJavacArguments(
            ((JavaCompileAction)
                actionsTestUtil()
                    .getActionForArtifactEndingWith(
                        actionsTestUtil()
                            .artifactClosureOf(
                                getGeneratingAction(
                                        getFileConfiguredTarget("//java/foo:a_deploy.jar")
                                            .getArtifact())
                                    .getInputs()),
                        "liba.jar")));

    assertThat(commandLine).containsAtLeast("--experimental_fix_deps_tool", "add_dep").inOrder();
  }

  @Test
  public void testAndroidBinaryExportsJavaCompilationArgsProvider() throws Exception {

    scratch.file("java/foo/A.java", "foo");
    scratch.file(
        "java/foo/BUILD",
        "android_binary(name = 'a', manifest = 'AndroidManifest.xml', ",
        "  srcs = ['A.java'], javacopts = ['-g:lines,source'])");

    final JavaCompilationArgsProvider provider =
        JavaInfo.getProvider(
            JavaCompilationArgsProvider.class, getConfiguredTarget("//java/foo:a"));

    assertThat(provider).isNotNull();
  }

  @Test
  public void testNoApplicationId_localResources() throws Exception {
    scratch.file(
        "java/a/r/BUILD",
        "android_binary(name = 'r',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               )");
    ConfiguredTarget r = getConfiguredTarget("//java/a/r:r");
    assertNoEvents();
    List<String> args = getGeneratingSpawnActionArgs(getResourceApk(r));
    Truth.assertThat(args).doesNotContain("--applicationId");
  }

  @Test
  public void testDisallowPrecompiledJars() throws Exception {
    checkError(
        "java/precompiled",
        "binary",
        // messages:
        "does not produce any android_binary srcs files (expected .java or .srcjar)",
        // build file:
        "android_binary(name = 'binary',",
        "    manifest='AndroidManifest.xml',",
        "    srcs = [':jar'])",
        "filegroup(name = 'jar',",
        "    srcs = ['lib.jar'])");
  }

  @Test
  public void testDesugarJava8Libs_noProguard() throws Exception {
    useConfiguration("--experimental_desugar_java8_libs");
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  manifest = 'AndroidManifest.xml',",
        "  multidex = 'native',",
        ")");

    ConfiguredTarget top = getConfiguredTarget("//java/com/google/android:foo");
    Artifact artifact = getBinArtifact("_dx/foo/_final_classes.dex.zip", top);
    assertWithMessage("_final_classes.dex.zip").that(artifact).isNotNull();
    Action generatingAction = getGeneratingAction(artifact);
    assertThat(ActionsTestUtil.baseArtifactNames(generatingAction.getInputs()))
        .containsAtLeast("classes.dex.zip", /*canned*/ "java8_legacy.dex.zip");
  }

  @Test
  public void testDesugarJava8Libs_withProguard() throws Exception {
    useConfiguration("--experimental_desugar_java8_libs");
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  manifest = 'AndroidManifest.xml',",
        "  multidex = 'native',",
        "  proguard_specs = ['foo.cfg'],",
        ")");

    ConfiguredTarget top = getConfiguredTarget("//java/com/google/android:foo");
    Artifact artifact = getBinArtifact("_dx/foo/_final_classes.dex.zip", top);
    assertWithMessage("_final_classes.dex.zip").that(artifact).isNotNull();
    Action generatingAction = getGeneratingAction(artifact);
    assertThat(ActionsTestUtil.baseArtifactNames(generatingAction.getInputs()))
        .containsAtLeast("classes.dex.zip", /*built*/ "_java8_legacy.dex.zip");
  }

  private List<String> generatingActionArgs(Artifact artifact) throws Exception {
    Action action = getGeneratingAction(artifact);
    return ((SpawnAction) action).getArguments();
  }

  @Test
  public void testDesugarJava8Libs_withProguardWithMap() throws Exception {
    useConfiguration("--experimental_desugar_java8_libs");
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  manifest = 'AndroidManifest.xml',",
        "  multidex = 'native',",
        "  proguard_specs = ['foo.cfg'],",
        "  proguard_generate_mapping = 1,",
        ")");

    ConfiguredTarget top = getConfiguredTarget("//java/com/google/android:foo");

    Artifact desugaredLibraryDex = getBinArtifact("_dx/foo/_java8_legacy.dex.zip", top);
    List<String> desugaredLibraryActionArgs = generatingActionArgs(desugaredLibraryDex);
    assertThat(desugaredLibraryActionArgs.get(0)).contains("build_java8_legacy_dex");
    Artifact desugaredLibraryDexProguardMap = getBinArtifact("_dx/foo/_java8_legacy.dex.map", top);
    MoreAsserts.assertContainsSublist(
        desugaredLibraryActionArgs,
        "--rules",
        getBinArtifact("_dx/foo/_java8_legacy.dex.pgcfg", top).getExecPathString());
    MoreAsserts.assertContainsSublist(
        desugaredLibraryActionArgs, "--output", desugaredLibraryDex.getExecPathString());
    MoreAsserts.assertContainsSublist(
        desugaredLibraryActionArgs,
        "--output_map",
        desugaredLibraryDexProguardMap.getExecPathString());

    Artifact proguardMap = getBinArtifact("foo_proguard.map", top);
    List<String> mergeProguardMapsActionArgs =
        ((SpawnAction) getGeneratingAction(proguardMap)).getArguments();
    assertThat(mergeProguardMapsActionArgs.get(0)).contains("merge_proguard_maps");
    assertThat(flagValues("--pg-map", mergeProguardMapsActionArgs))
        .isEqualTo(
            ImmutableSet.of(
                desugaredLibraryDexProguardMap.getExecPathString(),
                getBinArtifact("_dx/foo/_proguard_output_for_desugared_library.map", top)
                    .getExecPathString()));
    assertThat(flagValue("--pg-map-output", mergeProguardMapsActionArgs))
        .isEqualTo(proguardMap.getExecPathString());

    Artifact artifact = getBinArtifact("_dx/foo/_final_classes.dex.zip", top);
    assertWithMessage("_final_classes.dex.zip").that(artifact).isNotNull();
    Action generatingAction = getGeneratingAction(artifact);
    assertThat(ActionsTestUtil.baseArtifactNames(generatingAction.getInputs()))
        .containsAtLeast("classes.dex.zip", /*built*/ "_java8_legacy.dex.zip");
  }

  @Test
  public void testDesugarJava8Libs_withProguardWithoutSpecsWithMap() throws Exception {
    useConfiguration("--experimental_desugar_java8_libs");
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  manifest = 'AndroidManifest.xml',",
        "  multidex = 'native',",
        "  proguard_generate_mapping = 1,",
        ")");

    ConfiguredTarget top = getConfiguredTarget("//java/com/google/android:foo");

    Artifact desugaredLibraryDex = getBinArtifact("_dx/foo/_java8_legacy.dex.zip", top);
    assertThat(getGeneratingAction(desugaredLibraryDex)).isNull();

    Artifact proguardMap = getBinArtifact("foo_proguard.map", top);
    assertThat(getGeneratingAction(proguardMap)).isInstanceOf(FailAction.class);

    Artifact artifact = getBinArtifact("_dx/foo/_final_classes.dex.zip", top);
    assertWithMessage("_final_classes.dex.zip").that(artifact).isNotNull();
    Action generatingAction = getGeneratingAction(artifact);
    assertThat(ActionsTestUtil.baseArtifactNames(generatingAction.getInputs()))
        .containsAtLeast("classes.dex.zip", /*canned*/ "java8_legacy.dex.zip");
  }

  @Test
  public void testApplyProguardMapping() throws Exception {
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  proguard_apply_mapping = 'proguard.map',",
        "  proguard_specs = ['foo.pro'],",
        "  manifest = 'AndroidManifest.xml',",
        ")");

    ConfiguredTarget ct = getConfiguredTarget("//java/com/google/android:foo");

    Artifact artifact = artifactByPath(getFilesToBuild(ct), "_proguard.jar");
    Action generatingAction = getGeneratingAction(artifact);
    assertThat(Artifact.asExecPaths(generatingAction.getInputs()))
        .contains("java/com/google/android/proguard.map");
    // Cannot use assertThat().containsAllOf().inOrder() as that does not assert that the elements
    // are consecutive.
    MoreAsserts.assertContainsSublist(
        getGeneratingSpawnActionArgs(artifact),
        "-applymapping",
        "java/com/google/android/proguard.map");
  }

  @Test
  public void testApplyProguardMappingWithNoSpec() throws Exception {
    checkError(
        "java/com/google/android",
        "foo",
        // messages:
        "'proguard_apply_mapping' can only be used when 'proguard_specs' is also set",
        // build file:
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  proguard_apply_mapping = 'proguard.map',",
        "  manifest = 'AndroidManifest.xml',",
        ")");
  }

  @Test
  public void testApplyProguardDictionary() throws Exception {
    scratch.file(
        "java/com/google/android/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  proguard_apply_dictionary = 'dictionary.txt',",
        "  proguard_specs = ['foo.pro'],",
        "  manifest = 'AndroidManifest.xml',",
        ")");

    ConfiguredTarget ct = getConfiguredTarget("//java/com/google/android:foo");

    Artifact artifact = artifactByPath(getFilesToBuild(ct), "_proguard.jar");
    Action generatingAction = getGeneratingAction(artifact);
    assertThat(Artifact.asExecPaths(generatingAction.getInputs()))
        .contains("java/com/google/android/dictionary.txt");
    // Cannot use assertThat().containsAllOf().inOrder() as that does not assert that the elements
    // are consecutive.
    MoreAsserts.assertContainsSublist(
        getGeneratingSpawnActionArgs(artifact),
        "-obfuscationdictionary",
        "java/com/google/android/dictionary.txt");
    MoreAsserts.assertContainsSublist(
        getGeneratingSpawnActionArgs(artifact),
        "-classobfuscationdictionary",
        "java/com/google/android/dictionary.txt");
    MoreAsserts.assertContainsSublist(
        getGeneratingSpawnActionArgs(artifact),
        "-packageobfuscationdictionary",
        "java/com/google/android/dictionary.txt");
  }

  @Test
  public void testApplyProguardDictionaryWithNoSpec() throws Exception {
    checkError(
        "java/com/google/android",
        "foo",
        // messages:
        "'proguard_apply_dictionary' can only be used when 'proguard_specs' is also set",
        // build file:
        "android_binary(",
        "  name = 'foo',",
        "  srcs = ['foo.java'],",
        "  proguard_apply_dictionary = 'dictionary.txt',",
        "  manifest = 'AndroidManifest.xml',",
        ")");
  }

  @Test
  public void testFeatureFlagsAttributeSetsSelectInDependency() throws Exception {
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.file(
        "java/com/foo/BUILD",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_setting(",
        "  name = 'flag1@on',",
        "  flag_values = {':flag1': 'on'},",
        "  transitive_configs = [':flag1'],",
        ")",
        "config_feature_flag(",
        "  name = 'flag2',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_setting(",
        "  name = 'flag2@on',",
        "  flag_values = {':flag2': 'on'},",
        "  transitive_configs = [':flag2'],",
        ")",
        "android_library(",
        "  name = 'lib',",
        "  srcs = select({",
        "    ':flag1@on': ['Flag1On.java'],",
        "    '//conditions:default': ['Flag1Off.java'],",
        "  }) + select({",
        "    ':flag2@on': ['Flag2On.java'],",
        "    '//conditions:default': ['Flag2Off.java'],",
        "  }),",
        "  transitive_configs = [':flag1', ':flag2'],",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  deps = [':lib'],",
        "  feature_flags = {",
        "    'flag1': 'on',",
        "  },",
        "  transitive_configs = [':flag1', ':flag2'],",
        ")");
    ConfiguredTarget binary = getConfiguredTarget("//java/com/foo");
    List<String> inputs =
        prettyArtifactNames(actionsTestUtil().artifactClosureOf(getFinalUnsignedApk(binary)));

    assertThat(inputs).containsAtLeast("java/com/foo/Flag1On.java", "java/com/foo/Flag2Off.java");
    assertThat(inputs).containsNoneOf("java/com/foo/Flag1Off.java", "java/com/foo/Flag2On.java");
  }

  @Test
  public void testFeatureFlagsAttributeSetsSelectInBinary() throws Exception {
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.file(
        "java/com/foo/BUILD",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_setting(",
        "  name = 'flag1@on',",
        "  flag_values = {':flag1': 'on'},",
        "  transitive_configs = [':flag1'],",
        ")",
        "config_feature_flag(",
        "  name = 'flag2',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_setting(",
        "  name = 'flag2@on',",
        "  flag_values = {':flag2': 'on'},",
        "  transitive_configs = [':flag2'],",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  srcs = select({",
        "    ':flag1@on': ['Flag1On.java'],",
        "    '//conditions:default': ['Flag1Off.java'],",
        "  }) + select({",
        "    ':flag2@on': ['Flag2On.java'],",
        "    '//conditions:default': ['Flag2Off.java'],",
        "  }),",
        "  feature_flags = {",
        "    'flag1': 'on',",
        "  },",
        "  transitive_configs = [':flag1', ':flag2'],",
        ")");
    ConfiguredTarget binary = getConfiguredTarget("//java/com/foo");
    List<String> inputs =
        prettyArtifactNames(actionsTestUtil().artifactClosureOf(getFinalUnsignedApk(binary)));

    assertThat(inputs).containsAtLeast("java/com/foo/Flag1On.java", "java/com/foo/Flag2Off.java");
    assertThat(inputs).containsNoneOf("java/com/foo/Flag1Off.java", "java/com/foo/Flag2On.java");
  }

  @Test
  public void testFeatureFlagsAttributeSetsSelectInBinaryAlias() throws Exception {
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.file(
        "java/com/foo/BUILD",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_setting(",
        "  name = 'flag1@on',",
        "  flag_values = {':flag1': 'on'},",
        "  transitive_configs = [':flag1'],",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  srcs = select({",
        "    ':flag1@on': ['Flag1On.java'],",
        "    '//conditions:default': ['Flag1Off.java'],",
        "  }),",
        "  feature_flags = {",
        "    'flag1': 'on',",
        "  },",
        "  transitive_configs = [':flag1'],",
        ")",
        "alias(",
        "  name = 'alias',",
        "  actual = ':foo',",
        ")");
    ConfiguredTarget binary = getConfiguredTarget("//java/com/foo:alias");
    List<String> inputs =
        prettyArtifactNames(actionsTestUtil().artifactClosureOf(getFinalUnsignedApk(binary)));

    assertThat(inputs).contains("java/com/foo/Flag1On.java");
    assertThat(inputs).doesNotContain("java/com/foo/Flag1Off.java");
  }

  @Test
  public void testFeatureFlagsAttributeFailsAnalysisIfFlagValueIsInvalid() throws Exception {
    reporter.removeHandler(failFastHandler);
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.file(
        "java/com/foo/BUILD",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_setting(",
        "  name = 'flag1@on',",
        "  flag_values = {':flag1': 'on'},",
        "  transitive_configs = [':flag1'],",
        ")",
        "android_library(",
        "  name = 'lib',",
        "  srcs = select({",
        "    ':flag1@on': ['Flag1On.java'],",
        "    '//conditions:default': ['Flag1Off.java'],",
        "  }),",
        "  transitive_configs = [':flag1'],",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  deps = [':lib'],",
        "  feature_flags = {",
        "    'flag1': 'invalid',",
        "  },",
        "  transitive_configs = [':flag1'],",
        ")");
    assertThat(getConfiguredTarget("//java/com/foo")).isNull();
    assertContainsEvent(
        "in config_feature_flag rule //java/com/foo:flag1: "
            + "value must be one of [\"off\", \"on\"], but was \"invalid\"");
  }

  @Test
  public void testFeatureFlagsAttributeFailsAnalysisIfFlagValueIsInvalidEvenIfNotUsed()
      throws Exception {
    reporter.removeHandler(failFastHandler);
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.file(
        "java/com/foo/BUILD",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_setting(",
        "  name = 'flag1@on',",
        "  flag_values = {':flag1': 'on'},",
        "  transitive_configs = [':flag1'],",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  feature_flags = {",
        "    'flag1': 'invalid',",
        "  },",
        "  transitive_configs = [':flag1'],",
        ")");
    assertThat(getConfiguredTarget("//java/com/foo")).isNull();
    assertContainsEvent(
        "in config_feature_flag rule //java/com/foo:flag1: "
            + "value must be one of [\"off\", \"on\"], but was \"invalid\"");
  }

  @Test
  public void testFeatureFlagsAttributeFailsAnalysisIfFlagIsAliased() throws Exception {
    reporter.removeHandler(failFastHandler);
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.file(
        "java/com/foo/BUILD",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "alias(",
        "  name = 'alias',",
        "  actual = 'flag1',",
        "  transitive_configs = [':flag1'],",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  feature_flags = {",
        "    'alias': 'on',",
        "  },",
        "  transitive_configs = [':flag1'],",
        ")");
    assertThat(getConfiguredTarget("//java/com/foo")).isNull();
    assertContainsEvent(
        "in feature_flags attribute of android_binary rule //java/com/foo:foo: "
            + "Feature flags must be named directly, not through aliases; "
            + "use '//java/com/foo:flag1', not '//java/com/foo:alias'");
  }

  @Test
  public void testFeatureFlagsAttributeSetsFeatureFlagProviderValues() throws Exception {
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.file(
        "java/com/foo/reader.bzl",
        "def _impl(ctx):",
        "  ctx.actions.write(",
        "      ctx.outputs.java,",
        "      '\\n'.join([",
        "          str(target.label) + ': ' + target[config_common.FeatureFlagInfo].value",
        "          for target in ctx.attr.flags]))",
        "  return [DefaultInfo(files=depset([ctx.outputs.java]))]",
        "flag_reader = rule(",
        "  implementation=_impl,",
        "  attrs={'flags': attr.label_list(providers=[config_common.FeatureFlagInfo])},",
        "  outputs={'java': '%{name}.java'},",
        ")");
    scratch.file(
        "java/com/foo/BUILD",
        "load('//java/com/foo:reader.bzl', 'flag_reader')",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "config_feature_flag(",
        "  name = 'flag2',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "flag_reader(",
        "  name = 'FooFlags',",
        "  flags = [':flag1', ':flag2'],",
        "  transitive_configs = [':flag1', ':flag2'],",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  srcs = [':FooFlags.java'],",
        "  feature_flags = {",
        "    'flag1': 'on',",
        "  },",
        "  transitive_configs = [':flag1', ':flag2'],",
        ")");
    Artifact flagList =
        getFirstArtifactEndingWith(
            actionsTestUtil()
                .artifactClosureOf(getFinalUnsignedApk(getConfiguredTarget("//java/com/foo"))),
            "/FooFlags.java");
    FileWriteAction action = (FileWriteAction) getGeneratingAction(flagList);
    assertThat(action.getFileContents())
        .isEqualTo("@//java/com/foo:flag1: on\n@//java/com/foo:flag2: off");
  }

  @Test
  public void featureFlagsSetByAndroidBinaryAreInRequiredFragments() throws Exception {
    useConfiguration("--include_config_fragments_provider=direct");
    scratch.file(
        "java/com/foo/BUILD",
        "config_feature_flag(",
        "  name = 'flag1',",
        "  allowed_values = ['on', 'off'],",
        "  default_value = 'off',",
        ")",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  srcs = [':FooFlags.java'],",
        "  feature_flags = {",
        "    'flag1': 'on',",
        "  },",
        ")");
    ConfiguredTarget ct = getConfiguredTarget("//java/com/foo:foo");
    assertThat(ct.getProvider(RequiredConfigFragmentsProvider.class).getStarlarkOptions())
        .containsExactly(Label.parseAbsoluteUnchecked("//java/com/foo:flag1"));
  }

  @Test
  public void testNocompressExtensions() throws Exception {
    scratch.file(
        "java/r/android/BUILD",
        "android_binary(",
        "  name = 'r',",
        "  srcs = ['Foo.java'],",
        "  manifest = 'AndroidManifest.xml',",
        "  resource_files = ['res/raw/foo.apk'],",
        "  nocompress_extensions = ['.apk', '.so'],",
        ")");
    ConfiguredTarget binary = getConfiguredTarget("//java/r/android:r");
    ValidatedAndroidResources resource = getValidatedResources(binary);
    List<String> args = resourceArguments(resource);
    Artifact inputManifest =
        getFirstArtifactEndingWith(
            getGeneratingSpawnAction(resource.getManifest()).getInputs(), "AndroidManifest.xml");
    assertContainsSublist(
        args,
        ImmutableList.of(
            "--primaryData", "java/r/android/res::" + inputManifest.getExecPathString()));
    assertThat(args).contains("--uncompressedExtensions");
    assertThat(args.get(args.indexOf("--uncompressedExtensions") + 1)).isEqualTo(".apk,.so");
    assertThat(getGeneratingSpawnActionArgs(getCompressedUnsignedApk(binary)))
        .containsAtLeast("--nocompress_suffixes", ".apk", ".so")
        .inOrder();
    assertThat(getGeneratingSpawnActionArgs(getFinalUnsignedApk(binary)))
        .containsAtLeast("--nocompress_suffixes", ".apk", ".so")
        .inOrder();
  }

  @Test
  public void testFeatureFlagPolicyMustContainRuleToUseFeatureFlags() throws Exception {
    reporter.removeHandler(failFastHandler); // expecting an error
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.overwriteFile(
        "tools/allowlists/config_feature_flag/BUILD",
        "package_group(",
        "    name = 'config_feature_flag',",
        "    packages = ['//flag'])");
    scratch.file(
        "flag/BUILD",
        "config_feature_flag(",
        "    name = 'flag',",
        "    allowed_values = ['right', 'wrong'],",
        "    default_value = 'right',",
        "    visibility = ['//java/com/google/android/foo:__pkg__'],",
        ")");
    scratch.file(
        "java/com/google/android/foo/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  srcs = [':FooFlags.java'],",
        "  feature_flags = {",
        "    '//flag:flag': 'right',",
        "  },",
        "  transitive_configs = ['//flag:flag'],",
        ")");
    assertThat(getConfiguredTarget("//java/com/google/android/foo:foo")).isNull();
    assertContainsEvent(
        "in android_binary rule //java/com/google/android/foo:foo: "
            + "the attribute feature_flags is not available in this package");
  }

  @Test
  public void testFeatureFlagPolicyDoesNotBlockRuleIfInPolicy() throws Exception {
    useConfiguration("--enforce_transitive_configs_for_config_feature_flag");
    scratch.overwriteFile(
        "tools/allowlists/config_feature_flag/BUILD",
        "package_group(",
        "    name = 'config_feature_flag',",
        "    packages = ['//flag', '//java/com/google/android/foo'])");
    scratch.file(
        "flag/BUILD",
        "config_feature_flag(",
        "    name = 'flag',",
        "    allowed_values = ['right', 'wrong'],",
        "    default_value = 'right',",
        "    visibility = ['//java/com/google/android/foo:__pkg__'],",
        ")");
    scratch.file(
        "java/com/google/android/foo/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  srcs = [':FooFlags.java'],",
        "  feature_flags = {",
        "    '//flag:flag': 'right',",
        "  },",
        "  transitive_configs = ['//flag:flag'],",
        ")");
    assertThat(getConfiguredTarget("//java/com/google/android/foo:foo")).isNotNull();
    assertNoEvents();
  }

  @Test
  public void testFeatureFlagPolicyIsNotUsedIfFlagValuesNotUsed() throws Exception {
    scratch.overwriteFile(
        "tools/allowlists/config_feature_flag/BUILD",
        "package_group(",
        "    name = 'config_feature_flag',",
        "    packages = ['*super* busted package group'])");
    scratch.file(
        "java/com/google/android/foo/BUILD",
        "android_binary(",
        "  name = 'foo',",
        "  manifest = 'AndroidManifest.xml',",
        "  srcs = [':FooFlags.java'],",
        ")");
    assertThat(getConfiguredTarget("//java/com/google/android/foo:foo")).isNotNull();
    // the package_group is busted, so we would have failed to get this far if we depended on it
    assertNoEvents();
    // Check time: does this test actually test what we're testing for?
    reporter.removeHandler(failFastHandler);
    assertThat(getConfiguredTarget("//tools/allowlists/config_feature_flag:config_feature_flag"))
        .isNull();
    assertContainsEvent("*super* busted package group");
  }

  @Test
  public void testAapt2WithAndroidSdk() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    resource_files = [ 'res/values/values.xml' ], ",
        ")");

    ConfiguredTarget a = getConfiguredTarget("//java/a:a");
    Artifact apk = getImplicitOutputArtifact(a, AndroidRuleClasses.ANDROID_RESOURCES_APK);

    assertThat(getGeneratingSpawnActionArgs(apk))
        .containsAtLeast(
            "--aapt2",
            // The path to aapt2 is different between Blaze and Bazel, so we omit it here.
            // It's safe to do so as we've already checked for the `--aapt2` flag.
            "--tool",
            "AAPT2_PACKAGE");
  }

  @Test
  public void testAapt2WithAndroidSdkAndDependencies() throws Exception {
    scratch.file(
        "java/b/BUILD",
        "android_library(",
        "    name = 'b',",
        "    srcs = ['B.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    resource_files = [ 'res/values/values.xml' ], ",
        ")");

    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    deps = [ '//java/b:b' ],",
        "    resource_files = [ 'res/values/values.xml' ], ",
        ")");

    ConfiguredTarget a = getConfiguredTarget("//java/a:a");
    ConfiguredTarget b = getDirectPrerequisite(a, "//java/b:b");

    Artifact classJar =
        getImplicitOutputArtifact(a, AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR);
    Artifact apk = getImplicitOutputArtifact(a, AndroidRuleClasses.ANDROID_RESOURCES_APK);

    SpawnAction apkAction = getGeneratingSpawnAction(apk);
    assertThat(getGeneratingSpawnActionArgs(apk))
        .containsAtLeast(
            "--aapt2",
            // The path to aapt2 is different between Blaze and Bazel, so we omit it here.
            // It's safe to do so as we've already checked for the `--aapt2` flag.
            "--tool",
            "AAPT2_PACKAGE");

    assertThat(apkAction.getInputs().toList())
        .contains(getImplicitOutputArtifact(b, AndroidRuleClasses.ANDROID_COMPILED_SYMBOLS));

    SpawnAction classAction = getGeneratingSpawnAction(classJar);
    assertThat(classAction.getInputs().toList())
        .containsAtLeast(
            getImplicitOutputArtifact(a, AndroidRuleClasses.ANDROID_R_TXT),
            getImplicitOutputArtifact(b, AndroidRuleClasses.ANDROID_R_TXT));
  }

  @Test
  public void testAapt2ResourceShrinkingAction() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               shrink_resources = 1,",
        "               proguard_specs = ['proguard-spec.pro'],)");

    ConfiguredTargetAndData targetAndData =
        getConfiguredTargetAndData("//java/com/google/android/hello:hello");
    ConfiguredTarget binary = targetAndData.getConfiguredTarget();

    Artifact jar = getResourceClassJar(targetAndData);
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    assertThat(getGeneratingSpawnActionArgs(jar)).contains("--finalFields");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    assertThat(artifacts)
        .containsAtLeast(
            getFirstArtifactEndingWith(artifacts, "resource_files.zip"),
            getFirstArtifactEndingWith(artifacts, "proguard.jar"),
            getFirstArtifactEndingWith(artifacts, "shrunk.ap_"));

    List<String> processingArgs =
        getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "resource_files.zip"));

    assertThat(flagValue("--resourcesOutput", processingArgs))
        .endsWith("hello_files/resource_files.zip");

    List<String> proguardArgs =
        getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "proguard.jar"));

    assertThat(flagValue("-outjars", proguardArgs)).endsWith("hello_proguard.jar");

    List<String> shrinkingArgs =
        getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "shrunk.ap_"));

    assertThat(flagValue("--tool", shrinkingArgs)).isEqualTo("SHRINK_AAPT2");

    assertThat(flagValue("--aapt2", shrinkingArgs)).isEqualTo(flagValue("--aapt2", processingArgs));
    assertThat(flagValue("--resources", shrinkingArgs))
        .isEqualTo(flagValue("--resourcesOutput", processingArgs));
    assertThat(flagValue("--shrunkJar", shrinkingArgs))
        .isEqualTo(flagValue("-outjars", proguardArgs));
    assertThat(flagValue("--proguardMapping", shrinkingArgs))
        .isEqualTo(flagValue("-printmapping", proguardArgs));
    assertThat(flagValue("--rTxt", shrinkingArgs))
        .isEqualTo(flagValue("--rOutput", processingArgs));
    assertThat(flagValue("--resourcesConfigOutput", shrinkingArgs))
        .endsWith("resource_optimization.cfg");

    List<String> packageArgs =
        getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "_hello_proguard.cfg"));

    assertThat(flagValue("--tool", packageArgs)).isEqualTo("AAPT2_PACKAGE");
    assertThat(packageArgs).doesNotContain("--conditionalKeepRules");
  }

  @Test
  public void testAapt2ResourceShrinking_proguardSpecsAbsent_noShrunkApk() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               shrink_resources = 1,)");

    ConfiguredTargetAndData targetAndData =
        getConfiguredTargetAndData("//java/com/google/android/hello:hello");
    ConfiguredTarget binary = targetAndData.getConfiguredTarget();

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    assertThat(getFirstArtifactEndingWith(artifacts, "shrunk.ap_")).isNull();
  }

  @Test
  public void testAapt2ResourceCycleShrinking() throws Exception {
    useConfiguration("--experimental_android_resource_cycle_shrinking=true");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               shrink_resources = 1,",
        "               proguard_specs = ['proguard-spec.pro'],)");

    ConfiguredTargetAndData targetAndData =
        getConfiguredTargetAndData("//java/com/google/android/hello:hello");
    ConfiguredTarget binary = targetAndData.getConfiguredTarget();

    Artifact jar = getResourceClassJar(targetAndData);
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    assertThat(getGeneratingSpawnActionArgs(jar)).contains("--nofinalFields");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    List<String> packageArgs =
        getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "_hello_proguard.cfg"));

    assertThat(flagValue("--tool", packageArgs)).isEqualTo("AAPT2_PACKAGE");
    assertThat(packageArgs).contains("--conditionalKeepRules");
  }

  @Test
  public void testAapt2ResourceCycleShinkingWithoutResourceShrinking() throws Exception {
    useConfiguration("--experimental_android_resource_cycle_shrinking=true");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    resource_files = [ 'res/values/values.xml' ], ",
        "    shrink_resources = 0,",
        "    proguard_specs = ['proguard-spec.pro'],",
        ")");

    ConfiguredTargetAndData targetAndData =
        getConfiguredTargetAndData("//java/com/google/android/hello:a");
    ConfiguredTarget binary = targetAndData.getConfiguredTarget();

    Artifact jar = getResourceClassJar(targetAndData);
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    assertThat(getGeneratingSpawnActionArgs(jar)).doesNotContain("--nofinalFields");

    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(binary));

    List<String> packageArgs =
        getGeneratingSpawnActionArgs(getFirstArtifactEndingWith(artifacts, "_a_proguard.cfg"));

    assertThat(flagValue("--tool", packageArgs)).isEqualTo("AAPT2_PACKAGE");
    assertThat(packageArgs).doesNotContain("--conditionalKeepRules");
  }

  @Test
  public void testAapt2ResourceCycleShrinkingDisabledNoProguardSpecs() throws Exception {
    useConfiguration("--experimental_android_resource_cycle_shrinking=true");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               shrink_resources = 1)");

    ConfiguredTargetAndData targetAndData =
        getConfiguredTargetAndData("//java/com/google/android/hello:hello");

    Artifact jar = getResourceClassJar(targetAndData);
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    // Final fields should still be generated for non-ProGuarded builds.
    assertThat(getGeneratingSpawnActionArgs(jar)).contains("--finalFields");
  }

  @Test
  public void testAapt2ResourceCycleShrinkingDisabledNoProguardSpecsApplicationResources()
      throws Exception {
    useConfiguration("--experimental_android_resource_cycle_shrinking=true");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'hello',",
        "               srcs = ['Foo.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               shrink_resources = 1)");

    ConfiguredTargetAndData targetAndData =
        getConfiguredTargetAndData("//java/com/google/android/hello:hello");

    Artifact jar = getResourceClassJar(targetAndData);
    assertThat(getGeneratingAction(jar).getMnemonic()).isEqualTo("RClassGenerator");
    // Final fields should still be generated for non-ProGuarded builds.
    assertThat(getGeneratingSpawnActionArgs(jar)).contains("--finalFields");
  }

  @Test
  public void testOnlyProguardSpecs() throws Exception {
    useConfiguration(
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l2',",
        "                srcs = ['MoreMaps.java'],",
        "                neverlink = 1)",
        "android_library(name = 'l3',",
        "                idl_srcs = ['A.aidl'],",
        "                deps = [':l2'])",
        "android_library(name = 'l4',",
        "                srcs = ['SubMoreMaps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l3', ':l4'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");
    ConfiguredTargetAndData binary =
        getConfiguredTargetAndData("//java/com/google/android/hello:b");
    checkProguardUse(
        binary.getConfiguredTarget(),
        "b_proguard.jar",
        false,
        /*passes=*/ null,
        // no-op since passes is null.
        /*bytecodeOptimizationPassActions=*/ 0,
        binary.getConfiguration().getBinFragment(RepositoryName.MAIN)
            + "/java/com/google/android/hello/proguard/b/legacy_b_combined_library_jars.jar");
  }

  @Test
  public void testOnlyProguardSpecsProguardJar() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l2',",
        "                srcs = ['MoreMaps.java'],",
        "                neverlink = 1)",
        "android_library(name = 'l3',",
        "                idl_srcs = ['A.aidl'],",
        "                deps = [':l2'])",
        "android_library(name = 'l4',",
        "                srcs = ['SubMoreMaps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l3', ':l4'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_generate_mapping = 1,",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");

    ConfiguredTarget output = getConfiguredTarget("//java/com/google/android/hello:b_proguard.jar");
    assertProguardUsed(output);

    output = getConfiguredTarget("//java/com/google/android/hello:b_proguard.map");
    assertWithMessage("proguard.map is not in the rule output")
        .that(
            actionsTestUtil()
                .getActionForArtifactEndingWith(getFilesToBuild(output), "_proguard.map"))
        .isNotNull();
  }

  @Test
  public void testCommandLineForMultipleProguardSpecs() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l1',",
        "                srcs = ['Maps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l1'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:b");
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(getFilesToBuild(binary), "_proguard.jar");

    assertWithMessage("Proguard action does not contain expected inputs.")
        .that(prettyArtifactNames(action.getInputs()))
        .containsAtLeast(
            "java/com/google/android/hello/proguard-spec.pro",
            "java/com/google/android/hello/proguard-spec1.pro",
            "java/com/google/android/hello/proguard-spec2.pro");

    assertThat(action.getArguments())
        .containsExactly(
            getProguardBinary().getExecPathString(),
            "-forceprocessing",
            "-injars",
            execPathEndingWith(action.getInputs(), "b_deploy.jar"),
            "-outjars",
            execPathEndingWith(action.getOutputs(), "b_proguard.jar"),
            // Only one combined library jar
            "-libraryjars",
            execPathEndingWith(action.getInputs(), "legacy_b_combined_library_jars.jar"),
            "@" + execPathEndingWith(action.getInputs(), "b_proguard.cfg"),
            "@java/com/google/android/hello/proguard-spec.pro",
            "@java/com/google/android/hello/proguard-spec1.pro",
            "@java/com/google/android/hello/proguard-spec2.pro",
            "-printseeds",
            execPathEndingWith(action.getOutputs(), "_proguard.seeds"),
            "-printusage",
            execPathEndingWith(action.getOutputs(), "_proguard.usage"),
            "-printconfiguration",
            execPathEndingWith(action.getOutputs(), "_proguard.config"))
        .inOrder();
  }

  /** Regression test for b/17790639 */
  @Test
  public void testNoDuplicatesInProguardCommand() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l1',",
        "                srcs = ['Maps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l1'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:b");
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(getFilesToBuild(binary), "_proguard.jar");
    assertThat(action.getArguments())
        .containsExactly(
            getProguardBinary().getExecPathString(),
            "-forceprocessing",
            "-injars",
            execPathEndingWith(action.getInputs(), "b_deploy.jar"),
            "-outjars",
            execPathEndingWith(action.getOutputs(), "b_proguard.jar"),
            // Only one combined library jar
            "-libraryjars",
            execPathEndingWith(action.getInputs(), "legacy_b_combined_library_jars.jar"),
            "@" + execPathEndingWith(action.getInputs(), "b_proguard.cfg"),
            "@java/com/google/android/hello/proguard-spec.pro",
            "@java/com/google/android/hello/proguard-spec1.pro",
            "@java/com/google/android/hello/proguard-spec2.pro",
            "-printseeds",
            execPathEndingWith(action.getOutputs(), "_proguard.seeds"),
            "-printusage",
            execPathEndingWith(action.getOutputs(), "_proguard.usage"),
            "-printconfiguration",
            execPathEndingWith(action.getOutputs(), "_proguard.config"))
        .inOrder();
  }

  @Test
  public void testProguardMapping() throws Exception {
    useConfiguration(
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro'],",
        "               proguard_generate_mapping = 1)");
    checkProguardUse(
        getConfiguredTarget("//java/com/google/android/hello:b"),
        "b_proguard.jar",
        true,
        /*passes=*/ null,
        // no-op since passes is null.
        /*bytecodeOptimizationPassActions=*/ 0,
        getAndroidJarPath());
  }

  @Test
  public void testProguardMappingProvider() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l2',",
        "                srcs = ['MoreMaps.java'],",
        "                neverlink = 1)",
        "android_library(name = 'l3',",
        "                idl_srcs = ['A.aidl'],",
        "                deps = [':l2'])",
        "android_library(name = 'l4',",
        "                srcs = ['SubMoreMaps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b1',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l3', ':l4'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_generate_mapping = 1,",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])",
        "android_binary(name = 'b2',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l3', ':l4'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");

    ConfiguredTarget output = getConfiguredTarget("//java/com/google/android/hello:b1");
    assertProguardUsed(output);
    Artifact mappingArtifact = getBinArtifact("b1_proguard.map", output);
    ProguardMappingProvider mappingProvider = output.get(ProguardMappingProvider.PROVIDER);
    assertThat(mappingProvider.getProguardMapping()).isEqualTo(mappingArtifact);

    output = getConfiguredTarget("//java/com/google/android/hello:b2");
    assertProguardUsed(output);
    assertThat(output.get(ProguardMappingProvider.PROVIDER)).isNull();
  }

  @Test
  public void testProguardSpecFromLibraryUsedInBinary() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l2',",
        "                srcs = ['MoreMaps.java'],",
        "                proguard_specs = ['library_spec.cfg'])",
        "android_library(name = 'l3',",
        "                idl_srcs = ['A.aidl'],",
        "                proguard_specs = ['library_spec.cfg'],",
        "                deps = [':l2'])",
        "android_library(name = 'l4',",
        "                srcs = ['SubMoreMaps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l3', ':l4'],",
        "               proguard_specs = ['proguard-spec.pro'],",
        "               manifest = 'AndroidManifest.xml',)");
    assertProguardUsed(getConfiguredTarget("//java/com/google/android/hello:b"));
    assertProguardGenerated(getConfiguredTarget("//java/com/google/android/hello:b"));
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(
                    getFilesToBuild(getConfiguredTarget("//java/com/google/android/hello:b")),
                    "_proguard.jar");
    assertThat(prettyArtifactNames(action.getInputs()))
        .contains("java/com/google/android/hello/proguard-spec.pro");
    assertThat(prettyArtifactNames(action.getInputs()))
        .contains(
            "java/com/google/android/hello/validated_proguard/l2/java/com/google/android/hello/library_spec.cfg_valid");
    assertThat(prettyArtifactNames(action.getInputs())).containsNoDuplicates();
  }

  @Test
  public void testResourcesUsedInProguardGenerate() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               resource_files = ['res/values/strings.xml'],",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");
    scratch.file(
        "java/com/google/android/hello/res/values/strings.xml",
        "<resources><string name = 'hello'>Hello Android!</string></resources>");
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:b");
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(
                    actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "_proguard.cfg");

    assertProguardGenerated(binary);
    assertWithMessage("Generate proguard action does not contain expected input.")
        .that(prettyArtifactNames(action.getInputs()))
        .contains("java/com/google/android/hello/res/values/strings.xml");
  }

  @Test
  public void testUseSingleJarForLibraryJars() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l1',",
        "                srcs = ['Maps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l1'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");
    ConfiguredTargetAndData binary =
        getConfiguredTargetAndData("//java/com/google/android/hello:b");
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(
                    getFilesToBuild(binary.getConfiguredTarget()), "_proguard.jar");

    checkProguardLibJars(
        action,
        binary.getConfiguration().getBinFragment(RepositoryName.MAIN)
            + "/java/com/google/android/hello/proguard/b/legacy_b_combined_library_jars.jar");
  }

  @Test
  public void testUseSingleJarForFilteredLibraryJars() throws Exception {
    useConfiguration("--experimental_filter_library_jar_with_program_jar=true");
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_library(name = 'l1',",
        "                srcs = ['Maps.java'],",
        "                neverlink = 1)",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               deps = [':l1'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro', 'proguard-spec1.pro',",
        "                                 'proguard-spec2.pro'])");
    ConfiguredTargetAndData binary =
        getConfiguredTargetAndData("//java/com/google/android/hello:b");
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(
                    getFilesToBuild(binary.getConfiguredTarget()), "_proguard.jar");

    checkProguardLibJars(
        action,
        binary.getConfiguration().getBinFragment(RepositoryName.MAIN)
            + "/java/com/google/android/hello/proguard/b/legacy_b_combined_library_jars_filtered.jar");
  }

  @Test
  public void testOnlyOneLibraryJar() throws Exception {
    scratch.file(
        "java/com/google/android/hello/BUILD",
        "android_binary(name = 'b',",
        "               srcs = ['HelloApp.java'],",
        "               manifest = 'AndroidManifest.xml',",
        "               proguard_specs = ['proguard-spec.pro'],",
        "               proguard_generate_mapping = 1)");
    ConfiguredTarget binary = getConfiguredTarget("//java/com/google/android/hello:b");
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil()
                .getActionForArtifactEndingWith(getFilesToBuild(binary), "_proguard.jar");

    checkProguardLibJars(action, getAndroidJarPath());
  }

  @Test
  public void testApkInfoAccessibleFromStarlark() throws Exception {
    scratch.file(
        "java/com/google/android/BUILD",
        "load(':postprocess.bzl', 'postprocess')",
        "android_binary(name = 'b1',",
        "               srcs = ['b1.java'],",
        "               manifest = 'AndroidManifest.xml')",
        "postprocess(name = 'postprocess', dep = ':b1')");
    scratch.file(
        "java/com/google/android/postprocess.bzl",
        "def _impl(ctx):",
        "  return [DefaultInfo(files=depset(",
        "    [ctx.attr.dep[ApkInfo].signed_apk, ctx.attr.dep[ApkInfo].deploy_jar]))]",
        "postprocess = rule(implementation=_impl,",
        "              attrs={'dep': attr.label(providers=[ApkInfo])})");
    ConfiguredTarget postprocess = getConfiguredTarget("//java/com/google/android:postprocess");
    assertThat(postprocess).isNotNull();
    assertThat(
            prettyArtifactNames(postprocess.getProvider(FilesToRunProvider.class).getFilesToRun()))
        .containsExactly("java/com/google/android/b1.apk", "java/com/google/android/b1_deploy.jar");
  }

  @Test
  public void testInstrumentationInfoAccessibleFromStarlark() throws Exception {
    scratch.file(
        "java/com/google/android/instr/BUILD",
        "load(':instr.bzl', 'instr')",
        "android_binary(name = 'b1',",
        "               srcs = ['b1.java'],",
        "               instruments = ':b2',",
        "               manifest = 'AndroidManifest.xml')",
        "android_binary(name = 'b2',",
        "               srcs = ['b2.java'],",
        "               manifest = 'AndroidManifest.xml')",
        "instr(name = 'instr', dep = ':b1')");
    scratch.file(
        "java/com/google/android/instr/instr.bzl",
        "def _impl(ctx):",
        "  target = ctx.attr.dep[AndroidInstrumentationInfo].target.signed_apk",
        "  return [DefaultInfo(files=depset([target]))]",
        "instr = rule(implementation=_impl,",
        "             attrs={'dep': attr.label(providers=[AndroidInstrumentationInfo])})");
    ConfiguredTarget instr = getConfiguredTarget("//java/com/google/android/instr");
    assertThat(instr).isNotNull();
    assertThat(prettyArtifactNames(instr.getProvider(FilesToRunProvider.class).getFilesToRun()))
        .containsExactly("java/com/google/android/instr/b2.apk");
  }

  @Test
  public void testInstrumentationInfoCreatableFromStarlark() throws Exception {
    scratch.file(
        "java/com/google/android/instr/BUILD",
        "load(':instr.bzl', 'instr')",
        "android_binary(name = 'b1',",
        "               srcs = ['b1.java'],",
        "               instruments = ':b2',",
        "               manifest = 'AndroidManifest.xml')",
        "android_binary(name = 'b2',",
        "               srcs = ['b2.java'],",
        "               manifest = 'AndroidManifest.xml')",
        "instr(name = 'instr', dep = ':b1')");
    scratch.file(
        "java/com/google/android/instr/instr.bzl",
        "def _impl(ctx):",
        "  target = ctx.attr.dep[AndroidInstrumentationInfo].target",
        "  return [AndroidInstrumentationInfo(target=target)]",
        "instr = rule(implementation=_impl,",
        "             attrs={'dep': attr.label(providers=[AndroidInstrumentationInfo])})");
    ConfiguredTarget instr = getConfiguredTarget("//java/com/google/android/instr");
    assertThat(instr).isNotNull();
    assertThat(instr.get(AndroidInstrumentationInfo.PROVIDER).getTarget().getApk().prettyPrint())
        .isEqualTo("java/com/google/android/instr/b2.apk");
  }

  @Test
  public void testInstrumentationInfoProviderHasApks() throws Exception {
    scratch.file(
        "java/com/google/android/instr/BUILD",
        "android_binary(name = 'b1',",
        "               srcs = ['b1.java'],",
        "               instruments = ':b2',",
        "               manifest = 'AndroidManifest.xml')",
        "android_binary(name = 'b2',",
        "               srcs = ['b2.java'],",
        "               manifest = 'AndroidManifest.xml')");
    ConfiguredTarget b1 = getConfiguredTarget("//java/com/google/android/instr:b1");
    AndroidInstrumentationInfo provider = b1.get(AndroidInstrumentationInfo.PROVIDER);
    assertThat(provider.getTarget()).isNotNull();
    assertThat(provider.getTarget().getApk().prettyPrint())
        .isEqualTo("java/com/google/android/instr/b2.apk");
  }

  @Test
  public void testNoInstrumentationInfoProviderIfNotInstrumenting() throws Exception {
    scratch.file(
        "java/com/google/android/instr/BUILD",
        "android_binary(name = 'b1',",
        "               srcs = ['b1.java'],",
        "               manifest = 'AndroidManifest.xml')");
    ConfiguredTarget b1 = getConfiguredTarget("//java/com/google/android/instr:b1");
    AndroidInstrumentationInfo provider = b1.get(AndroidInstrumentationInfo.PROVIDER);
    assertThat(provider).isNull();
  }

  @Test
  public void testFilterActionWithInstrumentedBinary() throws Exception {
    scratch.file(
        "java/com/google/android/instr/BUILD",
        "android_binary(name = 'b1',",
        "               srcs = ['b1.java'],",
        "               instruments = ':b2',",
        "               manifest = 'AndroidManifest.xml')",
        "android_binary(name = 'b2',",
        "               srcs = ['b2.java'],",
        "               manifest = 'AndroidManifest.xml')");
    ConfiguredTarget b1 = getConfiguredTarget("//java/com/google/android/instr:b1");
    SpawnAction action =
        (SpawnAction)
            actionsTestUtil().getActionForArtifactEndingWith(getFilesToBuild(b1), "_filtered.jar");
    assertThat(action.getArguments())
        .containsAtLeast(
            "--inputZip",
            getFirstArtifactEndingWith(action.getInputs(), "b1_deploy.jar").getExecPathString(),
            "--filterZips",
            getFirstArtifactEndingWith(action.getInputs(), "b2_deploy.jar").getExecPathString(),
            "--outputZip",
            getFirstArtifactEndingWith(action.getOutputs(), "b1_filtered.jar").getExecPathString(),
            "--filterTypes",
            ".class",
            "--checkHashMismatch",
            "IGNORE",
            "--explicitFilters",
            "/BR\\.class$,/databinding/[^/]+Binding\\.class$,(^|/)R\\.class,(^|/)R\\$.*\\.class",
            "--outputMode",
            "DONT_CARE");
  }

  /**
   * 'proguard_specs' attribute gets read by an implicit outputs function: the current heuristic is
   * that if this attribute is configurable, we assume its contents are non-empty and thus create
   * the mybinary_proguard.jar output. Test that here.
   */
  @Test
  public void testConfigurableProguardSpecs() throws Exception {
    useConfiguration(
        "--experimental_use_dex_splitter_for_incremental_dexing=false",
        "--experimental_incremental_dexing_after_proguard_by_default=false",
        "--experimental_incremental_dexing_after_proguard=1");
    scratch.file(
        "conditions/BUILD",
        "config_setting(",
        "    name = 'a',",
        "    values = {'foo': 'a'})",
        "config_setting(",
        "    name = 'b',",
        "    values = {'foo': 'b'})");
    scratchConfiguredTarget(
        "java/foo",
        "abin",
        "android_binary(",
        "    name = 'abin',",
        "    srcs = ['a.java'],",
        "    proguard_specs = select({",
        "        '//conditions:a': [':file1.pro'],",
        "        '//conditions:b': [],",
        "        '//conditions:default': [':file3.pro'],",
        "    }) + [",
        // Add a long list here as a regression test for b/68238721
        "        'file4.pro',",
        "        'file5.pro',",
        "        'file6.pro',",
        "        'file7.pro',",
        "        'file8.pro',",
        "    ],",
        "    manifest = 'AndroidManifest.xml')");
    checkProguardUse(
        getConfiguredTarget("//java/foo:abin"),
        "abin_proguard.jar",
        /*expectMapping=*/ false,
        /*passes=*/ null,
        // no-op since passes is null.
        /*bytecodeOptimizationPassActions=*/ 0,
        getAndroidJarPath());
  }

  @Test
  public void alwaysSkipParsingActionWithAapt2() throws Exception {
    scratch.file(
        "java/b/BUILD",
        "android_library(",
        "    name = 'b',",
        "    srcs = ['B.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    resource_files = [ 'res/values/values.xml' ], ",
        ")");

    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    deps = [ '//java/b:b' ],",
        "    resource_files = [ 'res/values/values.xml' ], ",
        ")");

    ConfiguredTarget a = getConfiguredTarget("//java/a:a");
    ConfiguredTarget b = getDirectPrerequisite(a, "//java/b:b");

    List<String> resourceProcessingArgs =
        getGeneratingSpawnActionArgs(getValidatedResources(a).getApk());

    assertThat(resourceProcessingArgs).contains("AAPT2_PACKAGE");
    String directData =
        resourceProcessingArgs.get(resourceProcessingArgs.indexOf("--directData") + 1);
    assertThat(directData).contains("symbols.zip");
    assertThat(directData).doesNotContain("merged.bin");

    List<String> resourceMergingArgs =
        getGeneratingSpawnActionArgs(getValidatedResources(b).getJavaClassJar());

    assertThat(resourceMergingArgs).contains("MERGE_COMPILED");
  }

  @Test
  public void starlarkJavaInfoToAndroidBinaryAttributes() throws Exception {
    scratch.file(
        "java/r/android/extension.bzl",
        "def _impl(ctx):",
        "  dep_params = ctx.attr.dep[JavaInfo]",
        "  return [dep_params]",
        "my_rule = rule(",
        "    _impl,",
        "    attrs = {",
        "        'dep': attr.label(),",
        "    },",
        ")");
    scratch.file(
        "java/r/android/BUILD",
        "load(':extension.bzl', 'my_rule')",
        "android_library(",
        "    name = 'al_bottom_for_deps',",
        "    srcs = ['java/A.java'],",
        ")",
        "my_rule(",
        "    name = 'mya',",
        "    dep = ':al_bottom_for_deps',",
        ")",
        "android_binary(",
        "    name = 'foo_app',",
        "    srcs = ['java/B.java'],",
        "    deps = [':mya'],",
        "    manifest = 'AndroidManifest.xml',",
        // TODO(b/75051107): Remove the following line when fixed.
        "    incremental_dexing = 0,",
        ")");

    // Test that all bottom jars are on the runtime classpath of the app.
    ConfiguredTarget target = getConfiguredTarget("//java/r/android:foo_app");

    ImmutableList<Artifact> transitiveSrcJars =
        OutputGroupInfo.get(target).getOutputGroup(JavaSemantics.SOURCE_JARS_OUTPUT_GROUP).toList();
    assertThat(ActionsTestUtil.baseArtifactNames(transitiveSrcJars))
        .containsExactly("libal_bottom_for_deps-src.jar", "libfoo_app-src.jar");
    ImmutableList<Artifact> directSrcJar =
        OutputGroupInfo.get(target)
            .getOutputGroup(JavaSemantics.DIRECT_SOURCE_JARS_OUTPUT_GROUP)
            .toList();
    assertThat(ActionsTestUtil.baseArtifactNames(directSrcJar))
        .containsExactly("libfoo_app-src.jar");
  }

  @Test
  public void androidManifestMergerOrderAlphabetical_MergeesSortedByExecPath() throws Exception {
    useConfiguration("--android_manifest_merger_order=alphabetical");
    /*
     * Dependency hierarchy:
     * - //java/binary:application
     *   - //java/binary:library
     *     - //java/common:theme
     *     - //java/android:utility
     *       - //java/common:common
     *         - //java/android:core
     */
    scratch.overwriteFile(
        "java/android/BUILD",
        "android_library(",
        "    name = 'core',",
        "    manifest = 'core/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['core/res/values/strings.xml'],",
        ")",
        "android_library(",
        "    name = 'utility',",
        "    manifest = 'utility/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['utility/res/values/values.xml'],",
        "    deps = ['//java/common:common'],",
        ")");
    scratch.file(
        "java/binary/BUILD",
        "android_binary(",
        "    name = 'application',",
        "    srcs = ['App.java'],",
        "    manifest = 'app/AndroidManifest.xml',",
        "    deps = [':library'],",
        ")",
        "android_library(",
        "    name = 'library',",
        "    manifest = 'library/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    deps = ['//java/common:theme', '//java/android:utility'],",
        ")");
    scratch.file(
        "java/common/BUILD",
        "android_library(",
        "    name = 'common',",
        "    manifest = 'common/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['common/res/values/common.xml'],",
        "    deps = ['//java/android:core'],",
        ")",
        "android_library(",
        "    name = 'theme',",
        "    manifest = 'theme/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['theme/res/values/values.xml'],",
        ")");

    // These have to be found via the same inheritance hierarchy, because getDirectPrerequsite can
    // only traverse one level.
    ConfiguredTarget application = getConfiguredTarget("//java/binary:application");
    ConfiguredTarget library = getDirectPrerequisite(application, "//java/binary:library");
    ConfiguredTarget theme = getDirectPrerequisite(library, "//java/common:theme");
    ConfiguredTarget utility = getDirectPrerequisite(library, "//java/android:utility");
    ConfiguredTarget common = getDirectPrerequisite(utility, "//java/common:common");
    ConfiguredTarget core = getDirectPrerequisite(common, "//java/android:core");

    Artifact androidCoreManifest = getLibraryManifest(core);
    Artifact androidUtilityManifest = getLibraryManifest(utility);
    Artifact binaryLibraryManifest = getLibraryManifest(library);
    Artifact commonManifest = getLibraryManifest(common);
    Artifact commonThemeManifest = getLibraryManifest(theme);

    assertThat(getBinaryMergeeManifests(application))
        .containsExactlyEntriesIn(
            ImmutableMap.of(
                androidCoreManifest.getExecPath().toString(), "//java/android:core",
                androidUtilityManifest.getExecPath().toString(), "//java/android:utility",
                binaryLibraryManifest.getExecPath().toString(), "//java/binary:library",
                commonManifest.getExecPath().toString(), "//java/common:common",
                commonThemeManifest.getExecPath().toString(), "//java/common:theme"))
        .inOrder();
  }

  @Test
  public void androidManifestMergerOrderAlphabeticalByConfiguration_MergeesSortedByPathInBinOrGen()
      throws Exception {
    useConfiguration(
        "--android_manifest_merger_order=alphabetical_by_configuration");
    scratch.overwriteFile(
        "java/android/BUILD",
        "android_library(",
        "    name = 'core',",
        "    manifest = 'core/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['core/res/values/strings.xml'],",
        ")",
        "android_library(",
        "    name = 'utility',",
        "    manifest = 'utility/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['utility/res/values/values.xml'],",
        "    deps = ['//java/common:common'],",
        "    transitive_configs = ['//flags:a', '//flags:b'],",
        ")");
    scratch.file(
        "java/binary/BUILD",
        "android_binary(",
        "    name = 'application',",
        "    srcs = ['App.java'],",
        "    manifest = 'app/AndroidManifest.xml',",
        "    deps = [':library'],",
        "    feature_flags = {",
        "        '//flags:a': 'on',",
        "        '//flags:b': 'on',",
        "        '//flags:c': 'on',",
        "    },",
        "    transitive_configs = ['//flags:a', '//flags:b', '//flags:c'],",
        ")",
        "android_library(",
        "    name = 'library',",
        "    manifest = 'library/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    deps = ['//java/common:theme', '//java/android:utility'],",
        "    transitive_configs = ['//flags:a', '//flags:b', '//flags:c'],",
        ")");
    scratch.file(
        "java/common/BUILD",
        "android_library(",
        "    name = 'common',",
        "    manifest = 'common/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['common/res/values/common.xml'],",
        "    deps = ['//java/android:core'],",
        "    transitive_configs = ['//flags:a'],",
        ")",
        "android_library(",
        "    name = 'theme',",
        "    manifest = 'theme/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['theme/res/values/values.xml'],",
        "    transitive_configs = ['//flags:a', '//flags:b', '//flags:c'],",
        ")");
    scratch.file(
        "flags/BUILD",
        "config_feature_flag(",
        "    name = 'a',",
        "    allowed_values = ['on', 'off'],",
        "    default_value = 'off',",
        ")",
        "config_feature_flag(",
        "    name = 'b',",
        "    allowed_values = ['on', 'off'],",
        "    default_value = 'off',",
        ")",
        "config_feature_flag(",
        "    name = 'c',",
        "    allowed_values = ['on', 'off'],",
        "    default_value = 'off',",
        ")");

    assertThat(getBinaryMergeeManifests(getConfiguredTarget("//java/binary:application")).values())
        .containsExactly(
            "//java/android:core",
            "//java/android:utility",
            "//java/binary:library",
            "//java/common:common",
            "//java/common:theme")
        .inOrder();
  }

  @Test
  public void testAndroidStarlarkApiNativeLibs() throws Exception {
    scratch.file(
        "java/a/fetch_native_libs.bzl",
        "def _impl(ctx):",
        "  libs = ctx.attr.android_binary.android.native_libs",
        "  return [DefaultInfo(files = libs.values()[0])]",
        "fetch_native_libs = rule(implementation = _impl,",
        "    attrs = {",
        "        'android_binary': attr.label(),",
        "    },",
        ")");
    scratch.file(
        "java/a/BUILD",
        "load('//java/a:fetch_native_libs.bzl', 'fetch_native_libs')",
        "android_binary(",
        "    name = 'app',",
        "    srcs=['Main.java'],",
        "    manifest='AndroidManifest.xml',",
        "    deps=[':cc'],",
        ")",
        "cc_library(",
        "    name = 'cc',",
        "    srcs = ['cc.cc'],",
        ")",
        "fetch_native_libs(",
        "    name = 'clibs',",
        "    android_binary = 'app',",
        ")");
    ConfiguredTarget clibs = getConfiguredTarget("//java/a:clibs");

    assertThat(
            ActionsTestUtil.baseArtifactNames(
                clibs.getProvider(FileProvider.class).getFilesToBuild()))
        .containsExactly("libapp.so");
  }

  @Test
  public void testInstrumentsManifestMergeEnabled() throws Exception {
    // This is the incorrect behavior where dependency manifests are merged into the test apk.
    useConfiguration("--noexperimental_disable_instrumentation_manifest_merge");
    scratch.file(
        "java/com/google/android/instr/BUILD",
        "android_binary(",
        "    name = 'b1',",
        "    srcs = ['b1.java'],",
        "    instruments = ':b2',",
        "    deps = [':lib'],",
        "    manifest = 'test/AndroidManifest.xml',",
        ")",
        "android_library(",
        "    name = 'lib',",
        "    manifest = 'lib/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['lib/res/values/strings.xml'],",
        ")",
        "android_binary(",
        "    name = 'b2',",
        "    srcs = ['b2.java'],",
        "    deps = [':lib'],",
        "    manifest = 'bin/AndroidManifest.xml',",
        ")");
    assertThat(
            getBinaryMergeeManifests(getConfiguredTarget("//java/com/google/android/instr:b1"))
                .values())
        .containsExactly("//java/com/google/android/instr:lib");
  }

  @Test
  public void testInstrumentsManifestMergeDisabled() throws Exception {
    // This is the correct behavior where dependency manifests are not merged into the test apk.
    useConfiguration("--experimental_disable_instrumentation_manifest_merge");
    scratch.file(
        "java/com/google/android/instr/BUILD",
        "android_binary(",
        "    name = 'b1',",
        "    srcs = ['b1.java'],",
        "    instruments = ':b2',",
        "    deps = [':lib'],",
        "    manifest = 'test/AndroidManifest.xml',",
        ")",
        "android_library(",
        "    name = 'lib',",
        "    manifest = 'lib/AndroidManifest.xml',",
        "    exports_manifest = 1,",
        "    resource_files = ['lib/res/values/strings.xml'],",
        ")",
        "android_binary(",
        "    name = 'b2',",
        "    srcs = ['b2.java'],",
        "    deps = [':lib'],",
        "    manifest = 'bin/AndroidManifest.xml',",
        ")");
    assertThat(
            getBinaryMergeeManifests(getConfiguredTarget("//java/com/google/android/instr:b1"))
                .values())
        .isEmpty();
  }

  @Test
  public void testOptimizedJavaResourcesDisabled() throws Exception {
    useConfiguration("--noexperimental_get_android_java_resources_from_optimized_jar");
    ConfiguredTarget ct =
        scratchConfiguredTarget(
            "java/a",
            "a",
            "android_binary(",
            "    name = 'a',",
            "    srcs = ['A.java'],",
            "    manifest = 'AndroidManifest.xml',",
            "    proguard_specs = ['proguard.cfg'],",
            ")");
    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(ct));
    Artifact extractedResources = getFirstArtifactEndingWith(artifacts, "extracted_a_deploy.jar");
    String args = Joiner.on(" ").join(getGeneratingSpawnActionArgs(extractedResources));
    assertThat(args).contains("/a_deploy.jar");
    assertThat(args).doesNotContain("a_proguard.jar");
  }

  @Test
  public void testOptimizedJavaResourcesEnabled() throws Exception {
    useConfiguration("--experimental_get_android_java_resources_from_optimized_jar");
    ConfiguredTarget ct =
        scratchConfiguredTarget(
            "java/a",
            "a",
            "android_binary(",
            "    name = 'a',",
            "    srcs = ['A.java'],",
            "    manifest = 'AndroidManifest.xml',",
            "    proguard_specs = ['proguard.cfg'],",
            ")");
    Set<Artifact> artifacts = actionsTestUtil().artifactClosureOf(getFilesToBuild(ct));
    Artifact extractedResources = getFirstArtifactEndingWith(artifacts, "extracted_a_proguard.jar");
    String args = Joiner.on(" ").join(getGeneratingSpawnActionArgs(extractedResources));
    assertThat(args).doesNotContain("a_deploy.jar");
    assertThat(args).contains("/a_proguard.jar");
  }
}
