Delete package sandbox data when it is uninstalled.

Bug: 111890351
Test: manual
Change-Id: I989d507f3352959e824b161a94c0eaad6eed9bba
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 5544c81..fbdce7e 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -886,17 +886,28 @@
     return translateBool(e4crypt_destroy_user_storage(uuid_, userId, flags));
 }
 
-binder::Status VoldNativeService::mountExternalStorageForApp(const std::string& packageName,
-                                                             int32_t appId,
-                                                             const std::string& sandboxId,
-                                                             int32_t userId) {
+binder::Status VoldNativeService::prepareSandboxForApp(const std::string& packageName,
+                                                       int32_t appId, const std::string& sandboxId,
+                                                       int32_t userId) {
     ENFORCE_UID(AID_SYSTEM);
     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
     CHECK_ARGUMENT_SANDBOX_ID(sandboxId);
     ACQUIRE_LOCK;
 
-    return translate(VolumeManager::Instance()->mountExternalStorageForApp(packageName, appId,
-                                                                           sandboxId, userId));
+    return translate(
+        VolumeManager::Instance()->prepareSandboxForApp(packageName, appId, sandboxId, userId));
+}
+
+binder::Status VoldNativeService::destroySandboxForApp(const std::string& packageName,
+                                                       int32_t appId, const std::string& sandboxId,
+                                                       int32_t userId) {
+    ENFORCE_UID(AID_SYSTEM);
+    CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+    CHECK_ARGUMENT_SANDBOX_ID(sandboxId);
+    ACQUIRE_LOCK;
+
+    return translate(
+        VolumeManager::Instance()->destroySandboxForApp(packageName, appId, sandboxId, userId));
 }
 
 binder::Status VoldNativeService::startCheckpoint(int32_t retry, bool* _aidl_return) {
diff --git a/VoldNativeService.h b/VoldNativeService.h
index 6e14964..a79c38a 100644
--- a/VoldNativeService.h
+++ b/VoldNativeService.h
@@ -116,8 +116,10 @@
     binder::Status destroyUserStorage(const std::unique_ptr<std::string>& uuid, int32_t userId,
                                       int32_t flags);
 
-    binder::Status mountExternalStorageForApp(const std::string& packageName, int32_t appId,
-                                              const std::string& sandboxId, int32_t userId);
+    binder::Status prepareSandboxForApp(const std::string& packageName, int32_t appId,
+                                        const std::string& sandboxId, int32_t userId);
+    binder::Status destroySandboxForApp(const std::string& packageName, int32_t appId,
+                                        const std::string& sandboxId, int32_t userId);
 
     binder::Status startCheckpoint(int32_t retry, bool* _aidl_return);
     binder::Status needsCheckpoint(bool* _aidl_return);
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index ec18694..8b70867 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -834,8 +834,8 @@
     return 0;
 }
 
-int VolumeManager::mountExternalStorageForApp(const std::string& packageName, appid_t appId,
-                                              const std::string& sandboxId, userid_t userId) {
+int VolumeManager::prepareSandboxForApp(const std::string& packageName, appid_t appId,
+                                        const std::string& sandboxId, userid_t userId) {
     if (!GetBoolProperty(kIsolatedStorage, false)) {
         return 0;
     } else if (mStartedUsers.find(userId) == mStartedUsers.end()) {
@@ -843,7 +843,7 @@
         // be created when the user starts.
         return 0;
     }
-    LOG(VERBOSE) << "mountExternalStorageForApp: " << packageName << ", appId=" << appId
+    LOG(VERBOSE) << "prepareSandboxForApp: " << packageName << ", appId=" << appId
                  << ", sandboxId=" << sandboxId << ", userId=" << userId;
     mUserPackages[userId].push_back(packageName);
     mAppIds[packageName] = appId;
@@ -860,6 +860,71 @@
     return prepareSandboxes(userId, {packageName}, visibleVolLabels);
 }
 
+int VolumeManager::destroySandboxForApp(const std::string& packageName, appid_t appId,
+                                        const std::string& sandboxId, userid_t userId) {
+    if (!GetBoolProperty(kIsolatedStorage, false)) {
+        return 0;
+    }
+    LOG(VERBOSE) << "destroySandboxForApp: " << packageName << ", appId=" << appId
+                 << ", sandboxId=" << sandboxId << ", userId=" << userId;
+    auto& userPackages = mUserPackages[userId];
+    std::remove(userPackages.begin(), userPackages.end(), packageName);
+    // If the package is not uninstalled in any other users, remove appId and sandboxId
+    // corresponding to it from the internal state.
+    bool installedInAnyUser = false;
+    for (auto& it : mUserPackages) {
+        auto& packages = it.second;
+        if (std::find(packages.begin(), packages.end(), packageName) != packages.end()) {
+            installedInAnyUser = true;
+            break;
+        }
+    }
+    if (!installedInAnyUser) {
+        mAppIds.erase(packageName);
+        mSandboxIds.erase(appId);
+    }
+
+    std::vector<std::string> visibleVolLabels;
+    for (auto& volId : mVisibleVolumeIds) {
+        auto vol = findVolume(volId);
+        userid_t mountUserId = vol->getMountUserId();
+        if (mountUserId == userId || vol->isEmulated()) {
+            if (destroySandboxForAppOnVol(packageName, sandboxId, userId, vol->getLabel()) < 0) {
+                return -errno;
+            }
+        }
+    }
+    return 0;
+}
+
+int VolumeManager::destroySandboxForAppOnVol(const std::string& packageName,
+                                             const std::string& sandboxId, userid_t userId,
+                                             const std::string& volLabel) {
+    LOG(VERBOSE) << "destroySandboxOnVol: " << packageName << ", userId=" << userId
+                 << ", volLabel=" << volLabel;
+    std::string pkgSandboxTarget =
+        StringPrintf("/mnt/user/%d/package/%s", userId, packageName.c_str());
+    if (android::vold::UnmountTree(pkgSandboxTarget)) {
+        PLOG(ERROR) << "UnmountTree failed on " << pkgSandboxTarget;
+    }
+
+    std::string sandboxDir = StringPrintf("/mnt/runtime/write/%s", volLabel.c_str());
+    if (volLabel == mPrimary->getLabel() && mPrimary->isEmulated()) {
+        StringAppendF(&sandboxDir, "/%d", userId);
+    }
+    if (StartsWith(sandboxId, "shared:")) {
+        StringAppendF(&sandboxDir, "/Android/sandbox/shared/%s", sandboxId.substr(7).c_str());
+    } else {
+        StringAppendF(&sandboxDir, "/Android/sandbox/%s", sandboxId.c_str());
+    }
+
+    if (android::vold::DeleteDirContentsAndDir(sandboxDir) < 0) {
+        PLOG(ERROR) << "DeleteDirContentsAndDir failed on " << sandboxDir;
+        return -errno;
+    }
+    return 0;
+}
+
 int VolumeManager::onSecureKeyguardStateChanged(bool isShowing) {
     mSecureKeyguardShowing = isShowing;
     if (!mSecureKeyguardShowing) {
diff --git a/VolumeManager.h b/VolumeManager.h
index 5d211db..8982d8f 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -96,8 +96,10 @@
     int addAppIds(const std::vector<std::string>& packageNames, const std::vector<int32_t>& appIds);
     int addSandboxIds(const std::vector<int32_t>& appIds,
                       const std::vector<std::string>& sandboxIds);
-    int mountExternalStorageForApp(const std::string& packageName, appid_t appId,
-                                   const std::string& sandboxId, userid_t userId);
+    int prepareSandboxForApp(const std::string& packageName, appid_t appId,
+                             const std::string& sandboxId, userid_t userId);
+    int destroySandboxForApp(const std::string& packageName, appid_t appId,
+                             const std::string& sandboxId, userid_t userId);
 
     int onVolumeMounted(android::vold::VolumeBase* vol);
     int onVolumeUnmounted(android::vold::VolumeBase* vol);
@@ -162,6 +164,8 @@
                                const std::string& volumeRoot, const std::string& sandboxDirRoot);
     int mountPkgSpecificDir(const std::string& mntSourceRoot, const std::string& mntTargetRoot,
                             const std::string& packageName, const char* dirName);
+    int destroySandboxForAppOnVol(const std::string& packageName, const std::string& sandboxId,
+                                  userid_t userId, const std::string& volLabel);
 
     void handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk);
     void handleDiskChanged(dev_t device);
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index f825a30..ac65b54 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -99,8 +99,10 @@
                             int storageFlags);
     void destroyUserStorage(@nullable @utf8InCpp String uuid, int userId, int storageFlags);
 
-    void mountExternalStorageForApp(in @utf8InCpp String packageName, int appId,
-                                    in @utf8InCpp String sandboxId, int userId);
+    void prepareSandboxForApp(in @utf8InCpp String packageName, int appId,
+                              in @utf8InCpp String sandboxId, int userId);
+    void destroySandboxForApp(in @utf8InCpp String packageName, int appId,
+                              in @utf8InCpp String sandboxId, int userId);
 
     boolean startCheckpoint(int retry);
     boolean needsCheckpoint();