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

Commit 788947b7 authored by Songchun Fan's avatar Songchun Fan
Browse files

Consolidate installation logics from params/args classes

Move mLocks/mSettings/mPackages dependencies from InstallParams,
PackageHandler, VerificationParams into InstallPackageHelper.

Also cleaning up InitAndSystemPackageHelper to move some of the
core installation logic into InstallPackageHelper.

Current goal is to have the "core" installation logic in one place.
"core" means code blocks that uses mLock/mSettings/mPackages during
installation.

BYPASS_INCLUSIVE_LANGUAGE_REASON=need to deprecate some old constant
names first

BUG: 198177734
BUG: 201815903
Test: manual
Change-Id: Idb2bf634ce58e968846d6f56c1d501ee8b3aafa3
parent 2f96a4f6
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -83,19 +83,15 @@ final class DeletePackageHelper {
    private final UserManagerInternal mUserManagerInternal;
    private final PermissionManagerServiceInternal mPermissionManager;
    private final RemovePackageHelper mRemovePackageHelper;
    // TODO(b/201815903): remove dependency to InitAndSystemPackageHelper
    private final InitAndSystemPackageHelper mInitAndSystemPackageHelper;
    private final AppDataHelper mAppDataHelper;

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

@@ -105,7 +101,6 @@ final class DeletePackageHelper {
        mUserManagerInternal = mPm.mInjector.getUserManagerInternal();
        mPermissionManager = mPm.mInjector.getPermissionManagerServiceInternal();
        mRemovePackageHelper = new RemovePackageHelper(mPm, mAppDataHelper);
        mInitAndSystemPackageHelper = mPm.getInitAndSystemPackageHelper();
    }

    /**
@@ -282,7 +277,7 @@ final class DeletePackageHelper {
                            Slog.i(TAG, "Enabling system stub after removal; pkg: "
                                    + stubPkg.getPackageName());
                        }
                        mInitAndSystemPackageHelper.enableCompressedPackage(stubPkg, stubPs);
                        new InstallPackageHelper(mPm).enableCompressedPackage(stubPkg, stubPs);
                    } else if (DEBUG_COMPRESSION) {
                        Slog.i(TAG, "System stub disabled for all users, leaving uncompressed "
                                + "after removal; pkg: " + stubPkg.getPackageName());
@@ -422,7 +417,7 @@ final class DeletePackageHelper {
            // as well and fall back to existing code in system partition
            PackageSetting disabledPs = deleteInstalledSystemPackage(action, ps, allUserHandles,
                    flags, outInfo, writeSettings);
            mInitAndSystemPackageHelper.restoreDisabledSystemPackageLIF(
            new InstallPackageHelper(mPm).restoreDisabledSystemPackageLIF(
                    action, ps, allUserHandles, outInfo, writeSettings, disabledPs);
        } else {
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.getPackageName());
+1 −3
Original line number Diff line number Diff line
@@ -41,14 +41,12 @@ public final class DomainVerificationConnection implements DomainVerificationSer
    final PackageManagerService mPm;
    final PackageManagerInternal mPmInternal;
    final UserManagerInternal mUmInternal;
    final VerificationHelper mVerificationHelper;

    // TODO(b/198166813): remove PMS dependency
    DomainVerificationConnection(PackageManagerService pm) {
        mPm = pm;
        mPmInternal = mPm.mInjector.getLocalService(PackageManagerInternal.class);
        mUmInternal = mPm.mInjector.getLocalService(UserManagerInternal.class);
        mVerificationHelper = new VerificationHelper(mPm.mContext);
    }

    @Override
@@ -79,7 +77,7 @@ public final class DomainVerificationConnection implements DomainVerificationSer

    @Override
    public long getPowerSaveTempWhitelistAppDuration() {
        return mVerificationHelper.getVerificationTimeout();
        return VerificationUtils.getVerificationTimeout(mPm.mContext);
    }

    @Override
+4 −147
Original line number Diff line number Diff line
@@ -16,23 +16,13 @@

package com.android.server.pm;

import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.TAG;

import android.annotation.NonNull;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.util.Pair;
import android.util.Slog;

import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
import static com.android.server.pm.PackageManagerService.TAG;

import com.android.internal.util.ArrayUtils;
import com.android.server.pm.parsing.pkg.AndroidPackage;

abstract class HandlerParams {
    /** User handle for the user requesting the information or installation. */
    private final UserHandle mUser;
@@ -40,15 +30,13 @@ abstract class HandlerParams {
    int mTraceCookie;
    @NonNull
    final PackageManagerService mPm;
    final VerificationHelper mVerificationHelper;
    final BroadcastHelper mBroadcastHelper;
    final InstallPackageHelper mInstallPackageHelper;

    // TODO(b/198166813): remove PMS dependency
    HandlerParams(UserHandle user, PackageManagerService pm) {
        mUser = user;
        mPm = pm;
        mVerificationHelper = new VerificationHelper(mPm.mContext);
        mBroadcastHelper = new BroadcastHelper(mPm.mInjector);
        mInstallPackageHelper = new InstallPackageHelper(mPm);
    }

    UserHandle getUser() {
@@ -73,135 +61,4 @@ abstract class HandlerParams {

    abstract void handleStartCopy();
    abstract void handleReturnCode();

    Pair<Integer, String> verifyReplacingVersionCode(PackageInfoLite pkgLite,
            long requiredInstalledVersionCode, int installFlags) {
        if ((installFlags & PackageManager.INSTALL_APEX) != 0) {
            return verifyReplacingVersionCodeForApex(
                    pkgLite, requiredInstalledVersionCode, installFlags);
        }

        String packageName = pkgLite.packageName;
        synchronized (mPm.mLock) {
            // Package which currently owns the data that the new package will own if installed.
            // If an app is uninstalled while keeping data (e.g. adb uninstall -k), installedPkg
            // will be null whereas dataOwnerPkg will contain information about the package
            // which was uninstalled while keeping its data.
            AndroidPackage dataOwnerPkg = mPm.mPackages.get(packageName);
            if (dataOwnerPkg  == null) {
                PackageSetting ps = mPm.mSettings.getPackageLPr(packageName);
                if (ps != null) {
                    dataOwnerPkg = ps.getPkg();
                }
            }

            if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
                if (dataOwnerPkg == null) {
                    String errorMsg = "Required installed version code was "
                            + requiredInstalledVersionCode
                            + " but package is not installed";
                    Slog.w(TAG, errorMsg);
                    return Pair.create(
                            PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg);
                }

                if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
                    String errorMsg = "Required installed version code was "
                            + requiredInstalledVersionCode
                            + " but actual installed version is "
                            + dataOwnerPkg.getLongVersionCode();
                    Slog.w(TAG, errorMsg);
                    return Pair.create(
                            PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg);
                }
            }

            if (dataOwnerPkg != null) {
                if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
                        dataOwnerPkg.isDebuggable())) {
                    try {
                        checkDowngrade(dataOwnerPkg, pkgLite);
                    } catch (PackageManagerException e) {
                        String errorMsg = "Downgrade detected: " + e.getMessage();
                        Slog.w(TAG, errorMsg);
                        return Pair.create(
                                PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
                    }
                }
            }
        }
        return Pair.create(PackageManager.INSTALL_SUCCEEDED, null);
    }

    private Pair<Integer, String> verifyReplacingVersionCodeForApex(PackageInfoLite pkgLite,
            long requiredInstalledVersionCode, int installFlags) {
        String packageName = pkgLite.packageName;

        final PackageInfo activePackage = mPm.mApexManager.getPackageInfo(packageName,
                ApexManager.MATCH_ACTIVE_PACKAGE);
        if (activePackage == null) {
            String errorMsg = "Attempting to install new APEX package " + packageName;
            Slog.w(TAG, errorMsg);
            return Pair.create(PackageManager.INSTALL_FAILED_PACKAGE_CHANGED, errorMsg);
        }

        final long activeVersion = activePackage.getLongVersionCode();
        if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST
                && activeVersion != requiredInstalledVersionCode) {
            String errorMsg = "Installed version of APEX package " + packageName
                    + " does not match required. Active version: " + activeVersion
                    + " required: " + requiredInstalledVersionCode;
            Slog.w(TAG, errorMsg);
            return Pair.create(PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION, errorMsg);
        }

        final boolean isAppDebuggable = (activePackage.applicationInfo.flags
                & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        final long newVersionCode = pkgLite.getLongVersionCode();
        if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags, isAppDebuggable)
                && newVersionCode < activeVersion) {
            String errorMsg = "Downgrade of APEX package " + packageName
                    + " is not allowed. Active version: " + activeVersion
                    + " attempted: " + newVersionCode;
            Slog.w(TAG, errorMsg);
            return Pair.create(PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE, errorMsg);
        }

        return Pair.create(PackageManager.INSTALL_SUCCEEDED, null);
    }

    /**
     * Check and throw if the given before/after packages would be considered a
     * downgrade.
     */
    private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
            throws PackageManagerException {
        if (after.getLongVersionCode() < before.getLongVersionCode()) {
            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                    "Update version code " + after.versionCode + " is older than current "
                            + before.getLongVersionCode());
        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
            if (after.baseRevisionCode < before.getBaseRevisionCode()) {
                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                        "Update base revision code " + after.baseRevisionCode
                                + " is older than current " + before.getBaseRevisionCode());
            }

            if (!ArrayUtils.isEmpty(after.splitNames)) {
                for (int i = 0; i < after.splitNames.length; i++) {
                    final String splitName = after.splitNames[i];
                    final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
                    if (j != -1) {
                        if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                                    "Update split " + splitName + " revision code "
                                            + after.splitRevisionCodes[i]
                                            + " is older than current "
                                            + before.getSplitRevisionCodes()[j]);
                        }
                    }
                }
            }
        }
    }
}
+9 −425

File changed.

Preview size limit exceeded, changes collapsed.

+2691 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading