AAPT2: Fix issue where exported symbols (@+id/*) were not exported

Test: make AaptTestAppOne
Change-Id: If3218c880e83c2cfaf535a099db38504471be676
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index e94c0b4..d2aebfd 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -36,6 +36,7 @@
 #include "ValueVisitor.h"
 #include "cmd/Util.h"
 #include "compile/IdAssigner.h"
+#include "compile/XmlIdCollector.h"
 #include "filter/ConfigFilter.h"
 #include "format/Archive.h"
 #include "format/Container.h"
@@ -1235,19 +1236,10 @@
     return true;
   }
 
-  bool MergeCompiledFile(const ResourceFile& compiled_file, io::IFile* file, bool override) {
-    if (context_->IsVerbose()) {
-      context_->GetDiagnostics()->Note(DiagMessage()
-                                       << "merging '" << compiled_file.name
-                                       << "' from compiled file " << compiled_file.source);
-    }
-
-    if (!table_merger_->MergeFile(compiled_file, override, file)) {
-      return false;
-    }
-
+  bool MergeExportedSymbols(const Source& source,
+                            const std::vector<SourcedResourceName>& exported_symbols) {
     // Add the exports of this file to the table.
-    for (const SourcedResourceName& exported_symbol : compiled_file.exported_symbols) {
+    for (const SourcedResourceName& exported_symbol : exported_symbols) {
       ResourceName res_name = exported_symbol.name;
       if (res_name.package.empty()) {
         res_name.package = context_->GetCompilationPackage();
@@ -1259,7 +1251,7 @@
       }
 
       std::unique_ptr<Id> id = util::make_unique<Id>();
-      id->SetSource(compiled_file.source.WithLine(exported_symbol.line));
+      id->SetSource(source.WithLine(exported_symbol.line));
       bool result = final_table_.AddResourceAllowMangled(
           res_name, ConfigDescription::DefaultConfig(), std::string(), std::move(id),
           context_->GetDiagnostics());
@@ -1270,6 +1262,19 @@
     return true;
   }
 
+  bool MergeCompiledFile(const ResourceFile& compiled_file, io::IFile* file, bool override) {
+    if (context_->IsVerbose()) {
+      context_->GetDiagnostics()->Note(DiagMessage()
+                                       << "merging '" << compiled_file.name
+                                       << "' from compiled file " << compiled_file.source);
+    }
+
+    if (!table_merger_->MergeFile(compiled_file, override, file)) {
+      return false;
+    }
+    return MergeExportedSymbols(compiled_file.source, compiled_file.exported_symbols);
+  }
+
   // Takes a path to load as a ZIP file and merges the files within into the master ResourceTable.
   // If override is true, conflicting resources are allowed to override each other, in order of last
   // seen.
@@ -1573,6 +1578,19 @@
                                                        context_->GetPackageId()));
     }
 
+    // Extract symbols from AndroidManifest.xml, since this isn't merged like the other XML files
+    // in res/**/*.
+    {
+      XmlIdCollector collector;
+      if (!collector.Consume(context_, manifest_xml.get())) {
+        return false;
+      }
+
+      if (!MergeExportedSymbols(manifest_xml->file.source, manifest_xml->file.exported_symbols)) {
+        return false;
+      }
+    }
+
     for (const std::string& input : input_files) {
       if (!MergePath(input, false)) {
         context_->GetDiagnostics()->Error(DiagMessage() << "failed parsing input");