這兩對兼容性矩陣和清單旨在進行協調,以驗證框架和供應商實現是否可以相互配合。此驗證在框架兼容性矩陣和設備清單之間以及框架清單和設備兼容性矩陣之間匹配時成功。
此驗證在構建時、 OTA更新包生成時、啟動時和 VTS 兼容性測試中完成。
以下部分詳細介紹了各種組件使用的匹配規則。
框架兼容性矩陣版本匹配
要將設備清單與框架兼容性矩陣匹配,由manifest.target-level
指定的 Shipping FCM 版本必須完全等於由compatibility-matrix.level
指定的 FCM 版本。否則不匹配。
當使用libvintf
請求框架兼容性矩陣時,此匹配始終成功,因為libvintf
打開設備清單,檢索運輸 FCM 版本,並返回該運輸 FCM 版本的框架兼容性矩陣(加上更高 FCM 的兼容性矩陣中的一些可選 HAL版本)。
HAL 匹配
HAL 匹配規則標識清單文件中被認為由相應兼容性矩陣的所有者支持的hal
元素的版本。
HIDL 和原生 HAL
HIDL 和原生 HAL 的匹配規則如下。
- 多個
<hal>
元素使用單個AND關係進行評估。 -
<hal>
元素可能有<hal optional="true">
以將它們標記為不需要。 - 同一個
<hal>
中的多個<version>
元素具有OR關係。如果指定了兩個或多個,則只需要實現其中一個版本。 (請參見下面的DRM 示例。) - 當需要
<hal>
時,同一<hal>
中的多個<instance>
和<regex-instance>
元素使用單個AND關係進行評估。 (見下面的 DRM 示例。)
示例:模塊的成功 HAL 匹配
對於 2.5 版本的 HAL,匹配規則如下:
矩陣 | 匹配清單 |
---|---|
2.5 | 2.5-2.∞。在兼容性矩陣中, 2.5 是2.5-5 的簡寫。 |
2.5-7 | 2.5-2.∞。表示以下內容:
2.5-7 的框架兼容。 |
示例:DRM 模塊的成功 HAL 匹配
框架兼容性矩陣說明了 DRM HAL 的以下版本信息:
<hal> <name>android.hardware.drm <version>1.0</version> <version>3.1-2</version> <interface> <name>IDrmFactory</name> <instance>default</instance> <instance>specific</instance> </interface> </hal> <hal> <name>android.hardware.drm <version>2.0</version> <interface> <name>ICryptoFactory</name> <instance>default</instance> <regex-instance>[a-z]+/[0-9]+</regex-instance> </interface> </hal>
供應商必須實施以下實例之一;任何一個
android.hardware.drm@1.x::IDrmFactory/default // where x >= 0 android.hardware.drm@1.x::IDrmFactory/specific // where x >= 0或
android.hardware.drm@3.y::IDrmFactory/default // where y >= 1 android.hardware.drm@3.y::IDrmFactory/specific // where y >= 1
AND 還必須實現所有這些實例:
android.hardware.drm@2.z::ICryptoFactory/default // where z >= 0 android.hardware.drm@2.z::ICryptoFactory/${INSTANCE} // where z >= 0 and ${INSTANCE} matches [a-z]+/[0-9]+ // e.g. legacy/0
AIDL HAL
所有高於 Android 11 的 Android 版本(不包括 Android 11)都支持 VINTF 中的 AIDL HAL 版本。 AIDL HAL 的匹配規則與 HIDL 和原生 HAL 的匹配規則類似,只是沒有主要版本,並且每個 HAL 實例只有一個版本(如果未指定版本,則為1
)。
- 多個
<hal>
元素使用單個AND關係進行評估。 -
<hal>
元素可能有<hal optional="true">
以將它們標記為不需要。 - 當需要
<hal>
時,同一<hal>
中的多個<instance>
和<regex-instance>
元素使用單個AND關係進行評估。 (見下面的振動器示例。)
示例:模塊的成功 HAL 匹配
對於版本 5 的 HAL,匹配規則如下:
矩陣 | 匹配清單 |
---|---|
5 | 5-∞。在兼容性矩陣中, 5 是5-5 的簡寫。 |
5-7 | 5-∞。表示以下內容:
5-7 的框架兼容。 |
示例:多個模塊的成功 HAL 匹配
框架兼容性矩陣說明了振動器和相機 HAL 的以下版本信息:
<hal> <name>android.hardware.vibrator <version>1-2</version> <interface> <name>IVibrator</name> <instance>default</instance> <instance>specific</instance> </interface> </hal> <hal> <name>android.hardware.camera <version>5</version> <interface> <name>ICamera</name> <instance>default</instance> <regex-instance>[a-z]+/[0-9]+</regex-instance> </interface> </hal>
供應商必須實現所有這些實例:
android.hardware.vibrator.IVibrator/default // version >= 1 android.hardware.vibrator.IVibrator/specific // version >= 1 android.hardware.camera.ICamera/default // version >= 5 android.hardware.camera.ICamera/${INSTANCE} // with version >= 5, where ${INSTANCE} matches [a-z]+/[0-9]+ // e.g. legacy/0
內核匹配
框架兼容性矩陣的<kernel>
部分描述了框架對設備上 Linux 內核的要求。此信息旨在與設備的 VINTF 對象報告的有關內核的信息進行匹配。
匹配內核分支
每個內核分支後綴(例如, 5.4- r
)都映射到一個唯一的內核 FCM 版本(例如,5)。該映射與發布字母(例如 R)和 FCM 版本(例如 5)之間的映射相同。
VTS 測試強制設備在設備清單/vendor/etc/vintf/manifest.xml
中明確指定內核 FCM 版本,如果滿足以下條件之一:
- 內核 FCM 版本與目標 FCM 版本不同。例如,上述設備的目標 FCM 版本為 4,其內核 FCM 版本為 5(內核分支後綴
r
)。 - 內核 FCM 版本大於等於 5(內核分支後綴
r
)。
VTS 測試強制規定,如果指定了內核 FCM 版本,則內核 FCM 版本大於或等於設備清單中的目標 FCM 版本。
示例:確定內核分支
如果設備具有目標 FCM 版本 4(在 Android 10 中發布),但從4.19-r
分支運行內核,則設備清單應指定以下內容:
<manifest version="2.0" type="device" target-level="4"> <kernel target-level="5" /> </manifest>
VINTF 對像根據 FCM 版本 5 中指定的4.19-r
內核分支的要求檢查內核兼容性。這些要求是從 Android 源代碼樹中的kernel/configs/r/android-4.19
構建的。
示例:確定 GKI 的內核分支
如果設備使用通用內核映像 (GKI),並且/proc/version
中的內核版本字符串如下:
5.4.42-android12-0-00544-ged21d463f856
然後,VINTF 對像從內核版本中獲取 Android 版本,並使用它來確定內核 FCM 版本。在此示例中, android12
表示內核 FCM 版本 6(在 Android 12 中發布)。
有關如何解析內核版本字符串的詳細信息,請參閱GKI 版本控制。
匹配內核版本
一個矩陣可以包含多個<kernel>
部分,每個部分都有不同的version
屬性,格式如下:
${ver}.${major_rev}.${kernel_minor_rev}
VINTF 對象僅考慮來自 FCM 的<kernel>
部分,該部分具有與設備內核相同的${ver}
和${major_rev}
匹配的 FCM 版本(即version="${ver}.${major_rev}.${matrix_minor_rev}")
;其他部分被忽略。此外,內核的次要版本必須是兼容性矩陣中的值( ${kernel_minor_rev} >= ${matrix_minor_rev}
;)。如果沒有<kernel>
部分滿足這些要求,則它是不匹配的。
示例:選擇匹配要求
考慮以下假設情況,其中/system/etc/vintf
中的 FCM 聲明了以下要求(省略了頁眉和頁腳標籤):
<!-- compatibility_matrix.3.xml --> <kernel version="4.4.107" level="3"/> <!-- See kernel/configs/p/android-4.4/ for 4.4-p requirements --> <kernel version="4.9.84" level="3"/> <!-- See kernel/configs/p/android-4.9/ for 4.9-p requirements --> <kernel version="4.14.42" level="3"/> <!-- See kernel/configs/p/android-4.14/ for 4.14-p requirements --> <!-- compatibility_matrix.4.xml --> <kernel version="4.9.165" level="4"/> <!-- See kernel/configs/q/android-4.9/ for 4.9-q requirements --> <kernel version="4.14.105" level="4"/> <!-- See kernel/configs/q/android-4.14/ for 4.14-q requirements --> <kernel version="4.19.42" level="4"/> <!-- See kernel/configs/q/android-4.19/ for 4.19-q requirements --> <!-- compatibility_matrix.5.xml --> <kernel version="4.14.180" level="5"/> <!-- See kernel/configs/r/android-4.14/ for 4.14-r requirements --> <kernel version="4.19.123" level="5"/> <!-- See kernel/configs/r/android-4.19/ for 4.19-r requirements --> <kernel version="5.4.41" level="5"/> <!-- See kernel/configs/r/android-5.4/ for 5.4-r requirements -->
目標 FCM 版本、內核 FCM 版本和內核版本一起從 FCM 中選擇內核要求:
目標 FCM 版本 | 內核 FCM 版本 | 內核版本 | 匹配 |
---|---|---|---|
3 (P) | 未指定 | 4.4.106 | 不匹配(次要版本不匹配) |
3 (P) | 未指定 | 4.4.107 | 4.4-p |
3 (P) | 未指定 | 4.19.42 | 4.19-q (見下文註釋) |
3 (P) | 未指定 | 5.4.41 | 5.4-r (見下面的註釋) |
3 (P) | 3 (P) | 4.4.107 | 4.4-p |
3 (P) | 3 (P) | 4.19.42 | 不匹配(沒有4.19-p 內核分支) |
3 (P) | 4(問) | 4.19.42 | 4.19-q |
4(問) | 未指定 | 4.4.107 | 不匹配(沒有4.4-q 內核分支) |
4(問) | 未指定 | 4.9.165 | 4.9-q |
4(問) | 未指定 | 5.4.41 | 5.4-r (見下面的註釋) |
4(問) | 4(問) | 4.9.165 | 4.9-q |
4(問) | 4(問) | 5.4.41 | 不匹配(沒有5.4-q 內核分支) |
4(問) | 5(右) | 4.14.105 | 4.14-r |
4(問) | 5(右) | 5.4.41 | 5.4-r |
5(右) | 未指定 | 任何 | VTS 失敗(必須為目標 FCM 版本 5 指定內核 FCM 版本) |
5(右) | 4(問) | 任何 | VTS 失敗(內核 FCM 版本 < 目標 FCM 版本) |
5(右) | 5(右) | 4.14.180 | 4.14-r |
匹配內核配置
如果<kernel>
部分匹配,則該過程繼續嘗試將config
元素與/proc/config.gz
匹配。對於兼容性矩陣中的每個配置元素,它會查找/proc/config.gz
以查看配置是否存在。當匹配<kernel>
部分的兼容性矩陣中的配置項設置為n
時,它必須不在/proc/config.gz
中。最後,不在兼容性矩陣中的配置項可能會或可能不會出現在/proc/config.gz
中。
示例:匹配內核配置
<value type="string">bar</value>
匹配"bar"
。兼容性矩陣中省略了引號,但出現在/proc/config.gz
中。-
<value type="int">4096</value>
匹配4096
或0x1000
或0X1000
。 -
<value type="int">0x1000</value>
匹配4096
或0x1000
或0X1000
。 -
<value type="int">0X1000</value>
匹配4096
或0x1000
或0X1000
。 -
<value type="tristate">y</value>
匹配y
。 -
<value type="tristate">m</value>
匹配m
。 -
<value type="tristate">n</value>
表示配置項不能存在於/proc/config.gz
中。 -
<value type="range">1-0x3</value>
匹配1
、2
或3
或十六進制等效值。
示例:成功的內核匹配
FCM 版本 1 的框架兼容性矩陣具有以下內核信息:
<kernel version="4.14.42"> <config> <key>CONFIG_TRI</key> <value type="tristate">y</value> </config> <config> <key>CONFIG_NOEXIST</key> <value type="tristate">n</value> </config> <config> <key>CONFIG_DEC</key> <value type="int">4096</value> </config> <config> <key>CONFIG_HEX</key> <value type="int">0XDEAD</value> </config> <config> <key>CONFIG_STR</key> <value type="string">str</value> </config> <config> <key>CONFIG_EMPTY</key> <value type="string"></value> </config> </kernel>
首先匹配內核分支。內核分支在manifest.kernel.target-level
的設備清單中指定,如果未指定前者,則默認為manifest.level
。如果設備清單中的內核分支:
- 為 1,進行下一步並檢查內核版本。
- 為 2,與矩陣不匹配。 VINTF 對象改為從 FCM 版本 2 的矩陣中讀取內核要求。
然後,內核版本被匹配。如果uname()
中的設備報告:
- 4.9.84(與矩陣不匹配,除非有一個單獨的內核部分與
<kernel version="4.9.x">
,其中x <= 84
) - 4.14.41(不匹配矩陣,小於
version
) - 4.14.42(匹配矩陣)
- 4.14.43(匹配矩陣)
- 4.1.22(與矩陣不匹配,除非有一個單獨的內核部分,其中
<kernel version="4.1.x">
其中x <= 22
)
在選擇了適當的<kernel>
部分後,對於每個值不是n
的<config>
項,我們希望相應的條目出現在/proc/config.gz
中;對於每個值為n
的<config>
項,我們希望相應的條目不會出現在/proc/config.gz
中。我們希望<value>
的內容與等號(包括引號)之後的文本完全匹配,直到換行符或#
,前導和尾隨空格被截斷。
以下內核配置是成功匹配的示例:
# comments don't matter CONFIG_TRI=y # CONFIG_NOEXIST shouldn't exist CONFIG_DEC = 4096 # trailing comments and whitespaces are fine CONFIG_HEX=57005 # 0XDEAD == 57005 CONFIG_STR="str" CONFIG_EMPTY="" # empty string must have quotes CONFIG_EXTRA="extra config items are fine too"
以下內核配置是不成功匹配的示例:
CONFIG_TRI="y" # mismatch: quotes CONFIG_NOEXIST=y # mismatch: CONFIG_NOEXIST exists CONFIG_HEX=0x0 # mismatch; value doesn't match CONFIG_DEC="" # mismatch; type mismatch (expect int) CONFIG_EMPTY=1 # mismatch; expects "" # mismatch: CONFIG_STR is missing
SE 政策匹配
SE 策略需要以下匹配項:
-
<sepolicy-version>
為每個主要版本定義了一個封閉的次要版本範圍。設備報告的 sepolicy 版本必須在這些範圍之一內才能與框架兼容。匹配規則類似於 HAL 版本;如果 sepolicy 版本高於或等於該範圍的最低版本,則匹配。最高版本純粹是信息性的。 -
<kernel-sepolicy-version>
即policydb 版本。必須小於設備報告的security_policyvers()
。
示例:成功的 SE 策略匹配
框架兼容性矩陣說明了以下 sepolicy 信息:
<sepolicy> <kernel-sepolicy-version>30</kernel-sepolicy-version> <sepolicy-version>25.0</sepolicy-version> <sepolicy-version>26.0-3</sepolicy-version> </sepolicy>
在設備上:
-
security_policyvers()
返回的值必須大於等於 30。否則不匹配。例如:- 如果設備返回 29,則不匹配。
- 如果設備返回 31,則表示匹配。
- SE 策略版本必須是 25.0-∞ 或 26.0-∞ 之一。否則不匹配。 (“
26.0
”之後的“-3
”純粹是信息性的。)
AVB 版本匹配
AVB 版本包含 MAJOR 版本和 MINOR 版本,格式為 MAJOR.MINOR(如 1.0、2.1)。有關詳細信息,請參閱版本控制和兼容性。 AVB 版本具有以下系統屬性:
-
ro.boot.vbmeta.avb_version
是引導加載程序中的libavb
版本 ro.boot.avb_version
是 Android 操作系統中的libavb
版本 (init/fs_mgr
)
只有當相應的 libavb 已用於驗證 AVB 元數據(並返回 OK)時,系統屬性才會出現。如果發生驗證失敗(或根本沒有發生驗證),則不存在。
兼容性匹配比較以下內容:
- 來自框架兼容性矩陣的 sysprop
ro.boot.vbmeta.avb_version
和avb.vbmeta-version
;-
ro.boot.vbmeta.avb_version.MAJOR == avb.vbmeta-version.MAJOR
-
ro.boot.vbmeta.avb_version.MINOR >= avb.vbmeta-version.MINOR
-
- 來自框架兼容性矩陣的 sysprop
ro.boot.avb_version
和avb.vbmeta-version
。-
ro.boot.avb_version.MAJOR == avb.vbmeta-version.MAJOR
-
ro.boot.avb_version.MINOR >= avb.vbmeta-version.MINOR
-
引導加載程序或 Android 操作系統可能包含兩個libavb
庫副本,每個副本具有用於升級設備和啟動設備的不同 MAJOR 版本。在這種情況下,可以共享相同的未簽名系統映像,但最終簽名的系統映像不同(具有不同avb.vbmeta-version
):
/system
為 P,所有其他分區為 O)。示例:成功的 AVB 版本匹配
框架兼容性矩陣說明了以下 AVB 信息:
<avb> <vbmeta-version>2.1</vbmeta-version> </avb>
在設備上:
ro.boot.avb_version == 1.0 && ro.boot.vbmeta.avb_version == 2.1 mismatch
ro.boot.avb_version == 2.1 && ro.boot.vbmeta.avb_version == 3.0 mismatch
ro.boot.avb_version == 2.1 && ro.boot.vbmeta.avb_version == 2.3 match
ro.boot.avb_version == 2.3 && ro.boot.vbmeta.avb_version == 2.1 match
OTA期間匹配AVB版本
對於搭載 Android 9 或更低版本的設備,在更新到 Android 10 時,框架兼容性矩陣中的 AVB 版本要求與設備上當前的 AVB 版本相匹配。如果 AVB 版本在 OTA 期間有大版本升級(例如從 0.0 到 1.0),則 OTA 中的 VINTF 檢查兼容性並不能反映 OTA 後的兼容性。
為了緩解這個問題,OEM 可以在 OTA 包 ( compatibility.zip
) 中放置一個偽造的 AVB 版本以通過檢查。為此:
- 挑選以下 CL 到 Android 9 源代碼樹:
- 為設備定義
BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE
。它的值應該等於OTA之前的AVB版本,即設備啟動時的AVB版本。 - 重建 OTA 包。
這些更改會自動將BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE
作為compatibility-matrix.avb.vbmeta-version
放置在以下文件中:
- 設備上的
/system/compatibility_matrix.xml
(未在 Android 9 中使用) - OTA 包中的
compatibility.zip
中的system_matrix.xml
這些更改不會影響其他框架兼容性矩陣,包括/system/etc/vintf/compatibility_matrix.xml
。在 OTA 之後,/ /system/etc/vintf/compatibility_matrix.xml
中的新值將用於兼容性檢查。
VNDK 版本匹配
設備兼容性矩陣在compatibility-matrix.vendor-ndk.version
中聲明了所需的 VNDK 版本。如果設備兼容性矩陣沒有<vendor-ndk>
標記,則不會強加任何要求,因此它始終被視為匹配項。
如果設備兼容性矩陣確實具有<vendor-ndk>
標記,則會從框架清單中的框架提供的一組 VNDK 供應商快照中查找具有匹配<version>
的<vendor-ndk>
條目。如果這樣的條目不存在,則沒有匹配項。
如果確實存在這樣的條目,則設備兼容性矩陣中枚舉的庫集必須是框架清單中聲明的庫集的子集;否則,該條目不被視為匹配項。
- 作為一種特殊情況,如果設備兼容性矩陣中沒有枚舉庫,則該條目始終被視為匹配項,因為空集是任何集的子集。
示例:成功的 VNDK 版本匹配
如果設備兼容性矩陣對 VNDK 提出以下要求:
<!-- Example Device Compatibility Matrix --> <vendor-ndk> <version>27</version> <library>libjpeg.so</library> <library>libbase.so</library> </vendor-ndk>
在框架清單中,僅考慮版本為 27 的條目。
<!-- Framework Manifest Example A --> <vendor-ndk> <version>27</version> <library>libjpeg.so</library> <library>libbase.so</library> <library>libfoo.so</library> </vendor-ndk>
示例 A 匹配,因為 VNDK 版本 27 在框架清單中,並且{libjpeg.so, libbase.so, libfoo.so} ⊇ {libjpeg.so, libbase.so}
。
<!-- Framework Manifest Example B --> <vendor-ndk> <version>26</version> <library>libjpeg.so</library> <library>libbase.so</library> </vendor-ndk> <vendor-ndk> <version>27</version> <library>libbase.so</library> </vendor-ndk>
示例 B 不匹配。即使 VNDK 版本 27 在框架清單中,該快照中的框架也不支持libjpeg.so
。 VNDK 版本 26 被忽略。
系統 SDK 版本匹配
設備兼容性矩陣在compatibility-matrix.system-sdk.version
中聲明了一組所需的系統 SDK 版本。僅當該集合是框架清單中manifest.system-sdk.version
中聲明的所提供系統 SDK 版本的子集時,才存在匹配項。
- 作為一種特殊情況,如果設備兼容性矩陣中沒有枚舉系統 SDK 版本,則始終將其視為匹配,因為空集是任何集的子集。
示例:成功的系統 SDK 版本匹配
如果設備兼容性矩陣對 System SDK 提出以下要求:
<!-- Example Device Compatibility Matrix --> <system-sdk> <version>26</version> <version>27</version> </system-sdk>
然後,框架必須提供 System SDK 版本 26 和 27 來匹配。
<!-- Framework Manifest Example A --> <system-sdk> <version>26</version> <version>27</version> </system-sdk>
示例 A 是匹配項。
<!-- Framework Manifest Example B --> <system-sdk> <version>26</version> <version>27</version> <version>28</version> </system-sdk>
示例 B 是匹配項。
<!-- Framework Manifest Example C --> <system-sdk> <version>26</version> </system-sdk>
示例 C 不匹配,因為未提供系統 SDK 版本 27。