Disable duplicate asset checks for Robolectric tests

Since Robolectric tests only implement a small portion of an application which often includes test overrides, there is little need for costly duplicate asset detection within these tests, especially given the performance ramifications.

Additionally, AAPT2 already can perform its own duplicate resource validation during compilation and linking, so these additional checks are redundant for Robolectric tests where symbolsOut is not needed. If needed, these kinds of verifications would be more efficiently implemented within AAPT2 itself.

A new argument generate_out_symbols skips the costly process of checking for merge conflicts within Aapt2ResourcePackagingAction.java for Robolectric tests while preserving this functionality otherwise.

PiperOrigin-RevId: 924841916
Change-Id: Ib125fbe6e5803f6ea38649738cb040de07b0e9c6
diff --git a/rules/android_local_test/impl.bzl b/rules/android_local_test/impl.bzl
index 66a89ab..5aaf8eb 100644
--- a/rules/android_local_test/impl.bzl
+++ b/rules/android_local_test/impl.bzl
@@ -113,6 +113,7 @@
         java_package = java_package,
         shrink_resources = attrs.tristate.no,
         build_java_with_final_resources = True,
+        generate_out_symbols = False,
         crunch_png = False,
         aapt = get_android_toolchain(ctx).aapt2.files_to_run,
         android_jar = get_android_sdk(ctx).android_jar,
diff --git a/rules/resources.bzl b/rules/resources.bzl
index 97ad6b6..e3dea32 100644
--- a/rules/resources.bzl
+++ b/rules/resources.bzl
@@ -499,6 +499,7 @@
         should_compile_java_srcs = True,
         generate_minsdk_proguard_config = False,
         build_java_with_final_resources = False,
+        generate_out_symbols = True,
         feature_flags = "",
         crunch_png = True,
         aapt = None,
@@ -567,6 +568,7 @@
         non-final resources for linking against when building any srcs. This is
         generally only desirable for test targets that aren't potentially
         running compile-time optimizations.
+      generate_out_symbols: boolean. Whether to generate the merged symbols binary file.
       crunch_png: boolean. Determines whether `aapt2 compile` should crunch PNG files.
       aapt: FilesToRunProvider. The aapt executable or FilesToRunProvider.
       has_local_proguard_specs: If the target has proguard specs.
@@ -737,12 +739,13 @@
     resource_files_zip = ctx.actions.declare_file(
         "_migrated/" + ctx.label.name + "_files/resource_files.zip",
     )
+    out_symbols = ctx.actions.declare_file("_migrated/" + ctx.label.name + "_symbols/merged.bin") if generate_out_symbols else None
     _busybox.package(
         ctx,
         out_file = resource_apk,
         out_r_src_jar = r_java,
         out_r_txt = r_txt,
-        out_symbols = ctx.actions.declare_file("_migrated/" + ctx.label.name + "_symbols/merged.bin"),
+        out_symbols = out_symbols,
         out_manifest = processed_manifest,
         out_proguard_cfg = proguard_cfg,
         out_main_dex_proguard_cfg = main_dex_proguard_cfg,
diff --git a/src/tools/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java b/src/tools/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java
index 3645146..8212ed7 100644
--- a/src/tools/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java
+++ b/src/tools/java/com/google/devtools/build/android/Aapt2ResourcePackagingAction.java
@@ -318,32 +318,34 @@
                           .process(manifest));
 
       profiler.recordEndOf("compile").startTask("merge");
-
-      // Checks for merge conflicts, and write the merged data out.
-      final Path symbolsBin =
-          AndroidResourceMerger.mergeDataToSymbols(
-              ParsedAndroidData.loadedFrom(
-                  DependencyInfo.DependencyType.PRIMARY,
-                  ImmutableList.of(SerializedAndroidData.from(compiled)),
-                  executorService,
-                  dataDeserializer),
-              new DensitySpecificManifestProcessor(options.densities, densityManifest)
-                  .process(options.primaryData.getManifest()),
-              ImmutableList.<SerializedAndroidData>builder()
-                  .addAll(options.directData)
-                  .addAll(options.directAssets)
-                  .build(),
-              ImmutableList.<SerializedAndroidData>builder()
-                  .addAll(options.transitiveData)
-                  .addAll(options.transitiveAssets)
-                  .build(),
-              options.packageType,
-              symbols,
-              dataDeserializer,
-              options.throwOnResourceConflict,
-              executorService);
-      if (options.symbolsOut != null) {
-        Files.copy(symbolsBin, options.symbolsOut);
+      if (options.throwOnResourceConflict || options.symbolsOut != null) {
+        // Checks for merge conflicts, and write the merged data out. This only happens when
+        // --throwOnResourceConflict or --symbolsOut is specified.
+        final Path symbolsBin =
+            AndroidResourceMerger.mergeDataToSymbols(
+                ParsedAndroidData.loadedFrom(
+                    DependencyInfo.DependencyType.PRIMARY,
+                    ImmutableList.of(SerializedAndroidData.from(compiled)),
+                    executorService,
+                    dataDeserializer),
+                new DensitySpecificManifestProcessor(options.densities, densityManifest)
+                    .process(options.primaryData.getManifest()),
+                ImmutableList.<SerializedAndroidData>builder()
+                    .addAll(options.directData)
+                    .addAll(options.directAssets)
+                    .build(),
+                ImmutableList.<SerializedAndroidData>builder()
+                    .addAll(options.transitiveData)
+                    .addAll(options.transitiveAssets)
+                    .build(),
+                options.packageType,
+                symbols,
+                dataDeserializer,
+                options.throwOnResourceConflict,
+                executorService);
+        if (options.symbolsOut != null) {
+          Files.copy(symbolsBin, options.symbolsOut);
+        }
       }
 
       profiler.recordEndOf("merge").startTask("link");