PKMS启动详解(二)之怎么通过packages.xml对已安装应用信息进行持久化管理?
Android PackageManagerService系列博客目录:
PKMS启动详解系列博客概要
PKMS启动详解(一)之整体流程分析
PKMS启动详解(二)之怎么通过packages.xml对已安装应用信息进行持久化管理?
PKMS启动详解(三)之BOOT_PROGRESS_PMS_START流程分析
PKMS启动详解(四)之Android包信息体和包解析器(上)
PKMS启动详解(五)之Android包信息体和包解析器(中)
PKMS启动详解(六)之Android包信息体和包解析器(下)
PKMS启动详解(七)之BOOT_PROGRESS_PMS_SYSTEM_SCAN_START阶段流程分析
PKMS启动详解(八)之BOOT_PROGRESS_PMS_DATA_SCAN_START阶段流程分析
引言
在前面的博客PackageManagerService启动详解(一)之整体流程分析中我们概述了PKMS启动的整体流程,按照正常的逻辑本篇博客将要对PKMS启动的第一阶段BOOT_PROGRESS_PMS_START来个详细的分析,但是发现在这之前非常有必要单独拉出来一篇博客对该阶段将要涉及的Settings以及关联的packages.xml等文件来先分析一番,怎么说呢只有将这块分析透了后续才好进行下去。
是不是感觉上述的描述有点平淡无奇啊,不抛出点灵魂拷问,估计读者都没有兴趣要拍屁股走人了(是时候展示点真正的技术了):
1.PKMS对于扫描成功后的应用信息(也包括第三方安装成功的应用),有没有进行持久化的存储,进行持久化的存储位置是什么
2.如果有进行持久化,那么持久化的形式是什么
3.为什么PKMS需要对已经安装应用的相关信息进行持久化处理
4.对于安装应用被持久化的信息,PKSM是怎么加载的呢
5.PKMS服务既然是加会不会加载上述持久化的数据,如果要加载,是不是应该存在一个管理者,来全局管理,那个这个类是什么
6.系统应用被覆盖升级(即通过普通安装升级)之后重启,PKMS是怎么辨别是使用安装在data分区的还是使用在系统分区的呢
7.如果应用安装目录被删除了,那么PKMS对于它的数据目录会怎么处理呢
是不是前面这一番灵魂大拷问,激起了了你的战斗欲望。读者如果对PKMS服务的管理机制不是很熟悉的话,一时半会回答不上也没有关系!这篇文章要干的就是初步解决上面的疑问,然后为后续具体的PKMS扫描等相关流程打好基础。
注意:本篇的介绍是基于Android 7.xx平台为基础的(并且为了书写简便后续PackageManagerService统一简称为PKMS),其中涉及的代码路径如下:
--- frameworks/base/services/core/java/com/android/server/pm/
PackageSetting.java
Settings.java
PackageSettingBase.java
PackageSignatures.java
SettingBase.java
SharedUserSetting.java
--- frameworks/base/core/res/res/values/attrs_manifest.xml
--- frameworks/base/core/java/android/os/Process.java
--- frameworks/base//core/java/android/content/pm/ApplicationInfo.java
一.Android安装应用信息持久化区域是什么,涉及到了那些文件
做人要有始有终方得始终不是,博主是一个负责人的人,所以抛出了问题,必须解决问题不是,这不就安排上了!上面说的安装应用信息持久化区域其实在我们的Android终端的/data/system目录下,这个目录下存储了许多应用运行中生成的配置文件,关于PKMS有如下的几个文件,分别是:
- packages.xml:记录了系统中所有安装的应用信息,包括基本信息、签名和权限,这个是Android应用信息持久化的关键文件(章节1.2会详细介绍)
- pakcages-back.xml:packages.xml文件的备份,用于描述系统中所安装的所有 Package 信息,PMS 会先把数据写入 packages-backup.xml,信息写成功后,再改名为 packages.xml
- pakcages-stoped.xml:记录系统中被强制停止的运行的应用信息。系统在强制停止某个应- 用的时候,会将应用的信息记录在该文件中
- pakcages-stoped-backup.xml:pakcages-stoped.xml文件的备份
- package-usage.list:记录了应用的使用情况,譬如使用了多久
- packages.list:记录了应用的一些简单情况(章节1.1会详细介绍)
这里我们来看下我当前Android系统中相关存储区域涉及的文件信息,如下:

细心的读者看到上面的截图,估计会说博主你这个骗子,欺骗我们的感情,说好的pakcages-back.xml和pakcages-stoped-backup.xml文件怎么没有看到啊!我是无辜的,真的,我没有欺骗你们。
当Android对文件packages.xml和pakcages-stoped.xml写之前,会先把它们备份,如果写文件成功了,再把备份文件删除。如果写的时候,系统出问题了,重启后在需要读取这两个文件时,如果发现备份文件存在,会使用备份文件的内容,因为源文件可能已经损坏了。所以正常情况下我们是看不到的。
1.1 packages.list简介
packages.list文件内容相对简单,我们打开packages.list文件后,我们会发现其中对于系统中所有安装的应用都有类似如下的描述类容(这里我们选择了一个复杂点的):
com.android.settings 1000 0 /data/user_de/0/com.android.settings platform:privapp 3002,1023,1015,3003,3001,1021,3004,3005,1000,2002,2950,1010,1007
是不是被上述一长串信息整蒙了,读者朋友先展开想象,每个字符串代表的意思是什么呢!我们先看下Android源码中对于它的描述,如下:
// we store on each line the following information for now:
//
// pkgName - package name
// userId - application-specific user id
// debugFlag - 0 or 1 if the package is debuggable.
// dataPath - path to package's data path
// seinfo - seinfo label for the app (assigned at install time)
// gids - supplementary gids this app launches with
//
// NOTE: We prefer not to expose all ApplicationInfo flags for now.
//
// DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
// FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
// frameworks/base/libs/packagelistparser
// system/core/run-as/run-as.c
//
有了前面的英文注释,估计读者应该了解的差不多了,这里对每行使用用空格符分了六列,分别代表了每个应用六个相关的信息,如下:
- 第一列表示安装的应用的包名:也就是AndroidManifest.xml文件中的package=”xxx.xxx.xxx”设置的内容
- 第二列表示安装的应用userid:如果没有在AndroidManifext.xml里使用android:sharedUserId属性指定UID, 在应用安装的时候,系统会给这个应用自动分配一uid,以后应用运行时,就用这个UID运行
- 第三列表示安装的应用是否处于调试模式:由AndroidManifext.xml里android:debuggable指定,如果没有指定则通常情况默认为非调试模式,其值为0
- 第四列表示安装的应用的数据存放路径:一般是”/data/data/${package_name}”这样的文件夹
- 第五列表示安装的应用的seinfo信息:这个和Android的SELinux有关(如果对于SELinux不是很熟悉的读者可以详见博客Android SELinux开发多场景实战指南有非常详细的介绍),此时的platform是它的标签,我们可以通过如下的命令进行查看:

- 第六列是安装的应用的所属的user group:如果一个应用不属于任何group, 这里的值是none。
这里我们可以看到com.android.settings存在多个user group,这个也比较好理解就好像你,既属于国家,也属于你老婆,也属于你公司的一个组织罢了。
1.2 packages.xml简介
关于这块建议读者最好了解一下xml的语法,即元素,标签,属性,文本,XML树结构等概念,不是很清楚的可以简单看下博客XML树结构了解一下!
Android安装应用信息持久化核心的文件packages.xml要登场了,我们pull到本地听过文本编辑器打开基本是一样望不到头,它非常非常的长。我看了下我当前的Android终端设备中的该文件有6000多行,这还得了我要是贴上来不会爆了去啊,所以先列出这个文件的框架,以便对它有个整体的认知,然后我们逐一分析:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<packages>
<version sdkVersion="xxx" databaseVersion="xxx" fingerprint="xxx" />
<version volumeUuid="xxx" sdkVersion="xxx" databaseVersion="xxx" fingerprint="xxx" />
<permissions>
<item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />
...
</permissions>
<package name="com.android.providers.telephony" codePath="/system/priv-app/TelephonyProvider" nativeLibraryPath="/system/priv-app/TelephonyProvider/lib" publicFlags="1007402501" privateFlags="8" ft="11e8dc5d800" it="11e8dc5d800" ut="11e8dc5d800" version="25" versionName="7.1.2" applicationName="电话和短信存储" sharedUserId="1001" isOrphaned="true">
<sigs count="1">
<cert index="1" key="xxx" />

本文深入剖析Android系统中PackageManagerService如何对已安装应用信息进行持久化存储管理,重点介绍了packages.xml文件及其内部结构,以及Android系统如何加载和管理这些持久化信息。
最低0.47元/天 解锁文章
3302

被折叠的 条评论
为什么被折叠?



