Handle multiple packages of same name in 'aapt2 convert'

aapt2 currently looks-up packages only by package name and then verifies
whether the package ID has the expected value. For pre-L we need to be able
to handle resource tables having packages of same package name but
different IDs.

Note that this CL fixes only proto->binary conversion but many other aapt2
commands are still affected. This is because many transformations still
consider package name as sufficient identifier of a package.

Bug: 72143207
Test: Manual
Change-Id: Id8a920d6cd15bec747d3124270f5bcb7f48924cf
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 9905f82..95bf921 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -47,6 +47,13 @@
   return lhs->name.compare(0, lhs->name.size(), rhs.data(), rhs.size()) < 0;
 }
 
+template <typename T>
+static bool less_than_struct_with_name_and_id(const std::unique_ptr<T>& lhs,
+                                              const std::pair<StringPiece, Maybe<uint8_t>>& rhs) {
+  int name_cmp = lhs->name.compare(0, lhs->name.size(), rhs.first.data(), rhs.first.size());
+  return name_cmp < 0 || (name_cmp == 0 && lhs->id < rhs.second);
+}
+
 ResourceTablePackage* ResourceTable::FindPackage(const StringPiece& name) const {
   const auto last = packages.end();
   auto iter = std::lower_bound(packages.begin(), last, name,
@@ -79,6 +86,22 @@
   return package;
 }
 
+ResourceTablePackage* ResourceTable::CreatePackageAllowingDuplicateNames(const StringPiece& name,
+                                                                         const Maybe<uint8_t> id) {
+  const auto last = packages.end();
+  auto iter = std::lower_bound(packages.begin(), last, std::make_pair(name, id),
+                               less_than_struct_with_name_and_id<ResourceTablePackage>);
+
+  if (iter != last && name == (*iter)->name && id == (*iter)->id) {
+    return iter->get();
+  }
+
+  std::unique_ptr<ResourceTablePackage> new_package = util::make_unique<ResourceTablePackage>();
+  new_package->name = name.to_string();
+  new_package->id = id;
+  return packages.emplace(iter, std::move(new_package))->get();
+}
+
 ResourceTablePackage* ResourceTable::FindOrCreatePackage(const StringPiece& name) {
   const auto last = packages.end();
   auto iter = std::lower_bound(packages.begin(), last, name,