Matching Rules

The two pairs of compatibility matrices and manifests are meant to be reconciled at OTA time to verify the framework and vendor implementation can work with each other. This verification is successful upon a match between the framework compatibility matrix and the device manifest, as well as between the framework manifest and the device compatibility matrix. The following sections detail matching rules used by various components.

HAL matches

The HAL-match rule identifies the versions of hal elements in a manifest file that are considered supported by the owner of the corresponding compatibility matrix.

  • Multiple version elements are concatenated with OR (see camera example below).
  • Multiple <hal> elements with the same name are concatenated with AND.

Example: Successful HAL match for Camera module

For a HAL at version 2.5, the match rule is as follows:

Matrix Matching Manifest
2.5 2.5-2.∞. Shorthand for 2.5-5.
2.5-7 2.5-2.∞. Indicates the following:
  • 2.5 is the minimum required version, meaning a manifest providing HAL 2.0-2.4 is not compatible.
  • 2.7 is the maximum version that could be requested, meaning the owner of the compatibility matrix (framework or device) will not request versions beyond 2.7. The owner of the matching manifest can still serve version 2.10 (as an example) when 2.7 is requested. The compatibility-matrix owner knows only that the requested service is compatible with API version 2.7.
  • -7 is informational only and does not affect the OTA update process.
Thus, a device with a HAL at version 2.10 in its manifest file remains compatible with a framework that states camera: 2.5-7 in its compatibility matrix.

Example: Successful HAL match for DRM module

The framework compatibility matrix states the following version information for 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>
    </interface>
</hal>

A vendor must implement ONE of the following HALs:

android.hardware.drm@1.x::IDrmFactory/default          //where x >= 0
android.hardware.drm@1.x::IDrmFactory/specific         //where x >= 0
OR
android.hardware.drm@3.y::IDrmFactory/default          //where y >= 1
android.hardware.drm@3.y::IDrmFactory/specific         //where y >= 1

... AND must also implement this HAL:

android.hardware.drm@2.z::ICryptoFactory/default       //where z >= 0

Kernel matches

The <kernel> section of the framework compatibility matrix describes the framework's requirements of the Linux kernel on the device. This information is meant to be matched at OTA time against the information about the kernel that gets reported by the device's VINTF object.

A matrix can include multiple <kernel> sections, each with a different version attribute using the format:

${ver}.${major_rev}.${kernel_minor_rev}

The OTA considers only the <kernel> section with the same ${ver} and ${major_rev} as the device kernel (i.e., version="${ver}.${major_rev}.${matrix_minor_rev}"); other sections are ignored. In addition, the minor revision from the kernel must be a value from the compatibility matrix (${kernel_minor_rev} >= ${matrix_minor_rev};). If no <kernel> section meets these requirements, it is a non-match.

If the <kernel> section does match, the process continues by attempting to match config elements against /proc/config.gz. For each config element in the compatibility matrix, it looks up /proc/config.gz to see if the config is present. When a config item is set to n in the compatibility matrix for the matching <kernel> section, it must be absent from /proc/config.gz. Finally, a config item not in the compatibility matrix may or may not be present in /proc/config.gz.

Examples of matches:

  • <value type="string">bar</value> matches "bar". Quotes are omitted in the compatibility matrix but present in /proc/config.gz.
  • <value type="int">4096</value> matches 4096 or 0x1000 or 0X1000.
  • <value type="int">0x1000</value> matches 4096 or 0x1000 or 0X1000.
  • <value type="int">0X1000</value> matches 4096 or 0x1000 or 0X1000.
  • <value type="tristate">y</value> matches y.
  • <value type="tristate">m</value> matches m.
  • <value type="tristate">n</value> means the config item must NOT exist in /proc/config.gz.
  • <value type="range">1-0x3</value> matches 1, 2, or 3, or hexadecimal equivalent.

Example: Successful kernel match

A framework compatibility matrix has the following kernel information:

<kernel version="3.18.51">
   <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>

The kernel version is matched first. If a device in uname() reports:

  • 3.10.73 (no match to matrix unless there is a separate kernel section with <kernel version="3.10.x"> where x <= 73)
  • 3.18.50 (no match to matrix, smaller than version)
  • 3.18.51 (match to matrix)
  • 3.18.52 (match to matrix)
  • 4.1.22 (no match to matrix unless there is a separate kernel section with <kernel version="4.1.x"> where x <= 22)

After the appropriate <kernel> section is selected, for each <config> item with value other than n, we expect the corresponding entry to be present in /proc/config.gz; for each <config> item with value n, we expect the corresponding entry to not be present in /proc/config.gz. We expect the content of <value> to exactly match the text after the equal sign (including quotes), up to the newline character or #, with leading and trailing whitespace truncated.

The following kernel configuration is an example of a successful match:

# comments don't matter
CONFIG_TRI=y
# CONFIG_NOEXIST should not 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"

The following kernel configuration is an example of an unsuccessful match:

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 policy matches

SE policy requires the following matches:

  • <sepolicy-version> defines a closed range of minor versions for every major version. The sepolicy version reported by the device must fall within one of these ranges to be compatible with the framework. Match rules are similar to HAL versions; it is a match if the sepolicy version is higher or equal to the minimum version for the range. The maximum version is purely informational.
  • <kernel-sepolicy-version> i.e. policydb version. Must exactly match the security_policyvers() reported by the device.

Example: Successful SE policy match

The framework compatibility matrix states the following sepolicy information:

    <sepolicy>
        <kernel-sepolicy-version>30</kernel-sepolicy-version>
        <sepolicy-version>25.0</sepolicy-version>
        <sepolicy-version>26.0-3</sepolicy-version>
    </sepolicy>

On the device:

  • The value returned by security_policyvers() must exactly equal 30. Otherwise it is not a match.
  • SE Policy version must be one of 25.0-∞ or 26.0-∞. Otherwise it is not a match. (The "-3" after "26.0" is purely informational.)

AVB version matches

The AVB version contains a MAJOR version and MINOR version, with the format as MAJOR.MINOR (e.g., 1.0, 2.1). For details, refer to Versioning and Compatibility. AVB version has the following system properties:

  • ro.boot.vbmeta.avb_version is the libavb version in bootloader
  • ro.boot.avb_version is the libavb version in Android OS (init/fs_mgr)

The system property appears only when the corresponding libavb has been used to verify AVB metadata (and returns OK). It is absent if a verification failure occurred (or no verification occurred at all).

A compatibility match compares the following:

  • sysprop ro.boot.vbmeta.avb_version with avb.vbmeta-version from framework compatibility matrix;
    • 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 with avb.vbmeta-version from framework compatibility matrix.
    • ro.boot.avb_version.MAJOR == avb.vbmeta-version.MAJOR
    • ro.boot.avb_version.MINOR >= avb.vbmeta-version.MINOR

The bootloader or Android OS might contain two copies of libavb libraries, each with a different MAJOR version for upgrade devices and launch devices. In this case, the same unsigned system image can be shared but the final signed system images are different (with different avb.vbmeta-version):

Figure 1. AVB version matches (/system is P, all other partitions are O).


Figure 2. AVB version matches (all partitions are P).

Example: Successful AVB version match

The framework compatibility matrix states the following AVB information:

<avb>
    <vbmeta-version>2.1</vbmeta-version>
</avb>

On the device:

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