Android-PackageManagerService创建过程源码分析

一、初始化入口

PackageManagerService的创建是在SystemServer进程创建的时候,调用startBootstrapServices创建引导服务的时候,通过调用PackageManagerService.main方法进行创建的,但是创建PackageManagerService对象的时候需要依赖于两个部分,一个是Installer安装器,一个是mOnlyCore是否只解析核心应用的布尔值判断。

    private void startBootstrapServices() {
        ...
        // 启动Installer服务
        // 阻塞等待Installer完成启动,以便有机会创建具有适当权限的关键目录,如/data/user
        // 我们需要在初始化其他服务之前完成此任务
        Installer installer = mSystemServiceManager.startService(Installer.class);
        ...
        // 获取设备是否加密(手机设置密码),如果设备加密了,则只解析"core"核心应用
        // mOnlyCore = true
        String cryptState = VoldProperties.decrypt().orElse("");
        if (ENCRYPTING_STATE.equals(cryptState)) {
            Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
            mOnlyCore = true;
        } else if (ENCRYPTED_STATE.equals(cryptState)) {
            Slog.w(TAG, "Device encrypted - only parsing core apps");
            mOnlyCore = true;
        }
        ...
        // 调用PackageManagerService.main方法初始化对象
        try {
            Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
            mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                    mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
        } finally {
            Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
        }
        // 是否第一次启动PKMS
        mFirstBoot = mPackageManagerService.isFirstBoot();
        ...
        // 如果设备没有加密,操作该部分。管理A/B  OTA  dexopting
        if (!mOnlyCore) {
            boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                    false);
            if (!disableOtaDexopt) {
                traceBeginAndSlog("StartOtaDexOptService");
                try {
                    Watchdog.getInstance().pauseWatchingCurrentThread("moveab");
                    OtaDexoptService.main(mSystemContext, mPackageManagerService);
                } catch (Throwable e) {
                    reportWtf("starting OtaDexOptService", e);
                } finally {
                    Watchdog.getInstance().resumeWatchingCurrentThread("moveab");
                    traceEnd();
                }
            }
        }
    }
    private void startOtherServices() {
        ...
        if (!mOnlyCore) {
            traceBeginAndSlog("UpdatePackagesIfNeeded");
            try {
                Watchdog.getInstance().pauseWatchingCurrentThread("dexopt");
                // 如果设备没有加密,执行performDexOptUpgrade,完成dex优化
                mPackageManagerService.updatePackagesIfNeeded();
            } catch (Throwable e) {
                reportWtf("update packages", e);
            } finally {
                Watchdog.getInstance().resumeWatchingCurrentThread("dexopt");
            }
            traceEnd();
        }

        traceBeginAndSlog("PerformFstrimIfNeeded");
        try {
            // 最终执行performFstrim,完成磁盘的维护
            mPackageManagerService.performFstrimIfNeeded();
        } catch (Throwable e) {
            reportWtf("performing fstrim", e);
        }
        traceEnd();
        ...
        // PKMS准备就绪
        mPackageManagerService.systemReady();
        ...
    }

PackageManagerService的初始化

1.PackageManagerService#main

    public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // 检查Package编译相关系统属性
        PackageManagerServiceCompilerMapping.checkProperties();
        // 调用PackageManagerService构造方法
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        // 启动部分应用服务于多用户场景
        m.enableSystemUserPackages();
        // 往ServiceManager中注册"package"和"package_native"
        ServiceManager.addService("package", m);
        final PackageManagerNative pmn = m.new PackageManagerNative();
        ServiceManager.addService("package_native", pmn);
        return m;
    }

2.PackageManagerService构造函数

Android-PackageManagerService创建过程源码分析_第1张图片
image.png

在PKMS的构造函数中,有两个重要的锁:

  • mInstallLock:用来保护所有安装apk的访问权限,此操作通常涉及繁重的磁盘数据读写等操作,并且是单线程操作,所以有时候处理会很慢;这个锁不会在已经持有mPackages锁的情况下活的,相反,在已经持有mInstallLock锁的情况下,立即获取mPackages是安全的。
  • mPackages:用来解析内存中所有apk的package信息及相关状态。
    在PKMS的构造函数中,由五个阶段构成:
  • 阶段1:BOOT_PROGRESS_PMS_START

构造DisplayMetrics来保存分辨率等信息,创建PermissionManager来进行权限管理,创建Settings来保存安装包信息(例如:/data/system/目录下packages.xml、packages.list、packages-backup.xml等文件)

  • 阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

扫描apk目录(system/vendor/product/odm/oem等目录的priv-app、app-overlay包),清除安装时临时文件以及其他不必要的信息

  • 阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START

处理data目录的应用信息,及时更新,去除不必要的数据

  • 阶段4:BOOT_PROGRESS_PMS_SCAN_END

OTA升级后首次启动要 清除不必要的缓存数据,权限等默认项更新后要清理相关数据,更新packages.xml

  • 阶段5:BOOT_PROGRESS_PMS_READY

GC回收缓存

阶段1细节:

  • 构造DisplayMetrics对象mMetrics,保存分辨率等相关信息;
  • 创建Installer对象mInstaller,与installd交互
  • 创建PermissionManager对象mPermissionManager,进行权限管理,通过PermissionManagerService.create创建;
  • 构造Settings类对象mSettings,保存安装信息,清除路径不存在的孤立应用,主要涉及/data/system/目录的packages.xml、packages-backup.xml、packages.list、packages-stopped.xml、packages-stopped-backup.xml等文件
        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);
  • 构造PackageDexOptimizer及DexManager类,处理dex优化;
        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                "*dexopt*");
        mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock);
  • 创建SystemConfig实例,获取系统配置信息,配置共享lib库;
  • 创建PackageManager的handler线程,循环处理外部安装相关信息。

阶段1具体源码细节

(1)PackageManagerService构造器
    public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis());

        if (mSdkVersion <= 0) {
            Slog.w(TAG, "**** ro.build.version.sdk not set!");
        }

        mContext = context;
        // 一般为false,即非工厂生产模式
        mFactoryTest = factoryTest;
        // 标记是否只加载核心服务
        mOnlyCore = onlyCore;
        // TODO:构造DisplayMetrics,保存分辨率等相关信息;
        mMetrics = new DisplayMetrics();
        // TODO:创建Installer对象,与installd交互;
        mInstaller = installer;

        // 创建提供服务/数据的子组件。这里使用锁的顺序要注意:mInstallLock锁只能和mPackages锁
        // 一起使用的时候,mInstallLock锁只能先使用
        synchronized (mInstallLock) {
        synchronized (mPackages) {
            // 公开系统组件使用的私有服务
            // 本地服务
            LocalServices.addService(
                    PackageManagerInternal.class, new PackageManagerInternalImpl());
            // 多用户管理服务
            sUserManager = new UserManagerService(context, this,
                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
            mComponentResolver = new ComponentResolver(sUserManager,
                    LocalServices.getService(PackageManagerInternal.class),
                    mPackages);
            // TODO:创建mPermissionManager对象,进行权限管理。这里其实就是获取权限管理服务这个Binder
            mPermissionManager = PermissionManagerService.create(context,
                    mPackages /*externalLock*/);
            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
            // 创建Settings对象
            mSettings = new Settings(Environment.getDataDirectory(),
                    mPermissionManager.getPermissionSettings(), mPackages);
        }
        }
        // TODO:构造Settings类对象mSettings,保存安装信息,清除路径不存在的孤立应用
        // 主要涉及/data/system/目录的packages.xml、packages-backup.xml、packages.list、
        // packages-stopped.xml、packages-stopped-backup.xml等文件
        // 添加system、phone、log、nfc、bluetooth、shell、se、networkstack这八种shareUserId到mSettings中
        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);
        ...
        // TODO:
        // 构造PackageDexOptimizer和DexManager类,处理dex优化相关
        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
                "*dexopt*");
        mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock);
        // 创建ART虚拟机管理服务
        mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());

        mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
        // 权限变化监听器
        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
                FgThread.get().getLooper());
        // 获取默认的分辨率
        getDefaultDisplayMetrics(context, mMetrics);

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
        // TODO:创建SystemConfig实例,获取系统配置信息,配置共享lib库
        // 拿到SystemConfig()的对象,其中会调用SystemConfig的readPermissions()完成权限的读取
        SystemConfig systemConfig = SystemConfig.getInstance();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

        mProtectedPackages = new ProtectedPackages(mContext);

        mApexManager = new ApexManager(context);
        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            // TODO:创建PackageManager的handler线程,循环处理外部安装相关信息
            mHandlerThread = new ServiceThread(TAG,
                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
            // 应用Handler,用于处理消息,比如修改读取的packages.xml得到的Package对象
            mHandler = new PackageHandler(mHandlerThread.getLooper());
            // 进程记录Handler
            mProcessLoggingHandler = new ProcessLoggingHandler();
            // Watchdog监听ServiceThread是否超时:10分钟
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
            // Instant应用注册
            mInstantAppRegistry = new InstantAppRegistry(this);
            // 配置共享lib库
            ArrayMap libConfig
                    = systemConfig.getSharedLibraries();
            final int builtInLibCount = libConfig.size();
            for (int i = 0; i < builtInLibCount; i++) {
                String name = libConfig.keyAt(i);
                SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
                addBuiltInSharedLibraryLocked(entry.filename, name);
            }
            ...
            // 读取安装相关SELinux策略
            SELinuxMMAC.readInstallPolicy();
            // 返回栈加载
            FallbackCategoryProvider.loadFallbacks();
            // TODO:读取并解析/data/system/下的xml文件。TODO:看下面第二步
            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
            // 清理代码路径不存在的孤立软件包
            final int packageSettingCount = mSettings.mPackages.size();
            for (int i = packageSettingCount - 1; i >= 0; i--) {
                PackageSetting ps = mSettings.mPackages.valueAt(i);
                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
                    mSettings.mPackages.removeAt(i);
                    mSettings.enableSystemPackageLPw(ps.name);
                }
            }
            // 如果不是首次启动,也不是core应用,则拷贝预编译的Dex文件
            if (!mOnlyCore && mFirstBoot) {
                requestCopyPreoptedFiles();
            }
            ...
        }
        }
    }
(2)Settings构造器

这五个文件的扫描,第一次都是在系统刚启动的时候,创建SystemServer进程启动PKMS服务的时候进行扫描的。
readLPw()方法会扫描5个文件:

  • 1)"/data/system/packages.xml"
    所有安装的app信息
  • 2)"/data/system/packages-backup.xml"
    所有安装的app信息的备份的信息记录
  • 3)"/data/system/packages.list"
    所有安装的app信息
  • 4)"/data/system/packages-stopped.xml"
    所有强制停止的app信息
  • 5)"/data/system/packages-stopped-backup.xml"
    所有强制停止的app信息的备份的信息记录

这五个文件总共分为三组,其作用如下描述:
packages.xml:PKMS扫描完目标文件夹后会创建该文件。当系统进行程序安装、卸载和更新等操作时,均会更新该文件。该文件保存了系统中与package相关的一些信息。packages.xml的信息都会保存到Package对象中,当系统启动之后,再进行的安装、卸载和应用更新操作都会去修改packages.xml,进而将修改后的信息保存到Package对象中。比如安装的情况,会调用PackageInstallerActivity这个页面,在PackageInstallerActivity的onResume方法中就会加载布局并且对apk的信息进行解析,进而更新packages.xml和Package对象。
packages.list:描述系统中存在的所有非系统自带的APK的信息。当这些程序有变动时,PKMS就会更新该文件。
packages-stopped.xml:从系统自带的设置程序中进入应用程序页面,然后在选择强制停止(ForceStop)某个应用时,系统会将该应用的相关信息记录到此文件中。也就是改文件保存系统中被用户强制停止的Package信息。

    Settings(File dataDir, PermissionSettings permission,
            Object lock) {
        mLock = lock;
        mPermissions = permission;
        mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
        // mSystemDir指向目录"/data/system"
        mSystemDir = new File(dataDir, "system");
        // 创建"/data/system"目录
        mSystemDir.mkdirs();
        // 设置对应的权限
        FileUtils.setPermissions(mSystemDir.toString(),
                FileUtils.S_IRWXU|FileUtils.S_IRWXG
                |FileUtils.S_IROTH|FileUtils.S_IXOTH,
                -1, -1);
        // TODO:指向目录"/data/system/packages.xml"
        mSettingsFilename = new File(mSystemDir, "packages.xml");
        // TODO:指向目录"/data/system/packages-backup.xml"
        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
        // TODO:指向目录"/data/system/packages.list"
        mPackageListFilename = new File(mSystemDir, "packages.list");
        FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);

        final File kernelDir = new File("/config/sdcardfs");
        mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;

        // TODO:指向目录"/data/system/packages-stopped.xml"
        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
        // TODO:指向目录"/data/system/packages-stopped-backup.xml"
        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
    }
(3)Settings.readLPw
    boolean readLPw(@NonNull List users) {
        FileInputStream str = null;
        if (mBackupSettingsFilename.exists()) {
            try {
                str = new FileInputStream(mBackupSettingsFilename);
                mReadMessages.append("Reading from backup settings file\n");
                PackageManagerService.reportSettingsProblem(Log.INFO,
                        "Need to read from backup settings file");
                if (mSettingsFilename.exists()) {
                    // If both the backup and settings file exist, we
                    // ignore the settings since it might have been
                    // corrupted.
                    Slog.w(PackageManagerService.TAG, "Cleaning up settings file "
                            + mSettingsFilename);
                    mSettingsFilename.delete();
                }
            } catch (java.io.IOException e) {
                // We'll try for the normal settings file.
            }
        }
        // 清除对应的缓存
        mPendingPackages.clear();
        mPastSignatures.clear();
        mKeySetRefs.clear();
        mInstallerPackages.clear();

        try {
            if (str == null) {
                if (!mSettingsFilename.exists()) {
                    mReadMessages.append("No settings file found\n");
                    PackageManagerService.reportSettingsProblem(Log.INFO,
                            "No settings file; creating initial state");
                    // It's enough to just touch version details to create them
                    // with default values
                    findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
                    findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
                    return false;
                }
                str = new FileInputStream(mSettingsFilename);
            }
            // TODO:解析"/data/system/packages.xml"
            XmlPullParser parser = Xml.newPullParser();
            parser.setInput(str, StandardCharsets.UTF_8.name());

            int type;
            while ((type = parser.next()) != XmlPullParser.START_TAG
                    && type != XmlPullParser.END_DOCUMENT) {
                ;
            }

            if (type != XmlPullParser.START_TAG) {
                mReadMessages.append("No start tag found in settings file\n");
                PackageManagerService.reportSettingsProblem(Log.WARN,
                        "No start tag found in package manager settings");
                Slog.wtf(PackageManagerService.TAG,
                        "No start tag found in package manager settings");
                return false;
            }

            int outerDepth = parser.getDepth();
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                    continue;
                }
                // 根据xml的各个节点进行各种操作,例如读取权限、shared-user等
                String tagName = parser.getName();
                if (tagName.equals("package")) {
                    readPackageLPw(parser);
                } else if (tagName.equals("permissions")) {
                    mPermissions.readPermissions(parser);
                } else if (tagName.equals("permission-trees")) {
                    mPermissions.readPermissionTrees(parser);
                } else if (tagName.equals("shared-user")) {
                    readSharedUserLPw(parser);
                } else if (tagName.equals("preferred-packages")) {
                    // no longer used.
                } else if (tagName.equals("preferred-activities")) {
                    // Upgrading from old single-user implementation;
                    // these are the preferred activities for user 0.
                    readPreferredActivitiesLPw(parser, 0);
                } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
                    // TODO: check whether this is okay! as it is very
                    // similar to how preferred-activities are treated
                    readPersistentPreferredActivitiesLPw(parser, 0);
                } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
                    // TODO: check whether this is okay! as it is very
                    // similar to how preferred-activities are treated
                    readCrossProfileIntentFiltersLPw(parser, 0);
                } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
                    readDefaultAppsLPw(parser, 0);
                } else if (tagName.equals("updated-package")) {
                    readDisabledSysPackageLPw(parser);
                } else if (tagName.equals("renamed-package")) {
                    String nname = parser.getAttributeValue(null, "new");
                    String oname = parser.getAttributeValue(null, "old");
                    if (nname != null && oname != null) {
                        mRenamedPackages.put(nname, oname);
                    }
                } else if (tagName.equals("restored-ivi")) {
                    readRestoredIntentFilterVerifications(parser);
                } else if (tagName.equals("last-platform-version")) {
                    // Upgrade from older XML schema
                    final VersionInfo internal = findOrCreateVersion(
                            StorageManager.UUID_PRIVATE_INTERNAL);
                    final VersionInfo external = findOrCreateVersion(
                            StorageManager.UUID_PRIMARY_PHYSICAL);

                    internal.sdkVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
                    external.sdkVersion = XmlUtils.readIntAttribute(parser, "external", 0);
                    internal.fingerprint = external.fingerprint =
                            XmlUtils.readStringAttribute(parser, "fingerprint");

                } else if (tagName.equals("database-version")) {
                    // Upgrade from older XML schema
                    final VersionInfo internal = findOrCreateVersion(
                            StorageManager.UUID_PRIVATE_INTERNAL);
                    final VersionInfo external = findOrCreateVersion(
                            StorageManager.UUID_PRIMARY_PHYSICAL);

                    internal.databaseVersion = XmlUtils.readIntAttribute(parser, "internal", 0);
                    external.databaseVersion = XmlUtils.readIntAttribute(parser, "external", 0);

                } else if (tagName.equals("verifier")) {
                    final String deviceIdentity = parser.getAttributeValue(null, "device");
                    try {
                        mVerifierDeviceIdentity = VerifierDeviceIdentity.parse(deviceIdentity);
                    } catch (IllegalArgumentException e) {
                        Slog.w(PackageManagerService.TAG, "Discard invalid verifier device id: "
                                + e.getMessage());
                    }
                } else if (TAG_READ_EXTERNAL_STORAGE.equals(tagName)) {
                    final String enforcement = parser.getAttributeValue(null, ATTR_ENFORCEMENT);
                    mReadExternalStorageEnforced =
                            "1".equals(enforcement) ? Boolean.TRUE : Boolean.FALSE;
                } else if (tagName.equals("keyset-settings")) {
                    mKeySetManagerService.readKeySetsLPw(parser, mKeySetRefs);
                } else if (TAG_VERSION.equals(tagName)) {
                    final String volumeUuid = XmlUtils.readStringAttribute(parser,
                            ATTR_VOLUME_UUID);
                    final VersionInfo ver = findOrCreateVersion(volumeUuid);
                    ver.sdkVersion = XmlUtils.readIntAttribute(parser, ATTR_SDK_VERSION);
                    ver.databaseVersion = XmlUtils.readIntAttribute(parser, ATTR_DATABASE_VERSION);
                    ver.fingerprint = XmlUtils.readStringAttribute(parser, ATTR_FINGERPRINT);
                } else {
                    Slog.w(PackageManagerService.TAG, "Unknown element under : "
                            + parser.getName());
                    XmlUtils.skipCurrentTag(parser);
                }
            }

            str.close();

        } catch (XmlPullParserException e) {
            mReadMessages.append("Error reading: " + e.toString());
            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);

        } catch (java.io.IOException e) {
            mReadMessages.append("Error reading: " + e.toString());
            PackageManagerService.reportSettingsProblem(Log.ERROR, "Error reading settings: " + e);
            Slog.wtf(PackageManagerService.TAG, "Error reading package manager settings", e);
        }

        // If the build is setup to drop runtime permissions
        // on update drop the files before loading them.
        if (PackageManagerService.CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE) {
            final VersionInfo internal = getInternalVersion();
            if (!Build.FINGERPRINT.equals(internal.fingerprint)) {
                for (UserInfo user : users) {
                    mRuntimePermissionsPersistence.deleteUserRuntimePermissionsFile(user.id);
                }
            }
        }

        final int N = mPendingPackages.size();

        for (int i = 0; i < N; i++) {
            final PackageSetting p = mPendingPackages.get(i);
            final int sharedUserId = p.getSharedUserId();
            final Object idObj = getSettingLPr(sharedUserId);
            if (idObj instanceof SharedUserSetting) {
                final SharedUserSetting sharedUser = (SharedUserSetting) idObj;
                p.sharedUser = sharedUser;
                p.appId = sharedUser.userId;
                addPackageSettingLPw(p, sharedUser);
            } else if (idObj != null) {
                String msg = "Bad package setting: package " + p.name + " has shared uid "
                        + sharedUserId + " that is not a shared uid\n";
                mReadMessages.append(msg);
                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
            } else {
                String msg = "Bad package setting: package " + p.name + " has shared uid "
                        + sharedUserId + " that is not defined\n";
                mReadMessages.append(msg);
                PackageManagerService.reportSettingsProblem(Log.ERROR, msg);
            }
        }
        mPendingPackages.clear();

        if (mBackupStoppedPackagesFilename.exists()
                || mStoppedPackagesFilename.exists()) {
            // Read old file
            readStoppedLPw();
            mBackupStoppedPackagesFilename.delete();
            mStoppedPackagesFilename.delete();
            // Migrate to new file format
            writePackageRestrictionsLPr(UserHandle.USER_SYSTEM);
        } else {
            for (UserInfo user : users) {
                readPackageRestrictionsLPr(user.id);
            }
        }

        for (UserInfo user : users) {
            mRuntimePermissionsPersistence.readStateForUserSyncLPr(user.id);
        }

        /*
         * Make sure all the updated system packages have their shared users
         * associated with them.
         */
        final Iterator disabledIt = mDisabledSysPackages.values().iterator();
        while (disabledIt.hasNext()) {
            final PackageSetting disabledPs = disabledIt.next();
            final Object id = getSettingLPr(disabledPs.appId);
            if (id != null && id instanceof SharedUserSetting) {
                disabledPs.sharedUser = (SharedUserSetting) id;
            }
        }

        mReadMessages.append("Read completed successfully: " + mPackages.size() + " packages, "
                + mSharedUsers.size() + " shared uids\n");

        writeKernelMappingLPr();

        return true;
    }

阶段2细节:apk目录的扫描

  • 从init.rc中获取环境变量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH;
  • 对于旧版本升级的情况,将安装时获取权限变为运行时申请权限;
  • 扫描/system/vendor/product/odm/oem等目录的priv-app、app、overlay包;
  • 清除安装时临时文件以及其他不必要啊的信息。
    在PKMS的构造方法中会调用scanDirTracedLi函数,进行APK的扫描。会扫描很多的系统目录扫描APK。在这里就会解析AndroidManifest.xml文件。最终将解析成果交给了Package对象。
    Package这个类是PackageParser的静态内部类。Package这个对象会被保存在运行时内存里。
    public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        ...
        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            ...
            // TODO:这里从阶段1的位置继续
            // 记录扫描开始时间
            long startTime = SystemClock.uptimeMillis();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);
            // TODO:(1)从init.rc中获取环境变量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH
            final String bootClassPath = System.getenv("BOOTCLASSPATH");
            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
            ...
            // 获取system/framework目录
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
            // 获取内部版本
            final VersionInfo ver = mSettings.getInternalVersion();
            // 判断fingerprint是否有更新
            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
            ...
            // TODO:(2)对于旧版本升级的情况,将安装时获取权限变更为运行时申请权限;
            // 对于Android M之前版本升级上来的情况,需要将系统应用程序权限从安装升级到运行时
            mPromoteSystemApps =
                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;

            // 对于Android N之前版本升级上来的情况,需像首次启动一样处理Package
            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;

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

            int preUpgradeSdkVersion = ver.sdkVersion;

            // 在扫描之前保存预先存在的系统package的名称,不希望自动为新系统应用授予运行时权限
            if (mPromoteSystemApps) {
                Iterator pkgSettingIter = mSettings.mPackages.values().iterator();
                while (pkgSettingIter.hasNext()) {
                    PackageSetting ps = pkgSettingIter.next();
                    if (isSystemApp(ps)) {
                        mExistingSystemPackages.add(ps.name);
                    }
                }
            }
            // 准备解析package的缓存
            mCacheDir = preparePackageParserCache();

            // 设置flag,而不在扫描安装时更改文件路径
            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
            ...
            // TODO:(3)扫描system/vendor/product/odm/oem等目录的priv-app、app、overlay包;
            // 扫描对应的路径
            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_VENDOR,
                    0);
            scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT,
                    0);
            scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_PRODUCT_SERVICES,
                    0);
            scanDirTracedLI(new File(ODM_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_ODM,
                    0);
            scanDirTracedLI(new File(OEM_OVERLAY_DIR),
                    mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM_DIR,
                    scanFlags
                    | SCAN_AS_SYSTEM
                    | SCAN_AS_OEM,
                    0);
            ...
            // 修剪所有不再存在的系统软件包。
            final List possiblyDeletedUpdatedSystemApps = new ArrayList<>();
            // 存根软件包必须用/ data分区中的完整版本替换或被禁用。
            final List stubSystemApps = new ArrayList<>();
            // 删掉不存在的package
            if (!mOnlyCore) {
                final Iterator pkgIterator = mPackages.values().iterator();
                while (pkgIterator.hasNext()) {
                    final PackageParser.Package pkg = pkgIterator.next();
                    if (pkg.isStub) {
                        stubSystemApps.add(pkg.packageName);
                    }
                }
                final Iterator psit = mSettings.mPackages.values().iterator();
                while (psit.hasNext()) {
                    PackageSetting ps = psit.next();

                    // 如果不是系统应用,则不被允许disable
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                        continue;
                    }

                    // 如果应用被扫描,则不允许被擦除
                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
                    if (scannedPkg != null) {
                        // 如果系统应用被扫描且存在disable应用列表中,则只能通过OTA升级添加
                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
                            // 说明这个系统app有升级包,那么就将该系统app的
                            // PackageSetting从mDisabledSysPackages列表中移除,
                            // 并将系统app的升级包路径添加到mExpectingBetter列表中
                            // 等待后续处理。mExpectingBetter的类型为ArrayMap
                            removePackageLI(scannedPkg, true);
                            mExpectingBetter.put(ps.name, ps.codePath);
                        }

                        continue;
                    }

                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                        psit.remove();
                        logCriticalInfo(Log.WARN, "System package " + ps.name
                                + " no longer exists; it's data will be wiped");
                        // Actual deletion of code and data will be handled by later
                        // reconciliation step
                    } else {
                        // 如果这个系统app的升级包信息存储在mDisabledSysPackages列表中,但是没有发现这个升级包存在,
                        // 则将它加入possiblyDeletedUpdatedSystemApps列表中,代表这个系统app的升级包可能会被删除,
                        // 这里是可能而不是一定,是因为系统还没有扫描/data分区,只能将它暂时放到
                        // possiblyDeletedUpdatedSystemApps列表中,等扫描完成data分区后再进行处理。
                        final PackageSetting disabledPs =
                                mSettings.getDisabledSystemPkgLPr(ps.name);
                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
                                || disabledPs.pkg == null) {
                            possiblyDeletedUpdatedSystemApps.add(ps.name);
                        } else {
                            // We're expecting that the system app should remain disabled, but add
                            // it to expecting better to recover in case the data version cannot
                            // be scanned.
                            mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
                        }
                    }
                }
            }
            // TODO:(4)清除安装时临时文件以及其他不必要的信息
            // 删除临时文件
            deleteTempPackageFiles();
            ....
            // 删除没有关联应用的共享UID标识
            mSettings.pruneSharedUsersLPw();
            ...
        }
        }
    }

阶段3细节:apk的安装

对于不仅仅解析核心应用的情况下,还处理data目录的应用信息,及时更新,去除不必要的数据。

    public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        ...
        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            ...
            if (!mOnlyCore) {
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
                // 移除通过OTA删除的更新系统应用程序的禁用package设置
                // 如果更新不再存在,则完全删除该应用。否则,撤销其系统权限
                for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
                    final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
                    final PackageParser.Package pkg = mPackages.get(packageName);
                    final String msg;

                    // 从mSettings中的mDisabledSysPackages列表中删除对应的
                    // 系统app的PackageSetting信息
                    mSettings.removeDisabledSystemPackageLPw(packageName);

                    // 如果这个系统app的包信息不再PKMS的遍历mPackages中
                    // 则说明其实残留的app信息,后续会删除它的数据
                    if (pkg == null) {
                        // should have found an update, but, we didn't; remove everything
                        msg = "Updated system package " + packageName
                                + " no longer exists; removing its data";
                    } else {
                        // 如果这个系统app在mPackages中,那么不能删除
                        // 则需要进行重新扫描,先将该系统app的package信息从
                        // mPackages中移除,然后在进行重新扫描
                        msg = "Updated system package " + packageName
                                + " no longer exists; rescanning package on data";
    
                        // 删除packages.xml中该系统app的信息
                        removePackageLI(pkg, true);
                        try {
                            final File codePath = new File(pkg.applicationInfo.getCodePath());
                            scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
                        } catch (PackageManagerException e) {
                            Slog.e(TAG, "Failed to parse updated, ex-system package: "
                                    + e.getMessage());
                        }
                    }
                    ...
                }
                // 确保期望在userdata分区上显示的所有系统应用程序实际显示
                // 如果从未出现过,需要回滚以恢复系统版本
                for (int i = 0; i < mExpectingBetter.size(); i++) {
                    // 得到系统app的升级包路径
                    final String packageName = mExpectingBetter.keyAt(i);
                    if (!mPackages.containsKey(packageName)) {
                        final File scanFile = mExpectingBetter.valueAt(i);

                        logCriticalInfo(Log.WARN, "Expected better " + packageName
                                + " but never showed up; reverting to system");

                        final @ParseFlags int reparseFlags;
                        final @ScanFlags int rescanFlags;
                        // 根据系统app所在路径设置扫描的解析参数
                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM;
                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
                                || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_VENDOR
                                    | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(vendorAppDir, scanFile)
                                || FileUtils.contains(odmAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_VENDOR;
                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_OEM;
                        } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_PRODUCT
                                    | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(productAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_PRODUCT;
                        } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_PRODUCT_SERVICES
                                    | SCAN_AS_PRIVILEGED;
                        } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
                            reparseFlags =
                                    mDefParseFlags |
                                    PackageParser.PARSE_IS_SYSTEM_DIR;
                            rescanFlags =
                                    scanFlags
                                    | SCAN_AS_SYSTEM
                                    | SCAN_AS_PRODUCT_SERVICES;
                        } else {
                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                            continue;
                        }
                        // 将packageName对应的包设置数据(PackageSetting)添加到
                        // mSettings的mPackages中
                        mSettings.enableSystemPackageLPw(packageName);

                        try {
                            // 扫描系统app的升级包(扫描apk文件)
                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
                        } catch (PackageManagerException e) {
                            Slog.e(TAG, "Failed to parse original system package: "
                                    + e.getMessage());
                        }
                    }
                }
                // 解压缩并按照任何存在根系统应用程序。必须最后执行此操作以确保 替换或禁用所有存根
                installSystemStubPackages(stubSystemApps, scanFlags);
                ...
            }
            mExpectingBetter.clear();
            // 获取storage manager包名
            mStorageManagerPackage = getStorageManagerPackageName();
            // 解决受保护的action过滤器。只允许setup wizard(开机向导)为这些action设置高优先级过滤器
            mSetupWizardPackage = getSetupWizardPackageName();
            // 更新客户端以确保持有正确的共享库路径
            updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages));
            ...
            // 读取并更新要保留的package的上次使用时间
            mPackageUsage.read(mPackages);
            mCompilerStats.read();
            ...
        } 
        }
    }

阶段4细节:

  • sdk版本变更,更新权限;
  • OTA升级后首次启动,清除不必要的缓存数据;
  • 权限等默认项更新完后,清理相关数据;
  • 更新packages.xml
    public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        ...
        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            ...
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());
            // TODO:(1)sdk版本变更,更新权限;
            // 如果自上次启动以来,平台SDK已经改变,则需要重新授予应用程序权限以捕获出现的任何新权限
            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
            mPermissionManager.updateAllPermissions(
                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
                    mPermissionCallback);
            // 如果这是第一次启动或来自Android M之前的版本的升级,并且它是正常启动,则需要在所有
            // 已经定义的用户中初始化默认的首选应用程序
            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
                for (UserInfo user : sUserManager.getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(user.id);
                    primeDomainVerificationsLPw(user.id);
                }
            }
            // 在启动期间确实为系统用户准备存储,因为像SettingsProvider和SystemUI这样的核心系统应用程序无法等待用户启动
            final int storageFlags;
            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
                storageFlags = StorageManager.FLAG_STORAGE_DE;
            } else {
                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
            }
            ...
            // TODO:(2)OTA升级后首次启动,清除不必要的缓存数据;
            // 如果是在OTA之后首次启动,并且正常启动,那需要清除代码缓存目录,但不清除应用程序配置文件
            if (mIsUpgrade && !onlyCore) {
                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                for (int i = 0; i < mSettings.mPackages.size(); i++) {
                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
                        // No apps are running this early, so no need to freeze
                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
                                FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
            }
            // 安装Android-Q前的非系统应用程序在Launcher中隐藏他们的图标
            if (!onlyCore && mIsPreQUpgrade) {
                Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
                int size = mSettings.mPackages.size();
                for (int i = 0; i < size; i++) {
                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                        continue;
                    }
                    ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
                            UserHandle.USER_SYSTEM);
                }
            }
            // TODO:(3)权限等默认项更新完后,清理相关数据;
            // 仅在权限或其他默认配置更新后清除
            mExistingSystemPackages.clear();
            mPromoteSystemApps = false;
            ...
            // 所有变更均在扫描过程中完成
            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
            // TODO:(4)更新packages.xml
            // 降级去读取
            mSettings.writeLPr();
            ...
        }
        }
    }

阶段5细节:

主要是GC回收内存和一些其他细节处理

    public PackageManagerService(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        ...
        synchronized (mInstallLock) {
        // writer
        synchronized (mPackages) {
            ...
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());
            ...
            // PermissionController主持缺陷许可证的授予和角色管理,所以这是核心系统的一个关键部分。
            mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
            ...
            // 
            updateInstantAppInstallerLocked(null);
            // 阅读并更新dex文件的用法
            // 在PM init结束时执行此操作,以便所有程序包都已协调其数据目录
            // 此时知道了包的代码路径,因此可以验证磁盘文件并构建内部缓存
            // 使用文件预计很小,因此与其他活动(例如包扫描)相比,加载和验证它应该花费相当小的时间
            final Map> userPackages = new HashMap<>();
            for (int userId : userIds) {
                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
            }
            mDexManager.load(userPackages);
            if (mIsUpgrade) {
                MetricsLogger.histogram(null, "ota_package_manager_init_time",
                        (int) (SystemClock.uptimeMillis() - startTime));
            }
        }
        }
        // TODO:GC回收内存
        // 打开应用之后,及时回收处理
        Runtime.getRuntime().gc();
        // 上面的扫描在持有mPackages锁的同时对installd进行了多次调用
        mInstaller.setWarnIfHeld(mPackages);
    }

你可能感兴趣的:(Android-PackageManagerService创建过程源码分析)