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

Commit 45f54123 authored by Songchun Fan's avatar Songchun Fan
Browse files

[pm] package removal/deletion helper

Due to entangled dependencies between package deletion and stub system
installation, I had to slipt package delete helper into two classes.

DeletePackageHelper depends on RemovePackageHelper to clear internal
data structures. It also depends on InitAndSystemPackageHelper to
re-enable stub system packages after system package deletion.

InitAndSystemPackageHelper also depends on RemovePackageHelper, to
remove the data structures created for the stub package after the
decompressed package is installed.

I've created a TODO to clean up the stub package situation.

BUG: 200616235
Test: manual
Change-Id: I3d3bce937e670ff7c13b00e0f186211a1ffb3632
parent 7fe37e04
Loading
Loading
Loading
Loading
+818 −0

File added.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ class FileInstallArgs extends InstallArgs {
        if (mCodeFile == null || !mCodeFile.exists()) {
            return false;
        }
        mPm.removeCodePathLI(mCodeFile);
        mRemovePackageHelper.removeCodePathLI(mCodeFile);
        return true;
    }

+21 −56
Original line number Diff line number Diff line
@@ -85,12 +85,14 @@ import java.util.concurrent.ExecutorService;
 * further cleanup and eventually all the installation/scanning related logic will go to another
 * class.
 */
public class InitAndSystemPackageHelper {
    final PackageManagerService mPm;
final class InitAndSystemPackageHelper {
    private final PackageManagerService mPm;
    private final RemovePackageHelper mRemovePackageHelper;

    // TODO(b/198166813): remove PMS dependency
    public InitAndSystemPackageHelper(PackageManagerService pm) {
    InitAndSystemPackageHelper(PackageManagerService pm, RemovePackageHelper removePackageHelper) {
        mPm = pm;
        mRemovePackageHelper = removePackageHelper;
    }

    /**
@@ -203,7 +205,7 @@ public class InitAndSystemPackageHelper {
                                        + ", versionCode=" + ps.getVersionCode()
                                        + "; scanned versionCode="
                                        + scannedPkg.getLongVersionCode());
                        mPm.removePackageLI(scannedPkg, true);
                        mRemovePackageHelper.removePackageLI(scannedPkg, true);
                        mPm.mExpectingBetter.put(ps.getPackageName(), ps.getPath());
                    }

@@ -213,7 +215,7 @@ public class InitAndSystemPackageHelper {
                if (!mPm.mSettings.isDisabledSystemPackageLPr(ps.getPackageName())) {
                    logCriticalInfo(Log.WARN, "System package " + ps.getPackageName()
                            + " no longer exists; its data will be wiped");
                    mPm.removePackageDataLIF(ps, userIds, null, 0, false);
                    mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);
                } else {
                    // we still have a disabled system package, but, it still might have
                    // been removed. check the code path still exists and check there's
@@ -300,7 +302,7 @@ public class InitAndSystemPackageHelper {

                    // remove the package from the system and re-scan it without any
                    // special privileges
                    mPm.removePackageLI(pkg, true);
                    mRemovePackageHelper.removePackageLI(pkg, true);
                    try {
                        final File codePath = new File(pkg.getPath());
                        scanPackageHelper.scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
@@ -316,7 +318,7 @@ public class InitAndSystemPackageHelper {
                // partition], completely remove the package data.
                final PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
                if (ps != null && mPm.mPackages.get(packageName) == null) {
                    mPm.removePackageDataLIF(ps, userIds, null, 0, false);
                    mRemovePackageHelper.removePackageDataLIF(ps, userIds, null, 0, false);

                }
                logCriticalInfo(Log.WARN, msg);
@@ -486,7 +488,7 @@ public class InitAndSystemPackageHelper {
                    && errorCode != PackageManager.INSTALL_SUCCEEDED) {
                logCriticalInfo(Log.WARN,
                        "Deleting invalid package at " + parseResult.scanFile);
                mPm.removeCodePathLI(parseResult.scanFile);
                mRemovePackageHelper.removeCodePathLI(parseResult.scanFile);
            }
        }
    }
@@ -638,7 +640,7 @@ public class InitAndSystemPackageHelper {
        synchronized (mPm.mLock) {
            mPm.mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
        }
        mPm.removePackageLI(stubPkg, true /*chatty*/);
        mRemovePackageHelper.removePackageLI(stubPkg, true /*chatty*/);
        final ScanPackageHelper scanPackageHelper = new ScanPackageHelper(mPm);
        try {
            return scanPackageHelper.scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
@@ -646,7 +648,7 @@ public class InitAndSystemPackageHelper {
            Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
                    e);
            // Remove the failed install
            mPm.removeCodePathLI(scanFile);
            mRemovePackageHelper.removeCodePathLI(scanFile);
            throw e;
        }
    }
@@ -723,7 +725,7 @@ public class InitAndSystemPackageHelper {
            if (!dstCodePath.exists()) {
                return null;
            }
            mPm.removeCodePathLI(dstCodePath);
            mRemovePackageHelper.removeCodePathLI(dstCodePath);
            return null;
        }

@@ -737,52 +739,15 @@ public class InitAndSystemPackageHelper {
    }

    /**
     * Tries to delete system package.
     * Tries to restore the disabled system package after an update has been deleted.
     */
    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
    public void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
            @NonNull int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
            boolean writeSettings, int defParseFlags, List<ScanPartition> dirsToScanAsSystem)
    public void restoreDisabledSystemPackageLIF(DeletePackageAction action,
            PackageSetting deletedPs, @NonNull int[] allUserHandles,
            @Nullable PackageRemovedInfo outInfo,
            boolean writeSettings, int defParseFlags, List<ScanPartition> dirsToScanAsSystem,
            PackageSetting disabledPs)
            throws SystemDeleteException {
        final boolean applyUserRestrictions = outInfo != null && (outInfo.mOrigUsers != null);
        final AndroidPackage deletedPkg = deletedPs.getPkg();
        // Confirm if the system package has been updated
        // An updated system app can be deleted. This will also have to restore
        // the system pkg from system partition
        // reader
        final PackageSetting disabledPs = action.mDisabledPs;
        if (DEBUG_REMOVE) {
            Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
                    + " disabledPs=" + disabledPs);
        }
        Slog.d(TAG, "Deleting system pkg from data partition");

        if (DEBUG_REMOVE) {
            if (applyUserRestrictions) {
                Slog.d(TAG, "Remembering install states:");
                for (int userId : allUserHandles) {
                    final boolean finstalled = ArrayUtils.contains(outInfo.mOrigUsers, userId);
                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
                }
            }
        }

        if (outInfo != null) {
            // Delete the updated package
            outInfo.mIsRemovedPackageSystemUpdate = true;
        }

        if (disabledPs.getVersionCode() < deletedPs.getVersionCode()) {
            // Delete data for downgrades
            flags &= ~PackageManager.DELETE_KEEP_DATA;
        } else {
            // Preserve data by setting flag
            flags |= PackageManager.DELETE_KEEP_DATA;
        }

        mPm.deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
                outInfo, writeSettings);

        // writer
        synchronized (mPm.mLock) {
            // NOTE: The system package always needs to be enabled; even if it's for
@@ -802,7 +767,7 @@ public class InitAndSystemPackageHelper {
                    outInfo == null ? null : outInfo.mOrigUsers, writeSettings, defParseFlags,
                    dirsToScanAsSystem);
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
            Slog.w(TAG, "Failed to restore system package:" + deletedPs.getPackageName() + ": "
                    + e.getMessage());
            // TODO(b/194319951): can we avoid this; throw would come from scan...
            throw new SystemDeleteException(e);
@@ -812,7 +777,7 @@ public class InitAndSystemPackageHelper {
                // originally enabled, we'll install the compressed version of the application
                // and re-enable it afterward.
                final PackageSetting stubPs = mPm.mSettings.getPackageLPr(
                        deletedPkg.getPackageName());
                        deletedPs.getPackageName());
                if (stubPs != null) {
                    int userId = action.mUser == null
                            ? UserHandle.USER_ALL : action.mUser.getIdentifier();
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ abstract class InstallArgs {
    @Nullable String[] mInstructionSets;

    @NonNull final PackageManagerService mPm;
    @NonNull final RemovePackageHelper mRemovePackageHelper;

    InstallArgs(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer,
            int installFlags, InstallSource installSource, String volumeUuid,
@@ -90,6 +91,7 @@ abstract class InstallArgs {
        mForceQueryableOverride = forceQueryableOverride;
        mDataLoaderType = dataLoaderType;
        mPm = pm;
        mRemovePackageHelper = new RemovePackageHelper(mPm);
    }

    /** New install */
+5 −2
Original line number Diff line number Diff line
@@ -1538,6 +1538,8 @@ final class InstallParams extends HandlerParams {
            final ParsedPackage parsedPackage = scanRequest.mParsedPackage;
            final String packageName = parsedPackage.getPackageName();
            final PackageInstalledInfo res = reconciledPkg.mInstallResult;
            final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
            final DeletePackageHelper deletePackageHelper = new DeletePackageHelper(mPm);

            if (reconciledPkg.mPrepareResult.mReplace) {
                AndroidPackage oldPackage = mPm.mPackages.get(packageName);
@@ -1554,7 +1556,7 @@ final class InstallParams extends HandlerParams {
                        mPm.mSettings.getPackagesLocked());
                if (reconciledPkg.mPrepareResult.mSystem) {
                    // Remove existing system package
                    mPm.removePackageLI(oldPackage, true);
                    removePackageHelper.removePackageLI(oldPackage, true);
                    if (!disableSystemPackageLPw(oldPackage)) {
                        // We didn't need to disable the .apk as a current system package,
                        // which means we are replacing another update that is already
@@ -1572,7 +1574,8 @@ final class InstallParams extends HandlerParams {
                } else {
                    try {
                        // Settings will be written during the call to updateSettingsLI().
                        mPm.executeDeletePackageLIF(reconciledPkg.mDeletePackageAction, packageName,
                        deletePackageHelper.executeDeletePackageLIF(
                                reconciledPkg.mDeletePackageAction, packageName,
                                true, request.mAllUsers, false);
                    } catch (SystemDeleteException e) {
                        if (mPm.mIsEngBuild) {
Loading