Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e17569a authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Explicitly request clearing of external storage.

Similar to how we target DE and CE storage areas, callers need to
specifically ask to work with EXTERNAL storage.  This is because
external storage often lives on a separate device from where internal
DE and CE data lives.

As one specific example, if we're moving an app between two
"internal" storage devices, we don't want to clean up the data
for that package on external storage, since it's not being moved.

This change also expands to all mounted external storage devices,
not just the storage backed by the incoming UUID.

Bug: 113277754
Test: atest android.appsecurity.cts.StorageHostTest
Test: atest android.appsecurity.cts.ExternalStorageHostTest
Test: atest --test-mapping frameworks/base/services/core/java/com/android/server/pm/
Change-Id: Ib04325905ce14f080ce9127219acf1dd69444fac
parent 602b755d
Loading
Loading
Loading
Loading
+59 −39
Original line number Diff line number Diff line
@@ -569,11 +569,38 @@ binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::st
                remove_path_xattr(path, kXattrInodeCodeCache);
            }
        }
    }
    if (flags & FLAG_STORAGE_DE) {
        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;
        }

        auto extPath = findDataMediaPath(uuid, userId);
        auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
        if (access(path.c_str(), F_OK) == 0) {
            if (delete_dir_contents(path) != 0) {
                res = error("Failed to delete contents of " + path);
            }
        }
    }
    if (flags & FLAG_STORAGE_EXTERNAL) {
        std::lock_guard<std::recursive_mutex> lock(mMountsLock);
        for (const auto& n : mStorageMounts) {
            auto extPath = n.second;
            if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
                extPath += StringPrintf("/%d", userId);
            } else if (userId != 0) {
                // TODO: support devices mounted under secondary users
                continue;
            }
            if (flags & FLAG_CLEAR_CACHE_ONLY) {
                // Clear only cached data from shared storage
            path = StringPrintf("%s/Android/data/%s/cache", extPath.c_str(), pkgname);
                auto path = StringPrintf("%s/Android/data/%s/cache", extPath.c_str(), pkgname);
                if (delete_dir_contents(path, true) != 0) {
                    res = error("Failed to delete contents of " + path);
                }
@@ -581,7 +608,7 @@ binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::st
                // No code cache on shared storage
            } else {
                // Clear everything on shared storage
            path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
                auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
                if (delete_dir_contents(path, true) != 0) {
                    res = error("Failed to delete contents of " + path);
                }
@@ -595,23 +622,6 @@ binder::Status InstalldNativeService::clearAppData(const std::unique_ptr<std::st
                }
            }
        }
    if (flags & FLAG_STORAGE_DE) {
        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;
        }

        auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
        if (access(path.c_str(), F_OK) == 0) {
            if (delete_dir_contents(path) != 0) {
                res = error("Failed to delete contents of " + path);
            }
        }
    }
    return res;
}
@@ -662,20 +672,6 @@ binder::Status InstalldNativeService::destroyAppData(const std::unique_ptr<std::
        if (delete_dir_contents_and_dir(path) != 0) {
            res = error("Failed to delete " + path);
        }

        auto extPath = findDataMediaPath(uuid, userId);
        path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
        if (delete_dir_contents_and_dir(path, true) != 0) {
            res = error("Failed to delete " + path);
        }
        path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
        if (delete_dir_contents_and_dir(path, true) != 0) {
            res = error("Failed to delete " + path);
        }
        path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
        if (delete_dir_contents_and_dir(path, true) != 0) {
            res = error("Failed to delete " + path);
        }
    }
    if (flags & FLAG_STORAGE_DE) {
        auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
@@ -688,6 +684,30 @@ binder::Status InstalldNativeService::destroyAppData(const std::unique_ptr<std::
        // Verify if it's ok to do that.
        destroy_app_reference_profile(packageName);
    }
    if (flags & FLAG_STORAGE_EXTERNAL) {
        std::lock_guard<std::recursive_mutex> lock(mMountsLock);
        for (const auto& n : mStorageMounts) {
            auto extPath = n.second;
            if (n.first.compare(0, 14, "/mnt/media_rw/") != 0) {
                extPath += StringPrintf("/%d", userId);
            } else if (userId != 0) {
                // TODO: support devices mounted under secondary users
                continue;
            }
            auto path = StringPrintf("%s/Android/data/%s", extPath.c_str(), pkgname);
            if (delete_dir_contents_and_dir(path, true) != 0) {
                res = error("Failed to delete contents of " + path);
            }
            path = StringPrintf("%s/Android/media/%s", extPath.c_str(), pkgname);
            if (delete_dir_contents_and_dir(path, true) != 0) {
                res = error("Failed to delete contents of " + path);
            }
            path = StringPrintf("%s/Android/obb/%s", extPath.c_str(), pkgname);
            if (delete_dir_contents_and_dir(path, true) != 0) {
                res = error("Failed to delete contents of " + path);
            }
        }
    }
    return res;
}

+1 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ interface IInstalld {

    const int FLAG_STORAGE_DE = 0x1;
    const int FLAG_STORAGE_CE = 0x2;
    const int FLAG_STORAGE_EXTERNAL = 0x4;

    const int FLAG_CLEAR_CACHE_ONLY = 0x10;
    const int FLAG_CLEAR_CODE_CACHE_ONLY = 0x20;