当前位置:   article > 正文

PackageManagerService 整体以及Settings相关逻辑_no start tag found in package manager settings

no start tag found in package manager settings

PackageManagerService(简称PKMS),是Aandroid系统中核心服务之一,负责应用程序的安装、卸载、信息查询等工作。

PMS概述:

Android系统启动时,在SystemServer的main函数中会启动应用程序管理服务器PKMS。

[-->SystemServer.java]

  1. private void startBootstrapServices() {
  2. mPackageManagerService = PackageManagerService.main(mSystemContext, installer, //初始化PKMS
  3. mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
  4. mFirstBoot = mPackageManagerService.isFirstBoot(); //是否是第一次启动
  5. mPackageManager = mSystemContext.getPackageManager(); // 获取到PackageManager
  6. }

[PackageManagerService.java]

  1. public class PackageManagerService extends IPackageManager.Stub { //PKMS继承IPackageManager.Stub,实现其所有的接口
  2. public static final PackageManagerService main(Context context, Installer installer,
  3. boolean factoryTest, boolean onlyCore) {
  4. PackageManagerService m = new PackageManagerService(context, installer, //创建PackageManagerService
  5. factoryTest, onlyCore);
  6. ServiceManager.addService("package", m); //将PKMS加入到ServiceManager 这里相当于添加的是IPackageManager.Stub 服务端
  7. return m;
  8. }
  9. }

[SystemServer中获取PackageManager的过程 -->mSystemContext.getPackageManager()]

[ContextImpl.java]

  1. public PackageManager getPackageManager() {
  2. if (mPackageManager != null) {
  3. return mPackageManager;
  4. }
  5. IPackageManager pm = ActivityThread.getPackageManager(); //由ActivityThread获取IPackageManager
  6. if (pm != null) {
  7. // Doesn't matter if we make more than one instance.
  8. return (mPackageManager = new ApplicationPackageManager(this, pm)); //ApplicationPackageManager继承于PackageManager
  9. }
  10. return null;
  11. }

[ActivityThread.java]

  1. public static IPackageManager getPackageManager() {
  2. if (sPackageManager != null) {
  3. //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
  4. return sPackageManager;
  5. }
  6. IBinder b = ServiceManager.getService("package"); //获取到main函数中添加IPackageManager.Stub,获取到Binder服务端
  7. //Slog.v("PackageManager", "default service binder = " + b);
  8. sPackageManager = IPackageManager.Stub.asInterface(b); //返回IPackageManager.Stub.Proxy 代理对象
  9. //Slog.v("PackageManager", "default service = " + sPackageManager);
  10. return sPackageManager;
  11. }

[ApplicationPackageManager.java]

最后返回new ApplicationPackageManager(this, pm))

也就是返回new ApplicationPackageManager(this, IPackageManager.Stub.asInterface(b)))

PKMS类之间的继承关系图

 

简单概括以下PKMS的核心功能

1.解析AndroidManifest.xml清单文件,解析清单文件中的所有节点信息

2.扫描.apk文件,安装系统应用,安装本地应用

3.管理本地应用,主要有安装、卸载、应用信息查询等

客户端可以通过Context.getPackageManager()获得ApplicationPackageManager对象,ApplicationPackageManager对象的成员变量mPM指向的是IPackageManager.Stub.Proxy代理对象,通过Binder机制中的mRemote与服务端PackageManagerService通信,并调用PackageManagerService的方法。

 

1.PKMS启动流程图

 

1.1PKMS启动的七个步骤

第一步 到 第四步:

startBootstrapServices()首先启动Installer服务,也就是安装器,随后判断当前的设备是否处于加密

状态,如果是则只是解析核心应用,接着调用PackageManagerService的静态方法main来创建pms对

第一步: 启动Installer服务

第二步:获取设备是否加密(手机设置密码),如果设备加密了,则只解析"core"应用

第三步: 调用PKMS main方法初始化PackageManagerService,其中调用PackageManagerService()

构造函数创建了PKMS对象

第四步: 如果设备没有加密,操作它。管理A/B OTA dexopting。

  1. private void startBootstrapServices() {
  2. //..........省略
  3. //第一步:启动Installer,以便有机会创建合适的权限相关的目录,比如/data/user。需要在初始化其它服务之前完成此任务
  4. Installer installer = mSystemServiceManager.startService(Installer.class);
  5. //..........省略
  6. // Activity manager runs the show.
  7. traceBeginAndSlog("StartActivityManager");
  8. mActivityManagerService = mSystemServiceManager.startService( //启动AMS
  9. ActivityManagerService.Lifecycle.class).getService();
  10. mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
  11. mActivityManagerService.setInstaller(installer); //将installer设置给AMS
  12. traceEnd();
  13. //...........省略
  14. // Only run "core" apps if we're encrypting the device.
  15. //第二步:获取设备是否是加密状态(手机是否设置密码),如果设备是加密状态就只解析“core”APP,后面在PKMS中会利用mOnlyCore条件进行各种判断
  16. String cryptState = SystemProperties.get("vold.decrypt");
  17. if (ENCRYPTING_STATE.equals(cryptState)) {
  18. Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
  19. mOnlyCore = true;
  20. } else if (ENCRYPTED_STATE.equals(cryptState)) {
  21. Slog.w(TAG, "Device encrypted - only parsing core apps");
  22. mOnlyCore = true;
  23. }
  24. //...........省略
  25. //第三步: 调用PKMS的main方法初始化PackageManagerService
  26. mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
  27. mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
  28. //是否是第一次启动
  29. mFirstBoot = mPackageManagerService.isFirstBoot();
  30. mPackageManager = mSystemContext.getPackageManager();
  31. traceEnd();
  32. if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
  33. MetricsLogger.histogram(null, "boot_package_manager_init_ready",
  34. (int) SystemClock.elapsedRealtime());
  35. }
  36. //第四步:如果设备没有加密,就管理A/B OTA dexopting
  37. // Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
  38. // A/B artifacts after boot, before anything else might touch/need them.
  39. // Note: this isn't needed during decryption (we don't have /data anyways).
  40. if (!mOnlyCore) {
  41. boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
  42. false);
  43. if (!disableOtaDexopt) {
  44. traceBeginAndSlog("StartOtaDexOptService");
  45. try {
  46. OtaDexoptService.main(mSystemContext, mPackageManagerService);
  47. } catch (Throwable e) {
  48. reportWtf("starting OtaDexOptService", e);
  49. } finally {
  50. traceEnd();
  51. }
  52. }
  53. }
  54. }

第五步,第六步,第七步:

startOtherServices

第五步: 执行 updatePackagesIfNeeded ,完成dex优化;

第六步: 执行 performFstrimIfNeeded ,完成磁盘维护;

第七步: 调用systemReady,准备就绪。

  1. private void startOtherServices() {
  2. ...
  3. if (!mOnlyCore) {
  4. ...
  5. // 第五步:如果设备没有加密,执行performDexOptUpgrade,完成dex优化;
  6. mPackageManagerService.updatePackagesIfNeeded();
  7. }
  8. ...
  9. // 第六步:最终执行performFstrim,完成磁盘维护
  10. mPackageManagerService.performFstrimIfNeeded();
  11. ...
  12. // 第七步:PKMS准备就绪
  13. mPackageManagerService.systemReady();
  14. ...
  15. }

主要分析第三步:

  1. public static PackageManagerService main(Context context, Installer installer,
  2. boolean factoryTest, boolean onlyCore) {
  3. // Self-check for initial settings.
  4. //检查package编译相关的系统属性pm.dexopt.first-boot,pm.dexopt.boot,pm.dexopt.install,pm.dexopt.bg-dexopt,pm.dexopt.ab-ota等
  5. PackageManagerServiceCompilerMapping.checkProperties();
  6. //调用PKMS的构造函数
  7. PackageManagerService m = new PackageManagerService(context, installer,
  8. factoryTest, onlyCore);
  9. //启用部分应用服务于多用户场景
  10. m.enableSystemUserPackages();
  11. //往ServiceManager中注册"package"和"package_native"
  12. ServiceManager.addService("package", m);
  13. final PackageManagerNative pmn = m.new PackageManagerNative();
  14. ServiceManager.addService("package_native", pmn);
  15. return m;
  16. }

[PKMS构造方法]

PKMS中两个重要锁:

mInstallLock:用来保护所有安装apk的访问权限,此操作通常涉及繁重的磁盘数据读写操作,并且是单线程操作,故有时候会处理很慢,此锁不会在已经持有mPackages锁的情况下获得。反过来在已经持有mInstallLock锁的情况下,立即获取mPackages是安全的。

mPackages:用来解析内存中所有apk的package信息及相关状态。

PKMS构造函数的五个阶段

[阶段1:BOOT_PROGRESS_PMS_START]

(1)构造DisplayMetrics类:描述界面显示,尺寸,分辨率,密度。构造完后并获取默认的信息保存到变量mMetrics中

(2)构造Settings类:Setttings是Android的全局管理者,用于协助PKMS保存所有的安装包信息

(3)保存Installer对象

(4)获取系统配置信息:SystemConfig构造构造函数中会通过readPermissions()解析指定目录下的所有xml文件,然后把这些信息保存到systemConfig中,涉及目录有如下:

/system/etc/sysconfig

/system/etc/permissions

/oem/etc/sysconfig

/oem/etc/permissions

(5)创建名为PackageHandler的Handler线程,建立PackageHandler消息循环,用于处理外部安装请求等消息

(6)创建data下的各种目录,比如data/app,data/app-private

(7)创建用户管理服务UserManagerService

(8)把SystemConfig关于xml中的标签所指的动态库保存到mSharedLibraries,Settings.readLPw扫描解析data/system/packages.xml和data/system/packages-backup.xml

和Settings.readLPw对应是Settings.writeLPr,writeLPr将

  1. public PackageManagerService(Context context, Installer installer,
  2. boolean factoryTest, boolean onlyCore) {
  3. LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
  4. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
  5. mContext = context;
  6. mFactoryTest = factoryTest;// 一般为false,即非工厂模式
  7. mOnlyCore = onlyCore; //标记是否只加载核心服务
  8. mMetrics = new DisplayMetrics(); //构造DispalyMetrics保存分辨率等相关信息
  9. mInstaller = installer; //保存installer对象
  10. // Create sub-components that provide services / data. Order here is important.
  11. synchronized (mInstallLock) {
  12. synchronized (mPackages) {
  13. // Expose private service for system components to use.
  14. LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl()); //本地服务
  15. sUserManager = new UserManagerService(context, this,
  16. new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages); //多用户管理服务
  17. mComponentResolver = new ComponentResolver(sUserManager,
  18. LocalServices.getService(PackageManagerInternal.class),
  19. mPackages);
  20. mPermissionManager = PermissionManagerService.create(context, //权限管理服务,创建PermissionManager对象,进行权限管理
  21. mPackages /*externalLock*/);
  22. mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
  23. //构造Settings类,保存安装包信息,清除路径不存在的孤立应用,主要涉及/data/system/目录的packages.xml,packages-backup.xml,packages.list
  24. //packages-stopped.xml,packages-stopped-backup.xml等文件
  25. mSettings = new Settings(Environment.getDataDirectory(), //创建Settings对象
  26. mPermissionManager.getPermissionSettings(), mPackages);
  27. }
  28. }
  29. //添加system,phone,log,nfc,bluetooth,shell,se,networkstack 这8种shareUserId到mSettings
  30. mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
  31. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  32. mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
  33. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  34. mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
  35. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  36. mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
  37. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  38. mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
  39. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  40. mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
  41. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  42. mSettings.addSharedUserLPw("android.uid.se", SE_UID,
  43. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  44. mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
  45. ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
  46. String separateProcesses = SystemProperties.get("debug.separate_processes");
  47. if (separateProcesses != null && separateProcesses.length() > 0) {
  48. if ("*".equals(separateProcesses)) {
  49. mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
  50. mSeparateProcesses = null;
  51. Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
  52. } else {
  53. mDefParseFlags = 0;
  54. mSeparateProcesses = separateProcesses.split(",");
  55. Slog.w(TAG, "Running with debug.separate_processes: "
  56. + separateProcesses);
  57. }
  58. } else {
  59. mDefParseFlags = 0;
  60. mSeparateProcesses = null;
  61. }
  62. // 构造PackageDexOptimizer及DexManager类,处理dex优化
  63. mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
  64. "*dexopt*");
  65. mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock);
  66. //ART虚拟机管理服务
  67. mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
  68. mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
  69. mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);
  70. //权限变化监听器
  71. mOnPermissionChangeListeners = new OnPermissionChangeListeners(
  72. FgThread.get().getLooper());
  73. //获取默认分辨率
  74. getDefaultDisplayMetrics(context, mMetrics);
  75. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
  76. //创建SystemConfig实例,获取系统配置信息,配置共享lib库
  77. //在SystemConfig的构造函数中会调用readPermissions()读取/etc/permission和etc/sysconfig下面的xml文件
  78. SystemConfig systemConfig = SystemConfig.getInstance();
  79. mAvailableFeatures = systemConfig.getAvailableFeatures();
  80. Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
  81. mProtectedPackages = new ProtectedPackages(mContext);
  82. mApexManager = new ApexManager(context);
  83. synchronized (mInstallLock) {
  84. // writer
  85. synchronized (mPackages) {
  86. //启动PackageManager线程,负责apk的安装、卸载
  87. mHandlerThread = new ServiceThread(TAG,
  88. Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
  89. mHandlerThread.start();
  90. //创建PackageManager的Handler线程,循环处理外部安装相关消息。 应用handler
  91. mHandler = new PackageHandler(mHandlerThread.getLooper());
  92. //进程记录handler
  93. mProcessLoggingHandler = new ProcessLoggingHandler();
  94. //watchdog监听serviceThread是否超时: 10分钟
  95. Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
  96. //Instant应用注册
  97. mInstantAppRegistry = new InstantAppRegistry(this);
  98. //共享lib库配置
  99. ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
  100. = systemConfig.getSharedLibraries();
  101. final int builtInLibCount = libConfig.size();
  102. for (int i = 0; i < builtInLibCount; i++) {
  103. String name = libConfig.keyAt(i);
  104. SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
  105. addBuiltInSharedLibraryLocked(entry.filename, name);
  106. }
  107. // Now that we have added all the libraries, iterate again to add dependency
  108. // information IFF their dependencies are added.
  109. long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
  110. for (int i = 0; i < builtInLibCount; i++) {
  111. String name = libConfig.keyAt(i);
  112. SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
  113. final int dependencyCount = entry.dependencies.length;
  114. for (int j = 0; j < dependencyCount; j++) {
  115. final SharedLibraryInfo dependency =
  116. getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
  117. if (dependency != null) {
  118. getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
  119. }
  120. }
  121. }
  122. //读取安装相关的SE linux策略
  123. SELinuxMMAC.readInstallPolicy();
  124. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
  125. //返回栈加载
  126. FallbackCategoryProvider.loadFallbacks();
  127. Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
  128. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
  129. //通过mSettings读取data/system/下的packages.xml等文件
  130. mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
  131. Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
  132. // Clean up orphaned packages for which the code path doesn't exist
  133. // and they are an update to a system app - caused by bug/32321269
  134. //清理代码路径不存在的孤立软件包
  135. final int packageSettingCount = mSettings.mPackages.size();
  136. for (int i = packageSettingCount - 1; i >= 0; i--) {
  137. PackageSetting ps = mSettings.mPackages.valueAt(i);
  138. if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
  139. && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
  140. mSettings.mPackages.removeAt(i);
  141. mSettings.enableSystemPackageLPw(ps.name);
  142. }
  143. }
  144. //如果不是首次启动,并且不是core应用,则拷贝与编译DEX文件
  145. if (!mOnlyCore && mFirstBoot) {
  146. requestCopyPreoptedFiles();
  147. }
  148. //...............省略 只是第一阶段分析
  149. }

[接上面的mSettings.readLPw]

readLPw会扫描下面的5个文件

”data/system/packages.xml" 所有安装app信息

"data/syatem/packages-backup" 所有安装app的备份信息

"data/system/packages.list" 所有安装的app包名和所在安装目录

"data/system/packages-stopped.xml" 所有强制停止app信息

"data/system/packages-stopped-backup.xml" 所有强制停止app备份信息

以上文件分为三组:

packages.xml:PKMS扫描完目标文件夹后会创建该文件,当系统进行程序安装、卸载和更新等操作时,均会更新该文件。该文件保存了系统中与package相关的一些信息

packages.list:扫描系统中存在的所有非系统自带APK信息,里面包含app的包名,进程id,userID,和app安装目录等

packages-stopped.xml:从系统自带的设置程序中,强制停止某个应用,系统会将应用的相关信息记录到此文件中,该文件保存系统中被用户强制停止的package信息

这些目录的创建都是在Settings的构造函数中完成,得到目录后调用readLPw进行扫描

[Settings构造函数]

  1. Settings(File dataDir, PermissionSettings permission, Object lock) {
  2. mLock = lock;
  3. mPermissions = permission;
  4. mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
  5. mSystemDir = new File(dataDir, "system"); //mSystemDir指向目录 /data/system
  6. mSystemDir.mkdirs(); //创建data/system目录
  7. FileUtils.setPermissions(mSystemDir.toString(), //设置权限
  8. FileUtils.S_IRWXU|FileUtils.S_IRWXG
  9. |FileUtils.S_IROTH|FileUtils.S_IXOTH,
  10. -1, -1);
  11. mSettingsFilename = new File(mSystemDir, "packages.xml"); //mSettingsFilename指向 /data/system/packages.xml
  12. mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml"); //mBackupSettingsFilename指向 data/system/packages-backup.xml
  13. mPackageListFilename = new File(mSystemDir, "packages.list"); //mPackageListFilename指向 data/system/packages.list
  14. FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
  15. final File kernelDir = new File("/config/sdcardfs");
  16. mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
  17. // Deprecated: Needed for migration
  18. mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");//mStoppedPackagesFilename指向data/system/packages-stopped.xml
  19. mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
  20. }

[readLPw函数]

  1. boolean readLPw(@NonNull List<UserInfo> users) {
  2. //...............................
  3. try {
  4. if (str == null) {
  5. if (!mSettingsFilename.exists()) {
  6. mReadMessages.append("No settings file found\n");
  7. PackageManagerService.reportSettingsProblem(Log.INFO,
  8. "No settings file; creating initial state");
  9. // It's enough to just touch version details to create them
  10. // with default values
  11. findOrCreateVersion(StorageManager.UUID_PRIVATE_INTERNAL).forceCurrent();
  12. findOrCreateVersion(StorageManager.UUID_PRIMARY_PHYSICAL).forceCurrent();
  13. return false;
  14. }
  15. str = new FileInputStream(mSettingsFilename); //创建文件"读入"流,来解析packages.xml文件
  16. }
  17. XmlPullParser parser = Xml.newPullParser();
  18. parser.setInput(str, StandardCharsets.UTF_8.name());
  19. int type;
  20. while ((type = parser.next()) != XmlPullParser.START_TAG
  21. && type != XmlPullParser.END_DOCUMENT) {
  22. ;
  23. }
  24. if (type != XmlPullParser.START_TAG) {
  25. mReadMessages.append("No start tag found in settings file\n");
  26. PackageManagerService.reportSettingsProblem(Log.WARN,
  27. "No start tag found in package manager settings");
  28. Slog.wtf(PackageManagerService.TAG,
  29. "No start tag found in package manager settings");
  30. return false;
  31. }
  32. int outerDepth = parser.getDepth();
  33. while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
  34. && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
  35. if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
  36. continue;
  37. }
  38. //根据XML中的各个节点进行解析,读取permissions,shared-user等
  39. String tagName = parser.getName();
  40. if (tagName.equals("package")) {
  41. readPackageLPw(parser);
  42. } else if (tagName.equals("permissions")) {
  43. mPermissions.readPermissions(parser);
  44. } else if (tagName.equals("permission-trees")) {
  45. mPermissions.readPermissionTrees(parser);
  46. } else if (tagName.equals("shared-user")) {
  47. readSharedUserLPw(parser);
  48. } else if (tagName.equals("preferred-packages")) {
  49. // no longer used.
  50. } else if (tagName.equals("preferred-activities")) {
  51. // Upgrading from old single-user implementation;
  52. // these are the preferred activities for user 0.
  53. readPreferredActivitiesLPw(parser, 0);
  54. } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
  55. // TODO: check whether this is okay! as it is very
  56. // similar to how preferred-activities are treated
  57. readPersistentPreferredActivitiesLPw(parser, 0);
  58. } else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
  59. // TODO: check whether this is okay! as it is very
  60. // similar to how preferred-activities are treated
  61. readCrossProfileIntentFiltersLPw(parser, 0);
  62. } else if (tagName.equals(TAG_DEFAULT_BROWSER)) {
  63. readDefaultAppsLPw(parser, 0);
  64. } else if (tagName.equals("updated-package")) {
  65. readDisabledSysPackageLPw(parser);
  66. } else if (tagName.equals("cleaning-package")) {
  67. //.............................
  68. return true;
  69. }

[阶段2:BOOT_PROGRESS_PMS_SYSTEM_SCAN_START]

(1)从init.rc中获取环境变量 BOOTCLASSPATH和SYSTESERVERCLASSPATH

(2)对于旧版升级的情况,将安装时获取权限变更为运行时申请权限

(3)扫描system/vendor/product/odm/oem等目录的priv-app、app、overlay包

(4)清除安装时临时文件以及其它不必要信息

[PackageManagerService构造函数解析阶段2]

  1. public PackageManagerService(Context context, Installer installer,
  2. boolean factoryTest, boolean onlyCore) {
  3. long startTime = SystemClock.uptimeMillis(); //记录扫描开始时间
  4. EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
  5. startTime);
  6. final String bootClassPath = System.getenv("BOOTCLASSPATH"); //从init.rc中获取环境变量BOOTCLASSPATH和SYSTESERVERCLASSPATH
  7. final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
  8. //............................
  9. File frameworkDir = new File(Environment.getRootDirectory(), "framework");/获取system/framework目录
  10. final VersionInfo ver = mSettings.getInternalVersion();// 获取手机的版本 ,volumUuid
  11. mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
  12. if (mIsUpgrade) {
  13. logCriticalInfo(Log.INFO,
  14. "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
  15. }
  16. // when upgrading from pre-M, promote system app permissions from install to runtime
  17. //对于Aandroid M之前版本升级上来的情况,需将系统应用程序权限从安装升级到运行时
  18. mPromoteSystemApps =
  19. mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
  20. // When upgrading from pre-N, we need to handle package extraction like first boot,
  21. // as there is no profiling data available.
  22. mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
  23. mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
  24. mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;
  25. int preUpgradeSdkVersion = ver.sdkVersion;
  26. // save off the names of pre-existing system packages prior to scanning; we don't
  27. // want to automatically grant runtime permissions for new system apps
  28. //扫描之前保存预先存在的system packages,不希望自动为新system app赋予运行时权限
  29. if (mPromoteSystemApps) {
  30. Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
  31. while (pkgSettingIter.hasNext()) {
  32. PackageSetting ps = pkgSettingIter.next();
  33. if (isSystemApp(ps)) {
  34. mExistingSystemPackages.add(ps.name);
  35. }
  36. }
  37. }
  38. //准备解析package的缓存
  39. mCacheDir = preparePackageParserCache();
  40. // Set flag to monitor and not change apk file paths when
  41. // scanning install directories.
  42. int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
  43. if (mIsUpgrade || mFirstBoot) {
  44. scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
  45. }
  46. // Collect vendor/product/product_services overlay packages. (Do this before scanning
  47. // any apps.)
  48. // For security and version matching reason, only consider overlay packages if they
  49. // reside in the right directory.
  50. // 扫描以下各个路径的文件
  51. scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
  52. mDefParseFlags
  53. | PackageParser.PARSE_IS_SYSTEM_DIR,
  54. scanFlags
  55. | SCAN_AS_SYSTEM
  56. | SCAN_AS_VENDOR,
  57. 0);
  58. scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
  59. mDefParseFlags
  60. | PackageParser.PARSE_IS_SYSTEM_DIR,
  61. scanFlags
  62. | SCAN_AS_SYSTEM
  63. | SCAN_AS_PRODUCT,
  64. 0);
  65. scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
  66. mDefParseFlags
  67. | PackageParser.PARSE_IS_SYSTEM_DIR,
  68. scanFlags
  69. | SCAN_AS_SYSTEM
  70. | SCAN_AS_PRODUCT_SERVICES,
  71. 0);
  72. scanDirTracedLI(new File(ODM_OVERLAY_DIR),
  73. mDefParseFlags
  74. | PackageParser.PARSE_IS_SYSTEM_DIR,
  75. scanFlags
  76. | SCAN_AS_SYSTEM
  77. | SCAN_AS_ODM,
  78. 0);
  79. scanDirTracedLI(new File(OEM_OVERLAY_DIR),
  80. mDefParseFlags
  81. | PackageParser.PARSE_IS_SYSTEM_DIR,
  82. scanFlags
  83. | SCAN_AS_SYSTEM
  84. | SCAN_AS_OEM,
  85. 0);
  86. mParallelPackageParserCallback.findStaticOverlayPackages();
  87. // Find base frameworks (resource packages without code).
  88. scanDirTracedLI(frameworkDir,
  89. mDefParseFlags
  90. | PackageParser.PARSE_IS_SYSTEM_DIR,
  91. scanFlags
  92. | SCAN_NO_DEX
  93. | SCAN_AS_SYSTEM
  94. | SCAN_AS_PRIVILEGED,
  95. 0);
  96. if (!mPackages.containsKey("android")) {
  97. throw new IllegalStateException(
  98. "Failed to load frameworks package; check log for warnings");
  99. }
  100. // Collect privileged system packages.
  101. final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
  102. scanDirTracedLI(privilegedAppDir,
  103. mDefParseFlags
  104. | PackageParser.PARSE_IS_SYSTEM_DIR,
  105. scanFlags
  106. | SCAN_AS_SYSTEM
  107. | SCAN_AS_PRIVILEGED,
  108. 0);
  109. // Collect ordinary system packages.
  110. final File systemAppDir = new File(Environment.getRootDirectory(), "app");
  111. scanDirTracedLI(systemAppDir,
  112. mDefParseFlags
  113. | PackageParser.PARSE_IS_SYSTEM_DIR,
  114. scanFlags
  115. | SCAN_AS_SYSTEM,
  116. 0);
  117. // Collect privileged vendor packages.
  118. File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
  119. try {
  120. privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
  121. } catch (IOException e) {
  122. // failed to look up canonical path, continue with original one
  123. }
  124. scanDirTracedLI(privilegedVendorAppDir,
  125. mDefParseFlags
  126. | PackageParser.PARSE_IS_SYSTEM_DIR,
  127. scanFlags
  128. | SCAN_AS_SYSTEM
  129. | SCAN_AS_VENDOR
  130. | SCAN_AS_PRIVILEGED,
  131. 0);
  132. // Collect ordinary vendor packages.
  133. File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
  134. try {
  135. vendorAppDir = vendorAppDir.getCanonicalFile();
  136. } catch (IOException e) {
  137. // failed to look up canonical path, continue with original one
  138. }
  139. scanDirTracedLI(vendorAppDir,
  140. mDefParseFlags
  141. | PackageParser.PARSE_IS_SYSTEM_DIR,
  142. scanFlags
  143. | SCAN_AS_SYSTEM
  144. | SCAN_AS_VENDOR,
  145. 0);
  146. // Collect privileged odm packages. /odm is another vendor partition
  147. // other than /vendor.
  148. File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
  149. "priv-app");
  150. try {
  151. privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
  152. } catch (IOException e) {
  153. // failed to look up canonical path, continue with original one
  154. }
  155. scanDirTracedLI(privilegedOdmAppDir,
  156. mDefParseFlags
  157. | PackageParser.PARSE_IS_SYSTEM_DIR,
  158. scanFlags
  159. | SCAN_AS_SYSTEM
  160. | SCAN_AS_VENDOR
  161. | SCAN_AS_PRIVILEGED,
  162. 0);
  163. // Collect ordinary odm packages. /odm is another vendor partition
  164. // other than /vendor.
  165. File odmAppDir = new File(Environment.getOdmDirectory(), "app");
  166. try {
  167. odmAppDir = odmAppDir.getCanonicalFile();
  168. } catch (IOException e) {
  169. // failed to look up canonical path, continue with original one
  170. }
  171. scanDirTracedLI(odmAppDir,
  172. mDefParseFlags
  173. | PackageParser.PARSE_IS_SYSTEM_DIR,
  174. scanFlags
  175. | SCAN_AS_SYSTEM
  176. | SCAN_AS_VENDOR,
  177. 0);
  178. // Collect all OEM packages.
  179. final File oemAppDir = new File(Environment.getOemDirectory(), "app");
  180. scanDirTracedLI(oemAppDir,
  181. mDefParseFlags
  182. | PackageParser.PARSE_IS_SYSTEM_DIR,
  183. scanFlags
  184. | SCAN_AS_SYSTEM
  185. | SCAN_AS_OEM,
  186. 0);
  187. // Collected privileged /product packages.
  188. File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
  189. try {
  190. privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
  191. } catch (IOException e) {
  192. // failed to look up canonical path, continue with original one
  193. }
  194. scanDirTracedLI(privilegedProductAppDir,
  195. mDefParseFlags
  196. | PackageParser.PARSE_IS_SYSTEM_DIR,
  197. scanFlags
  198. | SCAN_AS_SYSTEM
  199. | SCAN_AS_PRODUCT
  200. | SCAN_AS_PRIVILEGED,
  201. 0);
  202. // Collect ordinary /product packages.
  203. File productAppDir = new File(Environment.getProductDirectory(), "app");
  204. try {
  205. productAppDir = productAppDir.getCanonicalFile();
  206. } catch (IOException e) {
  207. // failed to look up canonical path, continue with original one
  208. }
  209. scanDirTracedLI(productAppDir,
  210. mDefParseFlags
  211. | PackageParser.PARSE_IS_SYSTEM_DIR,
  212. scanFlags
  213. | SCAN_AS_SYSTEM
  214. | SCAN_AS_PRODUCT,
  215. 0);
  216. // Collected privileged /product_services packages.
  217. File privilegedProductServicesAppDir =
  218. new File(Environment.getProductServicesDirectory(), "priv-app");
  219. try {
  220. privilegedProductServicesAppDir =
  221. privilegedProductServicesAppDir.getCanonicalFile();
  222. } catch (IOException e) {
  223. // failed to look up canonical path, continue with original one
  224. }
  225. scanDirTracedLI(privilegedProductServicesAppDir,
  226. mDefParseFlags
  227. | PackageParser.PARSE_IS_SYSTEM_DIR,
  228. scanFlags
  229. | SCAN_AS_SYSTEM
  230. | SCAN_AS_PRODUCT_SERVICES
  231. | SCAN_AS_PRIVILEGED,
  232. 0);
  233. // Collect ordinary /product_services packages.
  234. File productServicesAppDir = new File(Environment.getProductServicesDirectory(), "app");
  235. try {
  236. productServicesAppDir = productServicesAppDir.getCanonicalFile();
  237. } catch (IOException e) {
  238. // failed to look up canonical path, continue with original one
  239. }
  240. scanDirTracedLI(productServicesAppDir,
  241. mDefParseFlags
  242. | PackageParser.PARSE_IS_SYSTEM_DIR,
  243. scanFlags
  244. | SCAN_AS_SYSTEM
  245. | SCAN_AS_PRODUCT_SERVICES,
  246. 0);
  247. // Prune any system packages that no longer exist.
  248. final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
  249. // Stub packages must either be replaced with full versions in the /data
  250. // partition or be disabled.
  251. final List<String> stubSystemApps = new ArrayList<>();
  252. //删除不存在的package
  253. if (!mOnlyCore) {
  254. // do this first before mucking with mPackages for the "expecting better" case
  255. final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
  256. while (pkgIterator.hasNext()) {
  257. final PackageParser.Package pkg = pkgIterator.next();
  258. if (pkg.isStub) {
  259. stubSystemApps.add(pkg.packageName);
  260. }
  261. }
  262. final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
  263. while (psit.hasNext()) {
  264. PackageSetting ps = psit.next();
  265. /*
  266. * If this is not a system app, it can't be a 不是系统应用,不被允许disable
  267. * disable system app.
  268. */
  269. if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
  270. continue;
  271. }
  272. /*
  273. * If the package is scanned, it's not erased. 如果应用被扫描,则不允许被擦除
  274. */
  275. final PackageParser.Package scannedPkg = mPackages.get(ps.name);
  276. if (scannedPkg != null) {
  277. /*
  278. * If the system app is both scanned and in the
  279. * disabled packages list, then it must have been
  280. * added via OTA. Remove it from the currently
  281. * scanned package so the previously user-installed
  282. * application can be scanned.
  283. */
  284. if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
  285. logCriticalInfo(Log.WARN,
  286. "Expecting better updated system app for " + ps.name
  287. + "; removing system app. Last known"
  288. + " codePath=" + ps.codePathString
  289. + ", versionCode=" + ps.versionCode
  290. + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
  291. removePackageLI(scannedPkg, true);
  292. mExpectingBetter.put(ps.name, ps.codePath);
  293. }
  294. continue;
  295. }
  296. if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
  297. psit.remove();
  298. logCriticalInfo(Log.WARN, "System package " + ps.name
  299. + " no longer exists; it's data will be wiped");
  300. // Actual deletion of code and data will be handled by later
  301. // reconciliation step
  302. } else {
  303. // we still have a disabled system package, but, it still might have
  304. // been removed. check the code path still exists and check there's
  305. // still a package. the latter can happen if an OTA keeps the same
  306. // code path, but, changes the package name.
  307. final PackageSetting disabledPs =
  308. mSettings.getDisabledSystemPkgLPr(ps.name);
  309. if (disabledPs.codePath == null || !disabledPs.codePath.exists()
  310. || disabledPs.pkg == null) {
  311. possiblyDeletedUpdatedSystemApps.add(ps.name);
  312. } else {
  313. // We're expecting that the system app should remain disabled, but add
  314. // it to expecting better to recover in case the data version cannot
  315. // be scanned.
  316. mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
  317. }
  318. }
  319. }
  320. }
  321. //delete tmp files 删除安装产生的临时文件
  322. deleteTempPackageFiles();
  323. final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
  324. // Remove any shared userIDs that have no associated packages 删除没有关联shared userID的package
  325. mSettings.pruneSharedUsersLPw();
  326. }

[阶段3:BOOT_PROGRESS_PMS_DATA_SCAN_START]

[PackageManagerService构造函数解析阶段3]

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

  1. public PackageManagerService(Context context, Installer installer,
  2. boolean factoryTest, boolean onlyCore) {
  3. if (!mOnlyCore) {
  4. EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
  5. SystemClock.uptimeMillis());
  6. scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
  7. // Remove disable package settings for updated system apps that were
  8. // removed via an OTA. If the update is no longer present, remove the
  9. // app completely. Otherwise, revoke their system privileges.
  10. for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
  11. final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
  12. final PackageParser.Package pkg = mPackages.get(packageName);
  13. final String msg;
  14. // remove from the disabled system list; do this first so any future
  15. // scans of this package are performed without this state
  16. mSettings.removeDisabledSystemPackageLPw(packageName);
  17. if (pkg == null) {
  18. // should have found an update, but, we didn't; remove everything
  19. msg = "Updated system package " + packageName
  20. + " no longer exists; removing its data";
  21. // Actual deletion of code and data will be handled by later
  22. // reconciliation step
  23. } else {
  24. // found an update; revoke system privileges
  25. msg = "Updated system package " + packageName
  26. + " no longer exists; rescanning package on data";
  27. // NOTE: We don't do anything special if a stub is removed from the
  28. // system image. But, if we were [like removing the uncompressed
  29. // version from the /data partition], this is where it'd be done.
  30. // remove the package from the system and re-scan it without any
  31. // special privileges
  32. removePackageLI(pkg, true);
  33. try {
  34. final File codePath = new File(pkg.applicationInfo.getCodePath());
  35. scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
  36. } catch (PackageManagerException e) {
  37. Slog.e(TAG, "Failed to parse updated, ex-system package: "
  38. + e.getMessage());
  39. }
  40. }
  41. // one final check. if we still have a package setting [ie. it was
  42. // previously scanned and known to the system], but, we don't have
  43. // a package [ie. there was an error scanning it from the /data
  44. // partition], completely remove the package data.
  45. final PackageSetting ps = mSettings.mPackages.get(packageName);
  46. if (ps != null && mPackages.get(packageName) == null) {
  47. removePackageDataLIF(ps, null, null, 0, false);
  48. }
  49. logCriticalInfo(Log.WARN, msg);
  50. }
  51. //确保期望显示在userdata分区上的所有应用程序都显示正确,如果从未出现过,就回滚以恢复系统版本
  52. for (int i = 0; i < mExpectingBetter.size(); i++) {
  53. final String packageName = mExpectingBetter.keyAt(i);
  54. if (!mPackages.containsKey(packageName)) {
  55. final File scanFile = mExpectingBetter.valueAt(i);
  56. logCriticalInfo(Log.WARN, "Expected better " + packageName
  57. + " but never showed up; reverting to system");
  58. final @ParseFlags int reparseFlags;
  59. final @ScanFlags int rescanFlags;
  60. if (FileUtils.contains(privilegedAppDir, scanFile)) {
  61. reparseFlags =
  62. mDefParseFlags |
  63. PackageParser.PARSE_IS_SYSTEM_DIR;
  64. rescanFlags =
  65. scanFlags
  66. | SCAN_AS_SYSTEM
  67. | SCAN_AS_PRIVILEGED;
  68. } else if (FileUtils.contains(systemAppDir, scanFile)) {
  69. reparseFlags =
  70. mDefParseFlags |
  71. PackageParser.PARSE_IS_SYSTEM_DIR;
  72. rescanFlags =
  73. scanFlags
  74. | SCAN_AS_SYSTEM;
  75. } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
  76. || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
  77. reparseFlags =
  78. mDefParseFlags |
  79. PackageParser.PARSE_IS_SYSTEM_DIR;
  80. rescanFlags =
  81. scanFlags
  82. | SCAN_AS_SYSTEM
  83. | SCAN_AS_VENDOR
  84. | SCAN_AS_PRIVILEGED;
  85. } else if (FileUtils.contains(vendorAppDir, scanFile)
  86. || FileUtils.contains(odmAppDir, scanFile)) {
  87. reparseFlags =
  88. mDefParseFlags |
  89. PackageParser.PARSE_IS_SYSTEM_DIR;
  90. rescanFlags =
  91. scanFlags
  92. | SCAN_AS_SYSTEM
  93. | SCAN_AS_VENDOR;
  94. } else if (FileUtils.contains(oemAppDir, scanFile)) {
  95. reparseFlags =
  96. mDefParseFlags |
  97. PackageParser.PARSE_IS_SYSTEM_DIR;
  98. rescanFlags =
  99. scanFlags
  100. | SCAN_AS_SYSTEM
  101. | SCAN_AS_OEM;
  102. } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
  103. reparseFlags =
  104. mDefParseFlags |
  105. PackageParser.PARSE_IS_SYSTEM_DIR;
  106. rescanFlags =
  107. scanFlags
  108. | SCAN_AS_SYSTEM
  109. | SCAN_AS_PRODUCT
  110. | SCAN_AS_PRIVILEGED;
  111. } else if (FileUtils.contains(productAppDir, scanFile)) {
  112. reparseFlags =
  113. mDefParseFlags |
  114. PackageParser.PARSE_IS_SYSTEM_DIR;
  115. rescanFlags =
  116. scanFlags
  117. | SCAN_AS_SYSTEM
  118. | SCAN_AS_PRODUCT;
  119. } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
  120. reparseFlags =
  121. mDefParseFlags |
  122. PackageParser.PARSE_IS_SYSTEM_DIR;
  123. rescanFlags =
  124. scanFlags
  125. | SCAN_AS_SYSTEM
  126. | SCAN_AS_PRODUCT_SERVICES
  127. | SCAN_AS_PRIVILEGED;
  128. } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
  129. reparseFlags =
  130. mDefParseFlags |
  131. PackageParser.PARSE_IS_SYSTEM_DIR;
  132. rescanFlags =
  133. scanFlags
  134. | SCAN_AS_SYSTEM
  135. | SCAN_AS_PRODUCT_SERVICES;
  136. } else {
  137. Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
  138. continue;
  139. }
  140. mSettings.enableSystemPackageLPw(packageName);
  141. try {
  142. //扫描APK
  143. scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
  144. } catch (PackageManagerException e) {
  145. Slog.e(TAG, "Failed to parse original system package: "
  146. + e.getMessage());
  147. }
  148. }
  149. }
  150. // Uncompress and install any stubbed system applications.
  151. // This must be done last to ensure all stubs are replaced or disabled.
  152. installSystemStubPackages(stubSystemApps, scanFlags);//解压缩并安装任何存根系统应用程序,必须最后执行此操作以确保替换或禁用所有存根
  153. //......................
  154. }
  155. }
  156. mExpectingBetter.clear();
  157. // Resolve the storage manager. 获取到storage manager包名
  158. mStorageManagerPackage = getStorageManagerPackageName();
  159. // Resolve protected action filters. Only the setup wizard is allowed to
  160. // have a high priority filter for these actions.
  161. mSetupWizardPackage = getSetupWizardPackageName();
  162. mComponentResolver.fixProtectedFilterPriorities();
  163. mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
  164. mWellbeingPackage = getWellbeingPackageName();
  165. mDocumenterPackage = getDocumenterPackageName();
  166. mConfiguratorPackage =
  167. mContext.getString(R.string.config_deviceConfiguratorPackageName);
  168. mAppPredictionServicePackage = getAppPredictionServicePackageName();
  169. mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
  170. // Now that we know all of the shared libraries, update all clients to have
  171. // the correct library paths. 更新客户端以确保持有正确的共享库路径
  172. updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages));
  173. for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
  174. // NOTE: We ignore potential failures here during a system scan (like
  175. // the rest of the commands above) because there's precious little we
  176. // can do about it. A settings error is reported, though.
  177. final List<String> changedAbiCodePath =
  178. adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
  179. if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
  180. for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
  181. final String codePathString = changedAbiCodePath.get(i);
  182. try {
  183. mInstaller.rmdex(codePathString,
  184. getDexCodeInstructionSet(getPreferredInstructionSet()));
  185. } catch (InstallerException ignored) {
  186. }
  187. }
  188. }
  189. // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
  190. // SELinux domain.
  191. setting.fixSeInfoLocked();
  192. }
  193. // Now that we know all the packages we are keeping,
  194. // read and update their last usage times. 读取并更新要保留的package的上次使用时间
  195. mPackageUsage.read(mPackages);
  196. mCompilerStats.read();
  197. }

[阶段4:BOOT_PROGRESS_PMS_SCAN_END]

[PackageManagerService构造函数解析阶段4]

(1)sdk版本变更,更新权限

(2)OTA升级后首次启动,清除不必要的缓存数据

(3)权限等默认项更新完后,清除相关数据

(4)更新packages.xml

  1. public PackageManagerService(Context context, Installer installer,
  2. boolean factoryTest, boolean onlyCore) {
  3. EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
  4. SystemClock.uptimeMillis());
  5. Slog.i(TAG, "Time to scan packages: "
  6. + ((SystemClock.uptimeMillis()-startTime)/1000f)
  7. + " seconds");
  8. // 如果子上次启动以来,平台sdk以改变,则需要重新授予应用程序权限以捕获出现任何新权限
  9. final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
  10. if (sdkUpdated) {
  11. Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
  12. + mSdkVersion + "; regranting permissions for internal storage");
  13. }
  14. mPermissionManager.updateAllPermissions(
  15. StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
  16. mPermissionCallback);
  17. ver.sdkVersion = mSdkVersion;
  18. // 如果是第一次启动或者来自Android M之前的版本升级,并且它是正常启动,那需要在所有一定以的用户中初始化默认的首选应用程序
  19. if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
  20. for (UserInfo user : sUserManager.getUsers(true)) {
  21. mSettings.applyDefaultPreferredAppsLPw(user.id);
  22. primeDomainVerificationsLPw(user.id);
  23. }
  24. }
  25. //在boot期间更早的为用户准备storage,因为像SettingsProvider和SystemUI这样的核心应用无法等到用户去启动
  26. final int storageFlags;
  27. if (StorageManager.isFileEncryptedNativeOrEmulated()) {
  28. storageFlags = StorageManager.FLAG_STORAGE_DE;
  29. } else {
  30. storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
  31. }
  32. //............................
  33. // 如果是在OTA之后的首次启动,并且是正常启动,那需要清除代码缓存目录,但不清除应用程序配置文件
  34. if (mIsUpgrade && !onlyCore) {
  35. Slog.i(TAG, "Build fingerprint changed; clearing code caches");
  36. for (int i = 0; i < mSettings.mPackages.size(); i++) {
  37. final PackageSetting ps = mSettings.mPackages.valueAt(i);
  38. if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
  39. // No apps are running this early, so no need to freeze
  40. clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
  41. FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
  42. | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
  43. }
  44. }
  45. ver.fingerprint = Build.FINGERPRINT;
  46. }
  47. // Grandfather existing (installed before Q) non-system apps to hide
  48. // 安装Android-Q前的非系统应用程序在Launcher中隐藏他们的图标
  49. if (!onlyCore && mIsPreQUpgrade) {
  50. Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
  51. int size = mSettings.mPackages.size();
  52. for (int i = 0; i < size; i++) {
  53. final PackageSetting ps = mSettings.mPackages.valueAt(i);
  54. if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
  55. continue;
  56. }
  57. ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
  58. UserHandle.USER_SYSTEM);
  59. }
  60. }
  61. // 仅在权限或其它默认配置更新后清除
  62. mExistingSystemPackages.clear();
  63. mPromoteSystemApps = false;
  64. // 所有变更均在扫描过程中完成
  65. ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
  66. // 更新packages.xml
  67. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
  68. mSettings.writeLPr();
  69. }

[阶段4:BOOT_PROGRESS_PMS_READY]

[PackageManagerService构造函数解析阶段5]

GC回收内存

Runtime.getRuntime().gc();

 

2.PKMS APK扫描

扫描APK的AndroidManifest.xml中的各个标签信息,例如"application"、"overlay"、"permission"、"uses-permission"等信息。再针对各个标签的子标签在进行扫描,例如application会扫描"activity"、"receiver"、"service"、"provider"等信息。

PKMS的构造函数中调用了scanDirTracedLI方法来扫描某个目录的apk文件。

android10.0中PKMS主要扫描以下路径的APK信息

/vendor/overlay 系统的APP类别

/product/overlay 系统的APP类别

/product_services/overlay 系统的APP类别

/odm/overlay 系统的APP类别

/oem/overlay 系统的APP类别

/system/framework 系统的APP类别

/system/priv-app 系统的APP类别

/system/app 系统的APP类别

/vendor/priv-app 系统的APP类别

/vendor/app 系统的APP类别

/odm/priv-app 系统的APP类别

/odm/app 系统的APP类别

/oem/app 系统的APP类别

/oem/priv-app 系统的APP类别

/product/priv-app 系统的APP类别

/product/app 系统的APP类别

/product_services/priv-app 系统的APP类别

/product_services/app 系统的APP类别

/product_services/priv-app 系统的APP类别

 

APK扫描整体流程图

3.APK安装的流程

(1)把APK的信息以IO流的形式写入到PackageInstaller.Session中

(2)调用PackageInstaller.Session的commit方法,将APK的信息交给PKMS处理

(3)进行APK的copy操作,进行安装

4.PKMS权限管理

读取/etc/sysconfig和/etc/permissions目录下的xml文件

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/199068
推荐阅读
相关标签
  

闽ICP备14008679号