当前位置: 首页 > news >正文

Android 14 PMS源码分析

源码参考:Search (aospxref.com)

一、简介

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

二、SystemServer.java

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

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

2.1 main

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

2.2 run

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

2.3 startBootstrapServices

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

三、PackageManagerService.Java

3.1 main

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

    public static PackageManagerService main(Context context,Installer installer, @NonNull DomainVerificationService domainVerificationService,boolean factoryTest) {// Self-check for initial settings.//自检初始设置PackageManagerServiceCompilerMapping.checkProperties();final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",Trace.TRACE_TAG_PACKAGE_MANAGER);t.traceBegin("create package manager");final PackageManagerTracedLock lock = new PackageManagerTracedLock();final Object installLock = new Object();HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);backgroundThread.start();Handler backgroundHandler = new Handler(backgroundThread.getLooper(),BACKGROUND_HANDLER_CALLBACK);//injector里面会初始化Settings、PackageDexOptimizer、DexManager等,后面需要用到PackageManagerServiceInjector injector = new PackageManagerServiceInjector(context, lock, installer, installLock, new PackageAbiHelperImpl(),backgroundHandler,SYSTEM_PARTITIONS,(i, pm) -> new ComponentResolver(i.getUserManagerService(), pm.mUserNeedsBadging),(i, pm) -> PermissionManagerService.create(context,i.getSystemConfig().getAvailableFeatures()),(i, pm) -> new UserManagerService(context, pm,new UserDataPreparer(installer, installLock, context), lock),//Settings用于保存所有包的动态设置(i, pm) -> new Settings(Environment.getDataDirectory(),RuntimePermissionsPersistence.createInstance(),i.getPermissionManagerServiceInternal(),domainVerificationService, backgroundHandler,lock),(i, pm) -> AppsFilterImpl.create(i,i.getLocalService(PackageManagerInternal.class)),(i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),//得到全局系统配置信息。(i, pm) -> SystemConfig.getInstance(),//创建Dex优化工具类(i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),i.getContext(), "*dexopt*"),(i, pm) -> new DexManager(i.getContext(), i.getPackageDexOptimizer(),i.getInstaller(), i.getInstallLock(), i.getDynamicCodeLogger()),(i, pm) -> new DynamicCodeLogger(i.getInstaller()),(i, pm) -> new ArtManagerService(i.getContext(), i.getInstaller(),i.getInstallLock()),(i, pm) -> ApexManager.getInstance(),(i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),(i, pm) -> (IncrementalManager)i.getContext().getSystemService(Context.INCREMENTAL_SERVICE),(i, pm) -> new DefaultAppProvider(() -> context.getSystemService(RoleManager.class),() -> LocalServices.getService(UserManagerInternal.class)),//用于存储屏幕的相关信息(i, pm) -> new DisplayMetrics(),(i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(),pm.mCacheDir,pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */,(i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), null,pm.mPackageParserCallback) /* scanningPackageParserProducer */,(i, pm) -> new PackageParser2(pm.mSeparateProcesses, i.getDisplayMetrics(), null,pm.mPackageParserCallback) /* preparingPackageParserProducer */,// Prepare a supplier of package parser for the staging manager to parse apex file
....if (Build.VERSION.SDK_INT <= 0) {Slog.w(TAG, "**** ro.build.version.sdk not set!");}//初始化PMS[见3.1]PackageManagerService m = new PackageManagerService(injector, factoryTest,PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL);t.traceEnd(); // "create package manager".....injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,selinuxChangeListener);injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_R_CHANGES,selinuxChangeListener);m.installAllowlistedSystemPackages();IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();//向ServiceManager注册服务ServiceManager.addService("package", iPackageManager);final PackageManagerNative pmn = new PackageManagerNative(m);ServiceManager.addService("package_native", pmn);return m;}

3.2 PackageManagerService()

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

PMS_START阶段

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

PMS_SYSTEM_SCAN_START阶段

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

PMS_DATA_SCAN_START阶段

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

PMS_SCAN_END阶段

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

PMS_READY阶段

  • 创建服务PackageInstallerService。

3.2.1 BOOT_PROGRESS_PMS_START

    public PackageManagerService(PackageManagerServiceInjector injector, boolean factoryTest,final String partitionsFingerprint, final boolean isEngBuild,final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {// 存储构建和版本信息mIsEngBuild = isEngBuild;  // 是否为工程版构建mIsUserDebugBuild = isUserDebugBuild;  // 是否为用户调试版本mSdkVersion = sdkVersion;  // 系统的 SDK 版本mIncrementalVersion = incrementalVersion;  // 增量构建版本// 通过 injector 注入依赖mInjector = injector;mInjector.getSystemWrapper().disablePackageCaches();final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",Trace.TRACE_TAG_PACKAGE_MANAGER);mPendingBroadcasts = new PendingPackageBroadcasts();// 启动 injector 的引导程序mInjector.bootstrap(this);mLock = injector.getLock();mPackageStateWriteLock = mLock;mInstallLock = injector.getInstallLock();LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);//第一阶段 BOOT_PROGRESS_PMS_STARTEventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,SystemClock.uptimeMillis());// 初始化上下文和其他服务mContext = injector.getContext();mFactoryTest = factoryTest;//用于存储屏幕的相关信息mMetrics = injector.getDisplayMetrics();//Installer对象mInstaller = injector.getInstaller();mEnableFreeCacheV2 = SystemProperties.getBoolean("fw.free_cache_v2", true);// Create sub-components that provide services / data. Order here is important.t.traceBegin("createSubComponents");// Expose private service for system components to use.LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());LocalManagerRegistry.addManager(PackageManagerLocal.class,new PackageManagerLocalImpl(this));LocalServices.addService(TestUtilityService.class, this);mTestUtilityService = LocalServices.getService(TestUtilityService.class);// 初始化用户管理和组件解析器mUserManager = injector.getUserManagerService();mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager);mComponentResolver = injector.getComponentResolver();mPermissionManager = injector.getPermissionManagerServiceInternal();//Android的全局管理者,用于协助PMS保存所有的安装包信息;[见3.3]mSettings = injector.getSettings();mIncrementalManager = mInjector.getIncrementalManager();mDefaultAppProvider = mInjector.getDefaultAppProvider();mLegacyPermissionManager = mInjector.getLegacyPermissionManagerInternal();PlatformCompat platformCompat = mInjector.getCompatibility();mPackageParserCallback = new PackageParser2.Callback() {@Overridepublic boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {return platformCompat.isChangeEnabled(changeId, appInfo);}@Overridepublic boolean hasFeature(String feature) {return PackageManagerService.this.hasSystemFeature(feature, 0);}};// CHECKSTYLE:ON IndentationCheckt.traceEnd();// 添加共享用户,如两个App的之间的数据是不共享的,如果它们有了共同的sharedUserId,就可以运行在同一个进程中共享数据。t.traceBegin("addSharedUsers");mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.log", LOG_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.se", SE_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);mSettings.addSharedUserLPw("android.uid.uwb", UWB_UID,ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);t.traceEnd();// 获取分离进程的系统属性String separateProcesses = SystemProperties.get("debug.separate_processes");if (separateProcesses != null && separateProcesses.length() > 0) {if ("*".equals(separateProcesses)) {mDefParseFlags = ParsingPackageUtils.PARSE_IGNORE_PROCESSES;mSeparateProcesses = null;Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");} else {mDefParseFlags = 0;mSeparateProcesses = separateProcesses.split(",");Slog.w(TAG, "Running with debug.separate_processes: "+ separateProcesses);}} else {mDefParseFlags = 0;mSeparateProcesses = null;}// 初始化 Dex 优化器和管理器mPackageDexOptimizer = injector.getPackageDexOptimizer();//Dex优化工具类mDexManager = injector.getDexManager();mDynamicCodeLogger = injector.getDynamicCodeLogger();//后台DexOpt服务mBackgroundDexOptService = injector.getBackgroundDexOptService();mArtManagerService = injector.getArtManagerService();mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper());mViewCompiler = injector.getViewCompiler();mSharedLibraries = mInjector.getSharedLibrariesImpl();mBackgroundHandler = injector.getBackgroundHandler();mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);t.traceBegin("get system config");SystemConfig systemConfig = injector.getSystemConfig();mAvailableFeatures = systemConfig.getAvailableFeatures();t.traceEnd();mProtectedPackages = new ProtectedPackages(mContext);// 初始化 APEX 和应用过滤器mApexManager = injector.getApexManager();mAppsFilter = mInjector.getAppsFilter();mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,mInjector.getUserManagerInternal(), new DeletePackageHelper(this));mChangedPackagesTracker = new ChangedPackagesTracker();// 应用安装目录mAppInstallDir = new File(Environment.getDataDirectory(), "app");mDomainVerificationConnection = new DomainVerificationConnection(this);mDomainVerificationManager = injector.getDomainVerificationManagerInternal();mDomainVerificationManager.setConnection(mDomainVerificationConnection);// 初始化各类HelpermBroadcastHelper = new BroadcastHelper(mInjector);mAppDataHelper = new AppDataHelper(this);mInstallPackageHelper = new InstallPackageHelper(this, mAppDataHelper);mRemovePackageHelper = new RemovePackageHelper(this, mAppDataHelper);mDeletePackageHelper = new DeletePackageHelper(this, mRemovePackageHelper,mAppDataHelper);mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);mPreferredActivityHelper = new PreferredActivityHelper(this);mResolveIntentHelper = new ResolveIntentHelper(mContext, mPreferredActivityHelper,injector.getCompatibility(), mUserManager, mDomainVerificationManager,mUserNeedsBadging, () -> mResolveInfo, () -> mInstantAppInstallerActivity,injector.getBackgroundHandler());mDexOptHelper = new DexOptHelper(this);mSuspendPackageHelper = new SuspendPackageHelper(this, mInjector, mUserManager,mBroadcastHelper, mProtectedPackages);mDistractingPackageHelper = new DistractingPackageHelper(this, mInjector, mBroadcastHelper,mSuspendPackageHelper);mStorageEventHelper = new StorageEventHelper(this, mDeletePackageHelper,mRemovePackageHelper);synchronized (mLock) {// Create the computer as soon as the state objects have been installed.  The// cached computer is the same as the live computer until the end of the// constructor, at which time the invalidation method updates it.mSnapshotStatistics = new SnapshotStatistics();// 初始化快照统计数据sSnapshotPendingVersion.incrementAndGet();mLiveComputer = createLiveComputer();registerObservers(true);// 注册观察者,监听系统状态的变化}Computer computer = mLiveComputer;// CHECKSTYLE:OFF IndentationChecksynchronized (mInstallLock) {// writer// 这里是包管理器服务的核心锁机制,用于在包安装过程中确保线程安全。synchronized (mLock) {mHandler = injector.getHandler();mProcessLoggingHandler = new ProcessLoggingHandler();//将PackageHandler添加到Watchdog的检测集中Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);// 加载共享库的配置ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig= systemConfig.getSharedLibraries();final int builtInLibCount = libConfig.size();for (int i = 0; i < builtInLibCount; i++) {mSharedLibraries.addBuiltInSharedLibraryLPw(libConfig.valueAt(i));}// Now that we have added all the libraries, iterate again to add dependency// information IFF their dependencies are added.// 添加共享库的依赖项long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;for (int i = 0; i < builtInLibCount; i++) {String name = libConfig.keyAt(i);SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);final int dependencyCount = entry.dependencies.length;for (int j = 0; j < dependencyCount; j++) {final SharedLibraryInfo dependency =computer.getSharedLibraryInfo(entry.dependencies[j], undefinedVersion);if (dependency != null) {computer.getSharedLibraryInfo(name, undefinedVersion).addDependency(dependency);}}}// 读取 SELinux 安装策略SELinuxMMAC.readInstallPolicy();t.traceBegin("loadFallbacks");FallbackCategoryProvider.loadFallbacks();t.traceEnd();// 读取用户设置,检查系统是否是首次启动t.traceBegin("read user settings");mFirstBoot = !mSettings.readLPw(computer,mInjector.getUserManagerInternal().getUsers(/* excludePartial= */ true,/* excludeDying= */ false,/* excludePreCreated= */ false));t.traceEnd();// 如果是第一次启动,设置安装程序的第一次启动标志if (mFirstBoot) {t.traceBegin("setFirstBoot: ");try {mInstaller.setFirstBoot();} catch (InstallerException e) {Slog.w(TAG, "Could not set First Boot: ", e);}t.traceEnd();}mPermissionManager.readLegacyPermissionsTEMP(mSettings.mPermissions);mPermissionManager.readLegacyPermissionStateTEMP();if (mFirstBoot) {DexOptHelper.requestCopyPreoptedFiles();}String customResolverActivityName = Resources.getSystem().getString(R.string.config_customResolverActivity);if (!TextUtils.isEmpty(customResolverActivityName)) {mCustomResolverComponentName = ComponentName.unflattenFromString(customResolverActivityName);}long startTime = SystemClock.uptimeMillis();

3.2.2 BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

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

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

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,startTime);final String bootClassPath = System.getenv("BOOTCLASSPATH");final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");if (bootClassPath == null) {Slog.w(TAG, "No BOOTCLASSPATH found!");}if (systemServerClassPath == null) {Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");}final VersionInfo ver = mSettings.getInternalVersion();mIsUpgrade =!partitionsFingerprint.equals(ver.fingerprint);if (mIsUpgrade) {PackageManagerServiceUtils.logCriticalInfo(Log.INFO,"Upgrading from " + ver.fingerprint + " (" + ver.buildFingerprint + ") to "+ PackagePartitions.FINGERPRINT + " (" + Build.FINGERPRINT + ")");}mInitAppsHelper = new InitAppsHelper(this, mApexManager, mInstallPackageHelper,mInjector.getSystemPartitions());// when upgrading from pre-M, promote system app permissions from install to runtimemPromoteSystemApps =mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;final WatchedArrayMap<String, PackageSetting> packageSettings =mSettings.getPackagesLocked();if (isDeviceUpgrading()) {// Save the names of pre-existing packages prior to scanning, so we can determine// which system packages are completely new due to an upgrade.mExistingPackages = new ArraySet<>(packageSettings.size());for (PackageSetting ps : packageSettings.values()) {mExistingPackages.add(ps.getPackageName());}// Triggering {@link com.android.server.pm.crossprofile.// CrossProfileIntentFilterHelper.updateDefaultCrossProfileIntentFilter} to update// {@link  CrossProfileIntentFilter}s between eligible users and their parentt.traceBegin("cross profile intent filter update");mInjector.getCrossProfileIntentFilterHelper().updateDefaultCrossProfileIntentFilter();t.traceEnd();}mCacheDir = PackageManagerServiceUtils.preparePackageParserCache(mIsEngBuild, mIsUserDebugBuild, mIncrementalVersion);mInitialNonStoppedSystemPackages = mInjector.getSystemConfig().getInitialNonStoppedSystemPackages();mShouldStopSystemPackagesByDefault = mContext.getResources().getBoolean(R.bool.config_stopSystemPackagesByDefault);final int[] userIds = mUserManager.getUserIds();//扫描system目录下的apps,[见3.2.2.1]PackageParser2 packageParser = mInjector.getScanningCachingPackageParser();mOverlayConfig = mInitAppsHelper.initSystemApps(packageParser, packageSettings, userIds,startTime);
3.2.2.1 InitAppsHelper.initSystemApps
    public OverlayConfig initSystemApps(PackageParser2 packageParser,WatchedArrayMap<String, PackageSetting> packageSettings,int[] userIds, long startTime) {// Prepare apex package info before scanning APKs, this information is needed when// scanning apk in apex.final List<ApexManager.ScanResult> apexScanResults = scanApexPackagesTraced(packageParser);mApexManager.notifyScanResult(apexScanResults);扫描system各个目录下的apps[见3.2.2.2]scanSystemDirs(packageParser, mExecutorService);// Parse overlay configuration files to set default enable state, mutability, and// priority of system overlays.final ArrayMap<String, File> apkInApexPreInstalledPaths = new ArrayMap<>();for (ApexManager.ActiveApexInfo apexInfo : mApexManager.getActiveApexInfos()) {for (String packageName : mApexManager.getApksInApex(apexInfo.apexModuleName)) {apkInApexPreInstalledPaths.put(packageName, apexInfo.preInstalledApexPath);}}final OverlayConfig overlayConfig = OverlayConfig.initializeSystemInstance(consumer -> mPm.forEachPackageState(mPm.snapshotComputer(),packageState -> {var pkg = packageState.getPkg();if (pkg != null) {consumer.accept(pkg, packageState.isSystem(),apkInApexPreInstalledPaths.get(pkg.getPackageName()));}}));// do this first before mucking with mPackages for the "expecting better" caseupdateStubSystemAppsList(mStubSystemApps);mInstallPackageHelper.prepareSystemPackageCleanUp(packageSettings,mPossiblyDeletedUpdatedSystemApps, mExpectingBetter, userIds);[见3.2.2.3]统计扫描多少个应用和耗时logSystemAppsScanningTime(startTime);return overlayConfig;}
3.2.2.2 InitAppsHelper.scanSystemDirs
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})private void scanSystemDirs(PackageParser2 packageParser, ExecutorService executorService) {File frameworkDir = new File(Environment.getRootDirectory(), "framework");// Collect vendor/product/system_ext overlay packages. (Do this before scanning// any apps.)// For security and version matching reason, only consider overlay packages if they// reside in the right directory.for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {final ScanPartition partition = mDirsToScanAsSystem.get(i);if (partition.getOverlayFolder() == null) {continue;}//扫描/vendor/overlay目录下的文件scanDirTracedLI(partition.getOverlayFolder(),mSystemParseFlags, mSystemScanFlags | partition.scanFlag,packageParser, executorService, partition.apexInfo);}//扫描/system/framework 目录下的文件scanDirTracedLI(frameworkDir,mSystemParseFlags, mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,packageParser, executorService, null);if (!mPm.mPackages.containsKey("android")) {throw new IllegalStateException("Failed to load frameworks package; check log for warnings");}for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {final ScanPartition partition = mDirsToScanAsSystem.get(i);if (partition.getPrivAppFolder() != null) {//扫描 /system/priv-app 目录下的文件scanDirTracedLI(partition.getPrivAppFolder(),mSystemParseFlags,mSystemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag,packageParser, executorService, partition.apexInfo);}scanDirTracedLI(partition.getAppFolder(),mSystemParseFlags, mSystemScanFlags | partition.scanFlag,packageParser, executorService, partition.apexInfo);}}
3.2.2.3 logSystemAppsScanningTime
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})private void logSystemAppsScanningTime(long startTime) {mCachedSystemApps = PackageCacher.sCachedPackageReadCount.get();// Remove any shared userIDs that have no associated packagesmPm.mSettings.pruneSharedUsersLPw();mSystemScanTime = SystemClock.uptimeMillis() - startTime;mSystemPackagesCount = mPm.mPackages.size();//统计扫描多少个system目录,平均耗时多少,可以在even log中查找Slog.i(TAG, "Finished scanning system apps. Time: " + mSystemScanTime+ " ms, packageCount: " + mSystemPackagesCount+ " , timePerPackage: "+ (mSystemPackagesCount == 0 ? 0 : mSystemScanTime / mSystemPackagesCount)+ " , cached: " + mCachedSystemApps);if (mIsDeviceUpgrading && mSystemPackagesCount > 0) {//CHECKSTYLE:OFF IndentationCheckFrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,mSystemScanTime / mSystemPackagesCount);//CHECKSTYLE:ON IndentationCheck}}

3.2.3 BOOT_PROGRESS_PMS_DATA_SCAN_START

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

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

            //该方法为扫描data目录下的apps,[见3.2.3.1]mInitAppsHelper.initNonSystemApps(packageParser, userIds, startTime);packageParser.close();mRequiredVerifierPackages = getRequiredButNotReallyRequiredVerifiersLPr(computer);mRequiredInstallerPackage = getRequiredInstallerLPr(computer);mRequiredUninstallerPackage = getRequiredUninstallerLPr(computer);// PermissionController hosts default permission granting and role management, so it's a// critical part of the core system.mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer);// Resolve the storage manager.mStorageManagerPackage = getStorageManagerPackageName(computer);// Resolve protected action filters. Only the setup wizard is allowed to// have a high priority filter for these actions.mSetupWizardPackage = getSetupWizardPackageNameImpl(computer);mComponentResolver.fixProtectedFilterPriorities(mSetupWizardPackage);mDefaultTextClassifierPackage = ensureSystemPackageName(computer,mContext.getString(R.string.config_servicesExtensionPackage));mSystemTextClassifierPackageName = ensureSystemPackageName(computer,mContext.getString(R.string.config_defaultTextClassifierPackage));mConfiguratorPackage = ensureSystemPackageName(computer,mContext.getString(R.string.config_deviceConfiguratorPackageName));mAppPredictionServicePackage = ensureSystemPackageName(computer,getPackageFromComponentString(R.string.config_defaultAppPredictionService));mIncidentReportApproverPackage = ensureSystemPackageName(computer,mContext.getString(R.string.config_incidentReportApproverPackage));mRetailDemoPackage = getRetailDemoPackageName();mOverlayConfigSignaturePackage = ensureSystemPackageName(computer,mInjector.getSystemConfig().getOverlayConfigSignaturePackage());mRecentsPackage = ensureSystemPackageName(computer,getPackageFromComponentString(R.string.config_recentsComponentName));mAmbientContextDetectionPackage = ensureSystemPackageName(computer,getPackageFromComponentString(R.string.config_defaultAmbientContextDetectionService));mWearableSensingPackage = ensureSystemPackageName(computer,getPackageFromComponentString(R.string.config_defaultWearableSensingService));// Now that we know all of the shared libraries, update all clients to have// the correct library paths.mSharedLibraries.updateAllSharedLibrariesLPw(null, null, Collections.unmodifiableMap(mPackages));for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {// NOTE: We ignore potential failures here during a system scan (like// the rest of the commands above) because there's precious little we// can do about it. A settings error is reported, though.final List<String> changedAbiCodePath =ScanPackageUtils.applyAdjustedAbiToSharedUser(setting,null /*scannedPackage*/,mInjector.getAbiHelper().getAdjustedAbiForSharedUser(setting.getPackageStates(), null /*scannedPackage*/));if (!useArtService() && // Skip for ART Service since it has its own dex file GC.changedAbiCodePath != null && changedAbiCodePath.size() > 0) {for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {final String codePathString = changedAbiCodePath.get(i);try {mInstaller.rmdex(codePathString,getDexCodeInstructionSet(getPreferredInstructionSet()));} catch (LegacyDexoptDisabledException e) {throw new RuntimeException(e);} catch (InstallerException ignored) {}}}// Adjust seInfo to ensure apps which share a sharedUserId are placed in the same// SELinux domain.setting.fixSeInfoLocked();setting.updateProcesses();}// Now that we know all the packages we are keeping,// read and update their last usage times.mPackageUsage.read(packageSettings);mCompilerStats.read();
3.2.3.1InitAppsHelper.initNonSystemApps
    public void initNonSystemApps(PackageParser2 packageParser, @NonNull int[] userIds,long startTime) {//扫描data app日志节点,BOOT_PROGRESS_PMS_DATA_SCAN_STARTEventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,SystemClock.uptimeMillis());if ((mScanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == SCAN_FIRST_BOOT_OR_UPGRADE) {fixInstalledAppDirMode();}//扫描/data/app目录下的文件  scanDirTracedLI(mPm.getAppInstallDir(), 0,mScanFlags | SCAN_REQUIRE_KNOWN, packageParser, mExecutorService, null);List<Runnable> unfinishedTasks = mExecutorService.shutdownNow();if (!unfinishedTasks.isEmpty()) {throw new IllegalStateException("Not all tasks finished before calling close: "+ unfinishedTasks);}fixSystemPackages(userIds);[见3.2.3.2]logNonSystemAppScanningTime(startTime);mExpectingBetter.clear();mPm.mSettings.pruneRenamedPackagesLPw();}
3.2.3.2 InitAppsHelper.logNonSystemAppScanningTime
    @GuardedBy({"mPm.mInstallLock", "mPm.mLock"})private void logNonSystemAppScanningTime(long startTime) {final int cachedNonSystemApps = PackageCacher.sCachedPackageReadCount.get()- mCachedSystemApps;final long dataScanTime = SystemClock.uptimeMillis() - mSystemScanTime - startTime;final int dataPackagesCount = mPm.mPackages.size() - mSystemPackagesCount;//统计总共扫描了多少个non-system apps,平均耗时多少,可以在even log里查看Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime+ " ms, packageCount: " + dataPackagesCount+ " , timePerPackage: "+ (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)+ " , cached: " + cachedNonSystemApps);if (mIsDeviceUpgrading && dataPackagesCount > 0) {//CHECKSTYLE:OFF IndentationCheckFrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,dataScanTime / dataPackagesCount);//CHECKSTYLE:OFF IndentationCheck}}

3.2.4 BOOT_PROGRESS_PMS_SCAN_END

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,SystemClock.uptimeMillis());Slog.i(TAG, "Time to scan packages: "+ ((SystemClock.uptimeMillis() - startTime) / 1000f)+ " seconds");// If the partitions fingerprint has changed since the last time we booted,// we need to re-grant app permission to catch any new ones that// appear.  This is really a hack, and means that apps can in some// cases get permissions that the user didn't initially explicitly// allow...  it would be nice to have some better way to handle// this situation.if (mIsUpgrade) {Slog.i(TAG, "Partitions fingerprint changed from " + ver.fingerprint + " to "+ PackagePartitions.FINGERPRINT+ "; regranting permissions for internal storage");}mPermissionManager.onStorageVolumeMounted(StorageManager.UUID_PRIVATE_INTERNAL, mIsUpgrade);ver.sdkVersion = mSdkVersion;// If this is the first boot or an update from pre-M, then we need to initialize the// default preferred apps across all defined users.//如果是第一次启动或者是Android M升级后的第一次启动,需要初始化所有用户定义的默认首选Appif (mPromoteSystemApps || mFirstBoot) {for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {mSettings.applyDefaultPreferredAppsLPw(user.id);}}// If this is first boot after an OTA, then we need to clear code cache directories.// Note that we do *not* clear the application profiles. These remain valid// across OTAs and are used to drive profile verification (post OTA) and// profile compilation (without waiting to collect a fresh set of profiles).//OTA后的第一次启动,会清除代码缓存目录。if (mIsUpgrade) {Slog.i(TAG, "Build fingerprint changed; clearing code caches");for (int i = 0; i < packageSettings.size(); i++) {final PackageSetting ps = packageSettings.valueAt(i);if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.getVolumeUuid())) {// No apps are running this early, so no need to freezemAppDataHelper.clearAppDataLIF(ps.getPkg(), UserHandle.USER_ALL,FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL| Installer.FLAG_CLEAR_CODE_CACHE_ONLY| Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);}}ver.buildFingerprint = Build.FINGERPRINT;ver.fingerprint = PackagePartitions.FINGERPRINT;}// Defer the app data fixup until we are done with app data clearing above.mPrepareAppDataFuture = mAppDataHelper.fixAppsDataOnBoot();// Legacy existing (installed before Q) non-system apps to hide// their icons in launcher.if (mIsPreQUpgrade) {Slog.i(TAG, "Allowlisting all existing apps to hide their icons");int size = packageSettings.size();for (int i = 0; i < size; i++) {final PackageSetting ps = packageSettings.valueAt(i);if ((ps.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) {continue;}ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,UserHandle.USER_SYSTEM);}}// clear only after permissions and other defaults have been updatedmPromoteSystemApps = false;// All the changes are done during package scanning.ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;// can downgrade to readert.traceBegin("write settings");// 把Settings的内容保存到packages.xml中writeSettingsLPrTEMP();t.traceEnd();

3.2.5 BOOT_PROGRESS_PMS_READY

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,SystemClock.uptimeMillis());.....//PackageInstallerService是用于管理安装会话的服务,它会为每次安装过程分配一个SessionIdmInstallerService = mInjector.getPackageInstallerService();final ComponentName instantAppResolverComponent = getInstantAppResolver(computer);if (instantAppResolverComponent != null) {if (DEBUG_INSTANT) {Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);}mInstantAppResolverConnection =mInjector.getInstantAppResolverConnection(instantAppResolverComponent);mInstantAppResolverSettingsComponent =getInstantAppResolverSettingsLPr(computer,instantAppResolverComponent);} else {mInstantAppResolverConnection = null;mInstantAppResolverSettingsComponent = null;}updateInstantAppInstallerLocked(null);// Read and update the usage of dex files.// Do this at the end of PM init so that all the packages have their// data directory reconciled.// At this point we know the code paths of the packages, so we can validate// the disk file and build the internal cache.// The usage file is expected to be small so loading and verifying it// should take a fairly small time compare to the other activities (e.g. package// scanning).final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();for (int userId : userIds) {userPackages.put(userId, computer.getInstalledPackages(/*flags*/ 0, userId).getList());}mDexManager.load(userPackages);mDynamicCodeLogger.load(userPackages);if (mIsUpgrade) {FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,SystemClock.uptimeMillis() - startTime);}//如果这是首次启动或OTA后的首次启动,则将文件路径设置为预加载包的应用元数据文件if (mFirstBoot || isDeviceUpgrading()) {ArrayMap<String, String> paths = systemConfig.getAppMetadataFilePaths();for (Map.Entry<String, String> entry : paths.entrySet()) {String pkgName = entry.getKey();String path = entry.getValue();File file = new File(path);if (!file.exists()) {path = null;}PackageSetting disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(pkgName);if (disabledPkgSetting == null) {PackageSetting pkgSetting = mSettings.getPackageLPr(pkgName);if (pkgSetting != null) {pkgSetting.setAppMetadataFilePath(path);} else {Slog.w(TAG, "Cannot set app metadata file for nonexistent package "+ pkgName);}} else {disabledPkgSetting.setAppMetadataFilePath(path);}}}
....}
http://www.dtcms.com/a/357009.html

相关文章:

  • Linux-搭建DNS服务器
  • 计算机三级嵌入式填空题——真题库(24)原题附答案速记
  • CMake xcode编译器属性设置技巧
  • JavaScript 数组核心操作实战:最值获取与排序实现(从基础到优化)
  • 线程安全及死锁问题
  • Linux之Docker虚拟化技术(二)
  • Python结构化模式匹配:解析器的革命性升级
  • 大模型 “轻量化” 之战:从千亿参数到端侧部署,AI 如何走进消费电子?
  • 【ACP】2025-最新-疑难题解析-11
  • 机器视觉opencv教程(二):二值化、自适应二值化
  • Partner 类开发:会议参与者可视化控件
  • 经典扫雷游戏实现:从零构建HTML5扫雷游戏
  • 科技大会用了煽情BGM
  • 【技术分享】系统崩溃后产生的CHK文件如何恢复?完整图文教程(附工具推荐)
  • 论文阅读:GOAT: GO to Any Thing
  • 智慧工地系统:基于Java微服务与信创国产化的建筑施工数字化管理平台
  • 开关电源设计“反馈回路”部分器件分析
  • Nginx的主要配置文件nginx.conf详细解读——及其不间断重启nginx服务等操作
  • 从Cloudflare到EdgeOne:我的个人站点加速之旅与性能对比实测
  • LeetCode Hot 100 Python (11~20)
  • 微服务入门指南(一):从单体架构到服务注册发现
  • 将自己的jar包发布到maven中央仓库(2025-08-29)
  • 【Web安全】文件上传下载安全测试的全面剖析与实践指南
  • 如何在实际应用中选择Blaze或Apache Gluten?
  • 深入解析PCIe 6.0拓扑架构:从根复合体到端点的完整连接体系
  • 【国内电子数据取证厂商龙信科技】ES 数据库重建
  • shell命令扩展
  • Qt类-扩充_xiaozuo
  • ArcGIS Pro中 Nodata和nan 黑边的处理
  • 沃尔玛AI系统Wally深度拆解:零售业库存周转提速18%,动态定价争议与员工转型成热议点