Refactor overlayable policy

To make it easier to add the actor policy in a follow up CL,
move most of the policy handling to a central location.

The strings and transformation between strings and flags is
now handled in libidmap2policies, with libandroidfw
containing the single source of policy flags.

This also extracts all the test resource IDs into an R.h
so they can be swapped without having to edit a dozen files
each time.

Bug: 130563563

Test: m aapt2_tests idmapt2_tests and run from host test output
Test: atest libandroidfw_tests

Change-Id: Ie533c9cebf938215df7586f00c38763ae467e606
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 74e2a098..234cbc4 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -32,11 +32,15 @@
 #include "util/Util.h"
 #include "xml/XmlPullParser.h"
 
+#include "idmap2/Policies.h"
+
 using ::aapt::ResourceUtils::StringBuilder;
 using ::aapt::text::Utf8Iterator;
 using ::android::ConfigDescription;
 using ::android::StringPiece;
 
+using android::idmap2::policy::kPolicyStringToFlag;
+
 namespace aapt {
 
 constexpr const char* sXliffNamespaceUri = "urn:oasis:names:tc:xliff:document:1.2";
@@ -1063,7 +1067,7 @@
 
   bool error = false;
   std::string comment;
-  OverlayableItem::PolicyFlags current_policies = OverlayableItem::Policy::kNone;
+  PolicyFlags current_policies = PolicyFlags::NONE;
   const size_t start_depth = parser->depth();
   while (xml::XmlPullParser::IsGoodEvent(parser->Next())) {
     xml::XmlPullParser::Event event = parser->event();
@@ -1073,7 +1077,7 @@
     } else if (event == xml::XmlPullParser::Event::kEndElement
                && parser->depth() == start_depth + 1) {
       // Clear the current policies when exiting the <policy> tags
-      current_policies = OverlayableItem::Policy::kNone;
+      current_policies = PolicyFlags::NONE;
       continue;
     } else if (event == xml::XmlPullParser::Event::kComment) {
       // Retrieve the comment of individual <item> tags
@@ -1088,7 +1092,7 @@
     const std::string& element_name = parser->element_name();
     const std::string& element_namespace = parser->element_namespace();
     if (element_namespace.empty() && element_name == "item") {
-      if (current_policies == OverlayableItem::Policy::kNone) {
+      if (current_policies == PolicyFlags::NONE) {
         diag_->Error(DiagMessage(element_source)
                          << "<item> within an <overlayable> must be inside a <policy> block");
         error = true;
@@ -1133,7 +1137,7 @@
       out_resource->child_resources.push_back(std::move(child_resource));
 
     } else if (element_namespace.empty() && element_name == "policy") {
-      if (current_policies != OverlayableItem::Policy::kNone) {
+      if (current_policies != PolicyFlags::NONE) {
         // If the policy list is not empty, then we are currently inside a policy element
         diag_->Error(DiagMessage(element_source) << "<policy> blocks cannot be recursively nested");
         error = true;
@@ -1141,21 +1145,14 @@
       } else if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
         // Parse the polices separated by vertical bar characters to allow for specifying multiple
         // policies. Items within the policy tag will have the specified policy.
-        static const auto kPolicyMap =
-            ImmutableMap<StringPiece, OverlayableItem::Policy>::CreatePreSorted({
-                {"odm", OverlayableItem::Policy::kOdm},
-                {"oem", OverlayableItem::Policy::kOem},
-                {"product", OverlayableItem::Policy::kProduct},
-                {"public", OverlayableItem::Policy::kPublic},
-                {"signature", OverlayableItem::Policy::kSignature},
-                {"system", OverlayableItem::Policy::kSystem},
-                {"vendor", OverlayableItem::Policy::kVendor},
-            });
-
         for (const StringPiece& part : util::Tokenize(maybe_type.value(), '|')) {
           StringPiece trimmed_part = util::TrimWhitespace(part);
-          const auto policy = kPolicyMap.find(trimmed_part);
-          if (policy == kPolicyMap.end()) {
+          const auto policy = std::find_if(kPolicyStringToFlag.begin(),
+                                           kPolicyStringToFlag.end(),
+                                           [trimmed_part](const auto& it) {
+                                             return trimmed_part == it.first;
+                                           });
+          if (policy == kPolicyStringToFlag.end()) {
             diag_->Error(DiagMessage(element_source)
                          << "<policy> has unsupported type '" << trimmed_part << "'");
             error = true;