PackageManagerService启动流程
前面通过APK的构建过程和APK的组成结构两篇铺垫,准备研究Apk的安装过程之前,先需要搞清楚PackageManagerService,也就是平时经常听到的PMS,是由SystemServer进程创建的系统服务之一。
用API 30的源码阅读PMS服务的初始化流程,新的源码和目前的书籍资料相差较大(普遍基于API 28),源码看起来就比较费时间,因为摸不着方向又没有参考只能硬啃。
1、PMS启动流程
回顾一下在SystemServer系统服务启动一文中SystemServer是如何创建Android系统众多服务的,SystemServer的主入口main方法如下:
/** * The main entry point from zygote. */ public static void main(String[] args) { new SystemServer().run(); }
1.1、SystemServer启动PMS
SystemServer通过三个重要的方法,分别启动:引导服务、核心服务和其它服务。
private void run() { ... // Start services. t.traceBegin("StartServices"); startBootstrapServices(t); startCoreServices(t); startOtherServices(t); ... // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
本次要研究的PackageManagerService就在启动引导服务的方法中被启动,可见PMS在Android系统中的重要性。下面截取startBootstrapServices()方法中启动PackageManagerService的部分:
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"); } // Now that the package manager has started, register the dex load reporter to capture any // dex files loaded by system server. // These dex files will be optimized by the BackgroundDexOptService. SystemServerDexLoadReporter.configureSystemServerDexReporter(mPackageManagerService); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); t.traceEnd(); ... }
1.2、PMS的入口方法main()
PackageManagerService比其它系统服务,如ActivityManagerService要复杂的多(见AMS服务的启动)。SystemServer进程中调用PackageManagerService的main(...)方法启动PMS,主方法如下:
public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore) { ... t.traceBegin("create package manager"); final Object lock = new Object(); final Object installLock = new Object(); Injector injector = new Injector( context, lock, installer, installLock, new PackageAbiHelperImpl(), (i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock), (i, pm) -> PermissionManagerService.create(context, lock), (i, pm) -> new UserManagerService(context, pm, new UserDataPreparer(installer, installLock, context, onlyCore), lock), (i, pm) -> new Settings(Environment.getDataDirectory(), i.getPermissionManagerServiceInternal().getPermissionSettings(), lock), new Injector.LocalServicesProducer<>(ActivityTaskManagerInternal.class), new Injector.LocalServicesProducer<>(ActivityManagerInternal.class), new Injector.LocalServicesProducer<>(DeviceIdleInternal.class), new Injector.LocalServicesProducer<>(StorageManagerInternal.class), new Injector.LocalServicesProducer<>(NetworkPolicyManagerInternal.class), new Injector.LocalServicesProducer<>(PermissionPolicyInternal.class), new Injector.LocalServicesProducer<>(DeviceStorageMonitorInternal.class), new Injector.SystemServiceProducer<>(DisplayManager.class), new Injector.SystemServiceProducer<>(StorageManager.class), new Injector.SystemServiceProducer<>(AppOpsManager.class), (i, pm) -> AppsFilter.create(pm.mPmInternal, i), (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat")); /** * 构造PackageManagerService */ PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest); t.traceEnd(); // "create package manager" ... //添加到ServiceManager中管理 ServiceManager.addService("package", m); final PackageManagerNative pmn = m.new PackageManagerNative(); ServiceManager.addService("package_native", pmn); return m; }
API 30源码中PackageManagerService构造方法和API 28相比增加了很多代码,其中一部分就是新增了Injector类,用来实现依赖注入。向其注入实现Producer接口的对象实例,后面很多地方都会从Injector中提取需要的对象实例,比如Settings、UserManagerService等。
interface Producer<T> { /** Produce an instance of type {@link T} */ T produce(Injector injector, PackageManagerService packageManager); }
Producer实例被保存在Singleton中,看到这里就容易理解这样设计是为了通过Injector->Singleton->Producer获取单实例。
static class Singleton<T> { private final Producer<T> mProducer; private volatile T mInstance = null; Singleton(Producer<T> producer) { this.mProducer = producer; } T get(Injector injector, PackageManagerService packageManagerService) { if (mInstance == null) { mInstance = mProducer.produce(injector, packageManagerService); } return mInstance; } }
在Injector构造的时候就已经构造了Settings实例:new Settings(Environment.getDataDirectory(),...)其构造方法如下:
Settings(File dataDir, PermissionSettings permission, Object lock) { mLock = lock; mPermissions = permission; mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock); /** * mSystemDir系统目录/data/system目录 */ mSystemDir = new File(dataDir, "system"); mSystemDir.mkdirs(); FileUtils.setPermissions(mSystemDir.toString(), FileUtils.S_IRWXU|FileUtils.S_IRWXG |FileUtils.S_IROTH|FileUtils.S_IXOTH, -1, -1); /** * Settings类构造方法中创建若干文件 */ mSettingsFilename = new File(mSystemDir, "packages.xml"); mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); 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; // Deprecated: Needed for migration mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml"); mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); }
Settings类构造方法中创建若干文件,这些都是和安装的Apk有关,用于保存Apk信息。主要涉及/data/system目录下的packages.xml、packages-backup.xml、packages.list、packages-stopped.xml、packages-stopped-backup.xml等文件,带-backup后缀的文件是另一个文件的备份。各文件具体含义如下:
/data/system/packages.xml和/data/system/packages-backup.xml:PMS扫描完目标文件夹后会创建该文件。当系统进行程序安装、卸载和更新等操作时,均会更新该文件。该文件保存了系统中与 package 相关的一些信息。
/data/system/packages.list和:描述系统中存在的所有非系统自带的APK的信息。当这些程序有变动时,PMS就会更新该文件。
/data/system/packages-stopped.xml和/data/system/packages-stopped-backup.xml:从系统自带的设置程序中进入应用程序页面,然后在选择强制停止(ForceStop)某个应用时,系统会将该应用的相关信息记录到此文件中。也就是该文件保存系统中被用户强制停止的 Package 的信息。
回到启动PackageManagerService的main()方法中,调用PackageManagerService的构造方法创建PMS实例。
2、PMS构造方法
PackageManagerService的构造方法长达800余行,不要惊讶,成百上千行的构造方法在AOSP源码中很常见,只需要拆分看,抓住重点代码看即可。
2.1、PMS构造的五个阶段
参考《Android 进阶指北》一书中,按照源码中EventLogTags标记将整个构造方法分为5个阶段:
阶段1:BOOT_PROGRESS_PMS_START
(1)构造DisplayMetrics保存分辨率信息
(2)从Injector初始化Installer对象,用于与installd交互
(3)readLPw()会扫描前面Settings构造时创建的5个文件
(4)创建SystemConfig实例,获取全局系统配置信息,配置共享lib库
(5)创建PackageHandler处理安装相关消息
阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START
(1)从init.rc中获取环境变量BOOTCLASSPATH和SYSTEMSERVERCLASSPATH
(2)扫描/system目录下的overlay/framework/app/priv-app等目录
(3)清除安装时临时文件以及其他不必要的信息。
阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START
(1)解析核心应用/data/app和/data/app-private
(2)处理data目录的应用信息:删除残留应用数据、移除普通应用系统权限等
(3)清除不必要的数据
阶段4:BOOT_PROGRESS_PMS_SCAN_END
(1)SDK版本变更,更新应用权限
(2)OTA升级后首次启动或者从LOLLIPOP_MR1升级后第一次启动,初始化默认首选项
(3)权限等默认项更新完后,清理缓存相关数据
(4)更新package.xml
阶段5:BOOT_PROGRESS_PMS_READY
(1)创建PackageInstallerService对象,分配SessionId管理每次Apk安装
(2)GC回收内存(可有可无)
2.2、PMS完整构造方法*
PackageManagerService完整构造方法如下,注释比较完善,开发者应该能够阅读整体构造代码实现的流程。
public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) { PackageManager.disableApplicationInfoCache(); PackageManager.disablePackageInfoCache(); // Avoid invalidation-thrashing by preventing cache invalidations from causing property // writes if the cache isn't enabled yet. We re-enable writes later when we're // done initializing. PackageManager.corkPackageInfoCache(); final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing", Trace.TRACE_TAG_PACKAGE_MANAGER); mPendingBroadcasts = new PendingPackageBroadcasts(); mInjector = injector; mInjector.bootstrap(this); mLock = injector.getLock(); mInstallLock = injector.getInstallLock(); LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START, SystemClock.uptimeMillis()); if (mSdkVersion <= 0) { Slog.w(TAG, "**** ro.build.version.sdk not set!"); } mContext = injector.getContext(); mFactoryTest = factoryTest; mOnlyCore = onlyCore; //获取屏幕信息 mMetrics = new DisplayMetrics(); mInstaller = injector.getInstaller(); //创建提供服务/数据的子组件。这里的顺序很重要。 t.traceBegin("createSubComponents"); // 公开专用服务以供系统组件使用。 mPmInternal = new PackageManagerInternalImpl(); LocalServices.addService(PackageManagerInternal.class, mPmInternal); mUserManager = injector.getUserManagerService(); mComponentResolver = injector.getComponentResolver(); mPermissionManager = injector.getPermissionManagerServiceInternal(); //用来保存各种apk信息 mSettings = injector.getSettings(); mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr"); mIncrementalManager = (IncrementalManager) mContext.getSystemService(Context.INCREMENTAL_SERVICE); 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(); t.traceBegin("addSharedUsers"); //添加分配UID映射,方便管理mInstallLock 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); t.traceEnd(); String separateProcesses = SystemProperties.get("debug.separate_processes"); if (separateProcesses != null && separateProcesses.length() > 0) { if ("*".equals(separateProcesses)) { mDefParseFlags = PackageParser.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 = new PackageDexOptimizer(mInstaller, mInstallLock, mContext, "*dexopt*"); mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock); mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock); mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper()); mViewCompiler = new ViewCompiler(mInstallLock, mInstaller); getDefaultDisplayMetrics(mInjector.getDisplayManager(), mMetrics); t.traceBegin("get system config"); SystemConfig systemConfig = SystemConfig.getInstance(); mAvailableFeatures = systemConfig.getAvailableFeatures(); ApplicationPackageManager.invalidateHasSystemFeatureCache(); t.traceEnd(); mProtectedPackages = new ProtectedPackages(mContext); mApexManager = ApexManager.getInstance(); mAppsFilter = mInjector.getAppsFilter(); final List<ScanPartition> scanPartitions = new ArrayList<>(); final List<ApexManager.ActiveApexInfo> activeApexInfos = mApexManager.getActiveApexInfos(); for (int i = 0; i < activeApexInfos.size(); i++) { final ScanPartition scanPartition = resolveApexToScanPartition(activeApexInfos.get(i)); if (scanPartition != null) { scanPartitions.add(scanPartition); } } mDirsToScanAsSystem = new ArrayList<>(); mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS); mDirsToScanAsSystem.addAll(scanPartitions); Slog.d(TAG, "Directories scanned as system partitions: " + mDirsToScanAsSystem); // CHECKSTYLE:OFF IndentationCheck synchronized (mInstallLock) { // writer synchronized (mLock) { // 创建名为 “PackageManager” 的线程,负责apk的安装、卸载 mHandlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND, true /**allowIo*/); mHandlerThread.start(); // 获取线程Looper以创建handler mHandler = new PackageHandler(mHandlerThread.getLooper()); mProcessLoggingHandler = new ProcessLoggingHandler(); // Watchdog监听ServiceThread是否超时:10分钟 WATCHDOG_TIMEOUT = 1000*60*10; Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT); mInstantAppRegistry = new InstantAppRegistry(this); ArrayMap<String, SystemConfig.SharedLibraryEntry> 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); } // 现在我们已经添加了所有库,再次迭代以添加依赖项信息,如果添加了它们的依赖项。 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 = getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion); if (dependency != null) { getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency); } } } SELinuxMMAC.readInstallPolicy(); t.traceBegin("loadFallbacks"); FallbackCategoryProvider.loadFallbacks(); t.traceEnd(); t.traceBegin("read user settings"); //会扫描5个文件 mFirstBoot = !mSettings.readLPw(mInjector.getUserManagerInternal().getUsers(false)); t.traceEnd(); // Clean up orphaned packages for which the code path doesn't exist // and they are an update to a system app - caused by bug/32321269 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); } } if (!mOnlyCore && mFirstBoot) { requestCopyPreoptedFiles(); } String customResolverActivityName = Resources.getSystem().getString( R.string.config_customResolverActivity); if (!TextUtils.isEmpty(customResolverActivityName)) { mCustomResolverComponentName = ComponentName.unflattenFromString( customResolverActivityName); } // 记录扫描开始时间 long startTime = SystemClock.uptimeMillis(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, startTime); //获取环境变量,init.rc 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!"); } // 获取system/framework目录 File frameworkDir = new File(Environment.getRootDirectory(), "framework"); final VersionInfo ver = mSettings.getInternalVersion(); mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint); if (mIsUpgrade) { logCriticalInfo(Log.INFO, "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT); } //从pre-M升级时,将系统应用权限从安装升级为运行时 mPromoteSystemApps = mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1; //从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; //在扫描之前保存先前存在的软件包的名称,以便我们可以确定由于升级而全新的系统软件包。 if (isDeviceUpgrading()) { mExistingPackages = new ArraySet<>(mSettings.mPackages.size()); for (PackageSetting ps : mSettings.mPackages.values()) { mExistingPackages.add(ps.name); } } mCacheDir = preparePackageParserCache(); //在扫描安装目录时设置标志以监视并且不更改apk文件路径。 int scanFlags = SCAN_BOOTING | SCAN_INITIAL; if (mIsUpgrade || mFirstBoot) { scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE; } final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR; final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM; PackageParser2 packageParser = new PackageParser2(mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback); ExecutorService executorService = ParallelPackageParser.makeExecutorService(); // 在扫描APK之前准备apex软件包信息,在apex中扫描apk时需要这些信息。 mApexManager.scanApexPackagesTraced(packageParser, executorService); //收集vendor /product/system_ext覆盖程序包。(在扫描任何应用程序之前执行此操作。) //出于安全和版本匹配的原因,仅当覆盖包位于正确的目录中时,才考虑它们。 for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) { final ScanPartition partition = mDirsToScanAsSystem.get(i); if (partition.getOverlayFolder() == null) { continue; } scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags, systemScanFlags | partition.scanFlag, 0, packageParser, executorService); } scanDirTracedLI(frameworkDir, systemParseFlags, systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0, packageParser, executorService); if (!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) { scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags, systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0, packageParser, executorService); } scanDirTracedLI(partition.getAppFolder(), systemParseFlags, systemScanFlags | partition.scanFlag, 0, packageParser, executorService); } // Parse overlay configuration files to set default enable state, mutability, and // priority of system overlays. mOverlayConfig = OverlayConfig.initializeSystemInstance( consumer -> mPmInternal.forEachPackage( pkg -> consumer.accept(pkg, pkg.isSystem()))); //删掉所有不再存在的系统软件包。 final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>(); // sub软件包必须用/data分区中的完整版本替换或被禁用。 final List<String> stubSystemApps = new ArrayList<>(); //删掉不存在的package if (!mOnlyCore) { // do this first before mucking with mPackages for the "expecting better" case final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator(); while (pkgIterator.hasNext()) { final AndroidPackage pkg = pkgIterator.next(); if (pkg.isStub()) { stubSystemApps.add(pkg.getPackageName()); } } final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); while (psit.hasNext()) { PackageSetting ps = psit.next(); /** * If this is not a system app, it can't be a * disable system app. */ // 如果不是系统应用,则不被允许disable if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { continue; } /** * If the package is scanned, it's not erased. */ // 如果应用被扫描,则不允许被擦除 final AndroidPackage scannedPkg = mPackages.get(ps.name); if (scannedPkg != null) { /** * If the system app is both scanned and in the * disabled packages list, then it must have been * added via OTA. Remove it from the currently * scanned package so the previously user-installed * application can be scanned. */ // 如果系统应用被扫描且存在disable应用列表中,则只能通过OTA升级添加 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { logCriticalInfo(Log.WARN, "Expecting better updated system app for " + ps.name + "; removing system app. Last known" + " codePath=" + ps.codePathString + ", versionCode=" + ps.versionCode + "; scanned versionCode=" + scannedPkg.getLongVersionCode()); 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"); // Assume package is truly gone and wipe residual permissions. mPermissionManager.updatePermissions(ps.name, null); // Actual deletion of code and data will be handled by later // reconciliation step } else { // we still have a disabled system package, but, it still might have // been removed. check the code path still exists and check there's // still a package. the latter can happen if an OTA keeps the same // code path, but, changes the package name. 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); } } } } final int cachedSystemApps = PackageCacher.sCachedPackageReadCount.get(); //删除没有关联应用的共享UID标识 mSettings.pruneSharedUsersLPw(); final long systemScanTime = SystemClock.uptimeMillis() - startTime; final int systemPackagesCount = mPackages.size(); Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime + " ms, packageCount: " + systemPackagesCount + " , timePerPackage: " + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount) + " , cached: " + cachedSystemApps); if (mIsUpgrade && systemPackagesCount > 0) { //CHECKSTYLE:OFF IndentationCheck FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED, BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME, systemScanTime / systemPackagesCount); //CHECKSTYLE:ON IndentationCheck } if (!mOnlyCore) { EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START, SystemClock.uptimeMillis()); scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0, packageParser, executorService); } packageParser.close(); List<Runnable> unfinishedTasks = executorService.shutdownNow(); if (!unfinishedTasks.isEmpty()) { throw new IllegalStateException("Not all tasks finished before calling close: " + unfinishedTasks); } if (!mOnlyCore) { // Remove disable package settings for updated system apps that were // removed via an OTA. If the update is no longer present, remove the // app completely. Otherwise, revoke their system privileges. for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) { final String packageName = possiblyDeletedUpdatedSystemApps.get(i); final AndroidPackage pkg = mPackages.get(packageName); final String msg; // remove from the disabled system list; do this first so any future // scans of this package are performed without this state mSettings.removeDisabledSystemPackageLPw(packageName); 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"; // Actual deletion of code and data will be handled by later // reconciliation step } else { // found an update; revoke system privileges msg = "Updated system package " + packageName + " no longer exists; rescanning package on data"; // NOTE: We don't do anything special if a stub is removed from the // system image. But, if we were [like removing the uncompressed // version from the /data partition], this is where it'd be done. // remove the package from the system and re-scan it without any // special privileges removePackageLI(pkg, true); try { final File codePath = new File(pkg.getCodePath()); scanPackageTracedLI(codePath, 0, scanFlags, 0, null); } catch (PackageManagerException e) { Slog.e(TAG, "Failed to parse updated, ex-system package: " + e.getMessage()); } } // one final check. if we still have a package setting [ie. it was // previously scanned and known to the system], but, we don't have // a package [ie. there was an error scanning it from the /data // partition], completely remove the package data. final PackageSetting ps = mSettings.mPackages.get(packageName); if (ps != null && mPackages.get(packageName) == null) { removePackageDataLIF(ps, null, null, 0, false); } logCriticalInfo(Log.WARN, msg); } /** * 确保确实出现了我们期望出现在userdata分区上的所有系统应用程序。 * 如果它们从未出现过,请向后爬并重新启动系统版本。 */ for (int i = 0; i < mExpectingBetter.size(); i++) { 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"); @ParseFlags int reparseFlags = 0; @ScanFlags int rescanFlags = 0; for (int i1 = mDirsToScanAsSystem.size() - 1; i1 >= 0; i1--) { final ScanPartition partition = mDirsToScanAsSystem.get(i1); if (partition.containsPrivApp(scanFile)) { reparseFlags = systemParseFlags; rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag; break; } if (partition.containsApp(scanFile)) { reparseFlags = systemParseFlags; rescanFlags = systemScanFlags | partition.scanFlag; break; } } if (rescanFlags == 0) { Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile); continue; } mSettings.enableSystemPackageLPw(packageName); //扫描APK try { scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null); } catch (PackageManagerException e) { Slog.e(TAG, "Failed to parse original system package: " + e.getMessage()); } } } // 解压缩并安装任何存根系统应用程序。 //必须最后执行此操作,以确保所有存根都被替换或禁用。 installSystemStubPackages(stubSystemApps, scanFlags); final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get() - cachedSystemApps; final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime; final int dataPackagesCount = mPackages.size() - systemPackagesCount; Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime + " ms, packageCount: " + dataPackagesCount + " , timePerPackage: " + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount) + " , cached: " + cachedNonSystemApps); if (mIsUpgrade && 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 } } mExpectingBetter.clear(); // Resolve the storage manager. mStorageManagerPackage = getStorageManagerPackageName(); // Resolve protected action filters. Only the setup wizard is allowed to // have a high priority filter for these actions. mSetupWizardPackage = getSetupWizardPackageNameImpl(); mComponentResolver.fixProtectedFilterPriorities(); mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName(); mSystemTextClassifierPackageName = getSystemTextClassifierPackageName(); mWellbeingPackage = getWellbeingPackageName(); mDocumenterPackage = getDocumenterPackageName(); mConfiguratorPackage = getDeviceConfiguratorPackageName(); mAppPredictionServicePackage = getAppPredictionServicePackageName(); mIncidentReportApproverPackage = getIncidentReportApproverPackageName(); mRetailDemoPackage = getRetailDemoPackageName(); //更新客户端以确保持有正确的共享库路径 updateAllSharedLibrariesLocked(null, null, Collections.unmodifiableMap(mPackages)); /** * 创建 SharedUserSetting 对象并添加到 Settings 的成员变量 mSharedUsers 中, * 在 Android 系统中,多个 package 通过设置 sharedUserId 属性可以运行在同一个进程, * 共享同一个 UID */ 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 = applyAdjustedAbiToSharedUser(setting, null /**scannedPackage*/, mInjector.getAbiHelper().getAdjustedAbiForSharedUser( setting.packages, null /**scannedPackage*/)); if (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 (InstallerException ignored) { } } } // 调整seInfo以确保共享sharedUserId的应用程序位于同一SELinux域中。 setting.fixSeInfoLocked(); setting.updateProcesses(); } // 现在我们知道了我们保留的所有程序包, // 读取并更新其上次使用时间。 mPackageUsage.read(mSettings.mPackages); mCompilerStats.read(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END, SystemClock.uptimeMillis()); Slog.i(TAG, "Time to scan packages: " + ((SystemClock.uptimeMillis()-startTime)/1000f) + " seconds"); // 如果自上次启动以来,平台SDK已改变,则需要重新授予应用程序权限以捕获出现的任何新权限 // If the platform SDK 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. final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion); if (sdkUpdated) { Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to " + mSdkVersion + "; regranting permissions for internal storage"); } 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); } } // Prepare storage for system user really early during boot, // since core system apps like SettingsProvider and SystemUI // can't wait for user to start final int storageFlags; if (StorageManager.isFileEncryptedNativeOrEmulated()) { storageFlags = StorageManager.FLAG_STORAGE_DE; } else { storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; } List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL, UserHandle.USER_SYSTEM, storageFlags, true /** migrateAppData */, true /** onlyCoreApps */); mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync", Trace.TRACE_TAG_PACKAGE_MANAGER); traceLog.traceBegin("AppDataFixup"); try { mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL, StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE); } catch (InstallerException e) { Slog.w(TAG, "Trouble fixing GIDs", e); } traceLog.traceEnd(); traceLog.traceBegin("AppDataPrepare"); if (deferPackages == null || deferPackages.isEmpty()) { return; } int count = 0; for (String pkgName : deferPackages) { AndroidPackage pkg = null; synchronized (mLock) { PackageSetting ps = mSettings.getPackageLPr(pkgName); if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) { pkg = ps.pkg; } } if (pkg != null) { synchronized (mInstallLock) { prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags, true /** maybeMigrateAppData */); } count++; } } traceLog.traceEnd(); Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages"); }, "prepareAppData"); // 如果这是OTA之后的首次启动,并且是正常启动,则 //我们需要清除代码缓存目录。 //请注意,我们不会清除应用程序配置文件。 这些仍然有效 //跨OTA,并且用于推动配置文件验证(在OTA之后)和 //概要文件编译(无需等待收集新的概要文件)。 if (mIsUpgrade && !mOnlyCore) { 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 | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES); } } ver.fingerprint = Build.FINGERPRINT; } // 祖父现有的(安装在Android Q之前)非系统应用程序,用于在启动器中隐藏其图标。 if (!mOnlyCore && 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); } } // 仅在权限和其他默认值已更新后清除 mPromoteSystemApps = false; // 所有更改都在软件包扫描期间完成。 ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION; // 可以降级为读者 t.traceBegin("write settings"); mSettings.writeLPr(); t.traceEnd(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY, SystemClock.uptimeMillis()); if (!mOnlyCore) { mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr(); mRequiredInstallerPackage = getRequiredInstallerLPr(); mRequiredUninstallerPackage = getRequiredUninstallerLPr(); mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr(); if (mIntentFilterVerifierComponent != null) { mIntentFilterVerifier = new IntentVerifierProxy(mContext, mIntentFilterVerifierComponent); } else { mIntentFilterVerifier = null; } mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr(); mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr( PackageManager.SYSTEM_SHARED_LIBRARY_SHARED, SharedLibraryInfo.VERSION_UNDEFINED); } else { mRequiredVerifierPackage = null; mRequiredInstallerPackage = null; mRequiredUninstallerPackage = null; mIntentFilterVerifierComponent = null; mIntentFilterVerifier = null; mServicesExtensionPackageName = null; mSharedSystemSharedLibraryPackageName = null; } // PermissionController hosts default permission granting and role management, so it's a // critical part of the core system. mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(); mSettings.setPermissionControllerVersion( getPackageInfo(mRequiredPermissionControllerPackage, 0, UserHandle.USER_SYSTEM).getLongVersionCode()); // Initialize InstantAppRegistry's Instant App list for all users. final int[] userIds = UserManagerService.getInstance().getUserIds(); for (AndroidPackage pkg : mPackages.values()) { if (pkg.isSystem()) { continue; } for (int userId : userIds) { final PackageSetting ps = getPackageSetting(pkg.getPackageName()); if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) { continue; } mInstantAppRegistry.addInstantAppLPw(userId, ps.appId); } } // Prepare a supplier of package parser for the staging manager to parse apex file // during the staging installation. final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2( mSeparateProcesses, mOnlyCore, mMetrics, null /** cacheDir */, mPackageParserCallback); mInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier); final Pair<ComponentName, String> instantAppResolverComponent = getInstantAppResolverLPr(); if (instantAppResolverComponent != null) { if (DEBUG_INSTANT) { Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent); } mInstantAppResolverConnection = new InstantAppResolverConnection( mContext, instantAppResolverComponent.first, instantAppResolverComponent.second); mInstantAppResolverSettingsComponent = getInstantAppResolverSettingsLPr(instantAppResolverComponent.first); } 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, getInstalledPackages(/**flags*/ 0, userId).getList()); } mDexManager.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); } } // synchronized (mLock) } // synchronized (mInstallLock) // CHECKSTYLE:ON IndentationCheck mModuleInfoProvider = new ModuleInfoProvider(mContext, this); // 缓存失效,并允许客户端缓存程序包信息。 PackageManager.uncorkPackageInfoCache(); // 现在,在打开每个应用程序zip之后,请确保已将其全部冲洗干净。 // 并不是真正需要的,但是可以使事情保持整洁。 t.traceBegin("GC"); Runtime.getRuntime().gc(); t.traceEnd(); // The initial scanning above does many calls into installd while // holding the mPackages lock, but we're mostly interested in yelling // once we have a booted system. mInstaller.setWarnIfHeld(mLock); PackageParser.readConfigUseRoundIcon(mContext.getResources()); mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L); }
3、PackageManager与PMS交互
在开发过程中,常常通过Context的getPackageManager()方法获取PackageManager实例:
/** Return PackageManager instance to find global package information. */ public abstract PackageManager getPackageManager();
Context抽象类的实现类是ContextImpl,关于Context在各种Context及其初始化流程一文中有详细的介绍。ContextImpl实现了getPackageManager()方法:
@Override public PackageManager getPackageManager() { if (mPackageManager != null) { return mPackageManager; } final IPackageManager pm = ActivityThread.getPackageManager(); final IPermissionManager permissionManager = ActivityThread.getPermissionManager(); if (pm != null && permissionManager != null) { // Doesn't matter if we make more than one instance. return (mPackageManager = new ApplicationPackageManager(this, pm, permissionManager)); } return null; }
通过ActivityThread获取IPackageManager和IPermissionManager远程调用接口实例:
@UnsupportedAppUsage public static IPackageManager getPackageManager() { if (sPackageManager != null) { return sPackageManager; } final IBinder b = ServiceManager.getService("package"); sPackageManager = IPackageManager.Stub.asInterface(b); return sPackageManager; } /** Returns the permission manager */ public static IPermissionManager getPermissionManager() { if (sPermissionManager != null) { return sPermissionManager; } final IBinder b = ServiceManager.getService("permissionmgr"); sPermissionManager = IPermissionManager.Stub.asInterface(b); return sPermissionManager; }
IPackageManager和IPermissionManager用来构造PackageManager实例。PackageManager是抽象类,它的实现类是ApplicationPackageManager。
protected ApplicationPackageManager(ContextImpl context, IPackageManager pm, IPermissionManager permissionManager) { mContext = context; mPM = pm; mPermissionManager = permissionManager; }
通过PackageManager执行的大部分操作,都是借助内部的IPackageManager接口实例mPM和系统PackageManagerService服务远程调用完成。
了解了PMS的启动,这也解释为什么Android手机安装的应用多了开机速度会变慢?其中原因之一就是每次开机启动PMS都会去解析一遍Apk的信息,应用数量多了当然启动耗时也就更长。
推荐阅读: