AAPT2: add flag for strict visibility

Will only detect whether a resource was defined as both 'public' and
'private' (but will allow overriding 'undefined' visiblity for now).

Test: TableMerger_test + manual
Bug: 72735798

Change-Id: If0749559c91c4d8820a6286fc9ddc80209c1e5e9
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index e819f51..91a55b3 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -102,7 +102,17 @@
 }
 
 static bool MergeEntry(IAaptContext* context, const Source& src, bool overlay,
-                       ResourceEntry* dst_entry, ResourceEntry* src_entry) {
+                       ResourceEntry* dst_entry, ResourceEntry* src_entry,
+                       bool strict_visibility) {
+  if (strict_visibility
+      && dst_entry->visibility.level != Visibility::Level::kUndefined
+      && src_entry->visibility.level != dst_entry->visibility.level) {
+      context->GetDiagnostics()->Error(
+          DiagMessage(src) << "cannot merge resource '" << dst_entry->name << "' with conflicting visibilities: "
+                           << "public and private");
+    return false;
+  }
+
   // Copy over the strongest visibility.
   if (src_entry->visibility.level > dst_entry->visibility.level) {
     // Only copy the ID if the source is public, or else the ID is meaningless.
@@ -234,7 +244,7 @@
         continue;
       }
 
-      if (!MergeEntry(context_, src, overlay, dst_entry, src_entry.get())) {
+      if (!MergeEntry(context_, src, overlay, dst_entry, src_entry.get(), options_.strict_visibility)) {
         error = true;
         continue;
       }