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

Commit 584b0681 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Delete package sandbox data when it is uninstalled.

Bug: 111890351
Test: manual
Change-Id: Ic4347744e849e6d7dbc026ebc2e8656b3f2d2ed0
parent b61b0e57
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package android.os.storage;

import android.annotation.NonNull;
import android.annotation.Nullable;

/**
 * Mount service local interface.
 *
@@ -81,18 +84,26 @@ public abstract class StorageManagerInternal {
    public abstract int getExternalStorageMountMode(int uid, String packageName);

    /**
     * Mount external storage for the given package.
     * Create storage sandbox for the given package.
     *
     * <p> This will involve calling into vold to setup appropriate bind mounts.
     *
     * @param packageName The package for which external storage will be mounted.
     * @param packageName The package for which the sandbox needs to be created.
     * @param appId The appId for the given package.
     * @param sharedUserId The sharedUserId for given package if it specified
     *      {@code android:sharedUserId} in the manifest, otherwise {@code null}
     * @param userId The userId in which the storage needs to be mounted.
     * @param userId The userId in which the sandbox needs to be created.
     */
    public abstract void prepareSandboxForApp(@NonNull String packageName, int appId,
            @Nullable String sharedUserId, int userId);

    /**
     * Delete storage sandbox for the given package.
     *
     * @param packageName The package for which the sandbox needs to be destroyed.
     * @param userId The userId in which the sandbox needs to be destroyed.
     */
    public abstract void mountExternalStorageForApp(String packageName, int appId,
            String sharedUserId, int userId);
    public abstract void destroySandboxForApp(@NonNull String packageName, int userId);

    /**
     * @return Labels of storage volumes that are visible to the given userId.
+36 −2
Original line number Diff line number Diff line
@@ -3754,7 +3754,7 @@ class StorageManagerService extends IStorageManager.Stub
        }

        @Override
        public void mountExternalStorageForApp(String packageName, int appId, String sharedUserId,
        public void prepareSandboxForApp(String packageName, int appId, String sharedUserId,
                int userId) {
            final String sandboxId;
            synchronized (mPackagesLock) {
@@ -3771,7 +3771,41 @@ class StorageManagerService extends IStorageManager.Stub
            }

            try {
                mVold.mountExternalStorageForApp(packageName, appId, sandboxId, userId);
                mVold.prepareSandboxForApp(packageName, appId, sandboxId, userId);
            } catch (Exception e) {
                Slog.wtf(TAG, e);
            }
        }

        @Override
        public void destroySandboxForApp(String packageName, int userId) {
            if (!ENABLE_ISOLATED_STORAGE) {
                return;
            }
            final int appId;
            final String sandboxId;
            synchronized (mPackagesLock) {
                final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId);
                userPackages.remove(packageName);
                appId = mAppIds.get(packageName);
                sandboxId = mSandboxIds.get(appId);

                // If the package is not uninstalled in any other users, remove appId and sandboxId
                // corresponding to it from the internal state.
                boolean installedInAnyUser = false;
                for (int i = mPackages.size() - 1; i >= 0; --i) {
                    if (mPackages.valueAt(i).contains(packageName)) {
                        installedInAnyUser = true;
                        break;
                    }
                }
                if (!installedInAnyUser) {
                    mAppIds.remove(packageName);
                    mSandboxIds.remove(appId);
                }
            }
            try {
                mVold.destroySandboxForApp(packageName, appId, sandboxId, userId);
            } catch (Exception e) {
                Slog.wtf(TAG, e);
            }
+35 −7
Original line number Diff line number Diff line
@@ -940,6 +940,7 @@ public class PackageManagerService extends IPackageManager.Stub
    private UserManagerInternal mUserManagerInternal;
    private ActivityManagerInternal mActivityManagerInternal;
    private ActivityTaskManagerInternal mActivityTaskManagerInternal;
    private StorageManagerInternal mStorageManagerInternal;
    private DeviceIdleController.LocalService mDeviceIdleController;
@@ -4598,6 +4599,13 @@ public class PackageManagerService extends IPackageManager.Stub
        return mDeviceIdleController;
    }
    private StorageManagerInternal getStorageManagerInternal() {
        if (mStorageManagerInternal == null) {
            mStorageManagerInternal = LocalServices.getService(StorageManagerInternal.class);
        }
        return mStorageManagerInternal;
    }
    /**
     * Update given flags when being used to request {@link PackageInfo}.
     */
@@ -9505,6 +9513,30 @@ public class PackageManagerService extends IPackageManager.Stub
            } catch (InstallerException e) {
                Slog.w(TAG, String.valueOf(e));
            }
            // If this package doesn't have a sharedUserId or there are no other packages
            // present with same sharedUserId, then delete the sandbox data too.
            try {
                final SharedUserSetting sharedUserSetting = mSettings.getSharedUserLPw(
                        pkg.mSharedUserId, 0 /* pkgFlags */,
                        0 /* pkgPrivateFlags */, false /* create */);
                boolean deleteSandboxData = true;
                if (sharedUserSetting != null && sharedUserSetting.packages != null) {
                    for (int i = sharedUserSetting.packages.size() - 1; i >= 0; --i) {
                        final PackageSetting packageSetting = sharedUserSetting.packages.valueAt(i);
                        if (!packageSetting.name.equals(pkg.packageName)
                                && packageSetting.readUserState(realUserId).isAvailable(
                                        MATCH_UNINSTALLED_PACKAGES)) {
                            deleteSandboxData = false;
                            break;
                        }
                    }
                }
                if (deleteSandboxData) {
                    getStorageManagerInternal().destroySandboxForApp(pkg.packageName, realUserId);
                }
            } catch (PackageManagerException e) {
                // Should not happen
            }
            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
        }
    }
@@ -19820,9 +19852,7 @@ public class PackageManagerService extends IPackageManager.Stub
        mDexManager.systemReady();
        mPackageDexOptimizer.systemReady();
        StorageManagerInternal storageManagerInternal = LocalServices.getService(
                StorageManagerInternal.class);
        storageManagerInternal.addExternalStoragePolicy(
        getStorageManagerInternal().addExternalStoragePolicy(
                new StorageManagerInternal.ExternalStorageMountPolicy() {
            @Override
            public int getMountMode(int uid, String packageName) {
@@ -21215,10 +21245,8 @@ public class PackageManagerService extends IPackageManager.Stub
        }
        prepareAppDataContentsLeafLIF(pkg, userId, flags);
        final StorageManagerInternal storageManagerInternal
                = LocalServices.getService(StorageManagerInternal.class);
        if (storageManagerInternal != null) {
            storageManagerInternal.mountExternalStorageForApp(
        if (getStorageManagerInternal() != null) {
            getStorageManagerInternal().prepareSandboxForApp(
                    pkg.packageName, appId, pkg.mSharedUserId, userId);
        }
    }