Обзор Vendor Native Development Kit (VNDK)

Vendor Native Development Kit (VNDK) – это набор библиотек, которые используются другими библиотеками или исполняемыми файлами в разделе поставщика или продукта во время выполнения для dlopen.

Прежней версии

Vendor NDK был представлен в Android 8.0, чтобы предоставить API для взаимодействия между фреймворком и кодом поставщика. VNDK успешно используется уже много лет, но у него есть недостатки:
  • Хранилище
    • Один VNDK APEX упаковывает все библиотеки VNDK, независимо от того, используются ли они с устройства или нет.
    • В GSI есть несколько версий VNDK APEX, чтобы поддерживать разные версии образов поставщика.
  • Возможность обновления
    • Сложно обновлять VNDK APEX отдельно от платформы.
    • Образы поставщиков часто обновляются по беспроводной сети, поэтому преимущества VNDK, упакованного в образ системы, снижаются.
Из-за этих проблем мы решили прекратить поддержку VNDK в Android 15.

Подробнее о прекращении поддержки VNDK

Все библиотеки VNDK упакованы в VNDK APEX и установлены в системный образ (-ext). После прекращения поддержки VNDK библиотеки, которые раньше входили в VNDK, устанавливаются в образ поставщика (или продукта) так же, как и другие библиотеки, доступные поставщику. Вместе с VNDK будут удалены следующие функции:
  • VNDK APEX для Android 15
  • Системные свойства, указывающие на версию целевого VNDK, удаляются, если разделы поставщика или продукта созданы для Android 15:
    • ro.vndk.version
    • ro.product.vndk.version
  • Оптимизация VNDK будет недоступна, поскольку VNDK отсутствует:
    • TARGET_VNDK_USING_CORE_VARIANT для устройств Android Go
    • use_vndk_as_stable для APEX-пакетов поставщиков
  • Снимок поставщика, который сильно зависит от VNDK.

Исключения из прекращения поддержки

Следующие функции не изменятся после прекращения поддержки VNDK:
  • VNDK APEX с версией VNDK 14 или ниже, которые необходимы для поддержки существующих образов поставщиков.
  • LL-NDK не входит в VNDK.

Зачем нужен VNDK?

В AOSP можно обновлять только фреймворк. При этом системный раздел можно обновить до последней версии фреймворка, а раздел поставщика останется без изменений. Несмотря на то, что они создаются в разное время, двоичные файлы в каждом разделе должны быть совместимы друг с другом.

Обновления только фреймворка могут привести к следующим проблемам:

  • Зависимость между модулями фреймворка и модулями поставщика. До Android 8.0 модули в разделе поставщика и системном разделе могли быть связаны друг с другом. Однако зависимости от модулей поставщиков накладывали нежелательные ограничения на разработку модулей фреймворка.
  • Расширения библиотек AOSP. Согласно требованиям Android, все устройства Android должны проходить CTS, когда системный раздел заменяется стандартным общим образом системы (GSI). Однако, когда поставщики расширяют библиотеки AOSP, чтобы повысить производительность или добавить дополнительные функции для своих реализаций HIDL, прошивка системного раздела стандартным образом с помощью GSI может нарушить реализацию HIDL поставщика. Рекомендации по предотвращению таких сбоев приведены в разделе Расширения VNDK.

Чтобы решить эти проблемы, в Android есть несколько функций, таких как VNDK (описана в этом разделе), HIDL, hwbinder, наложение дерева устройств и наложение sepolicy.

Условия использования VNDK

В документах, связанных с VNDK, используется следующая терминология:
  • Модули – это общие библиотеки или исполняемые файлы. Модули создают зависимости во время сборки.
  • Процессы – это задачи операционной системы, созданные на основе исполняемых файлов. Процессы создают зависимости во время выполнения.
  • Термины, относящиеся к фреймворку, связаны с разделом system:
    • Исполняемые файлы фреймворка – это исполняемые файлы в /system/bin или /system/xbin.
    • Общие библиотеки фреймворка – это общие библиотеки в каталоге /system/lib[64].
    • Модули фреймворка – это общие библиотеки и исполняемые файлы фреймворка.
    • Процессы фреймворка – это процессы, запущенные из исполняемых файлов фреймворка, например /system/bin/app_process.
  • Термины, относящиеся к поставщику, связаны с разделами vendor:
    • Исполняемые файлы поставщика – это исполняемые файлы в /vendor/bin.
    • Общие библиотеки поставщиков – это общие библиотеки в разделе /vendor/lib[64].
    • Модули поставщика – это исполняемые файлы и общие библиотеки поставщика.
    • Процессы поставщика – это процессы, запущенные исполняемыми файлами поставщика, например /vendor/bin/android.hardware.camera.provider@2.4-service.

Концепции VNDK

В идеальном мире Android 8.0 и более поздних версий процессы фреймворка не загружают общие библиотеки поставщика, все процессы поставщика загружают только общие библиотеки поставщика (и часть общих библиотек фреймворка), а связь между процессами фреймворка и процессами поставщика регулируется HIDL и аппаратным связывателем.

В таком мире стабильных общедоступных API из общих библиотек фреймворка может быть недостаточно для разработчиков модулей поставщиков (хотя API могут меняться между выпусками Android), поэтому часть общих библиотек фреймворка должна быть доступна для процессов поставщиков. Кроме того, поскольку требования к производительности могут привести к компромиссам, к некоторым HAL, критичным ко времени отклика, необходимо относиться по-другому.

В следующих разделах рассказывается о том, как VNDK обрабатывает общие библиотеки фреймворка для поставщиков и HAL, работающие в том же процессе (SP-HAL).

Общие библиотеки фреймворка для поставщика

В этом разделе описаны критерии классификации общих библиотек, доступных для процессов поставщика. Есть два подхода к поддержке модулей поставщиков в разных версиях Android:

  1. Стабилизируйте ABI/API общих библиотек фреймворка. Новые модули фреймворка и старые модули поставщика могут использовать одну и ту же общую библиотеку, чтобы уменьшить занимаемый объем памяти и размер хранилища. Уникальная общая библиотека также позволяет избежать нескольких проблем с двойной загрузкой. Однако затраты на разработку для поддержания стабильности ABI/API высоки, и стабилизировать все ABI/API, экспортируемые каждой общей библиотекой фреймворка, нереально.
  2. Копирование общих библиотек старого фреймворка Включает строгие ограничения на использование побочных каналов, под которыми понимаются все механизмы связи между модулями фреймворка и модулями поставщика, включая (но не ограничиваясь) binder, сокет, канал, общую память, общий файл и системные свойства. Связь должна быть только в том случае, если протокол связи заморожен и стабилен (например, HIDL через hwbinder). Двойная загрузка общих библиотек также может вызвать проблемы. Например, если объект, созданный новой библиотекой, передается в функции из старой библиотеки, может возникнуть ошибка, поскольку эти библиотеки могут интерпретировать объект по-разному.

В зависимости от характеристик общих библиотек используются разные подходы. В результате общие библиотеки фреймворка делятся на три подкатегории:

  • Библиотеки LL-NDK – это общие библиотеки фреймворка, которые считаются стабильными. Их разработчики стремятся поддерживать стабильность API/ABI.
    • В LL-NDK входят следующие библиотеки:libEGL.so, libGLESv1_CM.so, libGLESv2.so, libGLESv3.so, libandroid_net.so, libc.so, libdl.so, liblog.so, libm.so, libnativewindow.so, libneuralnetworks.so, libsync.so, libvndksupport.so и libvulkan.so.
  • Допустимые библиотеки VNDK – это общие библиотеки фреймворка, которые можно безопасно скопировать дважды. Модули фреймворка и модули поставщика могут быть связаны со своими копиями. Общая библиотека фреймворка может стать подходящей библиотекой VNDK, только если она соответствует следующим критериям:
    • Он не отправляет и не получает IPC в/из фреймворка.
    • Это не связано с виртуальной машиной ART.
    • Она не считывает и не записывает файлы или разделы с нестабильными форматами файлов.
    • У него нет лицензии на специальное ПО, требующей юридической проверки.
    • Владелец кода не возражает против его использования поставщиками.
  • Библиотеки только для фреймворка (FWK-ONLY) – это общие библиотеки фреймворка, которые не относятся к категориям, указанным выше. Эти библиотеки:
    • считаются внутренними деталями реализации фреймворка.
    • Не должен быть доступен для модулей поставщиков.
    • Нестабильные ABI/API и отсутствие гарантий совместимости API/ABI.
    • Не копируются.

HAL, работающий в том же процессе (SP-HAL)

HAL одного процесса (SP-HAL) – это набор предопределенных HAL, реализованных в виде общих библиотек поставщика и загруженных в процессы фреймворка. SP-HAL изолированы пространством имен компоновщика (управляет библиотеками и символами, видимыми для общих библиотек). SP-HAL должны зависеть только от LL-NDK и VNDK-SP.

VNDK-SP – это заранее определенный набор библиотек VNDK. Библиотеки VNDK-SP тщательно проверяются, чтобы убедиться, что двойная загрузка библиотек VNDK-SP в процессы фреймворка не вызывает проблем. Оба типа определяются Google.

Ниже перечислены одобренные библиотеки SP-HAL:

  • libGLESv1_CM_${driver}.so
  • libGLESv2_${driver}.so
  • libGLESv3_${driver}.so
  • libEGL_${driver}.so
  • vulkan.${driver}.so
  • android.hardware.renderscript@1.0-impl.so
  • android.hardware.graphics.mapper@2.0-impl.so

Библиотеки VNDK-SP указывают vndk: { support_system_process: true } в своих файлах Android.bp. Если также указан параметр vndk: {private:true}, то эти библиотеки называются VNDK-SP-Private и невидимы для SP-HALS.

Ниже перечислены библиотеки, предназначенные только для фреймворков, с исключениями для региональных продаж (FWK-ONLY-RS).

  • libft2.so (Renderscript)
  • libmediandk.so (Renderscript)

Управление версиями VNDK

Общие библиотеки VNDK имеют версии:

  • Системное свойство ro.vndk.version автоматически добавляется в /vendor/default.prop.
  • Общие библиотеки VNDK и VNDK-SP устанавливаются как VNDK apex com.android.vndk.v${ro.vndk.version} и монтируются в /apex/com.android.vndk.v${ro.vndk.version}.

Значение ro.vndk.version выбирается алгоритмом, описанным ниже.

  • Если BOARD_VNDK_VERSION не равно current, используйте BOARD_VNDK_VERSION.
  • Если BOARD_VNDK_VERSION равно current:
    • Если PLATFORM_VERSION_CODENAME – REL, используйте PLATFORM_SDK_VERSION (например, 28).
    • В противном случае используйте PLATFORM_VERSION_CODENAME (например, P).

Vendor Test Suite (VTS)

Набор тестов поставщика Android (VTS) требует, чтобы свойство ro.vndk.version было заполнено. ro.vndk.version должны быть определены как на новых устройствах, так и на тех, которые обновляются. Некоторые тестовые сценарии VNDK (например, VtsVndkFilesTest и VtsVndkDependencyTest) используют свойство ro.vndk.version для загрузки соответствующих наборов данных библиотек VNDK.