匹配規則

這兩對相容性矩陣和清單旨在進行協調,以驗證框架和供應商實作是否可以相互協作。當框架相容性矩陣與裝置清單之間以及框架清單與裝置相容性矩陣之間相符時,此驗證成功。

此驗證在建置時、 OTA更新套件產生時、啟動時以及 VTS 相容性測試中完成。

以下部分詳細介紹了各個組件所使用的匹配規則。

框架相容性矩陣版本匹配

要將設備清單與框架相容性矩陣相匹配, manifest.target-level指定的運輸 FCM 版本必須與compatibility-matrix.level指定的 FCM 版本完全相同。不然就沒比賽了

當使用libvintf請求框架相容性矩陣時,此匹配始終成功,因為libvintf打開設備清單,檢索運輸FCM 版本,並返回該運輸FCM 版本的框架兼容性矩陣(加上來自更高FCM 的兼容性矩陣的某些可選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.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 更新流程。
因此,清單檔案中具有版本 2.10 的 HAL 的裝置仍然與其相容性矩陣中聲明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-∞。在相容性矩陣中, 55-5的簡寫。
5-7 5-∞。表示以下內容:
  • 5 是所需的最低版本,這意味著提供 HAL 1-4 的清單不相容。
  • 7 是可以要求的最大版本,這表示相容性矩陣(框架或裝置)的擁有者不會要求超過 7 的版本。當請求 7 時,符合清單的擁有者仍然可以提供版本 10(作為範例) 。相容性矩陣擁有者只知道所要求的服務與 API 版本 7 相容。
  • -7僅供參考,不會影響 OTA 更新流程。
因此,清單檔案中具有版本 10 的 HAL 的裝置仍然與其相容性矩陣中聲明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(頁)未指定4.4.106不符(次要版本不符)
3(頁)未指定4.4.107 4.4-p
3(頁)未指定4.19.42 4.19-q (見下面的註釋)
3(頁)未指定5.4.41 5.4-r (見下面的註釋)
3(頁) 3(頁) 4.4.107 4.4-p
3(頁) 3(頁) 4.19.42不匹配(沒有4.19-p內核分支)
3(頁) 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>符合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>的內容與等號(包括引號)後面的文字完全匹配,直到換行符或# ,並截斷前導和尾隨空格。

以下核心配置是成功匹配的範例:

# 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是 bootloader 中的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庫副本,每個副本都有不同的主要版本用於升級裝置和啟動裝置。在這種情況下,可以共享相同的未簽名系統映像,但最終簽署的系統映像不同(具有不同的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 後的兼容性。

為了緩解這個問題,OEM 可以在 OTA 套件 ( compatibility.zip ) 中放置一個假的 AVB 版本來通過檢查。為此:

  1. 在 Android 9 原始碼樹中精選以下 CL:
  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 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版本匹配成功

如果設備相容性矩陣對系統 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。