比對規則

這兩組相容性矩陣和資訊清單應進行比對,確認架構和供應商實作項目可相互搭配運作。如果架構相容性矩陣與裝置資訊清單相符,且架構資訊清單與裝置相容性矩陣相符,驗證就會成功。

這項驗證會在建構時、OTA 更新套件產生時、啟動時,以及 VTS 相容性測試中進行。

以下各節將詳細說明各個元件使用的比對規則。

架構相容性矩陣版本相符

如要將裝置資訊清單與架構相容性矩陣相符,manifest.target-level 指定的出貨 FCM 版本必須與 compatibility-matrix.level 指定的 FCM 版本完全相同。否則不相符。

使用 libvintf 要求架構相容性矩陣時,一律會成功比對,因為 libvintf 會開啟裝置資訊清單、擷取出貨 FCM 版本,並傳回該出貨 FCM 版本的架構相容性矩陣 (加上較高 FCM 版本相容性矩陣中的一些選用 HAL)。

HAL 相符

HAL 比對規則會找出資訊清單檔案中 hal 元素的版本,這些版本會視為相應相容性矩陣擁有者支援的版本。

HIDL 和原生 HAL

HIDL 和原生 HAL 的比對規則如下:

  • 系統會使用單一 AND 關係評估多個 <hal> 元素。
  • <hal> 元素可以有 <hal optional="true">,將其標示為非必要。
  • 同一 <hal> 元素中的多個 <version> 元素具有 OR 關係。如果指定兩個以上,只需要實作其中一個版本。(請參閱「DRM 模組的 HAL 比對成功」。)
  • 如果需要 <hal>,系統會以單一 AND 關係評估同一 <hal> 元素中的多個 <instance><regex-instance> 元素。(請參閱「DRM 模組的 HAL 比對成功」)。

示例:模組的 HAL 比對成功

如果是 2.5 版的 HAL,比對規則如下:

矩陣 相符的資訊清單
2.5 2.5-2.∞。在相容性矩陣中,2.52.5-5 的簡寫。
2.5-7 2.5-2.∞。表示以下內容:
  • 最低版本需求為 2.5,也就是說,提供 HAL 2.0 至 2.4 的資訊清單不相容。
  • 2.7 是可要求的最高版本,也就是說,相容性矩陣 (架構或裝置) 的擁有者無法要求高於 2.7 的版本。即使要求的是 2.7 版,相符資訊清單的擁有者仍可提供 2.10 版 (舉例來說)。相容性矩陣擁有者只知道所要求的服務與 API 2.7 版相容。
  • -7 僅供參考,不會影響 OTA 更新程序。
因此,資訊清單檔案中 HAL 版本為 2.10 的裝置,仍與相容性矩陣中聲明 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

且必須實作所有這些例項:

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 以上版本支援 VINTF 中的 AIDL HAL 版本。 AIDL HAL 的比對規則與 HIDL 和原生 HAL 類似,但沒有主要版本,且每個 HAL 執行個體只有一個版本 (如果未指定版本,則為 1):

  • 系統會使用單一 AND 關係評估多個 <hal> 元素。
  • <hal> 元素可以有 <hal optional="true">,將其標示為非必要。
  • 如果需要 <hal>,系統會以單一 AND 關係評估同一 <hal> 中的多個 <instance><regex-instance> 元素。(請參閱「多個模組的 HAL 成功比對」)。

示例:模組的 HAL 比對成功

如果是 HAL 第 5 版,比對規則如下:

矩陣 相符的資訊清單
5 5-∞。在相容性矩陣中,55-5 的簡寫。
5-7 5-∞。表示以下內容:
  • 最低版本需求為 5,也就是說,提供 HAL 1 到 4 的資訊清單不相容。
  • 7 是可要求的最高版本,也就是說,相容性矩陣 (架構或裝置) 的擁有者不會要求高於 7 的版本。如果要求的是版本 7,相符資訊清單的擁有者仍可提供版本 10 (舉例來說)。相容性矩陣擁有者只知道所要求的服務與 API 版本 7 相容。
  • -7 僅供參考,不會影響 OTA 更新程序。
因此,資訊清單檔案中 HAL 版本為 10 的裝置,仍與相容性矩陣中聲明 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 賽事

架構相容性矩陣的 <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 分支的 Kernel,裝置資訊清單應指定下列項目:

<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 中與裝置核心 (即 version="${ver}.${major_rev}.${matrix_minor_rev}")) 具有相同 ${ver}${major_rev}<kernel> 區段,並忽略其他區段。此外,核心的次要修訂版本必須是相容性矩陣 (${kernel_minor_rev} >= ${matrix_minor_rev}) 中的值。如果沒有任何 <kernel> 區段符合這些規定,則為不相符。

範例:選取相符條件

假設 FCM /system/etc/vintf 聲明下列需求 (省略頁首和頁尾代碼):

<!-- 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.1074.4-p
3 (P)未指定4.19.424.19-q (請參閱表格後方的附註)
3 (P)未指定5.4.415.4-r (請參閱表格後方的附註)
3 (P)3 (P)4.4.1074.4-p
3 (P)3 (P)4.19.42不相符 (沒有 4.19-p 核心分支版本)
3 (P)4 (Q)4.19.424.19-q
4 (Q)未指定4.4.107不相符 (沒有 4.4-q 核心分支版本)
4 (Q)未指定4.9.1654.9-q
4 (Q)未指定5.4.415.4-r (請參閱表格後方的附註)
4 (Q)4 (Q)4.9.1654.9-q
4 (Q)4 (Q)5.4.41不相符 (沒有 5.4-q 核心分支版本)
4 (Q)5 (R)4.14.1054.14-r
4 (Q)5 (R)5.4.415.4-r
5 (R)未指定任何VTS 失敗 (必須指定目標 FCM 版本 5 的核心 FCM 版本)
5 (R)4 (Q)任何VTS 失敗 (核心 FCM 版本 < 目標 FCM 版本)
5 (R)5 (R)4.14.1804.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>相符 40960x10000X1000
  • <value type="int">0x1000</value>相符 40960x10000X1000
  • <value type="int">0X1000</value>相符 40960x10000X1000
  • <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>123 相符,或與十六進位等值相符。

範例:核心比對成功

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> 的內容應與等號後的文字完全相符 (包括引號),直到換行字元或 # 為止,並截斷開頭和結尾的空白字元。

以下是成功比對的 Kernel 設定範例:

# 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

SEPolicy 比對

SEPolicy 需要下列比對項目:

  • <sepolicy-version> 會為每個主要版本定義次要版本的封閉範圍。裝置回報的 SEPolicy 版本必須落在其中一個範圍內,才能與架構相容。比對規則與 HAL 版本類似;如果 SEPolicy 版本高於或等於範圍的最低版本,即為比對。最高版本僅供參考。
  • 也就是說,政策資料庫版本必須低於裝置回報的 security_policyvers()<kernel-sepolicy-version>

範例:成功比對 SEPolicy

架構相容性矩陣會列出下列 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,表示相符。
  • SEPolicy 版本必須為 25.0-∞ 或 26.0-∞,否則不符合條件。(-3 後方的 26.0 純粹是資訊用途)。

AVB 版本相符

AVB 版本包含主版本和次要版本,格式為 MAJOR.MINOR (例如 1.0、2.1)。詳情請參閱「版本管理與相容性」。AVB 版本具有下列系統屬性:

  • ro.boot.vbmeta.avb_version 是系統啟動載入程式中的libavb版本。
  • ro.boot.avb_version 是 Android 作業系統 (init/fs_mgr) 中的 libavb 版本。

只有在已使用對應的 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 OS 可能包含兩個 libavb 程式庫副本,升級裝置和推出裝置的每個副本都有不同的主要版本。在這種情況下,可以共用相同的「未簽署」系統映像檔,但最終的「已簽署」系統映像檔會有所不同 (具有不同的 avb.vbmeta-version):

圖 1. AVB 版本相符 (「/system」為 P,所有其他分割區為 O)。



圖 2. AVB 版本相符 (所有分區都是 P)。

範例:成功比對 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 後的相容性。

為解決這個問題,原始設備製造商可以在 OTA 套件 (compatibility.zip) 中放置假的 AVB 版本,以通過檢查。方法如下:

  1. 將下列 CL 挑選至 Android 9 來源樹狀結構:
  2. 為裝置定義 BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE。這個值應等於 OTA 前的 AVB 版本,也就是裝置推出時的 AVB 版本。
  3. 重建 OTA 套件。

這些變更會自動將 BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE放置在 compatibility-matrix.avb.vbmeta-version下列檔案中:

  • /system/compatibility_matrix.xml (Android 9 未使用)
  • OTA 套件中的 system_matrix.xmlcompatibility.zip

這些變更不會影響其他架構相容性矩陣,包括 /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 版本比對成功

如果裝置相容性矩陣中列出以下系統 SDK 要求:

<!-- Example Device Compatibility Matrix -->
<system-sdk>
    <version>26</version>
    <version>27</version>
</system-sdk>

然後,架構必須提供系統 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 未提供。