AAPT2: Support static lib referencing static lib

When a static library A references static library B,
and app C references both A and B, we get the following symbol merging,
symbols from library B get imported twice.

We must only check that symbol references to library B are valid
when building library A. We should only merge all the symbols
when building final app C.

Change-Id: I23cba33b0901dcbb5328d9c9dfaa6a979c073c36
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 9468860..c93ecc7 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -42,6 +42,8 @@
 }
 
 ResourceTable::ResourceTable() : mPackageId(kUnsetPackageId) {
+    // Make sure attrs always have type ID 1.
+    findOrCreateType(ResourceType::kAttr)->typeId = 1;
 }
 
 std::unique_ptr<ResourceTableType>& ResourceTable::findOrCreateType(ResourceType type) {
@@ -142,10 +144,30 @@
 }
 
 static constexpr const char16_t* kValidNameChars = u"._-";
+static constexpr const char16_t* kValidNameMangledChars = u"._-$";
+
+bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config,
+                                const SourceLine& source, std::unique_ptr<Value> value) {
+    return addResourceImpl(name, ResourceId{}, config, source, std::move(value), kValidNameChars);
+}
 
 bool ResourceTable::addResource(const ResourceNameRef& name, const ResourceId resId,
-        const ConfigDescription& config, const SourceLine& source,
-        std::unique_ptr<Value> value) {
+                                const ConfigDescription& config, const SourceLine& source,
+                                std::unique_ptr<Value> value) {
+    return addResourceImpl(name, resId, config, source, std::move(value), kValidNameChars);
+}
+
+bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
+                                            const ConfigDescription& config,
+                                            const SourceLine& source,
+                                            std::unique_ptr<Value> value) {
+    return addResourceImpl(name, ResourceId{}, config, source, std::move(value),
+                           kValidNameMangledChars);
+}
+
+bool ResourceTable::addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
+                                    const ConfigDescription& config, const SourceLine& source,
+                                    std::unique_ptr<Value> value, const char16_t* validChars) {
     if (!name.package.empty() && name.package != mPackage) {
         Logger::error(source)
                 << "resource '"
@@ -157,7 +179,7 @@
         return false;
     }
 
-    auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, kValidNameChars);
+    auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, validChars);
     if (badCharIter != name.entry.end()) {
         Logger::error(source)
                 << "resource '"
@@ -233,13 +255,18 @@
     return true;
 }
 
-bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config,
-                                const SourceLine& source, std::unique_ptr<Value> value) {
-    return addResource(name, ResourceId{}, config, source, std::move(value));
-}
-
 bool ResourceTable::markPublic(const ResourceNameRef& name, const ResourceId resId,
                                const SourceLine& source) {
+    return markPublicImpl(name, resId, source, kValidNameChars);
+}
+
+bool ResourceTable::markPublicAllowMangled(const ResourceNameRef& name, const ResourceId resId,
+                                           const SourceLine& source) {
+    return markPublicImpl(name, resId, source, kValidNameMangledChars);
+}
+
+bool ResourceTable::markPublicImpl(const ResourceNameRef& name, const ResourceId resId,
+                                   const SourceLine& source, const char16_t* validChars) {
     if (!name.package.empty() && name.package != mPackage) {
         Logger::error(source)
                 << "resource '"
@@ -251,7 +278,7 @@
         return false;
     }
 
-    auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, kValidNameChars);
+    auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, validChars);
     if (badCharIter != name.entry.end()) {
         Logger::error(source)
                 << "resource '"