Add a function to verify if idmap is made from given target/overlay packages

"--verify" will be used to verify if idmap corresponding to given fd is maded
from given target and overlay packages.

Test: building succeeded and tested on sailfish.
Bug: 37179531
Change-Id: Id19bdfd9c61670437f3e1a5c29762ce93586590f
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
index c13d318..524db14 100644
--- a/cmds/idmap/create.cpp
+++ b/cmds/idmap/create.cpp
@@ -221,3 +221,9 @@
     return create_and_write_idmap(target_apk_path, overlay_apk_path, fd, true) == 0 ?
         EXIT_SUCCESS : EXIT_FAILURE;
 }
+
+int idmap_verify_fd(const char *target_apk_path, const char *overlay_apk_path, int fd)
+{
+    return !is_idmap_stale_fd(target_apk_path, overlay_apk_path, fd) ?
+            EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp
index 3a237ff..8f86ed8 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -16,6 +16,7 @@
       idmap --scan target-package-name-to-look-for path-to-target-apk dir-to-hold-idmaps \\\
                    dir-to-scan [additional-dir-to-scan [additional-dir-to-scan [...]]]\n\
       idmap --inspect idmap \n\
+      idmap --verify target overlay fd \n\
 \n\
 DESCRIPTION \n\
       Idmap files play an integral part in the runtime resource overlay framework. An idmap \n\
@@ -57,6 +58,9 @@
       --inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\
                  debug-friendly format. \n\
 \n\
+      --verify: verify if idmap corresponding to file descriptor 'fd' (integer) is made from \n\
+                target package 'target' (path to apk) and overlay package 'overlay'. \n\
+\n\
 EXAMPLES \n\
       Create an idmap file: \n\
 \n\
@@ -167,6 +171,29 @@
         return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path);
     }
 
+    int maybe_verify_fd(const char *target_apk_path, const char *overlay_apk_path,
+            const char *idmap_str)
+    {
+        char *endptr;
+        int idmap_fd = strtol(idmap_str, &endptr, 10);
+        if (*endptr != '\0') {
+            fprintf(stderr, "error: failed to parse file descriptor argument %s\n", idmap_str);
+            return -1;
+        }
+
+        if (!verify_file_readable(target_apk_path)) {
+            ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
+            return -1;
+        }
+
+        if (!verify_file_readable(overlay_apk_path)) {
+            ALOGD("error: failed to read apk %s: %s\n", overlay_apk_path, strerror(errno));
+            return -1;
+        }
+
+        return idmap_verify_fd(target_apk_path, overlay_apk_path, idmap_fd);
+    }
+
     int maybe_scan(const char *target_package_name, const char *target_apk_path,
             const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
     {
@@ -235,6 +262,10 @@
         return maybe_create_path(argv[2], argv[3], argv[4]);
     }
 
+    if (argc == 5 && !strcmp(argv[1], "--verify")) {
+        return maybe_verify_fd(argv[2], argv[3], argv[4]);
+    }
+
     if (argc >= 6 && !strcmp(argv[1], "--scan")) {
         android::Vector<const char *> v;
         for (int i = 5; i < argc; i++) {
diff --git a/cmds/idmap/idmap.h b/cmds/idmap/idmap.h
index 8d4210b..5962108 100644
--- a/cmds/idmap/idmap.h
+++ b/cmds/idmap/idmap.h
@@ -25,6 +25,8 @@
 
 int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd);
 
+int idmap_verify_fd(const char *target_apk_path, const char *overlay_apk_path, int fd);
+
 // Regarding target_package_name: the idmap_scan implementation should
 // be able to extract this from the manifest in target_apk_path,
 // simplifying the external API.