Две пары матриц совместимости и манифестов должны быть согласованы, чтобы убедиться, что фреймворк и реализация поставщика могут работать друг с другом. Проверка считается успешной, если матрица совместимости фреймворка соответствует манифесту устройства, а манифест фреймворка – матрице совместимости устройства.
Проверка выполняется во время сборки, при создании пакета беспроводного обновления, во время загрузки и в тестах на совместимость VTS.
В следующих разделах подробно описаны правила сопоставления, используемые различными компонентами.
Соответствие версий матрицы совместимости фреймворков
Чтобы сопоставить манифест устройства с матрицей совместимости фреймворка, версия FCM, указанная в manifest.target-level, должна точно совпадать с версией FCM, указанной в compatibility-matrix.level. В противном случае соответствия не будет.
Если матрица совместимости фреймворка запрашивается с помощью libvintf, то сопоставление всегда будет успешным, поскольку libvintf открывает манифест устройства, извлекает версию FCM, которая поставляется с устройством, и возвращает матрицу совместимости фреймворка для этой версии FCM (плюс некоторые необязательные HAL из матриц совместимости для более высоких версий FCM).
Совпадения с HAL
Правило HAL-match определяет версии элементов hal в файле манифеста, которые считаются поддерживаемыми владельцем соответствующей матрицы совместимости.
HIDL и нативные HAL
Правила соответствия для HIDL и нативных HAL:
- Несколько элементов
<hal>оцениваются с помощью одного отношения AND. - У элементов
<hal>может быть атрибут<hal optional="true">, чтобы указать, что они не обязательны. - Несколько элементов
<version>в одном элементе<hal>связаны оператором ИЛИ. Если указано несколько версий, достаточно реализовать одну из них. (См. Успешное сопоставление HAL для модуля DRM.) - Несколько элементов
<instance>и<regex-instance>в одном элементе<hal>оцениваются с помощью одного отношения И, если элемент<hal>является обязательным. (См. Успешное сопоставление HAL для модуля DRM.)
Пример: успешное сопоставление HAL для модуля
Для HAL версии 2.5 правило соответствия выглядит следующим образом:
| Матрица | Соответствующий манифест |
|---|---|
2.5 |
2.5–2.∞. В таблице совместимости 2.5 – это сокращенная запись для 2.5-5. |
2.5-7 |
2.5–2.∞. Указывает на следующее:
2.5-7. |
Пример: успешное сопоставление HAL для модуля DRM
В матрице совместимости фреймворков указана следующая информация о версии для 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
HAL-уровни AIDL
Android и более поздние версии поддерживают версии для AIDL HAL в VINTF.
Правила сопоставления для AIDL HAL аналогичны правилам для HIDL и нативных HAL, за исключением того, что нет основных версий и существует ровно одна версия для каждого экземпляра HAL (1, если версия не указана):
- Несколько элементов
<hal>оцениваются с помощью одного отношения И. - У элементов
<hal>может быть атрибут<hal optional="true">, чтобы пометить их как необязательные. - Несколько элементов
<instance>и<regex-instance>в одном элементе<hal>оцениваются с помощью одного логического оператора И, если элемент<hal>является обязательным. (См. раздел Успешное сопоставление HAL для нескольких модулей.)
Пример успешного сопоставления HAL для модуля
Для HAL версии 5 правило соответствия выглядит следующим образом:
| Матрица | Соответствующий манифест |
|---|---|
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 4 (выпущена в Android 10), но используется ядро из ветки 4.19-r, в манифесте устройства должно быть указано следующее:
<manifest version="2.0" type="device" target-level="4"> <kernel target-level="5" /> </manifest>
Объект VINTF проверяет совместимость ядра с требованиями к ветви ядра 4.19-r, которая указана в FCM версии 5. Эти требования основаны на
kernel/configs/r/android-4.19
в дереве исходного кода Android.
Пример: как определить ветку ядра для 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 учитывает только раздел <kernel> из файла FCM с версией, совпадающей с версией ядра устройства (version="${ver}.${major_rev}.${matrix_minor_rev}")), а также с теми же значениями ${ver} и ${major_rev}. Другие разделы игнорируются. Кроме того, дополнительная версия ядра должна быть значением из матрицы совместимости (${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 (П) | Не указано | 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 (Q) | 4.19.42 | 4.19-q |
| 4 (Q) | Не указано | 4.4.107 | Нет совпадений (нет ветви ядра 4.4-q) |
| 4 (Q) | Не указано | 4.9.165 | 4.9-q |
| 4 (Q) | Не указано | 5.4.41 | 5.4-r (см. примечание после таблицы) |
| 4 (Q) | 4 (Q) | 4.9.165 | 4.9-q |
| 4 (Q) | 4 (Q) | 5.4.41 | Несоответствие (нет ветви ядра 5.4-q) |
| 4 (Q) | 5 (R) | 4.14.105 | 4.14-r |
| 4 (Q) | 5 (R) | 5.4.41 | 5.4-r |
| 5 (R) | Не указано | любой | Сбой VTS (необходимо указать версию FCM ядра для целевой версии FCM 5) |
| 5 (R) | 4 (Q) | любой | VTS не проходит (версия FCM ядра < целевой версии FCM) |
| 5 (R) | 5 (R) | 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>, для каждого элемента <config> со значением, отличным от n, в разделе /proc/config.gz должна быть соответствующая запись. Для каждого элемента <config> со значением n в разделе /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
Совпадения с правилами SEPolicy
SEPolicy требует следующих соответствий:
<sepolicy-version>определяет закрытый диапазон промежуточных версий для каждой основной версии. Версия SEPolicy, указанная устройством, должна входить в один из этих диапазонов, чтобы быть совместимой с фреймворком. Правила сопоставления аналогичны версиям HAL; это совпадение, если версия SEPolicy выше или равна минимальной версии для диапазона. Максимальная версия указана только для информации.<kernel-sepolicy-version>, то есть версия базы данных правил, должна быть меньше, чемsecurity_policyvers(), сообщенная устройством.
Пример успешного сопоставления 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 содержит основную и дополнительную версии в формате "ОСНОВНАЯ.ДОПОЛНИТЕЛЬНАЯ" (например, 1.0, 2.1). Подробнее об управлении версиями и совместимости… У версии AVB есть следующие системные свойства:
ro.boot.vbmeta.avb_version– это версияlibavbв загрузчике.ro.boot.avb_version– это версияlibavbв ОС Android (init/fs_mgr).
Системное свойство появляется, только если для проверки метаданных AVB использовался соответствующий libavb (и возвращается значение OK). Если проверка не была выполнена или завершилась неудачно, этот параметр отсутствует.
При проверке совместимости сравниваются следующие параметры:
- sysprop
ro.boot.vbmeta.avb_versionсavb.vbmeta-versionиз матрицы совместимости фреймворка:ro.boot.vbmeta.avb_version.MAJOR == avb.vbmeta-version.MAJORro.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.MAJORro.boot.avb_version.MINOR >= avb.vbmeta-version.MINOR
Загрузчик или ОС Android могут содержать две копии библиотек libavb, каждая из которых имеет разную ОС MAJOR для устройств с обновлением и устройств с запуском. В этом случае можно использовать одно и то же неподписанное системное изображение, но конечные подписанные системные изображения будут разными (с разными 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
Соответствие версии AVB во время беспроводного обновления
Если устройство было выпущено с Android 9 или более ранней версией, при обновлении до Android 10 требования к версии AVB в матрице совместимости фреймворка сравниваются с текущей версией AVB на устройстве. Если во время беспроводного обновления основная версия AVB меняется (например, с 0.0 на 1.0), проверка совместимости VINTF не отражает совместимость после обновления.
Чтобы устранить проблему, OEM-производитель может поместить поддельную версию AVB в пакет OTA (compatibility.zip), чтобы пройти проверку. Вот как это сделать:
- Выберите следующие CL в дереве исходного кода Android 9:
- Задайте
BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDEдля устройства. Его значение должно быть равно версии AVB до OTA, то есть версии AVB устройства на момент его запуска. - Соберите пакет OTA заново.
Эти изменения автоматически заменяют BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE на compatibility-matrix.avb.vbmeta-version в следующих файлах:
/system/compatibility_matrix.xml(не используется в Android 9).system_matrix.xmlвcompatibility.zipв пакете OTA
Эти изменения не влияют на другие матрицы совместимости фреймворка, включая /system/etc/vintf/compatibility_matrix.xml. После обновления по воздуху для проверки совместимости используется новое значение в поле /system/etc/vintf/compatibility_matrix.xml.
Соответствие версий VNDK
В матрице совместимости устройств указана требуемая версия VNDK в
compatibility-matrix.vendor-ndk.version. Если в матрице совместимости устройств нет тега <vendor-ndk>, требования не накладываются и устройство всегда считается совместимым.
Если в матрице совместимости устройств есть тег <vendor-ndk>, то из набора снимков VNDK поставщика, который предоставляется фреймворком в манифесте фреймворка, ищется запись <vendor-ndk> с соответствующим <version>. Если такой записи нет, соответствие не будет найдено.
Если такая запись существует, набор библиотек, перечисленных в матрице совместимости устройств, должен быть подмножеством набора библиотек, указанных в манифесте фреймворка. В противном случае запись не считается подходящей.
- Если в матрице совместимости устройств не указаны библиотеки, запись всегда считается соответствующей, поскольку пустое множество является подмножеством любого множества.
Пример успешного сопоставления версий 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>
Пример Б не соответствует. Несмотря на то что версия VNDK 27 указана в манифесте фреймворка, libjpeg.so не поддерживается фреймворком в этом снимке. VNDK версии 26 игнорируется.
Соответствие версии системного SDK
Матрица совместимости устройств объявляет набор необходимых версий системного SDK в compatibility-matrix.system-sdk.version. Совпадение будет только в том случае, если набор является подмножеством версий SDK, указанных в манифесте фреймворка в элементе manifest.system-sdk.version.
- В особом случае, если в матрице совместимости устройства не указаны версии системного 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>Пример А (совпадение):
<!-- Framework Manifest Example B -->
<system-sdk>
<version>26</version>
<version>27</version>
<version>28</version>
</system-sdk>Пример Б соответствует запросу:
<!-- Framework Manifest Example C -->
<system-sdk>
<version>26</version>
</system-sdk>Пример C не подходит, потому что версия 27 системного SDK не указана.