Add OverlayManagerImpl to create frro, idmap and get overlayInfos

Add OverlayManagerImpl to let applications create frro and idmap files
for overlaying itself's android resources.
* OverlayManagerImpl.java
  * check the FabricatedOverlayInternal.
* com_android_internal_content_om_OverlayManagerImpl.cpp
  * convert and read Java objects to native data.
  * call the APIs in libidmap2 to create frro and idmap files.

Add OverlayManagerImpl.cpp into AndroidRuntime by modifying Android.bp
* Add register_com_android_internal_content_om_OverlayManagerImpl
  register JNI methods
* add com_android_internal_content_om_OverlayManagerImpl.cpp
    * It's a adapter to delegate the tasks to SelfTargeting.cpp
    * dynamic link with libidmap2 by using dlopen and dlsym to call
      functions in libidmap2.

Add SelfTargeting.cpp into libidmap2
* createFrroFile
* createIdmapFile
* getFabricatedOverlayInfo

for interoperability between libandroid_runtime and libidmap2.
* move OverlayManifestInfo from libidmap2 to libandroidfw
* add FabricatedOverlayEntryParameters into libandroidfw

Bug: 205919743

Test: build
Test: atest \
                  OverlayHostTests \
                  OverlayDeviceTests \
                  SelfTargetingOverlayDeviceTests \
                  OverlayRemountedTest \
                  FrameworksServicesTests:com.android.server.om \
                  CtsContentTestCases:android.content.om.cts \
                  idmap2_tests

Change-Id: I5425f3229e9a3858e57427ef84e6abaf32e89b6e
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 7a08cbd..5f06c97 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -71,6 +71,7 @@
     host_supported: true,
     srcs: [
         "libidmap2/**/*.cpp",
+        "self_targeting/*.cpp",
     ],
     export_include_dirs: ["include"],
     target: {
diff --git a/cmds/idmap2/include/idmap2/ResourceContainer.h b/cmds/idmap2/include/idmap2/ResourceContainer.h
index 2452ff0..4d28321 100644
--- a/cmds/idmap2/include/idmap2/ResourceContainer.h
+++ b/cmds/idmap2/include/idmap2/ResourceContainer.h
@@ -46,14 +46,6 @@
   ~TargetResourceContainer() override = default;
 };
 
-struct OverlayManifestInfo {
-  std::string package_name;     // NOLINT(misc-non-private-member-variables-in-classes)
-  std::string name;             // NOLINT(misc-non-private-member-variables-in-classes)
-  std::string target_package;   // NOLINT(misc-non-private-member-variables-in-classes)
-  std::string target_name;      // NOLINT(misc-non-private-member-variables-in-classes)
-  ResourceId resource_mapping;  // NOLINT(misc-non-private-member-variables-in-classes)
-};
-
 struct OverlayData {
   struct ResourceIdValue {
     // The overlay resource id.
diff --git a/cmds/idmap2/include/idmap2/ResourceUtils.h b/cmds/idmap2/include/idmap2/ResourceUtils.h
index 2214a83..c2b0abe 100644
--- a/cmds/idmap2/include/idmap2/ResourceUtils.h
+++ b/cmds/idmap2/include/idmap2/ResourceUtils.h
@@ -30,13 +30,13 @@
 #define EXTRACT_ENTRY(resid) (0x0000ffff & (resid))
 
 // use typedefs to let the compiler warn us about implicit casts
-using ResourceId = uint32_t;  // 0xpptteeee
+using ResourceId = android::ResourceId;  // 0xpptteeee
 using PackageId = uint8_t;    // pp in 0xpptteeee
 using TypeId = uint8_t;       // tt in 0xpptteeee
 using EntryId = uint16_t;     // eeee in 0xpptteeee
 
-using DataType = uint8_t;    // Res_value::dataType
-using DataValue = uint32_t;  // Res_value::data
+using DataType = android::DataType;    // Res_value::dataType
+using DataValue = android::DataValue;  // Res_value::data
 
 struct TargetValue {
   DataType data_type;
diff --git a/cmds/idmap2/self_targeting/SelfTargeting.cpp b/cmds/idmap2/self_targeting/SelfTargeting.cpp
new file mode 100644
index 0000000..20aa7d3
--- /dev/null
+++ b/cmds/idmap2/self_targeting/SelfTargeting.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/stat.h>
+
+#include <fstream>
+#include <optional>
+
+#define LOG_TAG "SelfTargeting"
+
+#include "androidfw/ResourceTypes.h"
+#include "idmap2/BinaryStreamVisitor.h"
+#include "idmap2/FabricatedOverlay.h"
+#include "idmap2/Idmap.h"
+#include "idmap2/Result.h"
+
+using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask;
+using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
+using android::idmap2::BinaryStreamVisitor;
+using android::idmap2::Idmap;
+using android::idmap2::OverlayResourceContainer;
+
+namespace android::self_targeting {
+
+constexpr const mode_t kIdmapFilePermission = S_IRUSR | S_IWUSR;  // u=rw-, g=---, o=---
+
+extern "C" bool
+CreateFrroFile(std::string& out_err_result, std::string& packageName, std::string& overlayName,
+               std::string& targetPackageName, std::optional<std::string>& targetOverlayable,
+               std::vector<FabricatedOverlayEntryParameters>& entries_params,
+               const std::string& frro_file_path) {
+    android::idmap2::FabricatedOverlay::Builder builder(packageName, overlayName,
+                                                        targetPackageName);
+    if (targetOverlayable.has_value()) {
+        builder.SetOverlayable(targetOverlayable.value_or(std::string()));
+    }
+    for (const auto& entry_params : entries_params) {
+        const auto dataType = entry_params.data_type;
+        if (entry_params.data_binary_value.has_value()) {
+            builder.SetResourceValue(entry_params.resource_name, *entry_params.data_binary_value,
+                                     entry_params.configuration);
+        } else  if (dataType >= Res_value::TYPE_FIRST_INT && dataType <= Res_value::TYPE_LAST_INT) {
+           builder.SetResourceValue(entry_params.resource_name, dataType,
+                                    entry_params.data_value, entry_params.configuration);
+        } else if (dataType == Res_value::TYPE_STRING) {
+           builder.SetResourceValue(entry_params.resource_name, dataType,
+                                    entry_params.data_string_value , entry_params.configuration);
+        } else {
+            out_err_result = base::StringPrintf("Unsupported data type %d", dataType);
+            return false;
+        }
+    }
+
+    const auto frro = builder.Build();
+    std::ofstream fout(frro_file_path);
+    if (fout.fail()) {
+        out_err_result = base::StringPrintf("open output stream fail %s", std::strerror(errno));
+        return false;
+    }
+    auto result = frro->ToBinaryStream(fout);
+    if (!result) {
+        unlink(frro_file_path.c_str());
+        out_err_result = base::StringPrintf("to stream fail %s", result.GetErrorMessage().c_str());
+        return false;
+    }
+    fout.close();
+    if (fout.fail()) {
+        unlink(frro_file_path.c_str());
+        out_err_result = base::StringPrintf("output stream fail %s", std::strerror(errno));
+        return false;
+    }
+    if (chmod(frro_file_path.c_str(), kIdmapFilePermission) == -1) {
+        out_err_result = base::StringPrintf("Failed to change the file permission %s",
+                                            frro_file_path.c_str());
+        return false;
+    }
+    return true;
+}
+
+extern "C" bool
+CreateIdmapFile(std::string& out_err, const std::string& targetPath, const std::string& overlayPath,
+                const std::string& idmapPath, const std::string& overlayName) {
+    // idmap files are mapped with mmap in libandroidfw. Deleting and recreating the idmap
+    // guarantees that existing memory maps will continue to be valid and unaffected. The file must
+    // be deleted before attempting to create the idmap, so that if idmap  creation fails, the
+    // overlay will no longer be usable.
+    unlink(idmapPath.c_str());
+
+    const auto target = idmap2::TargetResourceContainer::FromPath(targetPath);
+    if (!target) {
+        out_err = base::StringPrintf("Failed to load target %s because of %s", targetPath.c_str(),
+                                     target.GetErrorMessage().c_str());
+        return false;
+    }
+
+    const auto overlay = OverlayResourceContainer::FromPath(overlayPath);
+    if (!overlay) {
+        out_err = base::StringPrintf("Failed to load overlay %s because of %s", overlayPath.c_str(),
+                                     overlay.GetErrorMessage().c_str());
+        return false;
+    }
+
+    // Overlay self target process. Only allow self-targeting types.
+    const auto fulfilled_policies = static_cast<PolicyBitmask>(
+            PolicyFlags::PUBLIC | PolicyFlags::SYSTEM_PARTITION | PolicyFlags::VENDOR_PARTITION |
+            PolicyFlags::PRODUCT_PARTITION | PolicyFlags::SIGNATURE | PolicyFlags::ODM_PARTITION |
+            PolicyFlags::OEM_PARTITION | PolicyFlags::ACTOR_SIGNATURE |
+            PolicyFlags::CONFIG_SIGNATURE);
+
+    const auto idmap = Idmap::FromContainers(**target, **overlay, overlayName,
+                                             fulfilled_policies, false /* enforce_overlayable */);
+    if (!idmap) {
+        out_err = base::StringPrintf("Failed to create idmap because of %s",
+                                     idmap.GetErrorMessage().c_str());
+        return false;
+    }
+
+    std::ofstream fout(idmapPath.c_str());
+    if (fout.fail()) {
+        out_err = base::StringPrintf("Failed to create idmap %s because of %s", idmapPath.c_str(),
+                                     strerror(errno));
+        return false;
+    }
+
+    BinaryStreamVisitor visitor(fout);
+    (*idmap)->accept(&visitor);
+    fout.close();
+    if (fout.fail()) {
+        unlink(idmapPath.c_str());
+        out_err = base::StringPrintf("Failed to write idmap %s because of %s", idmapPath.c_str(),
+                                     strerror(errno));
+        return false;
+    }
+    if (chmod(idmapPath.c_str(), kIdmapFilePermission) == -1) {
+        out_err = base::StringPrintf("Failed to change the file permission %s", idmapPath.c_str());
+        return false;
+    }
+    return true;
+}
+
+extern "C" bool
+GetFabricatedOverlayInfo(std::string& out_err, const std::string& overlay_path,
+                         OverlayManifestInfo& out_info) {
+    const auto overlay = idmap2::FabricatedOverlayContainer::FromPath(overlay_path);
+    if (!overlay) {
+        out_err = base::StringPrintf("Failed to write idmap %s because of %s",
+                                     overlay_path.c_str(), strerror(errno));
+        return false;
+    }
+
+    out_info = (*overlay)->GetManifestInfo();
+
+    return true;
+}
+
+}  // namespace android::self_targeting
+