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

Commit ae98895e authored by Songchun Fan's avatar Songchun Fan Committed by Song Chun Fan
Browse files

[pm] preserve installed state only for system app downgrade

This CL is currently a no-op because the installed state is already set to
true during the uninstallation for single-user scenarios. A follow-up CL
will actually change the installed state for single-user DELETE_KEEP_DATA.

Also adds a small refactoring such that all app data directory I/O called
from RemovePackageHelper.

BUG: 288142708
Test: presubmit
Change-Id: I286581355aa2139b3e7de8feed51eb13c528f42b
parent f1de35bf
Loading
Loading
Loading
Loading
+4 −64
Original line number Diff line number Diff line
@@ -23,9 +23,6 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.DELETE_SUCCEEDED;
import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;

import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.PackageManagerService.DEBUG_COMPRESSION;
@@ -72,14 +69,13 @@ import com.android.server.wm.ActivityTaskManagerInternal;

import dalvik.system.VMRuntime;

import java.util.Collections;
import java.util.List;

/**
 * Deletes a package. Uninstall if installed, or at least deletes the base directory if it's called
 * from a failed installation. Fixes user state after deletion.
 * Handles special treatments to system apps.
 * Relies on RemovePackageHelper to clear internal data structures.
 * Relies on RemovePackageHelper to clear internal data structures and remove app data.
 */
final class DeletePackageHelper {
    private static final boolean DEBUG_CLEAN_APKS = false;
@@ -90,24 +86,17 @@ final class DeletePackageHelper {
    private final UserManagerInternal mUserManagerInternal;
    private final PermissionManagerServiceInternal mPermissionManager;
    private final RemovePackageHelper mRemovePackageHelper;
    private final AppDataHelper mAppDataHelper;

    // TODO(b/198166813): remove PMS dependency
    DeletePackageHelper(PackageManagerService pm, RemovePackageHelper removePackageHelper,
            AppDataHelper appDataHelper) {
    DeletePackageHelper(PackageManagerService pm, RemovePackageHelper removePackageHelper) {
        mPm = pm;
        mUserManagerInternal = mPm.mInjector.getUserManagerInternal();
        mPermissionManager = mPm.mInjector.getPermissionManagerServiceInternal();
        mRemovePackageHelper = removePackageHelper;
        mAppDataHelper = appDataHelper;
    }

    DeletePackageHelper(PackageManagerService pm) {
        mPm = pm;
        mAppDataHelper = new AppDataHelper(mPm);
        mUserManagerInternal = mPm.mInjector.getUserManagerInternal();
        mPermissionManager = mPm.mInjector.getPermissionManagerServiceInternal();
        mRemovePackageHelper = new RemovePackageHelper(mPm, mAppDataHelper);
        this(pm, new RemovePackageHelper(pm));
    }

    /**
@@ -484,7 +473,7 @@ final class DeletePackageHelper {
                }
            }
            if (clearPackageStateAndReturn) {
                clearPackageStateForUserLIF(ps, userId, outInfo, flags);
                mRemovePackageHelper.clearPackageStateForUserLIF(ps, userId, outInfo, flags);
                mPm.scheduleWritePackageRestrictions(user);
                return;
            }
@@ -531,55 +520,6 @@ final class DeletePackageHelper {
        }
    }

    private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
            PackageRemovedInfo outInfo, int flags) {
        final AndroidPackage pkg;
        final SharedUserSetting sus;
        synchronized (mPm.mLock) {
            pkg = mPm.mPackages.get(ps.getPackageName());
            sus = mPm.mSettings.getSharedUserSettingLPr(ps);
        }

        mAppDataHelper.destroyAppProfilesLIF(pkg);

        final List<AndroidPackage> sharedUserPkgs =
                sus != null ? sus.getPackages() : Collections.emptyList();
        final PreferredActivityHelper preferredActivityHelper = new PreferredActivityHelper(mPm);
        final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManagerInternal.getUserIds()
                : new int[] {userId};
        for (int nextUserId : userIds) {
            if (DEBUG_REMOVE) {
                Slog.d(TAG, "Updating package:" + ps.getPackageName() + " install state for user:"
                        + nextUserId);
            }
            if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
                mAppDataHelper.destroyAppDataLIF(pkg, nextUserId,
                        FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
                ps.setCeDataInode(-1, nextUserId);
            }
            mAppDataHelper.clearKeystoreData(nextUserId, ps.getAppId());
            preferredActivityHelper.clearPackagePreferredActivities(ps.getPackageName(),
                    nextUserId);
            mPm.mDomainVerificationManager.clearPackageForUser(ps.getPackageName(), nextUserId);
        }
        mPermissionManager.onPackageUninstalled(ps.getPackageName(), ps.getAppId(), ps, pkg,
                sharedUserPkgs, userId);

        if (outInfo != null) {
            if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
                outInfo.mDataRemoved = true;
            }
            outInfo.mRemovedPackage = ps.getPackageName();
            outInfo.mInstallerPackageName = ps.getInstallSource().mInstallerPackageName;
            outInfo.mIsStaticSharedLib = pkg != null && pkg.getStaticSharedLibraryName() != null;
            outInfo.mRemovedAppId = ps.getAppId();
            outInfo.mRemovedUsers = userIds;
            outInfo.mBroadcastUsers = userIds;
            outInfo.mIsExternal = ps.isExternalStorage();
            outInfo.mRemovedPackageVersionCode = ps.getVersionCode();
        }
    }

    @GuardedBy("mPm.mInstallLock")
    private void deleteInstalledPackageLIF(PackageSetting ps,
            boolean deleteCodeAndResources, int flags, @NonNull int[] allUserHandles,
+5 −5
Original line number Diff line number Diff line
@@ -1967,9 +1967,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mApexManager = injector.getApexManager();
        mAppsFilter = mInjector.getAppsFilter();

        mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
                mInjector.getUserManagerInternal(), new DeletePackageHelper(this));

        mChangedPackagesTracker = new ChangedPackagesTracker();

        mAppInstallDir = new File(Environment.getDataDirectory(), "app");
@@ -1983,8 +1980,11 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mAppDataHelper = new AppDataHelper(this);
        mInstallPackageHelper = new InstallPackageHelper(this, mAppDataHelper);
        mRemovePackageHelper = new RemovePackageHelper(this, mAppDataHelper);
        mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper,
                mAppDataHelper);
        mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper);

        mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
                mInjector.getUserManagerInternal(), mDeletePackageHelper);

        mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);
        mPreferredActivityHelper = new PreferredActivityHelper(this);
        mResolveIntentHelper = new ResolveIntentHelper(mContext, mPreferredActivityHelper,
+53 −3
Original line number Diff line number Diff line
@@ -253,6 +253,56 @@ final class RemovePackageHelper {
        }
    }

    public void clearPackageStateForUserLIF(PackageSetting ps, int userId,
            PackageRemovedInfo outInfo, int flags) {
        final AndroidPackage pkg;
        final SharedUserSetting sus;
        synchronized (mPm.mLock) {
            pkg = mPm.mPackages.get(ps.getPackageName());
            sus = mPm.mSettings.getSharedUserSettingLPr(ps);
        }

        mAppDataHelper.destroyAppProfilesLIF(pkg);

        final List<AndroidPackage> sharedUserPkgs =
                sus != null ? sus.getPackages() : Collections.emptyList();
        final PreferredActivityHelper preferredActivityHelper = new PreferredActivityHelper(mPm);
        final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManagerInternal.getUserIds()
                : new int[] {userId};
        for (int nextUserId : userIds) {
            if (DEBUG_REMOVE) {
                Slog.d(TAG, "Updating package:" + ps.getPackageName() + " install state for user:"
                        + nextUserId);
            }
            if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
                mAppDataHelper.destroyAppDataLIF(pkg, nextUserId,
                        FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
                ps.setCeDataInode(-1, nextUserId);
            }
            mAppDataHelper.clearKeystoreData(nextUserId, ps.getAppId());
            preferredActivityHelper.clearPackagePreferredActivities(ps.getPackageName(),
                    nextUserId);
            mPm.mDomainVerificationManager.clearPackageForUser(ps.getPackageName(), nextUserId);
        }
        mPermissionManager.onPackageUninstalled(ps.getPackageName(), ps.getAppId(), ps, pkg,
                sharedUserPkgs, userId);

        if (outInfo != null) {
            if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
                outInfo.mDataRemoved = true;
            }
            outInfo.mRemovedPackage = ps.getPackageName();
            outInfo.mInstallerPackageName = ps.getInstallSource().mInstallerPackageName;
            outInfo.mIsStaticSharedLib = pkg != null && pkg.getStaticSharedLibraryName() != null;
            outInfo.mRemovedAppId = ps.getAppId();
            outInfo.mRemovedUsers = userIds;
            outInfo.mBroadcastUsers = userIds;
            outInfo.mIsExternal = ps.isExternalStorage();
            outInfo.mRemovedPackageVersionCode = ps.getVersionCode();
        }
    }

    // Called to clean up disabled system packages
    public void removePackageData(final PackageSetting deletedPs, @NonNull int[] allUserHandles,
            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
        synchronized (mPm.mInstallLock) {
@@ -314,7 +364,6 @@ final class RemovePackageHelper {
        int removedAppId = -1;

        // writer
        boolean installedStateChanged = false;
        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
            final SparseBooleanArray changedUsers = new SparseBooleanArray();
            synchronized (mPm.mLock) {
@@ -354,9 +403,10 @@ final class RemovePackageHelper {
                mPm.postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
            }
        }
        // make sure to preserve per-user disabled state if this removal was just
        // make sure to preserve per-user installed state if this removal was just
        // a downgrade of a system app to the factory package
        if (outInfo != null && outInfo.mOrigUsers != null) {
        boolean installedStateChanged = false;
        if (outInfo != null && outInfo.mOrigUsers != null && deletedPs.isSystem()) {
            if (DEBUG_REMOVE) {
                Slog.d(TAG, "Propagating install state across downgrade");
            }