Android(安卓)P PackageManagerService 初始化流程
16lz
2021-01-26
Android P PackageManagerService 初始化流程
-
概述
- 解析AndroidManifest.xml,主要包括AndroidManifest中节点信息的解析和target-name的分析和提炼,这部分和ActivityManagerService和WindowManagerService都有紧急的联系。关于AndroidManifest.xml中的属性设置,会单独拎出来讲解,本文不扩展讲解。
- 扫描本地文件,主要针对apk,主要是系统应用、本地安装应用等等。这部分会在下面仔细讲解。
- 管理本地apk,主要包括安装、删除等等。
- 下面称PackageManagerService为PKMS
-
PackageManagerService 启动
frameworks/base/services/java/com/android/server/SystemServer.java293 public static void main(String[] args) { //静态main函数294 new SystemServer().run(); //创建SystemServer 并执行其run函数295 }...307 private void run() {308 try {309 traceBeginAndSlog("InitBeforeStartServices");426 // Start services.427 try {428 traceBeginAndSlog("StartServices");429 startBootstrapServices(); //启动初始化需要启动的services...537 private void startBootstrapServices() {....627 traceBeginAndSlog("StartPackageManagerService");628 mPackageManagerService = PackageManagerService.main(mSystemContext, installer,629 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); ----> 执行PKMS的main函数630 mFirstBoot = mPackageManagerService.isFirstBoot();631 mPackageManager = mSystemContext.getPackageManager();frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java2305 public static PackageManagerService main(Context context, Installer installer,2306 boolean factoryTest, boolean onlyCore) {2307 // Self-check for initial settings.2308 PackageManagerServiceCompilerMapping.checkProperties();2309 2310 PackageManagerService m = new PackageManagerService(context, installer,2311 factoryTest, onlyCore); ---> 创建PackageManagerService,此构造函数为PKMS初始化的主战场2312 m.enableSystemUserPackages();2313 ServiceManager.addService("package", m);2314 final PackageManagerNative pmn = m.new PackageManagerNative();2315 ServiceManager.addService("package_native", pmn);2316 return m;2317 }...2402 public PackageManagerService(Context context, Installer installer,2403 boolean factoryTest, boolean onlyCore) {
-
PKMS初始化过程
我把PKMS的初始化划分为如下几个阶段:
-
第一阶段 :Settings 初始化
此阶段主要为解析PKMS的几个xml文件,并将其解析并存放到mSettings变量中。相关代码如下:
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java2430 mPermissionManager = PermissionManagerService.create(context,2431 new DefaultPermissionGrantedCallback() {2432 @Override2433 public void onDefaultRuntimePermissionsGranted(int userId) {2434 synchronized(mPackages) {2435 mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);2436 }2437 }2438 }, mPackages /*externalLock*/); //初始化 mPermissionManager2439 mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();2440 mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages); //创建mSettings2441 }2442 }2445 mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,2446 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);2447 mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,2448 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);2449 mSettings.addSharedUserLPw("android.uid.log", LOG_UID,2450 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);2451 mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,2452 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);2453 mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,2454 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);2455 mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,2456 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);2457 mSettings.addSharedUserLPw("android.uid.se", SE_UID,2458 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);...Android 系统中 UID/GID 介绍:UID 为用户 ID 的缩写,GID 为用户组 ID 的缩写,这两个概念均与 Linux 系统中进程的权限管理有关。一般说来,每一个进程都会有一个对应的 UID(即表示该进程属于哪个 user,不同 user 有不同权限)。一个进程也可分属不同的用户组(每个用户组都有对应的权限)。...2525 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");2526 mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false)); // 此方法会解析paxkages.xml文件2527 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);frameworks/base/services/core/java/com/android/server/pm/Settings.java439 mSettingsFilename = new File(mSystemDir, "packages.xml"); // 其实质就是 /data/system/pacages.xml440 mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");441 mPackageListFilename = new File(mSystemDir, "packages.list");...3016 str = new FileInputStream(mSettingsFilename);3017 }3018 XmlPullParser parser = Xml.newPullParser();3019 parser.setInput(str, StandardCharsets.UTF_8.name());...2978 boolean readLPw(@NonNull List
users) {2979 FileInputStream str = null;3036 int outerDepth = parser.getDepth();3037 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT3038 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {3039 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {3040 continue;3041 }3042 3043 String tagName = parser.getName();3044 if (tagName.equals("package")) {3045 readPackageLPw(parser);3046 } else if (tagName.equals("permissions")) {3047 mPermissions.readPermissions(parser);3048 } else if (tagName.equals("permission-trees")) {3049 mPermissions.readPermissionTrees(parser); -
第二阶段:清理不正常的APK
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java2529 // Clean up orphaned packages for which the code path doesn't exist2530 // and they are an update to a system app - caused by bug/323212692531 final int packageSettingCount = mSettings.mPackages.size();2532 android.util.Log.d(TAG, "wangwei packageSettingCount = " + packageSettingCount);2533 for (int i = packageSettingCount - 1; i >= 0; i--) {2534 PackageSetting ps = mSettings.mPackages.valueAt(i);2535 if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())2536 && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {2537 mSettings.mPackages.removeAt(i); //从第一阶段产生的msettings中将该异常的apk删除掉。2538 mSettings.enableSystemPackageLPw(ps.name); //因为删除掉的是系统预装的apk的升级版本,所以原本系统预装的apk需要再次被使能。2539 }2540 }有的情况,同学可能不能理解这里地方的用意。其实就是比如我手机预装了facebook,而随着时间的推移这个facebook可能会升级,这个时候升级就是安装到data分区了,system分区的是disable掉了。但是升级apk就有失败的可能, 如果升级这个apk失败,或者安装在data分区的文件不存在了。那么就需要把原来预装到system分区的低版本facebook使能。
-
第三阶段:加载 framework 环境变量
2561 final String bootClassPath = System.getenv("BOOTCLASSPATH");2562 // BOOTCLASSPATH=/system/framework/core-oj.jar:/system/framework/core-libart.jar:/system/framework/conscrypt.jar:2563 // /system/framework/okhttp.jar:/system/framework/bouncycastle.jar:/system/framework/apache-xml.jar:/system/framework/ext.jar:2564 // /system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:2565 // /system/framework/android.hidl.base-V1.0-java.jar:/system/framework/android.hidl.manager-V1.0-java.jar:/system/framework/framework-oahl-backward-compatibility.jar:2566 // /system/framework/android.test.base.jar2567 2568 final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");2569 // generic_x86_64:/ # env | grep "SYSTEMSERVERCLASSPATH"2570 // SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:2571 // /system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar其实就是加载 系统所需要的 frameworks相关的jar库。其变量的值我已经打印出来了。
-
第四阶段:扫描系统预装apk
1.在安卓的资源加载逻辑中,除了在apk源代码里面就指定需要加载或者用到的资源外,还可以有RRO和SRO两种资源替换方式。此处的overlay 则为RRO
2624 // Collect vendor/product overlay packages. (Do this before scanning any apps.)2625 // For security and version matching reason, only consider2626 // overlay packages if they reside in the right directory.2627 // 先查找 /vendor/overlay /product/overlay , overlay apk 里面只含有资源的定义, 所以要先加载overlay2628 // 问题3 overlay apk 的工作机制, overlay apk 映射表在哪里?2629 scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),2630 mDefParseFlags2631 | PackageParser.PARSE_IS_SYSTEM_DIR,2632 scanFlags2633 | SCAN_AS_SYSTEM2634 | SCAN_AS_VENDOR,2635 0);如果不清楚overlay apk的书写方式,请搜索查阅。此处主要扫描/vendor/overlay/*.apk /product/overlay/*.apk
- 扫描framework目录
2646 // Find base frameworks (resource packages without code).2647 scanDirTracedLI(frameworkDir,2648 mDefParseFlags2649 | PackageParser.PARSE_IS_SYSTEM_DIR,2650 scanFlags2651 | SCAN_NO_DEX2652 | SCAN_AS_SYSTEM2653 | SCAN_AS_PRIVILEGED,2654 0);
3.扫描/system/priv-app /system/app /vendor/priv-app /vendor/app /odm/priv-app /odm/app /oem/app /product/priv-app /product/app
相关代码如下:
2656 // Collect privileged system packages.2657 final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");2658 scanDirTracedLI(privilegedAppDir,2659 mDefParseFlags2660 | PackageParser.PARSE_IS_SYSTEM_DIR,2661 scanFlags2662 | SCAN_AS_SYSTEM2663 | SCAN_AS_PRIVILEGED,2664 0);2665 2666 // Collect ordinary system packages.2667 final File systemAppDir = new File(Environment.getRootDirectory(), "app");2668 scanDirTracedLI(systemAppDir,2669 mDefParseFlags2670 | PackageParser.PARSE_IS_SYSTEM_DIR,2671 scanFlags2672 | SCAN_AS_SYSTEM,2673 0);.....
-
扫描data/app 目录下面安装的apk
2876 scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);2877 2878 scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags2879 | PackageParser.PARSE_FORWARD_LOCK,2880 scanFlags | SCAN_REQUIRE_KNOWN, 0);
-
根据解析出来的msetting 变量内容与mpackage 扫描各个目录获取到的app列表进行对比
关键变量:mExpectingBetter
2911 /*2912 * Make sure all system apps that we expected to appear on2913 * the userdata partition actually showed up. If they never2914 * appeared, crawl back and revive the system version.2915 */2916 for (int i = 0; i < mExpectingBetter.size(); i++) {2917 final String packageName = mExpectingBetter.keyAt(i);2918 if (!mPackages.containsKey(packageName)) {2919 final File scanFile = mExpectingBetter.valueAt(i);2920 ...2990 mSettings.enableSystemPackageLPw(packageName);2991 2992 try {2993 scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null); //此处的 scanFile 已经是data分区的更新版本的app目录了。2994 } catch (PackageManagerException e) {2995 Slog.e(TAG, "Failed to parse original system package: "2996 + e.getMessage());2997 }
在扫描完system app之后,会对msetting 变量做一次遍历,主要找出系统app中被disable掉的app,此类型的app只可能是因为有用户的升级,才会导致该系统app被disable掉。扫描到类似这样的系统app,则将其加入到mExpectingBetter列表中。第六步的主要目的是将前面扫描的时候加入到mExpectingBetter 列表里面的app,定位到该app是system/vendor/product等属性。
-
更多相关文章
- Android系统修改汇总(MTK)
- android things中与标准android系统不同的地方
- android系统信息(内存,cpu,sd卡,电量,版本)的获取
- Android获取系统时间以及网络时间
- Mac系统下Android(安卓)SDK更新以及ADT无法在线下载
- 关于Android系统 和 Android应用程序
- Android(安卓)系统启动流程
- Android关于BuildToolVersion与ComplieSdkVersion的区别
- 拦截系统收到短信的Notification