OverlayManager Fabricated RROs

Adds registering and unregistering of FabricatedOverlay to the OMS.
The process that creates the fabricated overlays owns it and is the
only process allowed to unregister it.

When a fabricated overlay is registered, overlay settings for it are
initialized in all users. When a fabricated overlay is unregistered,
it is disabled and removed from all users. When a new user is created,
it will be able to use the fabricated overlay as well.

On boot, fabricated overlays that are not referenced in overlay
settings will be deleted.

When the package that created the fabricated overlay is uninstalled,
its fabricated overlays are also unregistered.

Bug: 172471315
Test: atest OverlayDeviceTests
Change-Id: I0539656f4c919246b13129579b0286c08a398dc2
diff --git a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
index 4a348ac..4f61801 100644
--- a/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
+++ b/cmds/idmap2/libidmap2/FabricatedOverlay.cpp
@@ -208,7 +208,7 @@
   return (*data)->crc;
 }
 
-Result<Unit> FabricatedOverlay::ToBinaryStream(std::ostream& stream) {
+Result<Unit> FabricatedOverlay::ToBinaryStream(std::ostream& stream) const {
   auto data = InitializeData();
   if (!data) {
     return data.GetError();
@@ -247,19 +247,24 @@
       new FabricatedOverlayContainer(std::move(overlay), {} /* path */));
 }
 
-Result<OverlayManifestInfo> FabContainer::FindOverlayInfo(const std::string& name) const {
+OverlayManifestInfo FabContainer::GetManifestInfo() const {
   const pb::FabricatedOverlay& overlay_pb = overlay_.overlay_pb_;
-  if (name != overlay_pb.name()) {
-    return Error("Failed to find name '%s' in fabricated overlay", name.c_str());
-  }
-
   return OverlayManifestInfo{
+      .package_name = overlay_pb.package_name(),
       .name = overlay_pb.name(),
       .target_package = overlay_pb.target_package_name(),
       .target_name = overlay_pb.target_overlayable(),
   };
 }
 
+Result<OverlayManifestInfo> FabContainer::FindOverlayInfo(const std::string& name) const {
+  const OverlayManifestInfo info = GetManifestInfo();
+  if (name != info.name) {
+    return Error("Failed to find name '%s' in fabricated overlay", name.c_str());
+  }
+  return info;
+}
+
 Result<OverlayData> FabContainer::GetOverlayData(const OverlayManifestInfo& info) const {
   const pb::FabricatedOverlay& overlay_pb = overlay_.overlay_pb_;
   if (info.name != overlay_pb.name()) {
diff --git a/cmds/idmap2/libidmap2/FileUtils.cpp b/cmds/idmap2/libidmap2/FileUtils.cpp
index 3af1f70..98a4cea 100644
--- a/cmds/idmap2/libidmap2/FileUtils.cpp
+++ b/cmds/idmap2/libidmap2/FileUtils.cpp
@@ -47,4 +47,19 @@
 }
 #endif
 
+std::string RandomStringForPath(const size_t length) {
+  constexpr char kChars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  constexpr size_t kCharLastIndex = sizeof(kChars) - 1;
+
+  std::string out_rand;
+  out_rand.reserve(length);
+
+  std::random_device rd;
+  std::uniform_int_distribution<int> dist(0, kCharLastIndex);
+  for (size_t i = 0; i < length; i++) {
+    out_rand[i] = kChars[dist(rd) % (kCharLastIndex)];
+  }
+  return out_rand;
+}
+
 }  // namespace android::idmap2::utils
diff --git a/cmds/idmap2/libidmap2/ResourceContainer.cpp b/cmds/idmap2/libidmap2/ResourceContainer.cpp
index 91cb43c..9147cca 100644
--- a/cmds/idmap2/libidmap2/ResourceContainer.cpp
+++ b/cmds/idmap2/libidmap2/ResourceContainer.cpp
@@ -118,15 +118,23 @@
     return Error("root element tag is not <manifest> in AndroidManifest.xml");
   }
 
+  std::string package_name;
+  if (auto result_str = manifest_it->GetAttributeStringValue("package")) {
+    package_name = *result_str;
+  } else {
+    return result_str.GetError();
+  }
+
   for (auto&& it : manifest_it) {
     if (it.event() != XmlParser::Event::START_TAG || it.name() != "overlay") {
       continue;
     }
 
     OverlayManifestInfo info{};
+    info.package_name = package_name;
     if (auto result_str = it.GetAttributeStringValue(kAttrName, "android:name")) {
       if (*result_str != name) {
-        // A value for android:name was found, but either the name does not match the requested
+        // A value for android:name was found, but either a the name does not match the requested
         // name, or an <overlay> tag with no name was requested.
         continue;
       }