Merge "AAPT2: Allow to inline XML into custom attribute"
diff --git a/tools/aapt2/compile/InlineXmlFormatParser.cpp b/tools/aapt2/compile/InlineXmlFormatParser.cpp
index 238e339..79b0933 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser.cpp
+++ b/tools/aapt2/compile/InlineXmlFormatParser.cpp
@@ -65,10 +65,6 @@
     }
 
     const ResourceName& name = ref.value().name.value();
-
-    // Use an empty string for the compilation package because we don't want to default to
-    // the local package if the user specified name="style" or something. This should just
-    // be the default namespace.
     Maybe<xml::ExtractedPackage> maybe_pkg = TransformPackageAlias(name.package);
     if (!maybe_pkg) {
       context_->GetDiagnostics()->Error(DiagMessage(src)
@@ -83,8 +79,15 @@
     InlineDeclaration decl;
     decl.el = el;
     decl.attr_name = name.entry;
-    if (!pkg.package.empty()) {
-      decl.attr_namespace_uri = xml::BuildPackageNamespace(pkg.package, private_namespace);
+
+    // We need to differentiate between no-namespace defined, or the alias resolves to an empty
+    // package, which means we must use the res-auto schema.
+    if (!name.package.empty()) {
+      if (pkg.package.empty()) {
+        decl.attr_namespace_uri = xml::kSchemaAuto;
+      } else {
+        decl.attr_namespace_uri = xml::BuildPackageNamespace(pkg.package, private_namespace);
+      }
     }
 
     inline_declarations_.push_back(std::move(decl));
diff --git a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
index 2b4ab96..ca4e01a 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
+++ b/tools/aapt2/compile/InlineXmlFormatParser_test.cpp
@@ -184,4 +184,42 @@
   // Confirm that all of the nested inline xmls are parsed out.
   ASSERT_THAT(parser.GetExtractedInlineXmlDocuments(), SizeIs(8u));
 }
+
+TEST(InlineXmlFormatParserTest, ExtractIntoAppAttribute) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <parent xmlns:app="http://schemas.android.com/apk/res-auto"
+              xmlns:aapt="http://schemas.android.com/aapt">
+            <aapt:attr name="app:foo">
+                <child />
+            </aapt:attr>
+      </parent>)");
+
+  doc->file.name = test::ParseNameOrDie("layout/main");
+
+  InlineXmlFormatParser parser;
+  ASSERT_TRUE(parser.Consume(context.get(), doc.get()));
+
+  ASSERT_THAT(doc->root, NotNull());
+  EXPECT_THAT(doc->root->FindAttribute(xml::kSchemaAuto, "foo"), NotNull());
+}
+
+TEST(InlineXmlFormatParserTest, ExtractIntoNoNamespaceAttribute) {
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<xml::XmlResource> doc = test::BuildXmlDom(R"(
+      <parent xmlns:aapt="http://schemas.android.com/aapt">
+            <aapt:attr name="foo">
+                <child />
+            </aapt:attr>
+      </parent>)");
+
+  doc->file.name = test::ParseNameOrDie("layout/main");
+
+  InlineXmlFormatParser parser;
+  ASSERT_TRUE(parser.Consume(context.get(), doc.get()));
+
+  ASSERT_THAT(doc->root, NotNull());
+  EXPECT_THAT(doc->root->FindAttribute({}, "foo"), NotNull());
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/xml/XmlDom_test.cpp b/tools/aapt2/xml/XmlDom_test.cpp
index 486b53a..ca46d53 100644
--- a/tools/aapt2/xml/XmlDom_test.cpp
+++ b/tools/aapt2/xml/XmlDom_test.cpp
@@ -154,6 +154,12 @@
       EXPECT_THAT(TransformPackageAlias("two"), Eq(make_value(ExtractedPackage{"com.two", false})));
       EXPECT_THAT(TransformPackageAlias("three"),
                   Eq(make_value(ExtractedPackage{"com.three", false})));
+    } else if (el->name == "View4") {
+      EXPECT_THAT(TransformPackageAlias("one"), Eq(make_value(ExtractedPackage{"com.one", false})));
+      EXPECT_THAT(TransformPackageAlias("two"), Eq(make_value(ExtractedPackage{"com.two", false})));
+      EXPECT_THAT(TransformPackageAlias("three"),
+                  Eq(make_value(ExtractedPackage{"com.three", false})));
+      EXPECT_THAT(TransformPackageAlias("four"), Eq(make_value(ExtractedPackage{"", true})));
     }
   }
 };
@@ -162,7 +168,9 @@
   std::unique_ptr<XmlResource> doc = test::BuildXmlDom(R"(
       <View1 xmlns:one="http://schemas.android.com/apk/res/com.one">
         <View2 xmlns:two="http://schemas.android.com/apk/res/com.two">
-          <View3 xmlns:three="http://schemas.android.com/apk/res/com.three" />
+          <View3 xmlns:three="http://schemas.android.com/apk/res/com.three">
+            <View4 xmlns:four="http://schemas.android.com/apk/res-auto" />
+          </View3>
         </View2>
       </View1>)");