Consider flags when mergine resource tables

Test: Automated
Bug: 329436914
Flag: EXEMPT Aconfig not supported on host tools
Change-Id: I372e3005c0d44ba2e7f3805a43bfc5b0a1bc1200
diff --git a/core/tests/resourceflaggingtests/Android.bp b/core/tests/resourceflaggingtests/Android.bp
index e8bb710..dd86094 100644
--- a/core/tests/resourceflaggingtests/Android.bp
+++ b/core/tests/resourceflaggingtests/Android.bp
@@ -34,12 +34,24 @@
 }
 
 genrule {
+    name: "resource-flagging-test-app-resources-compile2",
+    tools: ["aapt2"],
+    srcs: [
+        "flagged_resources_res/values/bools2.xml",
+    ],
+    out: ["values_bools2.arsc.flat"],
+    cmd: "$(location aapt2) compile $(in) -o $(genDir) " +
+        "--feature-flags test.package.falseFlag:ro=false,test.package.trueFlag:ro=true",
+}
+
+genrule {
     name: "resource-flagging-test-app-apk",
     tools: ["aapt2"],
     // The first input file in the list must be the manifest
     srcs: [
         "TestAppAndroidManifest.xml",
         ":resource-flagging-test-app-resources-compile",
+        ":resource-flagging-test-app-resources-compile2",
     ],
     out: ["resapp.apk"],
     cmd: "$(location aapt2) link -o $(out) --manifest $(in)",
diff --git a/core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml b/core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml
index f4defd9..8d01465 100644
--- a/core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml
+++ b/core/tests/resourceflaggingtests/flagged_resources_res/values/bools.xml
@@ -5,4 +5,6 @@
 
     <bool name="res2">false</bool>
     <bool name="res2" android:featureFlag="test.package.trueFlag">true</bool>
+
+    <bool name="res3">false</bool>
 </resources>
\ No newline at end of file
diff --git a/core/tests/resourceflaggingtests/flagged_resources_res/values/bools2.xml b/core/tests/resourceflaggingtests/flagged_resources_res/values/bools2.xml
new file mode 100644
index 0000000..e7563aa
--- /dev/null
+++ b/core/tests/resourceflaggingtests/flagged_resources_res/values/bools2.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+    <bool name="res3" android:featureFlag="test.package.trueFlag">true</bool>
+</resources>
\ No newline at end of file
diff --git a/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java b/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java
index a0cbe3c..ad8542e 100644
--- a/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java
+++ b/core/tests/resourceflaggingtests/src/com/android/resourceflaggingtests/ResourceFlaggingTest.java
@@ -63,6 +63,11 @@
         assertThat(getBoolean("res2")).isTrue();
     }
 
+    @Test
+    public void testFlagEnabledDifferentCompilationUnit() {
+        assertThat(getBoolean("res3")).isTrue();
+    }
+
     private boolean getBoolean(String name) {
         int resId = mResources.getIdentifier(name, "bool", "com.android.intenal.flaggedresources");
         assertThat(resId).isNotEqualTo(0);
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 45bf8e3..9444dd9 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -107,7 +107,7 @@
   Visibility::Level visibility_level = Visibility::Level::kUndefined;
   bool staged_api = false;
   bool allow_new = false;
-  FlagStatus flag_status;
+  FlagStatus flag_status = FlagStatus::NoFlag;
   std::optional<OverlayableItem> overlayable_item;
   std::optional<StagedId> staged_alias;
 
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 9530c17..4f76e7d 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -104,7 +104,7 @@
   // The actual Value.
   std::unique_ptr<Value> value;
 
-  FlagStatus flag_status;
+  FlagStatus flag_status = FlagStatus::NoFlag;
 
   ResourceConfigValue(const android::ConfigDescription& config, android::StringPiece product)
       : config(config), product(product) {
@@ -271,7 +271,7 @@
   std::optional<AllowNew> allow_new;
   std::optional<StagedId> staged_id;
   bool allow_mangled = false;
-  FlagStatus flag_status;
+  FlagStatus flag_status = FlagStatus::NoFlag;
 };
 
 struct NewResourceBuilder {
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index 67a4828..1942fc11 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -212,7 +212,11 @@
     collision_result =
         ResolveMergeCollision(override_styles_instead_of_overlaying, dst_value, src_value, pool);
   } else {
-    collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value);
+    collision_result = ResourceTable::ResolveFlagCollision(dst_config_value->flag_status,
+                                                           src_config_value->flag_status);
+    if (collision_result == CollisionResult::kConflict) {
+      collision_result = ResourceTable::ResolveValueCollision(dst_value, src_value);
+    }
   }
 
   if (collision_result == CollisionResult::kConflict) {
@@ -291,6 +295,7 @@
         } else {
           dst_config_value =
               dst_entry->FindOrCreateValue(src_config_value->config, src_config_value->product);
+          dst_config_value->flag_status = src_config_value->flag_status;
         }
 
         // Continue if we're taking the new resource.