Newly create idmap only when it is outdated

For now, OverlayManagerService calls Installd.idmap() whenever a user
is changed, and then a idmap is re-generated even though there are no
changes on its target apk and overlay apk.
This CL is to avoid such unnecessary re-generation of idmap. Instead
only a group id will be updated when the idmap isn't outdated.

Test: building succeeded and tested on sailfish.
Bug: 37179531
Change-Id: Id726cbbc621bd64f2a329798b2ab5436f0c28d70
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 989fcda..bdf69b9 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -1961,6 +1961,8 @@
 
     int idmap_fd = -1;
     char idmap_path[PATH_MAX];
+    struct stat target_apk_stat, overlay_apk_stat, idmap_stat;
+    bool outdated = false;
 
     if (flatten_path(IDMAP_PREFIX, IDMAP_SUFFIX, overlay_apk,
                 idmap_path, sizeof(idmap_path)) == -1) {
@@ -1968,8 +1970,22 @@
         goto fail;
     }
 
-    unlink(idmap_path);
-    idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644);
+    if (stat(idmap_path, &idmap_stat) < 0 ||
+            stat(target_apk, &target_apk_stat) < 0 ||
+            stat(overlay_apk, &overlay_apk_stat) < 0) {
+        outdated = true;
+    } else if (idmap_stat.st_mtime < target_apk_stat.st_mtime ||
+            idmap_stat.st_mtime < overlay_apk_stat.st_mtime) {
+        outdated = true;
+    }
+
+    if (outdated) {
+        unlink(idmap_path);
+        idmap_fd = open(idmap_path, O_RDWR | O_CREAT | O_EXCL, 0644);
+    } else {
+        idmap_fd = open(idmap_path, O_RDWR);
+    }
+
     if (idmap_fd < 0) {
         ALOGE("idmap cannot open '%s' for output: %s\n", idmap_path, strerror(errno));
         goto fail;
@@ -1983,6 +1999,11 @@
         goto fail;
     }
 
+    if (!outdated) {
+        close(idmap_fd);
+        return ok();
+    }
+
     pid_t pid;
     pid = fork();
     if (pid == 0) {