一、应用安装相关的目录 | PKMS相关目录
系统App安装目录:
1、/system/app,Android系统自带的应用的APP目录
2、/vendor/app,odm或者oem厂商预制系统App目录
3、/data/app/包名, 普通App安装目录
riva:/data/app # cd com.tencent.mm-1/
riva:/data/app/com.tencent.mm-1 # ls -l
total 363816
-rw-r--r-- 1 system system 186262860 2021-02-15 15:19 base.apk
drwxr-xr-x 3 system system 4096 2021-02-15 15:20 lib
drwxrwx--x 3 system install 4096 2021-02-15 15:20 oat
其整体的目录结构如下:
-/data/app/com.tencent.mm-1
--base.apk
--lib
---arm
----libDownloadProxy.so
----libEVadEmbed.so
---- ··· ···
--oat
---arm
----base.odex
4、/data/dalvik-cache,dex、odex保存目录
-/data/dalvik-cache
--arm
---system@app@Bluetooth@Bluetooth.apk@classes.art
---system@app@Bluetooth@Bluetooth.apk@classes.dex
---system@app@HybridPlatform@HybridPlatform.apk@classes.art
---system@app@HybridPlatform@HybridPlatform.apk@classes.dex
---system@framework@ConnectivityExt.jar@classes.dex
---system@framework@boot-WfdCommon.art
---system@framework@boot-WfdCommon.oat -> /system/framework/arm/boot-WfdCommon.oat
--- ··· ···
--arm64
---system@app@AntiSpam@AntiSpam.apk@classes.art
---system@app@AntiSpam@AntiSpam.apk@classes.dex
---system@app@BugReport@BugReport.apk@classes.art
---system@app@BugReport@BugReport.apk@classes.dex
---system@app@CatcherPatch@CatcherPatch.apk@classes.dex
---system@app@CertInstaller@CertInstaller.apk@classes.art
--- ··· ···
5、/data/data,用户数据目录,存放应用程序的数据
6、/data/system,App注册表目录
6.1、/data/system/packages.xml, 此文件在PKMS的启动过程中会被映射成为PKMS中的Setting数据结构,并且在后续的PKMS启动中会围绕着该数据结构进行频繁操作;记录了一个应用的基本信息、签名和声明的权限,从而将一个安装应用的信息进行了持久化的存储。
packages.xml文件中按层级主要分为以下几个模块标签:
- permission:系统中所有定义的权限的信息;其中每个item块代表一个权限;item块对应的数据结构为 BasePermission 类,表示系统中已有的权限。
- package:系统中所有安装的应用的详细信息;其中 ①name,表示已安装应用的包名;②codePath,表示已安装应用apk文件存放的路径,其值为 “/data/app/com.guding.vssq-1”;③nativeLibraryPath,表示应用的native库的存储路径,其值为“/data/app/com.guding.vssq-1/lib”;④primaryCpuAbi,表示当前应用以哪种abi架构运行;⑤publicFlags 和 privateFlags,指的是应用的属性;⑥ft、it、ut,分别表示 apk 文件上次被更改的时间、app第一次安装的时间、app上次被更新的时间;⑦version,是app的版本号信息,即为在AndroidManifest.xml 里配置的android:versioncode; ⑧sharedUserId, 表示为app分配的 user id;⑨ sigs,表示已安装应用的签名信息;⑩ perms,表示应用声明使用的权限,其中的 item 表示当前应用所拥有的的权限,perms 对应的是 PermissionState 类,可以将 ==BasePermission 理解为 权限持有者==,而 ==PermissionState 记录的是权限申请者的相关信息==,比如有无被授权等授权状态。
- updated-package:被覆盖升级的系统应用的相关信息
- shared-user:所有系统定义的shareuser信息,对应的类是 ==SharedUserSetting类==,SharedUserSetting 中存储的应用安装信息,最终会被添加到 Settings 中的 mSharedUsers 列表中统一进行管理。
- keyset-settings:已安装app签名的public key信息
<packages>
<permissions>
<item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />
...
</permissions>
<package name="com.android.emergency" codePath="/system/priv-app/EmergencyInfo" nativeLibraryPath="/system/priv-app/EmergencyInfo/lib" publicFlags="944291397" privateFlags="8" ft="11e8dc5d800" it="11e8dc5d800" ut="11e8dc5d800" version="25" sharedUserId="10013" isOrphaned="true">
<sigs count="1">
<cert index="0" />
</sigs>
<perms>
<item name="android.permission.MANAGE_USERS" granted="true" flags="0" />
</perms>
<proper-signing-keyset identifier="1" />
</package>
··· ···
<updated-package name="com.miui.video" codePath="/system/priv-app/MiuiVideo" ft="11e8dc5d800" it="11e8dc5d800" ut="11e8dc5d800" version="2018092190" nativeLibraryPath="/system/priv-app/MiuiVideo/lib" primaryCpuAbi="armeabi-v7a" userId="10030">
<perms>
<item name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" granted="true" flags="0" />
··· ···
</perms>
</updated-package>
<shared-user name="com.android.emergency.uid" userId="10013">
<sigs count="1">
<cert index="0" />
</sigs>
<perms>
<item name="android.permission.MANAGE_USERS" granted="true" flags="0" />
</perms>
</shared-user>
<shared-user name="com.guding.vssq" userId="10126">
<sigs count="1">
<cert index="2" />
</sigs>
<perms>
<item name="android.permission.RESTART_PACKAGES" granted="true" flags="0" />
··· ···
</perms>
</shared-user>
··· ···
<keyset-settings version="1">
<keys>
<public-key identifier="1" value="MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAx4ZWipr/JTrXTF0+b7/6Ev7UTNMkTxiWDsVRG7VR5BMRUZcjSEURLMPfm7rNPg9LNSjNh+05fVd9yQCOnLxqJfwGZNOj9EAkN4bbiyUNQPbxSMmjzW+8LdjSQDm9aolyob3uKMMIeYv6m7O1SYd7EPmOJl8RjAXyZFN9leKTORV7nSoxSF4MgjUhzKbQtyGoQyYAB21mniCsQ6pYi1LBHCpR8ExrsxrWroVzmRr+jklX1UlZH8uD7GLR2jWxcn3GtjABpe84e1pxhsHmjaEyV3K1MHsbxznvI2ue/gbVLcrx4ydo40A+VePsVgKM9WgM+zOXHM94cFcrxH0+Ov+jhQIBAw==">
<public-key identifier="2" value="XXX">
<public-key identifier="3" value="XXX">
··· ···
</keys>
<keysets>
<keyset identifier="1">
<key-id identifier="1" />
</keyset>
··· ···
</keysets>
</keyset-settings>
</packages>
二、APK的安装过程概述
APK的安装过程可能比大家预想的要复杂。粗略来看,可以分成两个阶段:
- 拷贝APK到安装目录。譬如通过
adb install
命令安装APK,APK文件会先拷贝到手机的/data/local/tmp目录,然后拷贝到手机的/data/app目录。这个过程是由PMS消息驱动的,INIT_COPY这个消息会触发PMS连接DefaultContainerService,MCS_BOUND这个消息表示已经连接上DefaultContainerService,实际的拷贝操作会在DefaultContainerService所在的进程中完成; - APK拷贝到安装目录后,便可以扫描APK文件。这个过程同开机时的包扫描过程相似,不同的仅仅是扫描一个APK文件,相同的是需要检查APK的合法性,判断APK的签名是否匹配,更新APK的权限,更新PMS的Settings等。
三、Android 中的 UID 和 PID
在 Android 中 PID 和 UID 都是用来识别应用程序的身份的,但是 UID 是为了不同的程序来使用共享的数据而使用的。
UID,在Android中,由于Android为单用户系统,这时UID便被赋予了新的使命:数据共享。
四、Android包的文件格式种类
apk包、jar包、so库文件
Android的包管理者很重要的一个职能就是识别不同的包,统一维护这些包的信息。其面临的第一个任务就是将这些静态的文件转化成内存的数据结构,这样才能将其管理起来。