Accept --overlay-name flag in idmap2

To support allowing for multiple <overlay> tags in one package, idmap2
must be able to generate an idmap for an individual <overlay> tag.

`idmap2 create` now accepts a --overlay-name flag that specifies which
tag to use to generate the idmap. The value of --overlay-name should be
set to the value of the android:name attribute on the <overlay> tag to
use.

If the flag is not present, idmap2 will look for an <overlay> tag with
no value for android:name.

Bug: 162841629
Test: libandroidfw_tests
Test: libidmap2_tests
Change-Id: I02316d0b88773f02c04a5d462be9825016fa496d
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 185e929..0362529 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -17,12 +17,10 @@
 #include <cstdio>  // fclose
 #include <fstream>
 #include <memory>
-#include <sstream>
 #include <string>
-#include <utility>
-#include <vector>
 
 #include "R.h"
+#include "TestConstants.h"
 #include "TestHelpers.h"
 #include "androidfw/ResourceTypes.h"
 #include "gmock/gmock.h"
@@ -43,38 +41,32 @@
     ASSERT_TRUE(result) << result.GetErrorMessage(); \
   } while (0)
 
-Result<ResourceMapping> TestGetResourceMapping(const android::StringPiece& local_target_apk_path,
-                                               const android::StringPiece& local_overlay_apk_path,
-                                               const OverlayManifestInfo& overlay_info,
+Result<ResourceMapping> TestGetResourceMapping(const std::string& local_target_apk_path,
+                                               const std::string& local_overlay_apk_path,
+                                               const std::string& overlay_name,
                                                const PolicyBitmask& fulfilled_policies,
                                                bool enforce_overlayable) {
-  const std::string target_apk_path(GetTestDataPath() + local_target_apk_path.data());
+  auto overlay_info =
+      ExtractOverlayManifestInfo(GetTestDataPath() + local_overlay_apk_path, overlay_name);
+  if (!overlay_info) {
+    return overlay_info.GetError();
+  }
+
+  const std::string target_apk_path(GetTestDataPath() + local_target_apk_path);
   std::unique_ptr<const ApkAssets> target_apk = ApkAssets::Load(target_apk_path);
   if (!target_apk) {
     return Error(R"(Failed to load target apk "%s")", target_apk_path.data());
   }
 
-  const std::string overlay_apk_path(GetTestDataPath() + local_overlay_apk_path.data());
+  const std::string overlay_apk_path(GetTestDataPath() + local_overlay_apk_path);
   std::unique_ptr<const ApkAssets> overlay_apk = ApkAssets::Load(overlay_apk_path);
   if (!overlay_apk) {
     return Error(R"(Failed to load overlay apk "%s")", overlay_apk_path.data());
   }
 
   LogInfo log_info;
-  return ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, overlay_info, fulfilled_policies,
-                                        enforce_overlayable, log_info);
-}
-
-Result<ResourceMapping> TestGetResourceMapping(const android::StringPiece& local_target_apk_path,
-                                               const android::StringPiece& local_overlay_apk_path,
-                                               const PolicyBitmask& fulfilled_policies,
-                                               bool enforce_overlayable) {
-  auto overlay_info = ExtractOverlayManifestInfo(GetTestDataPath() + local_overlay_apk_path.data());
-  if (!overlay_info) {
-    return overlay_info.GetError();
-  }
-  return TestGetResourceMapping(local_target_apk_path, local_overlay_apk_path, *overlay_info,
-                                fulfilled_policies, enforce_overlayable);
+  return ResourceMapping::FromApkAssets(*target_apk, *overlay_apk, *overlay_info,
+                                        fulfilled_policies, enforce_overlayable, log_info);
 }
 
 Result<Unit> MappingExists(const ResourceMapping& mapping, ResourceId target_resource,
@@ -136,13 +128,8 @@
 }
 
 TEST(ResourceMappingTests, ResourcesFromApkAssetsLegacy) {
-  OverlayManifestInfo info{};
-  info.target_package = "test.target";
-  info.target_name = "TestResources";
-  info.resource_mapping = 0U;  // no xml
-  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info,
-                                          PolicyFlags::PUBLIC,
-                                          /* enforce_overlayable */ false);
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay-legacy.apk", "",
+                                          PolicyFlags::PUBLIC, /* enforce_overlayable */ false);
 
   ASSERT_TRUE(resources) << resources.GetErrorMessage();
   auto& res = *resources;
@@ -158,11 +145,7 @@
 }
 
 TEST(ResourceMappingTests, ResourcesFromApkAssetsNonMatchingNames) {
-  OverlayManifestInfo info{};
-  info.target_package = "test.target";
-  info.target_name = "TestResources";
-  info.resource_mapping = 0x7f030003;  // xml/overlays_swap
-  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info,
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", "SwapNames",
                                           PolicyFlags::PUBLIC,
                                           /* enforce_overlayable */ false);
 
@@ -178,12 +161,8 @@
 }
 
 TEST(ResourceMappingTests, DoNotRewriteNonOverlayResourceId) {
-  OverlayManifestInfo info{};
-  info.target_package = "test.target";
-  info.target_name = "TestResources";
-  info.resource_mapping = 0x7f030001;  // xml/overlays_different_packages
-  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info,
-                                          PolicyFlags::PUBLIC,
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk",
+                                          "DifferentPackages", PolicyFlags::PUBLIC,
                                           /* enforce_overlayable */ false);
 
   ASSERT_TRUE(resources) << resources.GetErrorMessage();
@@ -192,19 +171,15 @@
   ASSERT_EQ(res.GetOverlayToTargetMap().size(), 1U);
   ASSERT_RESULT(MappingExists(res, R::target::string::str1, 0x0104000a,
                               false /* rewrite */));  // -> android:string/ok
-  ASSERT_RESULT(MappingExists(res, R::target::string::str3, 0x7f020001, true /* rewrite */));
+  ASSERT_RESULT(
+      MappingExists(res, R::target::string::str3, R::overlay::string::str3, true /* rewrite */));
 }
 
 TEST(ResourceMappingTests, InlineResources) {
-  OverlayManifestInfo info{};
-  info.target_package = "test.target";
-  info.target_name = "TestResources";
-  info.resource_mapping = 0x7f030002;  // xml/overlays_inline
-  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", info,
-                                          PolicyFlags::PUBLIC,
-                                          /* enforce_overlayable */ false);
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk", "Inline",
+                                          PolicyFlags::PUBLIC, /* enforce_overlayable */ false);
 
-  constexpr size_t overlay_string_pool_size = 8U;
+  constexpr size_t overlay_string_pool_size = 10U;
   ASSERT_TRUE(resources) << resources.GetErrorMessage();
   auto& res = *resources;
   ASSERT_EQ(res.GetTargetToOverlayMap().size(), 2U);
@@ -215,28 +190,8 @@
 }
 
 TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublic) {
-  auto resources =
-      TestGetResourceMapping("/target/target.apk", "/system-overlay/system-overlay.apk",
-                             PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC,
-                             /* enforce_overlayable */ true);
-
-  ASSERT_TRUE(resources) << resources.GetErrorMessage();
-  auto& res = *resources;
-  ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
-  ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
-                              R::system_overlay::string::policy_public, false /* rewrite */));
-  ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
-                              R::system_overlay::string::policy_system, false /* rewrite */));
-  ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
-                              R::system_overlay::string::policy_system_vendor,
-                              false /* rewrite */));
-}
-
-// Resources that are not declared as overlayable and resources that a protected by policies the
-// overlay does not fulfill must not map to overlay resources.
-TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
-  auto resources = TestGetResourceMapping("/target/target.apk",
-                                          "/system-overlay-invalid/system-overlay-invalid.apk",
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk",
+                                          TestConstants::OVERLAY_NAME_ALL_POLICIES,
                                           PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC,
                                           /* enforce_overlayable */ true);
 
@@ -244,22 +199,38 @@
   auto& res = *resources;
   ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
-                              R::system_overlay_invalid::string::policy_public,
-                              false /* rewrite */));
+                              R::overlay::string::policy_public, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
-                              R::system_overlay_invalid::string::policy_system,
-                              false /* rewrite */));
+                              R::overlay::string::policy_system, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
-                              R::system_overlay_invalid::string::policy_system_vendor,
-                              false /* rewrite */));
+                              R::overlay::string::policy_system_vendor, true /* rewrite */));
+}
+
+// Resources that are not declared as overlayable and resources that a protected by policies the
+// overlay does not fulfill must not map to overlay resources.
+TEST(ResourceMappingTests, CreateIdmapFromApkAssetsPolicySystemPublicInvalid) {
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk",
+                                          TestConstants::OVERLAY_NAME_ALL_POLICIES,
+                                          PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC,
+                                          /* enforce_overlayable */ true);
+
+  ASSERT_TRUE(resources) << resources.GetErrorMessage();
+  auto& res = *resources;
+  ASSERT_EQ(res.GetTargetToOverlayMap().size(), 3U);
+  ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
+                              R::overlay::string::policy_public, true /* rewrite */));
+  ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
+                              R::overlay::string::policy_system, true /* rewrite */));
+  ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
+                              R::overlay::string::policy_system_vendor, true /* rewrite */));
 }
 
 // Resources that are not declared as overlayable and resources that a protected by policies the
 // overlay does not fulfilled can map to overlay resources when overlayable enforcement is turned
 // off.
 TEST(ResourceMappingTests, ResourcesFromApkAssetsPolicySystemPublicInvalidIgnoreOverlayable) {
-  auto resources = TestGetResourceMapping("/target/target.apk",
-                                          "/system-overlay-invalid/system-overlay-invalid.apk",
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay.apk",
+                                          TestConstants::OVERLAY_NAME_ALL_POLICIES,
                                           PolicyFlags::SYSTEM_PARTITION | PolicyFlags::PUBLIC,
                                           /* enforce_overlayable */ false);
 
@@ -267,41 +238,33 @@
   auto& res = *resources;
   ASSERT_EQ(res.GetTargetToOverlayMap().size(), 11U);
   ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable,
-                              R::system_overlay_invalid::string::not_overlayable,
-                              false /* rewrite */));
-  ASSERT_RESULT(MappingExists(res, R::target::string::other,
-                              R::system_overlay_invalid::string::other, false /* rewrite */));
+                              R::overlay::string::not_overlayable, true /* rewrite */));
+  ASSERT_RESULT(
+      MappingExists(res, R::target::string::other, R::overlay::string::other, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor,
-                              R::system_overlay_invalid::string::policy_actor,
-                              false /* rewrite */));
-  ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm,
-                              R::system_overlay_invalid::string::policy_odm, false /* rewrite */));
-  ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem,
-                              R::system_overlay_invalid::string::policy_oem, false /* rewrite */));
+                              R::overlay::string::policy_actor, true /* rewrite */));
+  ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, R::overlay::string::policy_odm,
+                              true /* rewrite */));
+  ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, R::overlay::string::policy_oem,
+                              true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_product,
-                              R::system_overlay_invalid::string::policy_product,
-                              false /* rewrite */));
+                              R::overlay::string::policy_product, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
-                              R::system_overlay_invalid::string::policy_public,
-                              false /* rewrite */));
+                              R::overlay::string::policy_public, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
-                              R::system_overlay_invalid::string::policy_config_signature,
-                              false /* rewrite */));
+                              R::overlay::string::policy_config_signature, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature,
-                              R::system_overlay_invalid::string::policy_signature,
-                              false /* rewrite */));
+                              R::overlay::string::policy_signature, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
-                              R::system_overlay_invalid::string::policy_system,
-                              false /* rewrite */));
+                              R::overlay::string::policy_system, true /* rewrite */));
   ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
-                              R::system_overlay_invalid::string::policy_system_vendor,
-                              false /* rewrite */));
+                              R::overlay::string::policy_system_vendor, true /* rewrite */));
 }
 
-// Overlays that do not target an <overlayable> tag can overlay resources defined within any
-// <overlayable> tag.
+// Overlays that do not target an <overlayable> tag can overlay any resource if overlayable
+// enforcement is disabled.
 TEST(ResourceMappingTests, ResourcesFromApkAssetsNoDefinedOverlayableAndNoTargetName) {
-  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay-no-name.apk",
+  auto resources = TestGetResourceMapping("/target/target.apk", "/overlay/overlay-legacy.apk", "",
                                           PolicyFlags::PUBLIC,
                                           /* enforce_overlayable */ false);
 
@@ -321,9 +284,10 @@
 // Overlays that are neither pre-installed nor signed with the same signature as the target cannot
 // overlay packages that have not defined overlayable resources.
 TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPoliciesPublicFail) {
-  auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
-                                          "/overlay/overlay-no-name.apk", PolicyFlags::PUBLIC,
-                                          /* enforce_overlayable */ true);
+  auto resources =
+      TestGetResourceMapping("/target/target-no-overlayable.apk", "/overlay/overlay.apk",
+                             "NoTargetName", PolicyFlags::PUBLIC,
+                             /* enforce_overlayable */ true);
 
   ASSERT_TRUE(resources) << resources.GetErrorMessage();
   ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 0U);
@@ -334,46 +298,36 @@
 // defined overlayable resources.
 TEST(ResourceMappingTests, ResourcesFromApkAssetsDefaultPolicies) {
   auto CheckEntries = [&](const PolicyBitmask& fulfilled_policies) -> void {
-    auto resources = TestGetResourceMapping("/target/target-no-overlayable.apk",
-                                            "/system-overlay-invalid/system-overlay-invalid.apk",
-                                            fulfilled_policies,
-                                            /* enforce_overlayable */ true);
+    auto resources =
+        TestGetResourceMapping("/target/target-no-overlayable.apk", "/overlay/overlay.apk",
+                               TestConstants::OVERLAY_NAME_ALL_POLICIES, fulfilled_policies,
+                               /* enforce_overlayable */ true);
 
     ASSERT_TRUE(resources) << resources.GetErrorMessage();
     auto& res = *resources;
     ASSERT_EQ(resources->GetTargetToOverlayMap().size(), 11U);
     ASSERT_RESULT(MappingExists(res, R::target::string::not_overlayable,
-                                R::system_overlay_invalid::string::not_overlayable,
-                                false /* rewrite */));
-    ASSERT_RESULT(MappingExists(res, R::target::string::other,
-                                R::system_overlay_invalid::string::other, false /* rewrite */));
+                                R::overlay::string::not_overlayable, true /* rewrite */));
+    ASSERT_RESULT(MappingExists(res, R::target::string::other, R::overlay::string::other,
+                                true /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_actor,
-                                R::system_overlay_invalid::string::policy_actor,
-                                false /* rewrite */));
-    ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm,
-                                R::system_overlay_invalid::string::policy_odm,
-                                false /* rewrite */));
-    ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem,
-                                R::system_overlay_invalid::string::policy_oem,
-                                false /* rewrite */));
+                                R::overlay::string::policy_actor, true /* rewrite */));
+    ASSERT_RESULT(MappingExists(res, R::target::string::policy_odm, R::overlay::string::policy_odm,
+                                true /* rewrite */));
+    ASSERT_RESULT(MappingExists(res, R::target::string::policy_oem, R::overlay::string::policy_oem,
+                                true /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_product,
-                                R::system_overlay_invalid::string::policy_product,
-                                false /* rewrite */));
+                                R::overlay::string::policy_product, true /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_public,
-                                R::system_overlay_invalid::string::policy_public,
-                                false /* rewrite */));
+                                R::overlay::string::policy_public, true /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_config_signature,
-                                R::system_overlay_invalid::string::policy_config_signature,
-                                false /* rewrite */));
+                                R::overlay::string::policy_config_signature, true /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_signature,
-                                R::system_overlay_invalid::string::policy_signature,
-                                false /* rewrite */));
+                                R::overlay::string::policy_signature, true /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_system,
-                                R::system_overlay_invalid::string::policy_system,
-                                false /* rewrite */));
+                                R::overlay::string::policy_system, true /* rewrite */));
     ASSERT_RESULT(MappingExists(res, R::target::string::policy_system_vendor,
-                                R::system_overlay_invalid::string::policy_system_vendor,
-                                false /* rewrite */));
+                                R::overlay::string::policy_system_vendor, true /* rewrite */));
   };
 
   CheckEntries(PolicyFlags::SIGNATURE);