Add snapshotProfile APIs to installd

Add APIs that will snapshot the profile information of packages
in a well known location.

The snapshot ownership is given to AID_SYSTEM. The location is
next to the application reference profile:
/data/misc/profiles/ref/pkg_name/primary.prof.snapshot.

The intended flow for snapshotting profiles is:
mInstaller.snapshotProfile(appId, packageName, codePath);
// open profile snapshot
mInstaller.destroyProfileSnapshot(packageName, codePath);

The reference profile directory is made searchable by others
(in order for the system to be able to open the snapshot profile).

Test: installd_dexopt_test installd_utils_test
Bug: 30934496
Change-Id: Ic4973d5c67243d7724ecd24a238ed0ae8baadcc6
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 4246536..93353bf 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -436,7 +436,7 @@
             // profiles.
             int shared_app_gid = multiuser_get_shared_gid(0, appId);
             if ((shared_app_gid != -1) && fs_prepare_dir_strict(
-                    ref_profile_path.c_str(), 0700, shared_app_gid, shared_app_gid) != 0) {
+                    ref_profile_path.c_str(), 0701, shared_app_gid, shared_app_gid) != 0) {
                 return error("Failed to prepare " + ref_profile_path);
             }
         }
@@ -1833,6 +1833,29 @@
     return ok();
 }
 
+binder::Status InstalldNativeService::snapshotProfile(int32_t appId, const std::string& packageName,
+        const std::string& codePath, bool* _aidl_return) {
+    ENFORCE_UID(AID_SYSTEM);
+    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+    std::lock_guard<std::recursive_mutex> lock(mLock);
+
+    *_aidl_return = snapshot_profile(appId, packageName, codePath);
+    return ok();
+}
+
+binder::Status InstalldNativeService::destroyProfileSnapshot(const std::string& packageName,
+        const std::string& codePath) {
+    ENFORCE_UID(AID_SYSTEM);
+    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+    std::lock_guard<std::recursive_mutex> lock(mLock);
+
+    std::string snapshot = create_snapshot_profile_path(packageName, codePath);
+    if ((unlink(snapshot.c_str()) != 0) && (errno != ENOENT)) {
+        return error("Failed to destroy profile snapshot for " + packageName + ":" + codePath);
+    }
+    return ok();
+}
+
 binder::Status InstalldNativeService::dexopt(const std::string& apkPath, int32_t uid,
         const std::unique_ptr<std::string>& packageName, const std::string& instructionSet,
         int32_t dexoptNeeded, const std::unique_ptr<std::string>& outputPath, int32_t dexFlags,