Do not clean profiles unconditonally during app data clean up

The goal is to enable profiles to be persisted across OTAs.

This CL makes profile removal a dedicated path which will be called by
PackageManger during an app update or uninstall.

Profiles are cleared when:
- requested to do a full clean up of application data files
- specifically requested to clear them (e.g. app updates)

Profiles are destroyed (includes profile directory removal)
- for each user individually when its application data is destroyed
- for all users if the package gets uninstalled.

Bug: 27081617
Bug: 27688727
Change-Id: Id53c7625011af3cdbe8a58ac0982982fa461e5fd
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 47c78c3..53ff2d4 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -173,35 +173,43 @@
     return true;
 }
 
+static bool unlink_current_profile(const char* pkgname, userid_t user) {
+    std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
+    std::string profile = create_primary_profile(profile_dir);
+    if (unlink(profile.c_str()) != 0) {
+        if (errno != ENOENT) {
+            PLOG(WARNING) << "Could not unlink " << profile;
+            return false;
+        }
+    }
+    return true;
+}
+
 static bool unlink_current_profiles(const char* pkgname) {
     bool success = true;
     std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
     for (auto user : users) {
-        std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
-        std::string profile = create_primary_profile(profile_dir);
-        if (unlink(profile.c_str()) != 0) {
-            if (errno != ENOENT) {
-                PLOG(WARNING) << "Could not unlink " << profile;
-                success = false;
-            }
-        }
+        success &= unlink_current_profile(pkgname, user);
     }
     return success;
 }
 
-static bool unlink_all_profiles(const char* pkgname) {
+int clear_app_profiles(const char* pkgname) {
     bool success = true;
     success &= unlink_reference_profile(pkgname);
     success &= unlink_current_profiles(pkgname);
-    return success;
+    return success ? 0 : -1;
 }
 
 int clear_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) {
     std::string suffix = "";
+    bool only_cache = false;
     if (flags & FLAG_CLEAR_CACHE_ONLY) {
         suffix = CACHE_DIR_POSTFIX;
+        only_cache = true;
     } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
         suffix = CODE_CACHE_DIR_POSTFIX;
+        only_cache = true;
     }
 
     int res = 0;
@@ -217,17 +225,27 @@
             // TODO: include result once 25796509 is fixed
             delete_dir_contents(path);
         }
-        unlink_all_profiles(pkgname);
+        if (!only_cache) {
+            if (!unlink_current_profile(pkgname, userid)) {
+                res |= -1;
+            }
+        }
     }
     return res;
 }
 
-static int destroy_app_profiles(const char *pkgname, userid_t userid) {
-    // TODO: this doesn't destroy the marks for foreign dex use yet.
-    int res = 0;
-    res |= delete_dir_contents_and_dir(create_data_user_profile_package_path( userid, pkgname));
-    res |= delete_dir_contents_and_dir(create_data_ref_profile_package_path(pkgname));
-    return res;
+static int destroy_app_current_profiles(const char *pkgname, userid_t userid) {
+    return delete_dir_contents_and_dir(create_data_user_profile_package_path(userid, pkgname));
+}
+
+int destroy_app_profiles(const char *pkgname) {
+    int result = 0;
+    std::vector<userid_t> users = get_known_users(/*volume_uuid*/ nullptr);
+    for (auto user : users) {
+        result |= destroy_app_current_profiles(pkgname, user);
+    }
+    result |= delete_dir_contents_and_dir(create_data_ref_profile_package_path(pkgname));
+    return result;
 }
 
 int destroy_app_data(const char *uuid, const char *pkgname, userid_t userid, int flags) {
@@ -239,8 +257,8 @@
     if (flags & FLAG_STORAGE_DE) {
         res |= delete_dir_contents_and_dir(
                 create_data_user_de_package_path(uuid, userid, pkgname));
-        res |= destroy_app_profiles(pkgname, userid);
     }
+    destroy_app_current_profiles(pkgname, userid);
     return res;
 }
 
@@ -1777,11 +1795,6 @@
     return delete_dir_contents(apk_path, 1 /* also_delete_dir */ , NULL /* exclusion_predicate */);
 }
 
-int rm_profiles(const char* pkgname)
-{
-    return unlink_all_profiles(pkgname) ? 0 : -1;
-}
-
 int link_file(const char* relative_path, const char* from_base, const char* to_base) {
     char from_path[PKG_PATH_MAX];
     char to_path[PKG_PATH_MAX];