Add enforcement of idmap policies

Teaches idmap2 to recognize policy restrictions put on overlayable
resources. If overlayable enforcement is turned on for an overlay, then
any resources defined within the overlayable api of the target will have
policy restrictions imposed on them. All resources without overlayable
definitions will continue to be overlayable without policy restrictions.

Bug: 119390857
Test: atest idmap2 and booting

Co-authored-by: Ryan Mitchell <rtmitchell@google.com>
Change-Id: I7e435648eb6e4a87b0b90a7b2a0c3f33c1516ea6
diff --git a/cmds/idmap2/libidmap2/Idmap.cpp b/cmds/idmap2/libidmap2/Idmap.cpp
index 37d6af8..2890ae1 100644
--- a/cmds/idmap2/libidmap2/Idmap.cpp
+++ b/cmds/idmap2/libidmap2/Idmap.cpp
@@ -274,11 +274,23 @@
   return std::move(idmap);
 }
 
-std::unique_ptr<const Idmap> Idmap::FromApkAssets(const std::string& target_apk_path,
-                                                  const ApkAssets& target_apk_assets,
-                                                  const std::string& overlay_apk_path,
-                                                  const ApkAssets& overlay_apk_assets,
-                                                  std::ostream& out_error) {
+bool CheckOverlayable(const LoadedPackage& target_package, PolicyBitmask fulfilled_polices,
+                      ResourceId resid) {
+  const OverlayableInfo* info = target_package.GetOverlayableInfo(resid);
+  if (info == nullptr) {
+    // If the resource does not have an overlayable definition, allow the resource to be overlaid.
+    // Once overlayable enforcement is turned on, this check will return false.
+    return true;
+  }
+
+  // Enforce policy restrictions if the resource is declared as overlayable.
+  return (info->policy_flags & fulfilled_polices) != 0;
+}
+
+std::unique_ptr<const Idmap> Idmap::FromApkAssets(
+    const std::string& target_apk_path, const ApkAssets& target_apk_assets,
+    const std::string& overlay_apk_path, const ApkAssets& overlay_apk_assets,
+    const PolicyBitmask& fulfilled_policies, bool enforce_overlayable, std::ostream& out_error) {
   AssetManager2 target_asset_manager;
   if (!target_asset_manager.SetApkAssets({&target_apk_assets}, true, false)) {
     out_error << "error: failed to create target asset manager" << std::endl;
@@ -380,6 +392,15 @@
     if (target_resid == 0) {
       continue;
     }
+
+    if (enforce_overlayable && !CheckOverlayable(*target_pkg, fulfilled_policies, target_resid)) {
+      // The resources must be defined as overlayable and the overlay must fulfill at least one
+      // policy enforced on the overlayable resource
+      LOG(WARNING) << "overlay \"" << overlay_apk_path << "\" is not allowed to overlay resource \""
+                   << full_name << "\"" << std::endl;
+      continue;
+    }
+
     matching_resources.Add(target_resid, overlay_resid);
   }