Android 14 PMS源码分析

发布于:2025-08-30 ⋅ 阅读:(24) ⋅ 点赞:(0)

源码参考:Search (aospxref.com)

一、简介

PackageManagerService(简称 PMS),是 Android 系统核心服务之一,处理包管理相关的工作,常见的比如安装、卸载应用等。本章针对SyetemServer、PMS构造方法重点模块解析

二、SystemServer.java

PMS是在SystemServer中启动,所有我们从SystemServer为入口进行解析:

frameworks/base/services/java/com/android/server/SystemServer.java

2.1 main

public static void main(String[] args) {
       new SystemServer().run();
   }

2.2 run

    private void run() {
    ...
                //SYSTEM_SERVER_START
                EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
                    mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);
        // Start services.
        try {
            t.traceBegin("StartServices");
            //启动引导服务【见1.3】
            startBootstrapServices(t);
            //启动核心服务
            startCoreServices(t);
            //启动其他服务
            startOtherServices(t);
            startApexServices(t);
            // Only update the timeout after starting all the services so that we use
            // the default timeout to start system server.
            updateWatchdogTimeout(t);
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }
        ...
}

2.3 startBootstrapServices

private void startBootstrapServices() {
    …
    //启动installer服务,负责package安装、删除、迁移、更新的系统服务
        t.traceBegin("StartInstaller");
        Installer installer = mSystemServiceManager.startService(Installer.class);
        t.traceEnd();
    …
    //启动PMS服务
        t.traceBegin("StartPackageManagerService");
        try {
            Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
            mPackageManagerService = PackageManagerService.main(
                    mSystemContext, installer, domainVerificationService,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF);
        } finally {
            Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
        }
        //mFirstBoot是后续WMS创建时所需要的参数,系统服务之间是有依赖关系的,它们的启动顺序不能随意被更改。
        mFirstBoot = mPackageManagerService.isFirstBoot();
        mPackageManager = mSystemContext.getPackageManager();
        t.traceEnd();
    ...
}
private void startOtherServices() {
...
        t.traceBegin("MakePackageManagerServiceReady");
        mPackageManagerService.systemReady();
        t.traceEnd();
…
}

三、PackageManagerService.Java

3.1 main

main方法主要做了两件事,一个是创建PMS对象,另一个是将PMS注册到ServiceManager中。

    public static PackageManagerService main(Context context,
            Installer installer, @NonNull DomainVerificationService domainVerificationService,
            boolean factoryTest) {
        // Self-check for initial settings.
        //自检初始设置
        PackageManagerServiceCompilerMapping.checkProperties();
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                Trace.TRACE_TAG_PACKAGE_MANAGER);
        t.traceBegin("create package manager");
        final PackageManagerTracedLock lock = new PackageManagerTracedLock();
        final Object installLock = new Object();

        HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
                Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
        backgroundThread.start();
        Handler backgroundHandler = new Handler(backgroundThread.getLooper(),
                BACKGROUND_HANDLER_CALLBACK);
        //injector里面会初始化Settings、PackageDexOptimizer、DexManager等,后面需要用到
        PackageManagerServiceInjector injector = new PackageManagerServiceInjector(
                context, lock, installer, installLock, new PackageAbiHelperImpl(),
                backgroundHandler,
                SYSTEM_PARTITIONS,
                (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mUserNeedsBadging),
                (i, pm) -> PermissionManagerService.create(context,
                        i.getSystemConfig().getAvailableFeatures()),
                (i, pm) -> new UserManagerService(context, pm,
                        new UserDataPreparer(installer, installLock, context), lock),
                //Settings用于保存所有包的动态设置
                (i, pm) -> new Settings(Environment.getDataDirectory(),
                        RuntimePermissionsPersistence.createInstance(),
                        i.getPermissionManagerServiceInternal(),
                        domainVerificationService, backgroundHandler,
                        lock),
                (i, pm) -> AppsFilterImpl.create(i,
                        i.getLocalService(PackageManagerInternal.class)),
                (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
                //得到全局系统配置信息。
                (i, pm) -> SystemConfig.getInstance(),
                //创建Dex优化工具类
                (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
                        i.getContext(), "*dexopt*"),
                
                (i, pm) -> new DexManager(i.getContext(), i.getPackageDexOptimizer(),
                        i.getInstaller(), i.getInstallLock(), i.getDynamicCodeLogger()),
                (i, pm) -> new DynamicCodeLogger(i.getInstaller()),
                (i, pm) -> new ArtManagerService(i.getContext(), i.getInstaller(),
                        i.getInstallLock()),
                (i, pm) -> ApexManager.getInstance(),
                (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
                (i, pm) -> (IncrementalManager)
                        i.getContext().getSystemService(Context.INCREMENTAL_SERVICE),
                (i, pm) -> new DefaultAppProvider(() -> context.getSystemService(RoleManager.class),
                        () -> LocalServices.getService(UserManagerInternal.class)),
                 //用于存储屏幕的相关信息
                (i, pm) -> new DisplayMetrics(),
                (i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(),
                        pm.mCacheDir,
                        pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */,
                (i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), null,
                        pm.mPackageParserCallback) /* scanningPackageParserProducer */,
                (i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), null,
                        pm.mPackageParserCallback) /* preparingPackageParserProducer */,
                // Prepare a supplier of package parser for the staging manager to parse apex file
....

        if (Build.VERSION.SDK_INT <= 0) {
            Slog.w(TAG, "**** ro.build.version.sdk not set!");
        }
        //初始化PMS[见3.1]
        PackageManagerService m = new PackageManagerService(injector, factoryTest,
                PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,
                Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL);
        t.traceEnd(); // "create package manager"

.....
        injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
                selinuxChangeListener);
        injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_R_CHANGES,
                selinuxChangeListener);

        m.installAllowlistedSystemPackages();
        IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
         //向ServiceManager注册服务
        ServiceManager.addService("package", iPackageManager);
        final PackageManagerNative pmn = new PackageManagerNative(m);
        ServiceManager.addService("package_native", pmn);
        return m;
    }

3.2 PackageManagerService()

PMS的构造方法,这部分代码非常多,主要分5个阶段:

PMS_START阶段

  • 构造Settings类:这个是Android的全局管理者,用于协助PMS保存所有的安装包信息;
  • 保存Installer对象;
  • 初始化SystemConfig,获取系统配置信息,包括全局属性、groupid以及系统权限。初始化一些功能类,包括:PackageDexOptimizer (dex优化工具类) 、 DexManager(dex管理类)、PackageHandler(建立package相关操作的消息循环)等;
  • 创建data下的各种目录,比如data/app, data/app-private等。

PMS_SYSTEM_SCAN_START阶段

  • 通过scanDirTracedLI扫描系统目录文件,包括:/system/framework 、/system/priv-app 、/system/app 这俩都是放系统app、/vendor/overlay、/vendor/app、oem/app。

PMS_DATA_SCAN_START阶段

  • 通过scanDirTracedLI扫描/data/app和/data/app-private目录下的文件。

PMS_SCAN_END阶段

  • 将上述信息写回/data/system/packages.xml。

PMS_READY阶段

  • 创建服务PackageInstallerService。

3.2.1 BOOT_PROGRESS_PMS_START

    public PackageManagerService(PackageManagerServiceInjector injector, boolean factoryTest,
            final String partitionsFingerprint, final boolean isEngBuild,
            final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
        // 存储构建和版本信息
        mIsEngBuild = isEngBuild;  // 是否为工程版构建
        mIsUserDebugBuild = isUserDebugBuild;  // 是否为用户调试版本
        mSdkVersion = sdkVersion;  // 系统的 SDK 版本
        mIncrementalVersion = incrementalVersion;  // 增量构建版本
        
        // 通过 injector 注入依赖
        mInjector = injector;
        mInjector.getSystemWrapper().disablePackageCaches();
        
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                Trace.TRACE_TAG_PACKAGE_MANAGER);
        mPendingBroadcasts = new PendingPackageBroadcasts();
         // 启动 injector 的引导程序
        mInjector.bootstrap(this);
        mLock = injector.getLock();
        mPackageStateWriteLock = mLock;
        mInstallLock = injector.getInstallLock();
        LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
        //第一阶段 BOOT_PROGRESS_PMS_START
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis());
        // 初始化上下文和其他服务
        mContext = injector.getContext();
        mFactoryTest = factoryTest;
        //用于存储屏幕的相关信息
        mMetrics = injector.getDisplayMetrics();
        //Installer对象
        mInstaller = injector.getInstaller();
        mEnableFreeCacheV2 = SystemProperties.getBoolean("fw.free_cache_v2", true);

        // Create sub-components that provide services / data. Order here is important.
        t.traceBegin("createSubComponents");

        // Expose private service for system components to use.
        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
        LocalManagerRegistry.addManager(PackageManagerLocal.class,
                new PackageManagerLocalImpl(this));
        LocalServices.addService(TestUtilityService.class, this);
        mTestUtilityService = LocalServices.getService(TestUtilityService.class);
        // 初始化用户管理和组件解析器
        mUserManager = injector.getUserManagerService();
        mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager);
        mComponentResolver = injector.getComponentResolver();
        mPermissionManager = injector.getPermissionManagerServiceInternal();
        //Android的全局管理者,用于协助PMS保存所有的安装包信息;[见3.3]
        mSettings = injector.getSettings();
        mIncrementalManager = mInjector.getIncrementalManager();
        mDefaultAppProvider = mInjector.getDefaultAppProvider();
        mLegacyPermissionManager = mInjector.getLegacyPermissionManagerInternal();
        PlatformCompat platformCompat = mInjector.getCompatibility();
        mPackageParserCallback = new PackageParser2.Callback() {
            @Override
            public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
                return platformCompat.isChangeEnabled(changeId, appInfo);
            }

            @Override
            public boolean hasFeature(String feature) {
                return PackageManagerService.this.hasSystemFeature(feature, 0);
            }
        };

        // CHECKSTYLE:ON IndentationCheck
        t.traceEnd();
        // 添加共享用户,如两个App的之间的数据是不共享的,如果它们有了共同的sharedUserId,就可以运行在同一个进程中共享数据。
        t.traceBegin("addSharedUsers");
        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.uwb", UWB_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        t.traceEnd();
        // 获取分离进程的系统属性
        String separateProcesses = SystemProperties.get("debug.separate_processes");

        if (separateProcesses != null && separateProcesses.length() > 0) {
            if ("*".equals(separateProcesses)) {
                mDefParseFlags = ParsingPackageUtils.PARSE_IGNORE_PROCESSES;
                mSeparateProcesses = null;
                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
            } else {
                mDefParseFlags = 0;
                mSeparateProcesses = separateProcesses.split(",");
                Slog.w(TAG, "Running with debug.separate_processes: "
                        + separateProcesses);
            }
        } else {
            mDefParseFlags = 0;
            mSeparateProcesses = null;
        }
        // 初始化 Dex 优化器和管理器
        mPackageDexOptimizer = injector.getPackageDexOptimizer();
        //Dex优化工具类
        mDexManager = injector.getDexManager();
        mDynamicCodeLogger = injector.getDynamicCodeLogger();
        //后台DexOpt服务
        mBackgroundDexOptService = injector.getBackgroundDexOptService();
        mArtManagerService = injector.getArtManagerService();
        mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper());
        mViewCompiler = injector.getViewCompiler();
        mSharedLibraries = mInjector.getSharedLibrariesImpl();
        mBackgroundHandler = injector.getBackgroundHandler();

        mContext.getSystemService(DisplayManager.class)
                .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);

        t.traceBegin("get system config");
        SystemConfig systemConfig = injector.getSystemConfig();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        t.traceEnd();

        mProtectedPackages = new ProtectedPackages(mContext);
        // 初始化 APEX 和应用过滤器
        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");

        mDomainVerificationConnection = new DomainVerificationConnection(this);
        mDomainVerificationManager = injector.getDomainVerificationManagerInternal();
        mDomainVerificationManager.setConnection(mDomainVerificationConnection);
        // 初始化各类Helper
        mBroadcastHelper = new BroadcastHelper(mInjector);
        mAppDataHelper = new AppDataHelper(this);
        mInstallPackageHelper = new InstallPackageHelper(this, mAppDataHelper);
        mRemovePackageHelper = new RemovePackageHelper(this, mAppDataHelper);
        mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper,
                mAppDataHelper);
        mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);
        mPreferredActivityHelper = new PreferredActivityHelper(this);
        mResolveIntentHelper = new ResolveIntentHelper(mContext, mPreferredActivityHelper,
                injector.getCompatibility(), mUserManager, mDomainVerificationManager,
                mUserNeedsBadging, () -> mResolveInfo, () -> mInstantAppInstallerActivity,
                injector.getBackgroundHandler());
        mDexOptHelper = new DexOptHelper(this);
        mSuspendPackageHelper = new SuspendPackageHelper(this, mInjector, mUserManager,
                mBroadcastHelper, mProtectedPackages);
        mDistractingPackageHelper = new DistractingPackageHelper(this, mInjector, mBroadcastHelper,
                mSuspendPackageHelper);
        mStorageEventHelper = new StorageEventHelper(this, mDeletePackageHelper,
                mRemovePackageHelper);
      
        synchronized (mLock) {
            // Create the computer as soon as the state objects have been installed.  The
            // cached computer is the same as the live computer until the end of the
            // constructor, at which time the invalidation method updates it.
            mSnapshotStatistics = new SnapshotStatistics();// 初始化快照统计数据
            sSnapshotPendingVersion.incrementAndGet();
            mLiveComputer = createLiveComputer();
            registerObservers(true);// 注册观察者,监听系统状态的变化
        }

        Computer computer = mLiveComputer;
        // CHECKSTYLE:OFF IndentationCheck
        synchronized (mInstallLock) {
        // writer
        // 这里是包管理器服务的核心锁机制,用于在包安装过程中确保线程安全。
        synchronized (mLock) {
            mHandler = injector.getHandler();
            mProcessLoggingHandler = new ProcessLoggingHandler();
            //将PackageHandler添加到Watchdog的检测集中
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
            // 加载共享库的配置
            ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
                    = systemConfig.getSharedLibraries();
            final int builtInLibCount = libConfig.size();
            for (int i = 0; i < builtInLibCount; i++) {
                mSharedLibraries.addBuiltInSharedLibraryLPw(libConfig.valueAt(i));
            }

            // Now that we have added all the libraries, iterate again to add dependency
            // information IFF their dependencies are added.
            // 添加共享库的依赖项
            long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
            for (int i = 0; i < builtInLibCount; i++) {
                String name = libConfig.keyAt(i);
                SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
                final int dependencyCount = entry.dependencies.length;
                for (int j = 0; j < dependencyCount; j++) {
                    final SharedLibraryInfo dependency =
                        computer.getSharedLibraryInfo(entry.dependencies[j], undefinedVersion);
                    if (dependency != null) {
                        computer.getSharedLibraryInfo(name, undefinedVersion)
                                .addDependency(dependency);
                    }
                }
            }
            // 读取 SELinux 安装策略
            SELinuxMMAC.readInstallPolicy();

            t.traceBegin("loadFallbacks");
            FallbackCategoryProvider.loadFallbacks();
            t.traceEnd();
            // 读取用户设置,检查系统是否是首次启动
            t.traceBegin("read user settings");
            mFirstBoot = !mSettings.readLPw(computer,
                    mInjector.getUserManagerInternal().getUsers(
                    /* excludePartial= */ true,
                    /* excludeDying= */ false,
                    /* excludePreCreated= */ false));
            t.traceEnd();
            // 如果是第一次启动,设置安装程序的第一次启动标志
            if (mFirstBoot) {
                t.traceBegin("setFirstBoot: ");
                try {
                    mInstaller.setFirstBoot();
                } catch (InstallerException e) {
                    Slog.w(TAG, "Could not set First Boot: ", e);
                }
                t.traceEnd();
            }

            mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions);
            mPermissionManager.readLegacyPermissionStateTEMP();

            if (mFirstBoot) {
                DexOptHelper.requestCopyPreoptedFiles();
            }

            String customResolverActivityName = Resources.getSystem().getString(
                    R.string.config_customResolverActivity);
            if (!TextUtils.isEmpty(customResolverActivityName)) {
                mCustomResolverComponentName = ComponentName.unflattenFromString(
                        customResolverActivityName);
            }

            long startTime = SystemClock.uptimeMillis();

3.2.2 BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

/system可以称作为System分区,里面主要存储谷歌和其他厂商提供的Android系统相关文件和框架。Android系统架构分为应用层、应用框架层、系统运行库层(Native 层)、硬件抽象层(HAL层)和Linux内核层,除了Linux内核层在Boot分区,其他层的代码都在System分区。

该阶段主要在扫描各目录下的apps耗时,开机耗时需重点关注。

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);

            final String bootClassPath = System.getenv("BOOTCLASSPATH");
            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");

            if (bootClassPath == null) {
                Slog.w(TAG, "No BOOTCLASSPATH found!");
            }

            if (systemServerClassPath == null) {
                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
            }

            final VersionInfo ver = mSettings.getInternalVersion();
            mIsUpgrade =
                    !partitionsFingerprint.equals(ver.fingerprint);
            if (mIsUpgrade) {
                PackageManagerServiceUtils.logCriticalInfo(Log.INFO,
                        "Upgrading from " + ver.fingerprint + " (" + ver.buildFingerprint + ") to "
                                + PackagePartitions.FINGERPRINT + " (" + Build.FINGERPRINT + ")");
            }

            mInitAppsHelper = new InitAppsHelper(this, mApexManager, mInstallPackageHelper,
                    mInjector.getSystemPartitions());

            // when upgrading from pre-M, promote system app permissions from install to runtime
            mPromoteSystemApps =
                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;

            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
            mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;

            final WatchedArrayMap<String, PackageSetting> packageSettings =
                mSettings.getPackagesLocked();

            if (isDeviceUpgrading()) {
                // Save the names of pre-existing packages prior to scanning, so we can determine
                // which system packages are completely new due to an upgrade.
                mExistingPackages = new ArraySet<>(packageSettings.size());
                for (PackageSetting ps : packageSettings.values()) {
                    mExistingPackages.add(ps.getPackageName());
                }

                // Triggering {@link com.android.server.pm.crossprofile.
                // CrossProfileIntentFilterHelper.updateDefaultCrossProfileIntentFilter} to update
                // {@link  CrossProfileIntentFilter}s between eligible users and their parent
                t.traceBegin("cross profile intent filter update");
                mInjector.getCrossProfileIntentFilterHelper()
                        .updateDefaultCrossProfileIntentFilter();
                t.traceEnd();
            }

            mCacheDir = PackageManagerServiceUtils.preparePackageParserCache(
                    mIsEngBuild, mIsUserDebugBuild, mIncrementalVersion);

            mInitialNonStoppedSystemPackages = mInjector.getSystemConfig()
                    .getInitialNonStoppedSystemPackages();
            mShouldStopSystemPackagesByDefault = mContext.getResources()
                    .getBoolean(R.bool.config_stopSystemPackagesByDefault);

            final int[] userIds = mUserManager.getUserIds();
            //扫描system目录下的apps,[见3.2.2.1]
            PackageParser2 packageParser = mInjector.getScanningCachingPackageParser();
            mOverlayConfig = mInitAppsHelper.initSystemApps(packageParser, packageSettings, userIds,
                    startTime);
3.2.2.1 InitAppsHelper.initSystemApps
    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.
        final List<ApexManager.ScanResult> apexScanResults = scanApexPackagesTraced(packageParser);
        mApexManager.notifyScanResult(apexScanResults);
        扫描system各个目录下的apps[见3.2.2.2]
        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 : mApexManager.getActiveApexInfos()) {
            for (String packageName : mApexManager.getApksInApex(apexInfo.apexModuleName)) {
                apkInApexPreInstalledPaths.put(packageName, apexInfo.preInstalledApexPath);
            }
        }
        final OverlayConfig overlayConfig = OverlayConfig.initializeSystemInstance(
                consumer -> mPm.forEachPackageState(mPm.snapshotComputer(),
                        packageState -> {
                            var pkg = packageState.getPkg();
                            if (pkg != null) {
                                consumer.accept(pkg, packageState.isSystem(),
                                        apkInApexPreInstalledPaths.get(pkg.getPackageName()));
                            }
                        }));

        // do this first before mucking with mPackages for the "expecting better" case
        updateStubSystemAppsList(mStubSystemApps);
        mInstallPackageHelper.prepareSystemPackageCleanUp(packageSettings,
                mPossiblyDeletedUpdatedSystemApps, mExpectingBetter, userIds);
        [见3.2.2.3]统计扫描多少个应用和耗时
        logSystemAppsScanningTime(startTime);
        return overlayConfig;
    }
3.2.2.2 InitAppsHelper.scanSystemDirs
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private void scanSystemDirs(PackageParser2 packageParser, ExecutorService executorService) {
        File frameworkDir = new File(Environment.getRootDirectory(), "framework");

        // Collect vendor/product/system_ext overlay packages. (Do this before scanning
        // any apps.)
        // For security and version matching reason, only consider overlay packages if they
        // reside in the right directory.
        for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
            final ScanPartition partition = mDirsToScanAsSystem.get(i);
            if (partition.getOverlayFolder() == null) {
                continue;
            }
            //扫描/vendor/overlay目录下的文件
            scanDirTracedLI(partition.getOverlayFolder(),
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag,
                    packageParser, executorService, partition.apexInfo);
        }
        //扫描/system/framework 目录下的文件
        scanDirTracedLI(frameworkDir,
                mSystemParseFlags, mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,
                packageParser, executorService, null);
        if (!mPm.mPackages.containsKey("android")) {
            throw new IllegalStateException(
                    "Failed to load frameworks package; check log for warnings");
        }

        for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
            final ScanPartition partition = mDirsToScanAsSystem.get(i);
            if (partition.getPrivAppFolder() != null) {
                //扫描 /system/priv-app 目录下的文件
                scanDirTracedLI(partition.getPrivAppFolder(),
                        mSystemParseFlags,
                        mSystemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag,
                        packageParser, executorService, partition.apexInfo);
            }
            
            scanDirTracedLI(partition.getAppFolder(),
                    mSystemParseFlags, mSystemScanFlags | partition.scanFlag,
                    packageParser, executorService, partition.apexInfo);
        }
    }
3.2.2.3 logSystemAppsScanningTime
    @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();
        mSystemScanTime = SystemClock.uptimeMillis() - startTime;
        mSystemPackagesCount = mPm.mPackages.size();
        //统计扫描多少个system目录,平均耗时多少,可以在even log中查找
        Slog.i(TAG, "Finished scanning system apps. Time: " + mSystemScanTime
                + " ms, packageCount: " + mSystemPackagesCount
                + " , timePerPackage: "
                + (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,
                    mSystemScanTime / mSystemPackagesCount);
            //CHECKSTYLE:ON IndentationCheck
        }
    }

3.2.3 BOOT_PROGRESS_PMS_DATA_SCAN_START

data可以称为Data分区,它用来存储所有用户的个人数据和配置文件。下面列出Data分区部分子目录:

| 目录| 含义|
| :——–: | :——–:| :–: |
| app| 存储用户自己安装的App|
| data| 存储所有已安装的App数据的目录,每个App都有自己单独的子目录 |
| app-private| App的私有存储空间 |
| app-lib|存储所有App的Jni库 |
| system| 存放系统配置文件 |
| anr| 用于存储ANR发生时系统生成的traces.txt文件 |

            //该方法为扫描data目录下的apps,[见3.2.3.1]
            mInitAppsHelper.initNonSystemApps(packageParser, userIds, startTime);
            packageParser.close();

            mRequiredVerifierPackages = getRequiredButNotReallyRequiredVerifiersLPr(computer);
            mRequiredInstallerPackage = getRequiredInstallerLPr(computer);
            mRequiredUninstallerPackage = getRequiredUninstallerLPr(computer);

            // PermissionController hosts default permission granting and role management, so it's a
            // critical part of the core system.
            mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer);

            // Resolve the storage manager.
            mStorageManagerPackage = getStorageManagerPackageName(computer);

            // Resolve protected action filters. Only the setup wizard is allowed to
            // have a high priority filter for these actions.
            mSetupWizardPackage = getSetupWizardPackageNameImpl(computer);
            mComponentResolver.fixProtectedFilterPriorities(mSetupWizardPackage);

            mDefaultTextClassifierPackage = ensureSystemPackageName(computer,
                    mContext.getString(R.string.config_servicesExtensionPackage));
            mSystemTextClassifierPackageName = ensureSystemPackageName(computer,
                    mContext.getString(R.string.config_defaultTextClassifierPackage));
            mConfiguratorPackage = ensureSystemPackageName(computer,
                    mContext.getString(R.string.config_deviceConfiguratorPackageName));
            mAppPredictionServicePackage = ensureSystemPackageName(computer,
                    getPackageFromComponentString(R.string.config_defaultAppPredictionService));
            mIncidentReportApproverPackage = ensureSystemPackageName(computer,
                    mContext.getString(R.string.config_incidentReportApproverPackage));
            mRetailDemoPackage = getRetailDemoPackageName();
            mOverlayConfigSignaturePackage = ensureSystemPackageName(computer,
                    mInjector.getSystemConfig().getOverlayConfigSignaturePackage());
            mRecentsPackage = ensureSystemPackageName(computer,
                    getPackageFromComponentString(R.string.config_recentsComponentName));
            mAmbientContextDetectionPackage = ensureSystemPackageName(computer,
                    getPackageFromComponentString(
                            R.string.config_defaultAmbientContextDetectionService));
            mWearableSensingPackage = ensureSystemPackageName(computer,
                    getPackageFromComponentString(
                            R.string.config_defaultWearableSensingService));

            // Now that we know all of the shared libraries, update all clients to have
            // the correct library paths.
            mSharedLibraries.updateAllSharedLibrariesLPw(
                    null, null, Collections.unmodifiableMap(mPackages));

            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
                // NOTE: We ignore potential failures here during a system scan (like
                // the rest of the commands above) because there's precious little we
                // can do about it. A settings error is reported, though.
                final List<String> changedAbiCodePath =
                        ScanPackageUtils.applyAdjustedAbiToSharedUser(setting,
                                null /*scannedPackage*/,
                                mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
                                        setting.getPackageStates(), null /*scannedPackage*/));
                if (!useArtService() && // Skip for ART Service since it has its own dex file GC.
                        changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                        final String codePathString = changedAbiCodePath.get(i);
                        try {
                            mInstaller.rmdex(codePathString,
                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
                        } catch (LegacyDexoptDisabledException e) {
                            throw new RuntimeException(e);
                        } catch (InstallerException ignored) {
                        }
                    }
                }
                // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
                // SELinux domain.
                setting.fixSeInfoLocked();
                setting.updateProcesses();
            }

            // Now that we know all the packages we are keeping,
            // read and update their last usage times.
            mPackageUsage.read(packageSettings);
            mCompilerStats.read();
3.2.3.1InitAppsHelper.initNonSystemApps
    public void initNonSystemApps(PackageParser2 packageParser, @NonNull int[] userIds,
            long startTime) {
        //扫描data app日志节点,BOOT_PROGRESS_PMS_DATA_SCAN_START
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                SystemClock.uptimeMillis());

        if ((mScanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == SCAN_FIRST_BOOT_OR_UPGRADE) {
            fixInstalledAppDirMode();
        }
        //扫描/data/app目录下的文件  
        scanDirTracedLI(mPm.getAppInstallDir(), 0,
                mScanFlags | SCAN_REQUIRE_KNOWN, packageParser, mExecutorService, null);

        List<Runnable> unfinishedTasks = mExecutorService.shutdownNow();
        if (!unfinishedTasks.isEmpty()) {
            throw new IllegalStateException("Not all tasks finished before calling close: "
                    + unfinishedTasks);
        }
        fixSystemPackages(userIds);
        [见3.2.3.2]
        logNonSystemAppScanningTime(startTime);
        mExpectingBetter.clear();
        mPm.mSettings.pruneRenamedPackagesLPw();
    }
3.2.3.2 InitAppsHelper.logNonSystemAppScanningTime
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})
    private void logNonSystemAppScanningTime(long startTime) {
        final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get()
                - mCachedSystemApps;

        final long dataScanTime = SystemClock.uptimeMillis() - mSystemScanTime - startTime;
        final int dataPackagesCount = mPm.mPackages.size() - mSystemPackagesCount;
        //统计总共扫描了多少个non-system apps,平均耗时多少,可以在even log里查看
        Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
                + " ms, packageCount: " + dataPackagesCount
                + " , timePerPackage: "
                + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
                + " , cached: " + cachedNonSystemApps);
        if (mIsDeviceUpgrading && dataPackagesCount > 0) {
            //CHECKSTYLE:OFF IndentationCheck
            FrameworkStatsLog.write(
                    FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                    BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
                    dataScanTime / dataPackagesCount);
            //CHECKSTYLE:OFF IndentationCheck
        }
    }

3.2.4 BOOT_PROGRESS_PMS_SCAN_END

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());
            Slog.i(TAG, "Time to scan packages: "
                    + ((SystemClock.uptimeMillis() - startTime) / 1000f)
                    + " seconds");

            // If the partitions fingerprint has changed since the last time we booted,
            // we need to re-grant app permission to catch any new ones that
            // appear.  This is really a hack, and means that apps can in some
            // cases get permissions that the user didn't initially explicitly
            // allow...  it would be nice to have some better way to handle
            // this situation.
            if (mIsUpgrade) {
                Slog.i(TAG, "Partitions fingerprint changed from " + ver.fingerprint + " to "
                        + PackagePartitions.FINGERPRINT
                        + "; regranting permissions for internal storage");
            }
            mPermissionManager.onStorageVolumeMounted(
                    StorageManager.UUID_PRIVATE_INTERNAL, mIsUpgrade);
            ver.sdkVersion = mSdkVersion;

            // If this is the first boot or an update from pre-M, then we need to initialize the
            // default preferred apps across all defined users.
            //如果是第一次启动或者是Android M升级后的第一次启动,需要初始化所有用户定义的默认首选App
            if (mPromoteSystemApps || mFirstBoot) {
                for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(user.id);
                }
            }

            // If this is first boot after an OTA, then we need to clear code cache directories.
            // Note that we do *not* clear the application profiles. These remain valid
            // across OTAs and are used to drive profile verification (post OTA) and
            // profile compilation (without waiting to collect a fresh set of profiles).
            //OTA后的第一次启动,会清除代码缓存目录。
            if (mIsUpgrade) {
                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                for (int i = 0; i < packageSettings.size(); i++) {
                    final PackageSetting ps = packageSettings.valueAt(i);
                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.getVolumeUuid())) {
                        // No apps are running this early, so no need to freeze
                        mAppDataHelper.clearAppDataLIF(ps.getPkg(), UserHandle.USER_ALL,
                                FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
                                        | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
                    }
                }
                ver.buildFingerprint = Build.FINGERPRINT;
                ver.fingerprint = PackagePartitions.FINGERPRINT;
            }

            // Defer the app data fixup until we are done with app data clearing above.
            mPrepareAppDataFuture = mAppDataHelper.fixAppsDataOnBoot();

            // Legacy existing (installed before Q) non-system apps to hide
            // their icons in launcher.
            if (mIsPreQUpgrade) {
                Slog.i(TAG, "Allowlisting all existing apps to hide their icons");
                int size = packageSettings.size();
                for (int i = 0; i < size; i++) {
                    final PackageSetting ps = packageSettings.valueAt(i);
                    if ((ps.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) {
                        continue;
                    }
                    ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
                            UserHandle.USER_SYSTEM);
                }
            }

            // clear only after permissions and other defaults have been updated
            mPromoteSystemApps = false;

            // All the changes are done during package scanning.
            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;

            // can downgrade to reader
            t.traceBegin("write settings");
            // 把Settings的内容保存到packages.xml中
            writeSettingsLPrTEMP();
            t.traceEnd();

3.2.5 BOOT_PROGRESS_PMS_READY

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());

.....
            //PackageInstallerService是用于管理安装会话的服务,它会为每次安装过程分配一个SessionId
            mInstallerService = mInjector.getPackageInstallerService();
            final ComponentName instantAppResolverComponent = getInstantAppResolver(computer);
            if (instantAppResolverComponent != null) {
                if (DEBUG_INSTANT) {
                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
                }
                mInstantAppResolverConnection =
                        mInjector.getInstantAppResolverConnection(instantAppResolverComponent);
                mInstantAppResolverSettingsComponent =
                        getInstantAppResolverSettingsLPr(computer,
                                instantAppResolverComponent);
            } else {
                mInstantAppResolverConnection = null;
                mInstantAppResolverSettingsComponent = null;
            }
            updateInstantAppInstallerLocked(null);

            // Read and update the usage of dex files.
            // Do this at the end of PM init so that all the packages have their
            // data directory reconciled.
            // At this point we know the code paths of the packages, so we can validate
            // the disk file and build the internal cache.
            // The usage file is expected to be small so loading and verifying it
            // should take a fairly small time compare to the other activities (e.g. package
            // scanning).
            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
            for (int userId : userIds) {
                userPackages.put(userId, computer.getInstalledPackages(/*flags*/ 0, userId)
                        .getList());
            }
            mDexManager.load(userPackages);
            mDynamicCodeLogger.load(userPackages);
            if (mIsUpgrade) {
                FrameworkStatsLog.write(
                        FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                        BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
                        SystemClock.uptimeMillis() - startTime);
            }

            //如果这是首次启动或OTA后的首次启动,则将文件路径设置为预加载包的应用元数据文件
            if (mFirstBoot || isDeviceUpgrading()) {
                ArrayMap<String, String> paths = systemConfig.getAppMetadataFilePaths();
                for (Map.Entry<String, String> entry : paths.entrySet()) {
                    String pkgName = entry.getKey();
                    String path = entry.getValue();
                    File file = new File(path);
                    if (!file.exists()) {
                        path = null;
                    }
                    PackageSetting disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(pkgName);
                    if (disabledPkgSetting == null) {
                        PackageSetting pkgSetting = mSettings.getPackageLPr(pkgName);
                        if (pkgSetting != null) {
                            pkgSetting.setAppMetadataFilePath(path);
                        } else {
                            Slog.w(TAG, "Cannot set app metadata file for nonexistent package "
                                    + pkgName);
                        }
                    } else {
                        disabledPkgSetting.setAppMetadataFilePath(path);
                    }
                }
            }
....
    }