Android13 PMS是如何发动的

往常运用安卓实践便是在运用各种app,而下载的app实践是一个apk文件。这个apk文件的装置就交给了PackageManagerService来完成。PackageManagerService的发动也是在SystemServer中。这个过程比较长需求长一点的时间来理。

SystemServer.startBootstrapServices

//frameworks/base/services/java/com/android/server/SystemServer.java   
    Installer installer = mSystemServiceManager.startService(Installer.class);  
        IPackageManager iPackageManager;
    t.traceBegin("StartPackageManagerService");
    try {
      Watchdog.getInstance().pauseWatchingCurrentThread("packagemanagermain");
      Pair<PackageManagerService, IPackageManager> pmsPair = PackageManagerService.main(
          mSystemContext, installer, domainVerificationService,
          mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
      mPackageManagerService = pmsPair.first;
      iPackageManager = pmsPair.second;
     } finally {
      Watchdog.getInstance().resumeWatchingCurrentThread("packagemanagermain");
     }
  mFirstBoot = mPackageManagerService.isFirstBoot();

PackageManagerService的main办法初始化了PackageManagerService和IPackageManager,其间传入的installer需求特别重视一下,很关键的变量。

//frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static Pair<PackageManagerService, IPackageManager> main(Context context,
      Installer installer, @NonNull DomainVerificationService domainVerificationService,
      boolean factoryTest, boolean onlyCore) {
    // 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,并发动
    HandlerThread backgroundThread = new ServiceThread("PackageManagerBg",
        Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
    backgroundThread.start();
    Handler backgroundHandler = new Handler(backgroundThread.getLooper());
//真实的操作和相关的方针都放到了PackageManagerServiceInjector中。
    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, onlyCore),
            lock),
         (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(),
         (i, pm) -> new PackageDexOptimizer(i.getInstaller(), i.getInstallLock(),
            i.getContext(), "*dexopt*"),
         (i, pm) -> new DexManager(i.getContext(), i.getPackageDexOptimizer(),
            i.getInstaller(), i.getInstallLock()),
         (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, pm.mOnlyCore,
            i.getDisplayMetrics(), pm.mCacheDir,
            pm.mPackageParserCallback) /* scanningCachingPackageParserProducer */,
         (i, pm) -> new PackageParser2(pm.mSeparateProcesses, pm.mOnlyCore,
            i.getDisplayMetrics(), null,
            pm.mPackageParserCallback) /* scanningPackageParserProducer */,
         (i, pm) -> new PackageParser2(pm.mSeparateProcesses, false, i.getDisplayMetrics(),
            null, pm.mPackageParserCallback) /* preparingPackageParserProducer */,
        // Prepare a supplier of package parser for the staging manager to parse apex file
        // during the staging installation.
         (i, pm) -> new PackageInstallerService(
            i.getContext(), pm, i::getScanningPackageParser),
         (i, pm, cn) -> new InstantAppResolverConnection(
            i.getContext(), cn, Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE),
         (i, pm) -> new ModuleInfoProvider(i.getContext()),
         (i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
         (i, pm) -> domainVerificationService,
         (i, pm) -> {
          HandlerThread thread = new ServiceThread(TAG,
              Process.THREAD_PRIORITY_DEFAULT, true /*allowIo*/);
          thread.start();
          return new PackageHandler(thread.getLooper(), pm);
         },
        new DefaultSystemWrapper(),
        LocalServices::getService,
        context::getSystemService,
         (i, pm) -> new BackgroundDexOptService(i.getContext(), i.getDexManager(), pm),
         (i, pm) -> IBackupManager.Stub.asInterface(ServiceManager.getService(
            Context.BACKUP_SERVICE)),
         (i, pm) -> new SharedLibrariesImpl(pm, i));
​
    if (Build.VERSION.SDK_INT <= 0) {
      Slog.w(TAG, "**** ro.build.version.sdk not set!");
     }
  //创立一个PackageManagerService实例
    PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest,
        PackagePartitions.FINGERPRINT, Build.IS_ENG, Build.IS_USERDEBUG,
        Build.VERSION.SDK_INT, Build.VERSION.INCREMENTAL);
    t.traceEnd(); // "create package manager"
.......
      //依据用户类型装置或卸载体系运用装置包
    m.installAllowlistedSystemPackages();
       //创立IPackageManager并增加到ServiceManager中,客户端交互
    IPackageManagerImpl iPackageManager = m.new IPackageManagerImpl();
    ServiceManager.addService("package", iPackageManager);
     //创立native的PackageManager,注册到ServiceManager中
    final PackageManagerNative pmn = new PackageManagerNative(m);
    ServiceManager.addService("package_native", pmn);
    LocalManagerRegistry.addManager(PackageManagerLocal.class, m.new PackageManagerLocalImpl());
   //回来PackageManagerService和IPackageManager
    return Pair.create(m, iPackageManager);
   }

在main办法中重要的就几件事

  1. 创立PackageManagerServiceInjector
  2. 创立PackageManagerService
  3. 创立iPackageManager增加到ServiceManager中
  4. 创立PackageManagerNative增加到ServiceManager中

PackageManagerServiceInjector便是很简单的做了一层封装,把所有相关的方针都初始化都保存了起来。接下来看PackageManagerService,这个初始化函数十分长,所以分几段来看,可以依据log分为BOOT_PROGRESS_PMS_START,BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,BOOT_PROGRESS_PMS_SCAN_END,BOOT_PROGRESS_PMS_READY,这几个阶段

BOOT_PROGRESS_PMS_START

 public PackageManagerService(PackageManagerServiceInjector injector, boolean onlyCore,
      boolean factoryTest, final String buildFingerprint, final boolean isEngBuild,
      final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
    mIsEngBuild = isEngBuild;
    mIsUserDebugBuild = isUserDebugBuild;
    mSdkVersion = sdkVersion;
    mIncrementalVersion = incrementalVersion;
    mInjector = injector;
    mInjector.getSystemWrapper().disablePackageCaches();
​
    final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
        Trace.TRACE_TAG_PACKAGE_MANAGER);
    mPendingBroadcasts = new PendingPackageBroadcasts();
    mInjector.bootstrap(this);
    mLock = injector.getLock();
    mPackageStateWriteLock = mLock;
    mInstallLock = injector.getInstallLock();//重要的lock
    LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
        SystemClock.uptimeMillis());//BOOT_PROGRESS_PMS_START阶段mContext = injector.getContext();
    mFactoryTest = factoryTest;
    mOnlyCore = onlyCore;//是否只发动中心业务
    mMetrics = injector.getDisplayMetrics();
    mInstaller = injector.getInstaller();//获取installer
    mEnableFreeCacheV2 = SystemProperties.getBoolean("fw.free_cache_v2", true);
    // 将当前PackageManagerInternal注册到了LocalServices中
    LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
    LocalServices.addService(TestUtilityService.class, this);
    mTestUtilityService = LocalServices.getService(TestUtilityService.class);
      //......中间都是获取PackageManagerServiceInjector的一些成员变量
    // 创立了Settings类了,mSettings办理着app的装置信息,这儿增加了6个app的包名到同享用户列表,一起设置权限为体系等级的权限uid
       mSettings = injector.getSettings();
    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);
       //dex到odex/oat的转化
      mPackageDexOptimizer = injector.getPackageDexOptimizer();
    mDexManager = injector.getDexManager();
    mBackgroundDexOptService = injector.getBackgroundDexOptService();
       //ART虚拟机办理服务
    mArtManagerService = injector.getArtManagerService();
    mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper());
    mViewCompiler = injector.getViewCompiler();
       //同享库
    mSharedLibraries = mInjector.getSharedLibrariesImpl();
        //获取分辨率
    mContext.getSystemService(DisplayManager.class)
         .getDisplay(Display.DEFAULT_DISPLAY).getMetrics(mMetrics);
​
    t.traceBegin("get system config");
       //获取体系配置
    SystemConfig systemConfig = injector.getSystemConfig();
    mAvailableFeatures = systemConfig.getAvailableFeatures();
    t.traceEnd();
        //约束几个体系app的访问,如launcher
    mProtectedPackages = new ProtectedPackages(mContext);
    mApexManager = injector.getApexManager();
    mAppsFilter = mInjector.getAppsFilter();mInstantAppRegistry = new InstantAppRegistry(mContext, mPermissionManager,
        mInjector.getUserManagerInternal(), new DeletePackageHelper(this));
      //仿制监听包变化的事件,装置卸载等
    mChangedPackagesTracker = new ChangedPackagesTracker();
        //非体系app的途径
    mAppInstallDir = new File(Environment.getDataDirectory(), "app");
     //.....中间初始化了各种操作类
    // CHECKSTYLE:OFF IndentationCheck
    synchronized (mInstallLock) {
    // writer
    synchronized (mLock) {
        //获取装置线程的handler,同样是injector中创立的
      mHandler = injector.getHandler();
      mProcessLoggingHandler = new ProcessLoggingHandler();
      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);
           }
         }
       }
​
      SELinuxMMAC.readInstallPolicy();
​
      t.traceBegin("loadFallbacks");
      FallbackCategoryProvider.loadFallbacks();
      t.traceEnd();
​
      t.traceBegin("read user settings");
     //依据/data/system下的XML判别是不是第一次发动
      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 (!mOnlyCore && mFirstBoot) {
       //假如都不是就仿制dex
        DexOptHelper.requestCopyPreoptedFiles();
       }
​

这儿做的还都是准备工作,获取了需求的一系列方针和途径,比较重要的点便是创立了Settings。

//frameworks/base/services/core/java/com/android/server/pm/Settings.java
Settings(File dataDir, RuntimePermissionsPersistence runtimePermissionsPersistence,
      LegacyPermissionDataProvider permissionDataProvider,
      @NonNull DomainVerificationManagerInternal domainVerificationManager,
      @NonNull Handler handler,
      @NonNull PackageManagerTracedLock lock)  {
​
        ...
     
    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);
    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中保存了装置包信息,packages-stopped.xml标记为抛弃不重视,首要文件便是/data/system/下的packages.xml,packages-backup.xml,packages.list,packages-backup作为备份文件,其他两个文件的作用是

  • packages.xml: PKMS 扫描完方针文件夹后会创立该文件。当体系进行程序装置、卸载和更新等操作时,均会更新该文件。该文件保存了体系中与 package 相关的一些信息。
  • packages.list:描述体系中存在的所有非体系自带的 APK 的信息。当这些程序有变化时,PKMS 就会更新该文件。
//frameworks/base/services/core/java/com/android/server/pm/Settings.java
 boolean readLPw(@NonNull Computer computer, @NonNull List<UserInfo> users) {
    FileInputStream str = null;
    final ArrayMap<String, Long> originalFirstInstallTimes = new ArrayMap<>();
​
    try {
      if (str == null) {
        if (!mSettingsFilename.exists()) {//假如不存在就回来false,也便是第一次创立
          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);
       }
      final TypedXmlPullParser parser = Xml.resolvePullParser(str);
          //...假如存在这些xml文件就经过TypedXmlPullParser解析这些xml文件,保存在Settings中return true;
   }

BOOT_PROGRESS_PMS_SYSTEM_SCAN_START

 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
          startTime);
          //获取bootClassPath和systemServerClassPath下的环境变量
      final String bootClassPath = System.getenv("BOOTCLASSPATH");
      final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
​
      final VersionInfo ver = mSettings.getInternalVersion();
            //判别是否晋级了
      mIsUpgrade =
          !buildFingerprint.equals(ver.fingerprint);
      if (mIsUpgrade) {
        PackageManagerServiceUtils.logCriticalInfo(Log.INFO, "Upgrading from "
            + ver.fingerprint + " to " + PackagePartitions.FINGERPRINT);
       }
        //初始化app的类
      mInitAppsHelper = new InitAppsHelper(this, mApexManager, mInstallPackageHelper,
        mInjector.getSystemPartitions());
​
          //假如是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;
​
      final WatchedArrayMap<String, PackageSetting> packageSettings =
        mSettings.getPackagesLocked();
​
            //扫描之前就存在的体系package的名称,这样就可以确定哪些更新的
      if (isDeviceUpgrading()) {
        mExistingPackages = new ArraySet<>(packageSettings.size());
        for (PackageSetting ps : packageSettings.values()) {
          mExistingPackages.add(ps.getPackageName());
         }
       }
            //获取缓存目录
      mCacheDir = PackageManagerServiceUtils.preparePackageParserCache(
          mIsEngBuild, mIsUserDebugBuild, mIncrementalVersion);
​
      final int[] userIds = mUserManager.getUserIds();
            //获取PackageParser2
      PackageParser2 packageParser = mInjector.getScanningCachingPackageParser();
            //扫描体系app
      mOverlayConfig = mInitAppsHelper.initSystemApps(packageParser, packageSettings, userIds,startTime);
            //体系app以外的app
      mInitAppsHelper.initNonSystemApps(packageParser, userIds, startTime);
      packageParser.close();
​
      // 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.
            //只允许装置导游这个运用具有高等级的action
      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));
​
      // 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.
          //假如晋级导致abi发生了变化,那么就卸载原来api的代码
        final List<String> changedAbiCodePath =
            ScanPackageUtils.applyAdjustedAbiToSharedUser(
                setting, null /*scannedPackage*/,
                mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
                    setting.getPackageStates(), 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) {
             }
           }
         }
        // 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.
          // 读取并更新保存的package的上次运用时间
      mPackageUsage.read(packageSettings);
      mCompilerStats.read();

这儿最重要的便是经过mInitAppsHelper获取了体系apk和其他的apk的信息。

//frameworks/base/services/core/java/com/android/server/pm/InitAppsHelper.java
 public OverlayConfig initSystemApps(PackageParser2 packageParser,
      WatchedArrayMap<String, PackageSetting> packageSettings,
      int[] userIds, long startTime) {
       ...
     
    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);
       }
     }
       ....
   
    return overlayConfig;
   }
private void scanSystemDirs(PackageParser2 packageParser, ExecutorService executorService) {
   ///system/framework途径下
    File frameworkDir = new File(Environment.getRootDirectory(), "framework");
​
    scanDirTracedLI(frameworkDir, null,
        mSystemParseFlags,
        mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,
        packageParser, executorService);
    //....其他体系app途径也相同就不展现了
   }

scanSystemDirs中便是经过scanDirTracedLI扫描各种途径下的apk。

      private void scanDirTracedLI(File scanDir, List<File> frameworkSplits,
      int parseFlags, int scanFlags,
      PackageParser2 packageParser, ExecutorService executorService) {
    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
    try {
      if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
        // when scanning apk in apexes, we want to check the maxSdkVersion
        parseFlags |= PARSE_APK_IN_APEX;
       }
      mInstallPackageHelper.installPackagesFromDir(scanDir, frameworkSplits, parseFlags,
          scanFlags, packageParser, executorService);
     } finally {
      Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }
   }

scanDirTracedLI调用了InstallPackageHelper.installPackagesFromDir来装置

//frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
public void installPackagesFromDir(File scanDir, List<File> frameworkSplits, int parseFlags,
      int scanFlags, PackageParser2 packageParser,
      ExecutorService executorService) {
    final File[] files = scanDir.listFiles();
    
    ParallelPackageParser parallelPackageParser =
        new ParallelPackageParser(packageParser, executorService, frameworkSplits);
​
    // Submit files for parsing in parallel
    int fileCount = 0;
    for (File file : files) {
      final boolean isPackage = (isApkFile(file) || file.isDirectory())
          && !PackageInstallerService.isStageName(file.getName());
      if (!isPackage) {
        // Ignore entries which are not packages
        continue;
       }
      if ((scanFlags & SCAN_DROP_CACHE) != 0) {
        final PackageCacher cacher = new PackageCacher(mPm.getCacheDir());
        Log.w(TAG, "Dropping cache of " + file.getAbsolutePath());
        cacher.cleanCachedResult(file);
       }
      parallelPackageParser.submit(file, parseFlags);
      fileCount++;
     }
​
    // Process results one by one
    for (; fileCount > 0; fileCount--) {
      ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
      Throwable throwable = parseResult.throwable;
      int errorCode = PackageManager.INSTALL_SUCCEEDED;
      String errorMsg = null;
​
      if (throwable == null) {
        // TODO(b/194319951): move lower in the scan chain
        // Static shared libraries have synthetic package names
        if (parseResult.parsedPackage.isStaticSharedLibrary()) {
          PackageManagerService.renameStaticSharedLibraryPackage(
              parseResult.parsedPackage);
         }
        try {
          addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
              null);
         } catch (PackageManagerException e) {
          errorCode = e.error;
          errorMsg = "Failed to scan " + parseResult.scanFile + ": " + e.getMessage();
          Slog.w(TAG, errorMsg);
         }
       } else if (throwable instanceof PackageManagerException) {
        PackageManagerException e = (PackageManagerException) throwable;
        errorCode = e.error;
        errorMsg = "Failed to parse " + parseResult.scanFile + ": " + e.getMessage();
        Slog.w(TAG, errorMsg);
       } else {
        throw new IllegalStateException("Unexpected exception occurred while parsing "
            + parseResult.scanFile, throwable);
       }
​
      ...
      
     }
   }

经过ParallelPackageParser.submit提交装置使命,ParallelPackageParser.submit.take获取使命结果。

//frameworks/base/services/core/java/com/android/server/pm/ParallelPackageParser.java
public void submit(File scanFile, int parseFlags) {
    mExecutorService.submit(() -> {
      ParseResult pr = new ParseResult();
      Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parallel parsePackage [" + scanFile + "]");
      try {
        pr.scanFile = scanFile;
        pr.parsedPackage = parsePackage(scanFile, parseFlags);
       } catch (Throwable e) {
        pr.throwable = e;
       } finally {
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
       }
      try {
        mQueue.put(pr);
       } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        mInterruptedInThread = Thread.currentThread().getName();
       }
     });
   }
 public ParseResult take() {
    try {
      if (mInterruptedInThread != null) {
        throw new InterruptedException("Interrupted in " + mInterruptedInThread);
       }
      return mQueue.take();
     } catch (InterruptedException e) {
      // We cannot recover from interrupt here
      Thread.currentThread().interrupt();
      throw new IllegalStateException(e);
     }
   }

submit和take便是经过一个 BlockingQueue完成解析和获取使命。解析是parsePackage来完成的。

  protected ParsedPackage parsePackage(File scanFile, int parseFlags)
      throws PackageManagerException {
    return mPackageParser.parsePackage(scanFile, parseFlags, true, mFrameworkSplits);
   }
​

这儿的mPackageParser便是前面的参数PackageParser2

//frameworks/base/services/core/java/com/android/server/pm/parsing/PackageParser2.java
public ParsedPackage parsePackage(File packageFile, int flags, boolean useCaches,
      List<File> frameworkSplits) throws PackageManagerException {
  //判别缓存是否存在,存在就直接运用缓存
    if (useCaches && mCacher != null) {
      ParsedPackage parsed = mCacher.getCachedResult(packageFile, flags);
      if (parsed != null) {
        return parsed;
       }
     }
​
    long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
    ParseInput input = mSharedResult.get().reset();
     //解析apk文件
    ParseResult<ParsingPackage> result = parsingUtils.parsePackage(input, packageFile, flags,
        frameworkSplits);
    ParsedPackage parsed = (ParsedPackage) result.getResult().hideAsParsed();
    long cacheTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
  //增加到缓存
    if (mCacher != null) {
      mCacher.cacheResult(packageFile, flags, parsed);
     }
    return parsed;
   }

又到了parsingUtils.parsePackage

//frameworks/base/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java
 public ParseResult<ParsingPackage> parsePackage(ParseInput input, File packageFile, int flags,
      List<File> frameworkSplits) {
    if (((flags & PARSE_FRAMEWORK_RES_SPLITS) != 0)
        && frameworkSplits.size() > 0
        && packageFile.getAbsolutePath().endsWith("/framework-res.apk")) {
      return parseClusterPackage(input, packageFile, frameworkSplits, flags);
     } else if (packageFile.isDirectory()) {//是一个目录就运用parseClusterPackage
      return parseClusterPackage(input, packageFile, /* frameworkSplits= */null, flags);
     } else {//是单独一个apk就运用parseMonolithicPackage
      return parseMonolithicPackage(input, packageFile, flags);
     }
   }

总算到了解析看下简单的parseMonolithicPackage

 private ParseResult<ParsingPackage> parseMonolithicPackage(ParseInput input, File apkFile,
      int flags) {
  //先经过parseMonolithicPackageLite开始解析这个apk,这儿会解析出minsdkversion,versionCode 这些基本信息
    final ParseResult<PackageLite> liteResult =
        ApkLiteParseUtils.parseMonolithicPackageLite(input, apkFile, flags);
    if (liteResult.isError()) {
      return input.error(liteResult);
     }
​
    final PackageLite lite = liteResult.getResult();
    if (mOnlyCoreApps && !lite.isCoreApp()) {
      return input.error(INSTALL_PARSE_FAILED_ONLY_COREAPP_ALLOWED,
          "Not a coreApp: " + apkFile);
     }
        //AssetManager和文件信息的封装,用于后边运用AssetManager加载资源
    final SplitAssetLoader assetLoader = new DefaultSplitAssetLoader(lite, flags);
    try {
     //真实解析apk
      final ParseResult<ParsingPackage> result = parseBaseApk(input,
          apkFile,
          apkFile.getCanonicalPath(),
          assetLoader, flags);
      if (result.isError()) {
        return input.error(result);
       }
​
      return input.success(result.getResult()
           .setUse32BitAbi(lite.isUse32bitAbi()));
     } catch (IOException e) {
      return input.error(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
          "Failed to get path: " + apkFile, e);
     } finally {
      IoUtils.closeQuietly(assetLoader);
     }
   }

parseMonolithicPackage先经过parseMonolithicPackageLite来开始处理apk,获取PackageLite。然后调用了parseBaseApk详细处理apk。

private ParseResult<ParsingPackage> parseBaseApk(ParseInput input, File apkFile,
      String codePath, SplitAssetLoader assetLoader, int flags) {
 //获取apk文件
    final String apkPath = apkFile.getAbsolutePath();
    final AssetManager assets;
    try {
      assets = assetLoader.getBaseAssetManager();
     } catch (IllegalArgumentException e) {
      return input.error(e.getCause() instanceof IOException ? INSTALL_FAILED_INVALID_APK
           : INSTALL_PARSE_FAILED_NOT_APK, e.getMessage(), e);
     }
    final int cookie = assets.findCookieForPath(apkPath);
      //创立xml解析方针
    try (XmlResourceParser parser = assets.openXmlResourceParser(cookie,
        ANDROID_MANIFEST_FILENAME)) {
      final Resources res = new Resources(assets, mDisplayMetrics, null);
​
      ParseResult<ParsingPackage> result = parseBaseApk(input, apkPath, codePath, res,
          parser, flags);
​
      final ParsingPackage pkg = result.getResult();
     
      ....
​
      return input.success(pkg);
     } catch (Exception e) {
      return input.error(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
          "Failed to read manifest from " + apkPath, e);
     }
   }
private ParseResult<ParsingPackage> parseBaseApk(ParseInput input, String apkPath,
      String codePath, Resources res, XmlResourceParser parser, int flags)
      throws XmlPullParserException, IOException {
            ...
       
      final ParseResult<ParsingPackage> result =
          parseBaseApkTags(input, pkg, manifestArray, res, parser, flags);
          
            ...
      
   }
​

层层调用到了parseBaseApkTags来解析androidmanifest中的各个标签。

 private ParseResult<ParsingPackage> parseBaseApkTags(ParseInput input, ParsingPackage pkg,
      TypedArray sa, Resources res, XmlResourceParser parser, int flags)
      throws XmlPullParserException, IOException {
         .....
      
    boolean foundApp = false;
    final int depth = parser.getDepth();
    int type;
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
        && (type != XmlPullParser.END_TAG
        || parser.getDepth() > depth)) {
      if (type != XmlPullParser.START_TAG) {
        continue;
       }
​
      String tagName = parser.getName();
      final ParseResult result;
​
      // <application> has special logic, so it's handled outside the general method
      if (TAG_APPLICATION.equals(tagName)) {
        if (foundApp) {
          if (RIGID_PARSER) {
            result = input.error("<manifest> has more than one <application>");
           } else {
            Slog.w(TAG, "<manifest> has more than one <application>");
            result = input.success(null);
           }
         } else {
          foundApp = true;
          result = parseBaseApplication(input, pkg, res, parser, flags);
         }
       } else {
        result = parseBaseApkTag(tagName, input, pkg, res, parser, flags);
       }
     
        .....
     
    return input.success(pkg);
   }

假如是application标签,那么就调用parseBaseApplication办法,因为四大组件等都在这个标签下面,其他通parseBaseApkTag解析。

  private ParseResult<ParsingPackage> parseBaseApplication(ParseInput input,
      ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
      throws XmlPullParserException, IOException {
      .....
    
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
        && (type != XmlPullParser.END_TAG
        || parser.getDepth() > depth)) {
      if (type != XmlPullParser.START_TAG) {
        continue;
       }
​
      final ParseResult result;
      String tagName = parser.getName();
      boolean isActivity = false;
      switch (tagName) {
        case "activity":
          isActivity = true;
          // fall-through
        case "receiver":
          ParseResult<ParsedActivity> activityResult =
              ParsedActivityUtils.parseActivityOrReceiver(mSeparateProcesses, pkg,
                  res, parser, flags, sUseRoundIcon, null /*defaultSplitName*/,
                  input);
​
          if (activityResult.isSuccess()) {
            ParsedActivity activity = activityResult.getResult();
            if (isActivity) {
              hasActivityOrder |= (activity.getOrder() != 0);
              pkg.addActivity(activity);
             } else {
              hasReceiverOrder |= (activity.getOrder() != 0);
              pkg.addReceiver(activity);
             }
           }
​
          result = activityResult;
          break;
        
         .....
         
   }

这儿就经过解析了标签,依据标签调用不同的解析办法。四大组件的信息PMS就都获取到了。

BOOT_PROGRESS_PMS_SCAN_END

 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
          SystemClock.uptimeMillis()); 
mPermissionManager.onStorageVolumeMounted(
          StorageManager.UUID_PRIVATE_INTERNAL, mIsUpgrade);
      ver.sdkVersion = mSdkVersion;
​
      // If this is the first boot or an update from pre-M, and it is a normal
      // boot, then we need to initialize the default preferred apps across
      // all defined users.
            //假如是从M晋级或许第一次发动,初始化默许运用
      if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
        for (UserInfo user : mInjector.getUserManagerInternal().getUsers(true)) {
          mSettings.applyDefaultPreferredAppsLPw(user.id);
         }
       }
​
            //假如是第一次OTA晋级之后的发动,那就删去代码缓存的目录
      if (mIsUpgrade && !mOnlyCore) {
        Slog.i(TAG, "Build fingerprint changed; clearing code caches");
        for (int i = 0; i < packageSettings.size(); i++) {
          final PackageSetting ps = packageSettings.valueAt(i);
          if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.getVolumeUuid())) {
            // No apps are running this early, so no need to freeze
            mAppDataHelper.clearAppDataLIF(ps.getPkg(), UserHandle.USER_ALL,
                FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
                    | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
           }
         }
        ver.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.
          //装置Q前的非体系运用程序在Launcher中隐藏他们的图标
      if (!mOnlyCore && mIsPreQUpgrade) {
        Slog.i(TAG, "Allowlisting all existing apps to hide their icons");
        int size = packageSettings.size();
        for (int i = 0; i < size; i++) {
          final PackageSetting ps = packageSettings.valueAt(i);
          if ((ps.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) {
            continue;
           }
          ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
              UserHandle.USER_SYSTEM);
         }
       }
​
      // clear only after permissions and other defaults have been updated
      mPromoteSystemApps = false;
​
      // All the changes are done during package scanning.
      ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
​
      // can downgrade to reader
      t.traceBegin("write settings");
      writeSettingsLPrTEMP();
      t.traceEnd();

BOOT_PROGRESS_PMS_READY

 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
          SystemClock.uptimeMillis());
            ...
​
            //权限控制器
      mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer);
      mSettings.setPermissionControllerVersion(
          computer.getPackageInfo(mRequiredPermissionControllerPackage, 0,
              UserHandle.USER_SYSTEM).getLongVersionCode());
​
            //指定体系中用于运转运用程序的 Sandbox 运用程序的包名,低于体系要求的最低版别就要运转在Sandbox              运用程序中
      mRequiredSdkSandboxPackage = getRequiredSdkSandboxPackageName(computer);
​
      ...
​
      final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
      for (int userId : userIds) {
        userPackages.put(userId, computer.getInstalledPackages(/*flags*/ 0, userId)
             .getList());
       }
            //经过mDexManager将用户已经装置的app的dex交给 mDexManager 进行处理
      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);
       }
​
      // Rebuild the live computer since some attributes have been rebuilt.
      mLiveComputer = createLiveComputer();
​
     } // synchronized (mLock)
     } // synchronized (mInstallLock)
    // CHECKSTYLE:ON IndentationCheck
​
    mModuleInfoProvider = mInjector.getModuleInfoProvider();
​
    mInjector.getSystemWrapper().enablePackageCaches();
    t.traceBegin("GC");
        //触发gc收回运用资源
    VMRuntime.getRuntime().requestConcurrentGC();
    t.traceEnd();
​
        //圆角资源
    ParsingPackageUtils.readConfigUseRoundIcon(mContext.getResources());
​
    mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);

SystemServer.startOtherServices

//frameworks/base/services/java/com/android/server/SystemServer.java    
private void startOtherServices() {
   ...
  if (!mOnlyCore) {
     ...
    //假如不是只发动中心运用,检查是否更新
    mPackageManagerService.updatePackagesIfNeeded();
   }
   ...
  // 最终履行performFstrim,完成磁盘维护
  mPackageManagerService.performFstrimIfNeeded();
   ...
  //PKMS准备就绪
  mPackageManagerService.systemReady();
   ...
}

到这儿PackageManagerService就初始化成功了。

参考地址

blog.csdn.net/lijie266498…

cs.android.com/

gityuan.com/2016/11/06/…