AAPT2: include package name in styleable children

When writing partial R files, also include the package of the styleable
child:
<declare-styleable name="ds1">
    <attr name="font"/>
    <attr name="android:font"/>
    <attr name="tools:font"/>
    <attr name="com.foo.bar:font"/>
</declare-styleable>
will produce:
default int styleable ds1_font
default int styleable ds1_android_font
default int styleable ds1_tools_font
default int styleable ds1_com_foo_bar_font

Bug: 73927419
Test: manual, see description
Change-Id: Ica493408c7c6d9e7fae2b693c96fbc20a723ce08
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 6fe8610..a17a0d3 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -30,6 +30,7 @@
 #include "Flags.h"
 #include "ResourceParser.h"
 #include "ResourceTable.h"
+#include "cmd/Util.h"
 #include "compile/IdAssigner.h"
 #include "compile/InlineXmlFormatParser.h"
 #include "compile/Png.h"
@@ -328,6 +329,12 @@
                 // nested under their parent and use its visibility.
                 r_txt_printer.Print("default int styleable ");
                 r_txt_printer.Print(entry->name);
+                // If the package name is present, also include it in the mangled name (e.g.
+                // "android")
+                if (!attr.name.value().package.empty()) {
+                  r_txt_printer.Print("_");
+                  r_txt_printer.Print(MakePackageSafeName(attr.name.value().package));
+                }
                 r_txt_printer.Print("_");
                 r_txt_printer.Println(attr.name.value().entry);
               }
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index 8b3a670..4e77e9a 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -145,7 +145,7 @@
 //
 // See frameworks/base/core/java/android/content/pm/PackageParser.java which
 // checks this at runtime.
-static std::string MakePackageSafeName(const std::string &name) {
+std::string MakePackageSafeName(const std::string &name) {
   std::string result(name);
   bool first = true;
   for (char &c : result) {
diff --git a/tools/aapt2/cmd/Util.h b/tools/aapt2/cmd/Util.h
index 7611c15..fb8753e 100644
--- a/tools/aapt2/cmd/Util.h
+++ b/tools/aapt2/cmd/Util.h
@@ -60,6 +60,13 @@
 Maybe<AppInfo> ExtractAppInfoFromBinaryManifest(const xml::XmlResource& xml_res,
                                                 IDiagnostics* diag);
 
+// Returns a copy of 'name' which conforms to the regex '[a-zA-Z]+[a-zA-Z0-9_]*' by
+// replacing nonconforming characters with underscores.
+//
+// See frameworks/base/core/java/android/content/pm/PackageParser.java which
+// checks this at runtime.
+std::string MakePackageSafeName(const std::string &name);
+
 }  // namespace aapt
 
 #endif /* AAPT_SPLIT_UTIL_H */