Accept weak-weak merge, if one side has no format specified, as auto-resolvable.

There are dozens of conflicts among appcompat and Material that would get auto-resolved as a result of this change. The alternative would be to get them to promote all their weak attribute definitions to strong.

RELNOTES: None.
PiperOrigin-RevId: 244071490
diff --git a/src/test/java/com/google/devtools/build/android/AttributeResourcesAndroidDataMergerTest.java b/src/test/java/com/google/devtools/build/android/AttributeResourcesAndroidDataMergerTest.java
index a306e06..3913245 100644
--- a/src/test/java/com/google/devtools/build/android/AttributeResourcesAndroidDataMergerTest.java
+++ b/src/test/java/com/google/devtools/build/android/AttributeResourcesAndroidDataMergerTest.java
@@ -83,17 +83,40 @@
             TestParameters.builder()
                 .set1(Strength.WEAK, 1)
                 .set2(Strength.WEAK, 0xFFFF)
-                .setExpectedMergeConflict(
+                .setExpectedMergedAndroidData(
                     ctx ->
-                        MergeConflict.of(
-                            ctx.fqnFactory.parse("attr/ambiguousName"),
-                            DataResourceXml.createWithNoNamespace(
-                                ctx.transitiveRoot1.resolve("res/values/attrs.xml"),
-                                AttrXmlResourceValue.weakFromFormatEntries(
-                                    ReferenceResourceXmlAttrValue.asEntry())),
-                            DataResourceXml.createWithNoNamespace(
-                                ctx.transitiveRoot2.resolve("res/values/attrs.xml"),
-                                AttrXmlResourceValue.weakFromFormatEntries())))
+                        UnwrittenMergedAndroidData.of(
+                            ctx.primary.getManifest(),
+                            ParsedAndroidDataBuilder.empty(),
+                            ParsedAndroidDataBuilder.buildOn(ctx.fqnFactory)
+                                .overwritable(
+                                    xml("attr/ambiguousName")
+                                        .root(ctx.primaryRoot)
+                                        .source(ctx.transitiveAttr1.overwrite(ctx.transitiveAttr2))
+                                        .value(
+                                            AttrXmlResourceValue.weakFromFormatEntries(
+                                                ReferenceResourceXmlAttrValue.asEntry())))
+                                .build()))
+                .build()
+          },
+          {
+            TestParameters.builder()
+                .set1(Strength.WEAK, 0xFFFF)
+                .set2(Strength.WEAK, 1)
+                .setExpectedMergedAndroidData(
+                    ctx ->
+                        UnwrittenMergedAndroidData.of(
+                            ctx.primary.getManifest(),
+                            ParsedAndroidDataBuilder.empty(),
+                            ParsedAndroidDataBuilder.buildOn(ctx.fqnFactory)
+                                .overwritable(
+                                    xml("attr/ambiguousName")
+                                        .root(ctx.primaryRoot)
+                                        .source(ctx.transitiveAttr2.overwrite(ctx.transitiveAttr1))
+                                        .value(
+                                            AttrXmlResourceValue.weakFromFormatEntries(
+                                                ReferenceResourceXmlAttrValue.asEntry())))
+                                .build()))
                 .build()
           },
           {
@@ -214,6 +237,24 @@
           },
           {
             TestParameters.builder()
+                .set1(Strength.WEAK, 1)
+                .set2(Strength.WEAK, 2)
+                .setExpectedMergeConflict(
+                    ctx ->
+                        MergeConflict.of(
+                            ctx.fqnFactory.parse("attr/ambiguousName"),
+                            DataResourceXml.createWithNoNamespace(
+                                ctx.transitiveRoot1.resolve("res/values/attrs.xml"),
+                                AttrXmlResourceValue.weakFromFormatEntries(
+                                    ReferenceResourceXmlAttrValue.asEntry())),
+                            DataResourceXml.createWithNoNamespace(
+                                ctx.transitiveRoot2.resolve("res/values/attrs.xml"),
+                                AttrXmlResourceValue.weakFromFormatEntries(
+                                    StringResourceXmlAttrValue.asEntry()))))
+                .build()
+          },
+          {
+            TestParameters.builder()
                 .set1(Strength.STRONG, 1)
                 .set2(Strength.WEAK, 1)
                 .setExpectedMergedAndroidData(
diff --git a/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java b/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java
index 50a7a7f..3f37fcf 100644
--- a/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java
+++ b/src/tools/android/java/com/google/devtools/build/android/xml/AttrXmlResourceValue.java
@@ -453,6 +453,12 @@
       return 1;
     } else if (!that.weak && weak && (formats.isEmpty() || formats.equals(that.formats))) {
       return -1;
+    } else if (weak && that.weak) {
+      if (!formats.isEmpty() && that.formats.isEmpty()) {
+        return 1;
+      } else if (formats.isEmpty() && !that.formats.isEmpty()) {
+        return -1;
+      }
     }
     return 0;
   }