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

Commit dcd0b0ab authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Delete package sandbox data when it is uninstalled."

parents b1424bc4 584b0681
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);
        }
    }