APEX - Android(安卓)Q
引自https://source.android.com/devices/tech/ota/apex
因本人忘性越来越大,故记录一下本文加深下记忆,描述有些问题的地方见谅。
建议有英文阅读能力的同学自行访问官方网址。
Android Pony EXpress (APEX) 是Android 10引入的一种容器格式,用于底层系统模块的安装flow。因为不用符合Android标准应用程序格式, 因此该格式的引用可以促进更新系统模块。底层模块包括像Native的services和库、HALs、ART等。
背景
尽管Android支持底层系统模块以安装Android应用程序的方式更新,但仍然有以下缺点
1、基于APK的模块无法在启动流程中更早的启动。PackageManager 是apk的重要存储中心,且只能被activity manager启动。因此,APK的模块只能在启动序列较晚的阶段中准备好。
2、APK的格式(尤其是manifest)对系统模块来说并不是非常适合
设计
本节介绍APEX文件格式和APEX Manager。APEX Manager是管理APEX文件的Service。
APEX文件格式
APEX文件格式如下
Note: 上图应该是Android Q的,R应该又有些变化
从顶层看,APEX文件是一个Zip文件,其中的文件均是未压缩的。
其中的四个文件有
- apex_manifest.json
- AndroidManifest.xml
- apex_pubkey
- apex_payload.img
apex_manifest.json文件包括package name和版本,用来标识该APEX文件
AndroidManifest.xml可以允许APEX文件使用一些apk的工具,像adb、package manager、 app install app等。举个例子APEX文件可以使用aapt检查文件的metadata。该文件还包括packcage name和版本号,这些内容通常也会再apex_manifest.json文件中。
apex_payload.img是依赖dm-verity的EXT4文件系统镜像。该镜像在运行时通过一个回环设备加载。具体地说,metadata和hash tree是通过libavb创建的。apex_payload.img还没有被解析,因为要求该文件是可挂载的。一些常规文件包含在该镜像中。
apex_pubkey是用来给文件系统签名的公钥。该公钥确保下载的apex文件是以编译阶段相同的方式签名。
APEX Manager
APEX Manger是个独立的Native进程,用来验证、卸载、安装APEX文件。该进程会在启动序列的早期启动并准备好。预安装的APEX文件通常在设备的/system/apex目录下。当没有其他更新可用时,APEX Manger默认使用这些package。
APEX使用Package Manager更新的过程如下:
- APEX文件通过adb、packeage安装app等方式下载
- Package Manager识别出该文件是APEX文件,将该文件传送给APEX Manager
- APEX Manger验证APEX文件
- 当APEX文件验证成功,APEX Manger更新内部数据库,标识该APEX文件将会在下次启动后使用
- 安装的请求程序接受到了验证成功的广播
- 为继续安装,Android系统将会自动重启
- 重启时,APEX Manger启动,读取内部数据库,为每个APEX文件做如下步骤:
- 验证APEX文件
- 为APEX文件建立回环设备
- 在环回设备的顶部创建设备映射块设备
- 挂载设备映射块设备到一个唯一的目录下
当所有的APEX文件均被加载后,APEX Manger会创建一个binder service以便让其他的系统组件查询已安装的APEX文件列表。举个例子,系统组件可以查询到所有已安装的APEX文件列表以及其挂载位置。
APEX文件是一个APK文件
APEX文件是一个有效的APK文件,因为它有使用APK签名机制签名。这就允许了apex文件使用一些apk的基本功能,像包安装app、签名组件和package manager。
AnroidManifest.xml包括信息有package name、versionCode,还有可选项的targetSdkVersion、minSdkVersion和maxSdkVersion。这些信息就允许APEX文件可以使用apk的现有传输途径,像ADB等。
文件支持类型
APEX格式支持以下类型:
Native层的共享库
Naive层的可执行bin档
JAR文件
数据文件
配置文件
这不意味着APEX可以完全替换这些文件类型,还要看平台支持和接口的稳定程度。
签名
APEX文件签名需要两个过程。首先,apex_payload.img文件单独被签名。接着,整个APEX文件通过APK签名方案V3签名。两个过程使用的是不同的Key。
在设备端,安装了公钥(对应vbmeta签名的私钥)。APEX Manger通过公钥验证APEX文件可以被安装。
APEX built-in部分
APEX文件可以位于内置分区中,如/system。分区已经在dm verity上,因此APEX文件直接挂载在环回设备上。
如果APEX存在于内置分区中,则可以通过提供具有相同包名和更高版本代码的APEX包来更新APEX。新的APEX存储在/data中,与apk类似,新版本会隐藏内置分区中已经存在的版本。但与apk不同的是,APEX的新版本只在重启后才被激活。
编译APEX文件
本节描述如何编译一个APEX文件。下面展示名为apex.test的APEX文件。
Android.bp文件如下:
apex_manifest.json如下:
file_contexts如下:
文件类型和路径如下(相应文件放到子目录中)
File type | Location in APEX |
---|---|
Shared libraries | /lib and /lib64 (/lib/arm for translated arm in x86) |
Executables | /bin |
Java libraries | /javalib |
Prebuilts | /etc |
依赖传递
APEX将自动include可执行bin档或者Native共享库的依赖。举个例子,比如LibFoo依赖LibBar,当LibFoo在APEX的native_shared_libs属性中时,LibBar也会被include进来。
vbmeta 签名
需要给每个APEX使用不同的Key进行加密。当需要一个新的Key时,会创建一对公私密钥对和生成一个apex_key模块。使用Key属性去给APEX加密。公钥文件(avb_pubkey)就会自动放到APEX里。
上面的例子就是生成了id为foo的公钥。公钥签名了APEX后,将该id记录在了APEX中。在运行期间,apexd会通过id 找到在设备上的公钥,并来验证APEX文件。
ZIP 签名
使用APKs签名方式签名APEXs文件。APEXs需要签名两次,一次是签名给小文件系统中apex_payload.img,一次是整个文件。
这个文件的签名,可以选择以下三个方式的一种进行设置certificate属性:
不设置:如果未设置该属性,APEX将会使用PRODUCT_DEFAULT_DEV_CERTIFICATE flag指示的证书位置,如该flag没有设置,将默认build/target/product/security/testkey。
:
例子如下
安装APEX文件
安装一个apex文件,使用adb工具
使用APEX文件
在reboot后,APEX被挂载在/apex/@
Client端可以使用绑定的挂载目录从APEX读取和执行文件。
通常如下方式访问APEX:
- OEM或者ODM会在出厂设置时,在/system/apex中预加载apex
- 通过/apex//访问APEX
- 更新版本的APEX被安装/data/apex后,reboot后通过该路径访问新的APEX
使用APEX更新服务
使用APEX更新service
1、service定义的地方增加updatable标签
2、为更新service创建新的rc文件,使用override标签重定义service
service的定义只能再APEX的rc文件中,APEX不支持动作触发
如果service被标记updatable,那么只能再APEX激活后,才会启动service。
配置系统支持APEX更新
配置如下的 system property为true,才能支持APEX更新
或者
更多相关文章
- Android的Zipalign优化
- Android(安卓)Studio删除无用的资源文件
- Android(安卓)NDK开发之旅1--NDK介绍
- Android(安卓)Studio报错org.junit不存在问题
- android中搭建phonegap开发环境
- Android源码树添加新的APP(含第三方so、jar)
- 关于Android(安卓)Pie(Android(安卓)9.0),你想知道的都在这了
- 分析Android(安卓)根文件系统启动过程(init守护进程分析)
- Android(安卓)开发技巧之Log发送UDP报文,Socket编程