// 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 {};");
    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");
    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 testOptimizedDexingWithLegacyMultidex() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    proguard_specs = ['specs.pgcfg'],",
        "    proguard_generate_mapping = True,",
        "    multidex = 'legacy')");
    scratch.file(
        "tools/fake/BUILD",
        "cc_binary(",
        "    name = 'optimizing_dexer',",
        "    srcs = ['main.cc'])");
    useConfiguration("--optimizing_dexer=//tools/fake:optimizing_dexer");

    ConfiguredTarget binary = getConfiguredTarget("//java/a:a");
    Artifact proguardedJar =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "a_proguard.jar");
    Artifact proguardMap =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "a_proguard.map");

    Artifact dexedZip =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "/_dx/a/classes.dex.zip");
    SpawnAction proguard = getGeneratingSpawnAction(proguardedJar);
    SpawnAction dexer = getGeneratingSpawnAction(dexedZip);
    assertThat(dexer).isEqualTo(getGeneratingSpawnAction(proguardMap));
    List<String> dexerArgs = dexer.getArguments();

    assertThat(dexerArgs).contains("--release");
    assertThat(dexerArgs).contains("--no-desugaring");
    MoreAsserts.assertContainsSublist(dexerArgs, "--lib", getAndroidJarPath());
    Artifact mainDexList =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)),
            "/_dx/a/main_dex_list.txt");
    MoreAsserts.assertContainsSublist(
        dexerArgs, "--main-dex-list", mainDexList.getExecPath().getPathString());
    Artifact proguardMapInput =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)),
            "/proguard/a/legacy_a_pre_dexing.map");
    MoreAsserts.assertContainsSublist(
        dexerArgs, "--pg-map", proguardMapInput.getExecPath().getPathString());
  }

  @Test
  public void testOptimizedDexingWithNativeMultidex() throws Exception {
    scratch.file(
        "java/a/BUILD",
        "android_binary(",
        "    name = 'a',",
        "    srcs = ['A.java'],",
        "    manifest = 'AndroidManifest.xml',",
        "    proguard_specs = ['specs.pgcfg'],",
        "    proguard_generate_mapping = True,",
        "    multidex = 'native')");
    scratch.file(
        "tools/fake/BUILD",
        "cc_binary(",
        "    name = 'optimizing_dexer',",
        "    srcs = ['main.cc'])");
    useConfiguration("--optimizing_dexer=//tools/fake:optimizing_dexer");

    // The behavior should match legacy multidex except for the main dex list and min sdk, so we
    // only check those flags.
    ConfiguredTarget binary = getConfiguredTarget("//java/a:a");
    Artifact dexedZip =
        ActionsTestUtil.getFirstArtifactEndingWith(
            actionsTestUtil().artifactClosureOf(getFilesToBuild(binary)), "/_dx/a/classes.dex.zip");
    SpawnAction dexer = getGeneratingSpawnAction(dexedZip);
    List<String> dexerArgs = dexer.getArguments();
    assertThat(dexerArgs).doesNotContain("--main-dex-list");
    MoreAsserts.assertContainsSublist(dexerArgs, "--min-api", "21");
  }

  @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 =
        getExecConfiguredTarget("//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 a 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.parseCanonicalUnchecked("//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");
  }
}
