PackageManagerService 既然是系统服务,那么肯定是通过 SystemServer 启动的,所以我们首先看一下 SystemServer 服务中启动 PackageManagerService 相关代码。
一、PMS启动
1、SystemServer
源码路径:/frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer {private PackageManagerService mPackageManagerService;private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {t.traceBegin("StartPackageManagerService");try {Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");mPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);} finally {Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");}// 现在包管理器已经启动,请注册索引加载报告程序以捕获系统服务器加载的任何索引文件。// 这些索引文件将被后台dexoptservice优化SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService);mFirstBoot = mPackageManagerService.isFirstBoot();mPackageManager = mSystemContext.getPackageManager();t.traceEnd();}
}
这里通过 PackageManagerService.main 来启动 PackageManagerService 服务。同时这里在调用 OtaDexoptService.main 时也传入了 mPackageManagerService。
// 管理A/B OTA采用。这是一个引导服务,因为我们需要它在引导后重命名A/B工件,在其他任何东西可能接触/需要它们之前。
if (!mOnlyCore) {boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false);if (!disableOtaDexopt) {t.traceBegin("StartOtaDexOptService");try {Watchdog.getInstance().pauseWatchingCurrentThread("moveab");OtaDexoptService.main(mSystemContext, mPackageManagerService);} catch (Throwable e) {reportWtf("starting OtaDexOptService", e);} finally {Watchdog.getInstance().resumeWatchingCurrentThread("moveab");t.traceEnd();}}
}
2、PackageManagerService
源码位置:/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) {// 自检初始设置PackageManagerServiceCompilerMapping.checkProperties();……PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest);t.traceEnd(); // "创建包管理器"……m.installWhitelistedSystemPackages();ServiceManager.addService("package", m);final PackageManagerNative pmn = m.new PackageManagerNative();ServiceManager.addService("package_native", pmn);return m;
}
在这里 new 了一个新的 PackageManagerService,接下来看一下 PackageManagerService 的构造函数。
二、构造函数
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {PackageManager.disableApplicationInfoCache();PackageManager.disablePackageInfoCache();……// 第一阶段:BOOT_PROGRESS_PMS_STARTEventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis());……// 1.创建DisplayMetricsmMetrics = new DisplayMetrics();// 2.创建InstallermInstaller = injector.getInstaller();……// 3.创建mPermissionManagermPermissionManager = injector.getPermissionManagerServiceInternal();// 4.创建mSettingsmSettings = injector.getSettings();……mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID, ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);……// 5.创建PackageDexOptimizer和DexManagermPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext, "*dexopt*");mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);……// 6.创建SystemConfigSystemConfig systemConfig = SystemConfig.getInstance();……// CHECKSTYLE:OFF IndentationChecksynchronized (mInstallLock) {// writersynchronized (mLock) {mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);mHandlerThread.start();// 7.创建PackageManager.handlermHandler = new PackageHandler(mHandlerThread.getLooper());mProcessLoggingHandler = new ProcessLoggingHandler();Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);……// 第二阶段:BOOT_PROGRESS_PMS_SYSTEM_SCAN_STARTEventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, startTime);// 1.获取环境变量final String bootClassPath = System.getenv("BOOTCLASSPATH");final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");……// 2.从pre-M升级时,将系统应用程序权限从安装提升到运行时mPromoteSystemApps = mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;// 当从pre-N升级时,我们需要像第一次引导一样处理包提取,因为没有可用的分析数据。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;……// 3.扫描apkmApexManager.scanApexPackagesTraced(packageParser, executorService);……// 解析覆盖配置文件以设置系统覆盖的默认启用状态、可变性和优先级。mOverlayConfig = OverlayConfig.initializeSystemInstance(consumer -> mPmInternal.forEachPackage(pkg -> consumer.accept(pkg, pkg.isSystem())));……// 4.删除任何没有关联包的共享useridmSettings.pruneSharedUsersLPw();……if (!mOnlyCore) {// 第三阶段:BOOT_PROGRESS_PMS_DATA_SCAN_STARTEventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, SystemClock.uptimeMillis());// 扫描 /system/app 目录下的APK文件scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0, packageParser, executorService);}packageParser.close();if (!mOnlyCore) {// 删除通过OTA删除的更新系统应用程序的禁用包设置。// 如果更新不再存在,完全删除应用程序。否则,撤销其系统权限。for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {final String packageName = possiblyDeletedUpdatedSystemApps.get(i);……// 从禁用系统列表中删除mSettings.removeDisabledSystemPackageLPw(packageName);……}……}……// 读取并更新保存所有包的最后使用时间。mPackageUsage.read(mSettings.mPackages);mCompilerStats.read();// 第四阶段:BOOT_PROGRESS_PMS_SCAN_ENDEventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, SystemClock.uptimeMillis());// 1.SDK发生了变化,重新授予应用权限。final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);ver.sdkVersion = mSdkVersion;// 第一次启动或从pre-M版本更新,初始化所有已定义用户的默认首选应用程序。if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {mSettings.applyDefaultPreferredAppsLPw(user.id);primeDomainVerificationsLPw(user.id);}}……// 2.OTA第一次引导,清除代码缓存目录。if (mIsUpgrade && !mOnlyCore) {// 构建改变,清除代码缓存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)) {clearAppDataLIF(ps.pkg, 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.fingerprint = Build.FINGERPRINT;}……// 3.更新了权限和其他默认值后,才能清除mPromoteSystemApps = false;// 所有更改都是在包扫描期间完成的。ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;// can downgrade to readert.traceBegin("write settings");mSettings.writeLPr();t.traceEnd();// 第五阶段:BOOT_PROGRESS_PMS_READYEventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, SystemClock.uptimeMillis());……// 包解析器供应商,解析apex文件。final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2(mSeparateProcesses, mOnlyCore, mMetrics, null /* cacheDir */,mPackageParserCallback);// 1.创建PackageInstallerServicemInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier);……}}……// 2.GC回收t.traceBegin("GC");Runtime.getRuntime().gc();t.traceEnd();……
}
PackageManagerService 构造函数代码比较多,但总结起来主要包含下面五个阶段。
1、BOOT_PROGRESS_PMS_START
(1)构造 DisplayMetrics,保存分辨率等相关信息;
(2)创建 Installer 对象,与 installd 交互;
(3)创建 mPermissionManager对象,进行权限管理;
(4)构造Settings类,保存安装包信息,清除路径不存在的孤立应用,主要涉及 /data/system/ 目录的 packages.xml、packages-backup.xml、packages.list、packages-stopped.xml、packages-stopped-backup.xml 等文件。
- packages.xml:记录了系统中所有安装的应用信息,包括基本信息、签名和权限。
- pakcages-back.xml:packages.xml文件的备份。
- pakcages-stoped.xml:记录系统中被强制停止的运行的应用信息,系统在强制停止某个应用的时候,会将应用的信息记录在该文件中。
- pakcages-stoped-backup.xml:pakcages-stoped.xml文件的备份。
- packages.list:保存普通应用的数据目录和uid等信息。
(5)构造PackageDexOptimizer及DexManager类,处理dex优化;
(6)创建SystemConfig实例,获取系统配置信息,配置共享lib库;
(7)创建PackageManager的handler线程,循环处理外部安装相关消息。
2、BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
(1)从 init.rc 中获取环境变量 BOOTCLASSPATH 和 SYSTEMSERVERCLASSPATH;
(2)对于旧版本升级的情况,将安装时获取权限变更为运行时申请权限;
(3)扫描 system/vendor/product/odm/oem 等目录的 priv-app、app、overlay 包;
(4)清除安装时临时文件以及其他不必要的信息。
3、BOOT_PROGRESS_PMS_DATA_SCAN_START
处理 data 目录的应用信息,及时更新,祛除不必要的数据。
4、BOOT_PROGRESS_PMS_SCAN_END
(1)sdk版本变更,更新权限;
(2)OTA升级后首次启动,清除不必要的缓存数据;
(3)权限等默认项更新完后,清理相关数据;
(4)更新 package.xml。
5、BOOT_PROGRESS_PMS_READY
(1)创建 PackageInstallerService 对象;
(2)GC 回收内存。