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

Commit f9975966 authored by Songchun Fan's avatar Songchun Fan Committed by Android (Google) Code Review
Browse files

Merge "Revert^4 "[pm] remove circular dependency in init helper"" into tm-dev

parents 0ad0c076 d78b924c
Loading
Loading
Loading
Loading
+121 −82
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_CHECK_MAX_SDK_VERSION;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.parsing.ApkLiteParseUtils;
import android.os.Environment;
@@ -61,14 +62,24 @@ import java.util.concurrent.ExecutorService;
 * further cleanup and eventually all the installation/scanning related logic will go to another
 * class.
 */
final class InitAndSystemPackageHelper {
final class InitAppsHelper {
    private final PackageManagerService mPm;

    private final List<ScanPartition> mDirsToScanAsSystem;
    private final int mScanFlags;
    private final int mSystemParseFlags;
    private final int mSystemScanFlags;
    private final InstallPackageHelper mInstallPackageHelper;
    private final ApexManager mApexManager;
    private final ExecutorService mExecutorService;
    /* Tracks how long system scan took */
    private long mSystemScanTime;
    /* Track of the number of cached system apps */
    private int mCachedSystemApps;
    /* Track of the number of system apps */
    private int mSystemPackagesCount;
    private final boolean mIsDeviceUpgrading;
    private final boolean mIsOnlyCoreApps;
    private final List<ScanPartition> mSystemPartitions;

    /**
     * Tracks new system packages [received in an OTA] that we expect to
@@ -76,21 +87,33 @@ final class InitAndSystemPackageHelper {
     * are package location.
     */
    private final ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
    /* Tracks of any system packages that no longer exist that needs to be pruned. */
    private final List<String> mPossiblyDeletedUpdatedSystemApps = new ArrayList<>();
    // Tracks of stub packages that must either be replaced with full versions in the /data
    // partition or be disabled.
    private final List<String> mStubSystemApps = new ArrayList<>();

    // TODO(b/198166813): remove PMS dependency
    InitAndSystemPackageHelper(PackageManagerService pm) {
    InitAppsHelper(PackageManagerService pm, ApexManager apexManager,
            InstallPackageHelper installPackageHelper,
            List<ScanPartition> systemPartitions) {
        mPm = pm;
        mInstallPackageHelper = new InstallPackageHelper(pm);
        mApexManager = apexManager;
        mInstallPackageHelper = installPackageHelper;
        mSystemPartitions = systemPartitions;
        mDirsToScanAsSystem = getSystemScanPartitions();
        mIsDeviceUpgrading = mPm.isDeviceUpgrading();
        mIsOnlyCoreApps = mPm.isOnlyCoreApps();
        // Set flag to monitor and not change apk file paths when scanning install directories.
        int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
        if (mPm.isDeviceUpgrading() || mPm.isFirstBoot()) {
        if (mIsDeviceUpgrading || mPm.isFirstBoot()) {
            mScanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
        } else {
            mScanFlags = scanFlags;
        }
        mSystemParseFlags = mPm.getDefParseFlags() | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
        mSystemScanFlags = scanFlags | SCAN_AS_SYSTEM;
        mExecutorService = ParallelPackageParser.makeExecutorService();
    }

    private List<File> getFrameworkResApkSplitFiles() {
@@ -118,7 +141,7 @@ final class InitAndSystemPackageHelper {

    private List<ScanPartition> getSystemScanPartitions() {
        final List<ScanPartition> scanPartitions = new ArrayList<>();
        scanPartitions.addAll(mPm.mInjector.getSystemPartitions());
        scanPartitions.addAll(mSystemPartitions);
        scanPartitions.addAll(getApexScanPartitions());
        Slog.d(TAG, "Directories scanned as system partitions: " + scanPartitions);
        return scanPartitions;
@@ -126,8 +149,7 @@ final class InitAndSystemPackageHelper {

    private List<ScanPartition> getApexScanPartitions() {
        final List<ScanPartition> scanPartitions = new ArrayList<>();
        final List<ApexManager.ActiveApexInfo> activeApexInfos =
                mPm.mApexManager.getActiveApexInfos();
        final List<ApexManager.ActiveApexInfo> activeApexInfos = mApexManager.getActiveApexInfos();
        for (int i = 0; i < activeApexInfos.size(); i++) {
            final ScanPartition scanPartition = resolveApexToScanPartition(activeApexInfos.get(i));
            if (scanPartition != null) {
@@ -151,97 +173,120 @@ final class InitAndSystemPackageHelper {
        return null;
    }

    public OverlayConfig initPackages(
            WatchedArrayMap<String, PackageSetting> packageSettings, int[] userIds,
            long startTime) {
        PackageParser2 packageParser = mPm.mInjector.getScanningCachingPackageParser();

        ExecutorService executorService = ParallelPackageParser.makeExecutorService();
    /**
     * Install apps from system dirs.
     */
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    public OverlayConfig initSystemApps(PackageParser2 packageParser,
            WatchedArrayMap<String, PackageSetting> packageSettings,
            int[] userIds, long startTime) {
        // Prepare apex package info before scanning APKs, this information is needed when
        // scanning apk in apex.
        mPm.mApexManager.scanApexPackagesTraced(packageParser, executorService);
        mApexManager.scanApexPackagesTraced(packageParser, mExecutorService);

        scanSystemDirs(packageParser, executorService);
        scanSystemDirs(packageParser, mExecutorService);
        // Parse overlay configuration files to set default enable state, mutability, and
        // priority of system overlays.
        final ArrayMap<String, File> apkInApexPreInstalledPaths = new ArrayMap<>();
        for (ApexManager.ActiveApexInfo apexInfo : mPm.mApexManager.getActiveApexInfos()) {
            for (String packageName : mPm.mApexManager.getApksInApex(apexInfo.apexModuleName)) {
        for (ApexManager.ActiveApexInfo apexInfo : mApexManager.getActiveApexInfos()) {
            for (String packageName : mApexManager.getApksInApex(apexInfo.apexModuleName)) {
                apkInApexPreInstalledPaths.put(packageName, apexInfo.preInstalledApexPath);
            }
        }
        OverlayConfig overlayConfig = OverlayConfig.initializeSystemInstance(
        final OverlayConfig overlayConfig = OverlayConfig.initializeSystemInstance(
                consumer -> mPm.forEachPackage(mPm.snapshotComputer(),
                        pkg -> consumer.accept(pkg, pkg.isSystem(),
                                apkInApexPreInstalledPaths.get(pkg.getPackageName()))));
        // Prune any system packages that no longer exist.
        final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
        // Stub packages must either be replaced with full versions in the /data
        // partition or be disabled.
        final List<String> stubSystemApps = new ArrayList<>();

        if (!mPm.isOnlyCoreApps()) {
        if (!mIsOnlyCoreApps) {
            // do this first before mucking with mPackages for the "expecting better" case
            updateStubSystemAppsList(stubSystemApps);
            updateStubSystemAppsList(mStubSystemApps);
            mInstallPackageHelper.prepareSystemPackageCleanUp(packageSettings,
                    possiblyDeletedUpdatedSystemApps, mExpectingBetter, userIds);
                    mPossiblyDeletedUpdatedSystemApps, mExpectingBetter, userIds);
        }

        final int cachedSystemApps = PackageCacher.sCachedPackageReadCount.get();
        logSystemAppsScanningTime(startTime);
        return overlayConfig;
    }

    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private void logSystemAppsScanningTime(long startTime) {
        mCachedSystemApps = PackageCacher.sCachedPackageReadCount.get();

        // Remove any shared userIDs that have no associated packages
        mPm.mSettings.pruneSharedUsersLPw();
        final long systemScanTime = SystemClock.uptimeMillis() - startTime;
        final int systemPackagesCount = mPm.mPackages.size();
        Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
                + " ms, packageCount: " + systemPackagesCount
        mSystemScanTime = SystemClock.uptimeMillis() - startTime;
        mSystemPackagesCount = mPm.mPackages.size();
        Slog.i(TAG, "Finished scanning system apps. Time: " + mSystemScanTime
                + " ms, packageCount: " + mSystemPackagesCount
                + " , timePerPackage: "
                + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
                + " , cached: " + cachedSystemApps);
        if (mPm.isDeviceUpgrading() && systemPackagesCount > 0) {
                + (mSystemPackagesCount == 0 ? 0 : mSystemScanTime / mSystemPackagesCount)
                + " , cached: " + mCachedSystemApps);
        if (mIsDeviceUpgrading && mSystemPackagesCount > 0) {
            //CHECKSTYLE:OFF IndentationCheck
            FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                    BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,
                    systemScanTime / systemPackagesCount);
                    mSystemScanTime / mSystemPackagesCount);
            //CHECKSTYLE:ON IndentationCheck
        }
    }

        if (!mPm.isOnlyCoreApps()) {
    /**
     * Install apps/updates from data dir and fix system apps that are affected.
     */
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    public void initNonSystemApps(PackageParser2 packageParser, @NonNull int[] userIds,
            long startTime) {
        if (!mIsOnlyCoreApps) {
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                    SystemClock.uptimeMillis());
            scanDirTracedLI(mPm.getAppInstallDir(), /* frameworkSplits= */ null, 0,
                    mScanFlags | SCAN_REQUIRE_KNOWN, 0,
                    packageParser, executorService);

                    mScanFlags | SCAN_REQUIRE_KNOWN,
                    packageParser, mExecutorService);
        }

        List<Runnable> unfinishedTasks = executorService.shutdownNow();
        List<Runnable> unfinishedTasks = mExecutorService.shutdownNow();
        if (!unfinishedTasks.isEmpty()) {
            throw new IllegalStateException("Not all tasks finished before calling close: "
                    + unfinishedTasks);
        }
        if (!mIsOnlyCoreApps) {
            fixSystemPackages(userIds);
            logNonSystemAppScanningTime(startTime);
        }
        mExpectingBetter.clear();
        mPm.mSettings.pruneRenamedPackagesLPw();
    }

        if (!mPm.isOnlyCoreApps()) {
            mInstallPackageHelper.cleanupDisabledPackageSettings(possiblyDeletedUpdatedSystemApps,
    /**
     * Clean up system packages now that some system package updates have been installed from
     * the data dir. Also install system stub packages as the last step.
     */
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private void fixSystemPackages(@NonNull int[] userIds) {
        mInstallPackageHelper.cleanupDisabledPackageSettings(mPossiblyDeletedUpdatedSystemApps,
                userIds, mScanFlags);
        mInstallPackageHelper.checkExistingBetterPackages(mExpectingBetter,
                    stubSystemApps, mSystemScanFlags, mSystemParseFlags);
                mStubSystemApps, mSystemScanFlags, mSystemParseFlags);

        // Uncompress and install any stubbed system applications.
        // This must be done last to ensure all stubs are replaced or disabled.
            mInstallPackageHelper.installSystemStubPackages(stubSystemApps, mScanFlags);
        mInstallPackageHelper.installSystemStubPackages(mStubSystemApps, mScanFlags);
    }

    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private void logNonSystemAppScanningTime(long startTime) {
        final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get()
                    - cachedSystemApps;
                - mCachedSystemApps;

            final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
            final int dataPackagesCount = mPm.mPackages.size() - systemPackagesCount;
        final long dataScanTime = SystemClock.uptimeMillis() - mSystemScanTime - startTime;
        final int dataPackagesCount = mPm.mPackages.size() - mSystemPackagesCount;
        Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
                + " ms, packageCount: " + dataPackagesCount
                + " , timePerPackage: "
                + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
                + " , cached: " + cachedNonSystemApps);
            if (mPm.isDeviceUpgrading() && dataPackagesCount > 0) {
        if (mIsDeviceUpgrading && dataPackagesCount > 0) {
            //CHECKSTYLE:OFF IndentationCheck
            FrameworkStatsLog.write(
                    FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
@@ -250,12 +295,6 @@ final class InitAndSystemPackageHelper {
            //CHECKSTYLE:OFF IndentationCheck
        }
    }
        mExpectingBetter.clear();

        mPm.mSettings.pruneRenamedPackagesLPw();
        packageParser.close();
        return overlayConfig;
    }

    /**
     * First part of init dir scanning
@@ -274,13 +313,13 @@ final class InitAndSystemPackageHelper {
                continue;
            }
            scanDirTracedLI(partition.getOverlayFolder(), /* frameworkSplits= */ null,
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag, 0,
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag,
                    packageParser, executorService);
        }

        scanDirTracedLI(frameworkDir, null,
                mSystemParseFlags,
                mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
                mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,
                packageParser, executorService);
        if (!mPm.mPackages.containsKey("android")) {
            throw new IllegalStateException(
@@ -292,11 +331,11 @@ final class InitAndSystemPackageHelper {
            if (partition.getPrivAppFolder() != null) {
                scanDirTracedLI(partition.getPrivAppFolder(), /* frameworkSplits= */ null,
                        mSystemParseFlags,
                        mSystemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
                        mSystemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag,
                        packageParser, executorService);
            }
            scanDirTracedLI(partition.getAppFolder(), /* frameworkSplits= */ null,
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag, 0,
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag,
                    packageParser, executorService);
        }
    }
@@ -315,7 +354,7 @@ final class InitAndSystemPackageHelper {
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private void scanDirTracedLI(File scanDir, List<File> frameworkSplits,
            int parseFlags, int scanFlags,
            long currentTime, PackageParser2 packageParser, ExecutorService executorService) {
            PackageParser2 packageParser, ExecutorService executorService) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
        try {
            if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
@@ -323,7 +362,7 @@ final class InitAndSystemPackageHelper {
                parseFlags |= PARSE_CHECK_MAX_SDK_VERSION;
            }
            mInstallPackageHelper.installPackagesFromDir(scanDir, frameworkSplits, parseFlags,
                    scanFlags, currentTime, packageParser, executorService);
                    scanFlags, packageParser, executorService);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
+15 −15
Original line number Diff line number Diff line
@@ -3062,7 +3062,7 @@ final class InstallPackageHelper {
        final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
        removePackageHelper.removePackageLI(stubPkg, true /*chatty*/);
        try {
            return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
            return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, null);
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
                    e);
@@ -3194,7 +3194,7 @@ final class InstallPackageHelper {
                        | ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
        @PackageManagerService.ScanFlags int scanFlags = mPm.getSystemPackageScanFlags(codePath);
        final AndroidPackage pkg = scanSystemPackageTracedLI(
                        codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
                codePath, parseFlags, scanFlags, null);

        PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());

@@ -3368,7 +3368,7 @@ final class InstallPackageHelper {
                mRemovePackageHelper.removePackageLI(pkg, true);
                try {
                    final File codePath = new File(pkg.getPath());
                    scanSystemPackageTracedLI(codePath, 0, scanFlags, 0, null);
                    scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "Failed to parse updated, ex-system package: "
                            + e.getMessage());
@@ -3389,7 +3389,7 @@ final class InstallPackageHelper {

    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    public void installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags,
            int scanFlags, long currentTime, PackageParser2 packageParser,
            int scanFlags, PackageParser2 packageParser,
            ExecutorService executorService) {
        final File[] files = scanDir.listFiles();
        if (ArrayUtils.isEmpty(files)) {
@@ -3432,7 +3432,7 @@ final class InstallPackageHelper {
                            parseResult.parsedPackage);
                }
                try {
                    addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags, currentTime,
                    addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
                            null);
                } catch (PackageManagerException e) {
                    errorCode = e.error;
@@ -3495,7 +3495,7 @@ final class InstallPackageHelper {

            try {
                final AndroidPackage newPkg = scanSystemPackageTracedLI(
                        scanFile, reparseFlags, rescanFlags, 0, null);
                        scanFile, reparseFlags, rescanFlags, null);
                // We rescanned a stub, add it to the list of stubbed system packages
                if (newPkg.isStub()) {
                    stubSystemApps.add(packageName);
@@ -3509,14 +3509,14 @@ final class InstallPackageHelper {

    /**
     *  Traces a package scan.
     *  @see #scanSystemPackageLI(File, int, int, long, UserHandle)
     *  @see #scanSystemPackageLI(File, int, int, UserHandle)
     */
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    public AndroidPackage scanSystemPackageTracedLI(File scanFile, final int parseFlags,
            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
            int scanFlags, UserHandle user) throws PackageManagerException {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
        try {
            return scanSystemPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
            return scanSystemPackageLI(scanFile, parseFlags, scanFlags, user);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
@@ -3528,7 +3528,7 @@ final class InstallPackageHelper {
     */
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags,
            long currentTime, UserHandle user) throws PackageManagerException {
            UserHandle user) throws PackageManagerException {
        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
@@ -3544,7 +3544,7 @@ final class InstallPackageHelper {
            PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage);
        }

        return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
        return addForInitLI(parsedPackage, parseFlags, scanFlags, user);
    }

    /**
@@ -3563,11 +3563,11 @@ final class InstallPackageHelper {
    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
    private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
            @ParsingPackageUtils.ParseFlags int parseFlags,
            @PackageManagerService.ScanFlags int scanFlags, long currentTime,
            @PackageManagerService.ScanFlags int scanFlags,
            @Nullable UserHandle user) throws PackageManagerException {

        final Pair<ScanResult, Boolean> scanResultPair = scanSystemPackageLI(
                parsedPackage, parseFlags, scanFlags, currentTime, user);
                parsedPackage, parseFlags, scanFlags, user);
        final ScanResult scanResult = scanResultPair.first;
        boolean shouldHideSystemApp = scanResultPair.second;
        if (scanResult.mSuccess) {
@@ -3762,7 +3762,7 @@ final class InstallPackageHelper {

    private Pair<ScanResult, Boolean> scanSystemPackageLI(ParsedPackage parsedPackage,
            @ParsingPackageUtils.ParseFlags int parseFlags,
            @PackageManagerService.ScanFlags int scanFlags, long currentTime,
            @PackageManagerService.ScanFlags int scanFlags,
            @Nullable UserHandle user) throws PackageManagerException {
        final boolean scanSystemPartition =
                (parseFlags & ParsingPackageUtils.PARSE_IS_SYSTEM_DIR) != 0;
@@ -3950,7 +3950,7 @@ final class InstallPackageHelper {
        }

        final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags,
                scanFlags | SCAN_UPDATE_SIGNATURE, currentTime, user, null);
                scanFlags | SCAN_UPDATE_SIGNATURE, 0 /* currentTime */, user, null);
        return new Pair<>(scanResult, shouldHideSystemApp);
    }

+13 −11

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ public final class PackageManagerServiceTestParams {
    public AppDataHelper appDataHelper;
    public InstallPackageHelper installPackageHelper;
    public RemovePackageHelper removePackageHelper;
    public InitAndSystemPackageHelper initAndSystemPackageHelper;
    public InitAppsHelper initAndSystemPackageHelper;
    public DeletePackageHelper deletePackageHelper;
    public PreferredActivityHelper preferredActivityHelper;
    public ResolveIntentHelper resolveIntentHelper;
+1 −1
Original line number Diff line number Diff line
@@ -151,7 +151,7 @@ public final class StorageEventHelper extends StorageEventListener {
                final AndroidPackage pkg;
                try {
                    pkg = installPackageHelper.scanSystemPackageTracedLI(
                            ps.getPath(), parseFlags, SCAN_INITIAL, 0, null);
                            ps.getPath(), parseFlags, SCAN_INITIAL, null);
                    loaded.add(pkg);

                } catch (PackageManagerException e) {