引自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加密。公鑰