АПЕКС поставщика

Вы можете использовать формат файла APEX для упаковки и установки модулей ОС Android нижнего уровня. Он позволяет независимо создавать и устанавливать такие компоненты, как собственные службы и библиотеки, реализации HAL, встроенное ПО, файлы конфигурации и т. д.

Вендорные APEX автоматически устанавливаются системой сборки в раздел /vendor и активируются apexd во время выполнения, как и APEX в других разделах.

Случаи использования

Модуляризация образов поставщиков

APEX облегчают естественное объединение и модульность реализаций функций в образах поставщиков.

Когда образы поставщиков создаются как комбинация APEX независимых поставщиков, производители устройств могут легко выбирать реализации конкретного поставщика, необходимые для их устройства. Производители могут даже создать APEX нового поставщика, если ни один из предоставленных APEX не соответствует их потребностям или у них есть совершенно новое специальное оборудование.

Например, OEM-производитель может выбрать в своем устройстве реализацию Wi-Fi AOSP APEX, реализацию Bluetooth SoC APEX и специальную реализацию OEM-телефонии APEX.

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

Итерация разработчика

Вендорные APEX помогают разработчикам быстрее выполнять итерации при разработке вендорных модулей, объединяя всю реализацию функций, например Wi-Fi HAL, внутри вендорного APEX. Затем разработчики могут создавать и индивидуально использовать APEX поставщика для тестирования изменений вместо того, чтобы перестраивать весь образ поставщика.

Это упрощает и ускоряет цикл итерации разработки для разработчиков, которые в основном работают над одной функциональной областью и хотят выполнять итерации только над этой функциональной областью.

Естественное объединение функциональной области в APEX также упрощает процесс создания, отправки и тестирования изменений для этой функциональной области. Например, при переустановке APEX автоматически обновляются все встроенные библиотеки или файлы конфигурации, входящие в состав APEX.

Объединение функциональной области в APEX также упрощает отладку или возврат в случае обнаружения плохого поведения устройства. Например, если в новой сборке телефония работает плохо, разработчики могут попробовать установить на устройство более старую реализацию телефонии APEX (без необходимости прошивать полную сборку) и посмотреть, восстановится ли хорошее поведение.

Пример рабочего процесса:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

Примеры

Основы

См. главную страницу формата файла APEX для получения общей информации APEX, включая требования к устройству, сведения о формате файла и этапы установки.

В Android.bp установка vendor: true делает модуль APEX APEX поставщика.

apex {
  ..
  vendor: true,
  ..
}

Двоичные файлы и общие библиотеки

APEX включает в себя транзитивные зависимости внутри полезных данных APEX, если только они не имеют стабильных интерфейсов.

Стабильные собственные интерфейсы для зависимостей APEX от поставщиков включают cc_library с stubs , ndk_library или llndk_library . Эти зависимости исключаются из упаковки и записываются в манифест APEX. Манифест обрабатывается linkerconfig , поэтому внешние собственные зависимости доступны во время выполнения.

В отличие от APEX в разделе /system , APEX поставщика обычно привязаны к конкретной версии VNDK. Библиотеки VNDK гарантируют стабильность ABI в рамках выпуска, поэтому мы можем рассматривать библиотеки VNDK как стабильные и уменьшать размер APEX поставщиков, исключая их из APEX с помощью свойства use_vndk_as_stable .

В приведенном ниже фрагменте APEX будет содержать как двоичный файл ( my_service ), так и его нестабильные зависимости (файлы *.so ). Он не будет содержать библиотеки VNDK, даже если my_service собран с использованием библиотек VNDK, таких как libbase . Вместо этого во время выполнения my_service будет использовать libbase из библиотек VNDK, предоставляемых системой.

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

В приведенном ниже фрагменте APEX будет содержать общую библиотеку my_standalone_lib и все ее нестабильные зависимости (как описано выше).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

HAL-реализации

Чтобы определить реализацию HAL, предоставьте соответствующие двоичные файлы и библиотеки внутри APEX поставщика, как показано в следующих примерах:

Чтобы полностью инкапсулировать реализацию HAL, APEX должен также указать все соответствующие фрагменты VINTF и сценарии инициализации.

Фрагменты ВИНТФ

Фрагменты VINTF могут быть предоставлены поставщиком APEX, если фрагменты расположены в каталоге etc/vintf APEX.

Используйте свойство prebuilts для встраивания фрагментов VINTF в APEX.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

Скрипты инициализации

APEX может включать сценарии инициализации двумя способами: (A) предварительно созданный текстовый файл в полезной нагрузке APEX или (B) обычный сценарий инициализации в /vendor/etc . Вы можете установить оба для одного и того же APEX.

Скрипт инициализации в APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

Сценарии инициализации в APEX могут иметь только определения service . Сценарии инициализации в Vendor APEX также могут иметь директивы on <property> .

Будьте осторожны при использовании директив on . Поскольку сценарии инициализации в APEX анализируются и выполняются после активации APEX, некоторые события или свойства использовать нельзя. Используйте apex.all.ready=true , чтобы запускать действия как можно раньше.

Прошивка

Пример:

Встройте прошивку в APEX поставщика с типом модуля prebuilt_firmware следующим образом.

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

Модули prebuilt_firmware устанавливаются в каталог <apex name>/etc/firmware APEX. ueventd сканирует каталоги /apex/*/etc/firmware , чтобы найти модули прошивки.

file_contexts APEX должен правильно помечать любые записи полезной нагрузки встроенного ПО, чтобы гарантировать доступность этих файлов для ueventd во время выполнения; обычно достаточно vendor_file . Например:

(/.*)? u:object_r:vendor_file:s0

Модули ядра

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

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

file_contexts APEX должен правильно помечать все записи полезной нагрузки модуля ядра. Например:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

Модули ядра должны быть установлены явно. Следующий пример сценария инициализации в разделе поставщика показывает установку через insmod :

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

Наложения ресурсов среды выполнения

Пример:

Встраивайте наложения ресурсов среды выполнения в APEX поставщика с помощью свойства rros .

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

Другие файлы конфигурации

APEX поставщика поддерживают различные другие файлы конфигурации, которые обычно находятся в разделе поставщика в качестве предварительно созданных внутри APEX поставщика, и добавляются новые.

Примеры:

Дополнительные возможности разработки

Выбор APEX при загрузке

Пример:

Разработчики также могут установить несколько версий APEX разных производителей с одинаковым именем и ключом APEX, а затем выбирать, какая версия активируется во время каждой загрузки, используя постоянные системные свойства. В некоторых случаях использования разработчиками это может быть проще, чем установка новой копии APEX с помощью adb install .

Примеры использования:

  • Установите 3 версии поставщика Wi-Fi HAL APEX: команды контроля качества могут запускать ручное или автоматическое тестирование, используя одну версию, затем перезагрузиться в другую версию и повторно запустить тесты, а затем сравнить окончательные результаты.
  • Установите 2 версии камеры HAL поставщика APEX, текущую и экспериментальную . Разработчики Dogfoods могут использовать экспериментальную версию без загрузки и установки дополнительного файла, поэтому они могут легко заменить ее обратно.

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

Ожидаемые форматы ключа свойства:

  • Загрузочная конфигурация
    • Используется для установки значения по умолчанию в BoardConfig.mk .
    • androidboot.vendor.apex.<apex name>
  • Постоянный sysprop
    • Используется для изменения значения по умолчанию, установленного на уже загруженном устройстве.
    • Переопределяет значение bootconfig, если оно присутствует.
    • persist.vendor.apex.<apex name>

Значением свойства должно быть имя файла APEX, который необходимо активировать.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

Версия по умолчанию также должна быть настроена с помощью bootconfig в BoardConfig.mk :

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

После загрузки устройства измените активированную версию, установив постоянный системный параметр:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

Если устройство поддерживает обновление bootconfig после прошивки (например, с помощью команд fastboot oem ), то изменение свойства bootconfig для многократно установленного APEX также меняет версию, активируемую при загрузке.

Для виртуальных эталонных устройств на базе Cuttlefish вы можете использовать команду --extra_bootconfig_args , чтобы установить свойство bootconfig непосредственно во время запуска. Например:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";
,

Вы можете использовать формат файла APEX для упаковки и установки модулей ОС Android нижнего уровня. Он позволяет независимо создавать и устанавливать такие компоненты, как собственные службы и библиотеки, реализации HAL, встроенное ПО, файлы конфигурации и т. д.

Вендорные APEX автоматически устанавливаются системой сборки в раздел /vendor и активируются apexd во время выполнения, как и APEX в других разделах.

Случаи использования

Модуляризация образов поставщиков

APEX облегчают естественное объединение и модульность реализаций функций в образах поставщиков.

Когда образы поставщиков создаются как комбинация APEX независимых поставщиков, производители устройств могут легко выбирать реализации конкретного поставщика, необходимые для их устройства. Производители могут даже создать APEX нового поставщика, если ни один из предоставленных APEX не соответствует их потребностям или у них есть совершенно новое специальное оборудование.

Например, OEM-производитель может выбрать в своем устройстве реализацию Wi-Fi AOSP APEX, реализацию Bluetooth SoC APEX и специальную реализацию OEM-телефонии APEX.

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

Итерация разработчика

Вендорные APEX помогают разработчикам быстрее выполнять итерации при разработке вендорных модулей, объединяя всю реализацию функций, например Wi-Fi HAL, внутри вендорного APEX. Затем разработчики могут создавать и индивидуально использовать APEX поставщика для тестирования изменений вместо того, чтобы перестраивать весь образ поставщика.

Это упрощает и ускоряет цикл итерации разработки для разработчиков, которые в основном работают над одной функциональной областью и хотят выполнять итерации только над этой функциональной областью.

Естественное объединение функциональной области в APEX также упрощает процесс создания, отправки и тестирования изменений для этой функциональной области. Например, при переустановке APEX автоматически обновляются все встроенные библиотеки или файлы конфигурации, входящие в состав APEX.

Объединение функциональной области в APEX также упрощает отладку или возврат в случае обнаружения плохого поведения устройства. Например, если в новой сборке телефония работает плохо, разработчики могут попробовать установить на устройство более старую реализацию телефонии APEX (без необходимости прошивать полную сборку) и посмотреть, восстановится ли хорошее поведение.

Пример рабочего процесса:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

Примеры

Основы

См. главную страницу формата файла APEX для получения общей информации APEX, включая требования к устройству, сведения о формате файла и этапы установки.

В Android.bp установка vendor: true делает модуль APEX APEX поставщика.

apex {
  ..
  vendor: true,
  ..
}

Двоичные файлы и общие библиотеки

APEX включает в себя транзитивные зависимости внутри полезных данных APEX, если только они не имеют стабильных интерфейсов.

Стабильные собственные интерфейсы для зависимостей APEX от поставщиков включают cc_library с stubs , ndk_library или llndk_library . Эти зависимости исключаются из упаковки и записываются в манифест APEX. Манифест обрабатывается linkerconfig , поэтому внешние собственные зависимости доступны во время выполнения.

В отличие от APEX в разделе /system , APEX поставщика обычно привязаны к конкретной версии VNDK. Библиотеки VNDK гарантируют стабильность ABI в рамках выпуска, поэтому мы можем рассматривать библиотеки VNDK как стабильные и уменьшать размер APEX поставщиков, исключая их из APEX с помощью свойства use_vndk_as_stable .

В приведенном ниже фрагменте APEX будет содержать как двоичный файл ( my_service ), так и его нестабильные зависимости (файлы *.so ). Он не будет содержать библиотеки VNDK, даже если my_service собран с использованием библиотек VNDK, таких как libbase . Вместо этого во время выполнения my_service будет использовать libbase из библиотек VNDK, предоставляемых системой.

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

В приведенном ниже фрагменте APEX будет содержать общую библиотеку my_standalone_lib и все ее нестабильные зависимости (как описано выше).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

HAL-реализации

Чтобы определить реализацию HAL, предоставьте соответствующие двоичные файлы и библиотеки внутри APEX поставщика, как показано в следующих примерах:

Чтобы полностью инкапсулировать реализацию HAL, APEX должен также указать все соответствующие фрагменты VINTF и сценарии инициализации.

Фрагменты ВИНТФ

Фрагменты VINTF могут быть предоставлены поставщиком APEX, если фрагменты расположены в каталоге etc/vintf APEX.

Используйте свойство prebuilts для встраивания фрагментов VINTF в APEX.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

Скрипты инициализации

APEX может включать сценарии инициализации двумя способами: (A) предварительно созданный текстовый файл в полезной нагрузке APEX или (B) обычный сценарий инициализации в /vendor/etc . Вы можете установить оба для одного и того же APEX.

Скрипт инициализации в APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

Сценарии инициализации в APEX могут иметь только определения service . Сценарии инициализации в Vendor APEX также могут иметь директивы on <property> .

Будьте осторожны при использовании директив on . Поскольку сценарии инициализации в APEX анализируются и выполняются после активации APEX, некоторые события или свойства использовать нельзя. Используйте apex.all.ready=true , чтобы запускать действия как можно раньше.

Прошивка

Пример:

Встройте прошивку в APEX поставщика с типом модуля prebuilt_firmware следующим образом.

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

Модули prebuilt_firmware устанавливаются в каталог <apex name>/etc/firmware APEX. ueventd сканирует каталоги /apex/*/etc/firmware , чтобы найти модули прошивки.

file_contexts APEX должен правильно помечать любые записи полезной нагрузки встроенного ПО, чтобы гарантировать доступность этих файлов для ueventd во время выполнения; обычно достаточно vendor_file . Например:

(/.*)? u:object_r:vendor_file:s0

Модули ядра

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

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

file_contexts APEX должен правильно помечать все записи полезной нагрузки модуля ядра. Например:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

Модули ядра должны быть установлены явно. Следующий пример сценария инициализации в разделе поставщика показывает установку через insmod :

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

Наложения ресурсов среды выполнения

Пример:

Встраивайте наложения ресурсов среды выполнения в APEX поставщика с помощью свойства rros .

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

Другие файлы конфигурации

APEX поставщика поддерживают различные другие файлы конфигурации, которые обычно находятся в разделе поставщика в качестве предварительно созданных внутри APEX поставщика, и добавляются новые.

Примеры:

Дополнительные возможности разработки

Выбор APEX при загрузке

Пример:

Разработчики также могут установить несколько версий APEX разных производителей с одинаковым именем и ключом APEX, а затем выбирать, какая версия активируется во время каждой загрузки, используя постоянные системные свойства. В некоторых случаях использования разработчиками это может быть проще, чем установка новой копии APEX с помощью adb install .

Примеры использования:

  • Установите 3 версии поставщика Wi-Fi HAL APEX: команды контроля качества могут запускать ручное или автоматическое тестирование, используя одну версию, затем перезагрузиться в другую версию и повторно запустить тесты, а затем сравнить окончательные результаты.
  • Установите 2 версии камеры HAL поставщика APEX, текущую и экспериментальную . Разработчики Dogfoods могут использовать экспериментальную версию без загрузки и установки дополнительного файла, поэтому они могут легко заменить ее обратно.

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

Ожидаемые форматы ключа свойства:

  • Загрузочная конфигурация
    • Используется для установки значения по умолчанию в BoardConfig.mk .
    • androidboot.vendor.apex.<apex name>
  • Постоянный sysprop
    • Используется для изменения значения по умолчанию, установленного на уже загруженном устройстве.
    • Переопределяет значение bootconfig, если оно присутствует.
    • persist.vendor.apex.<apex name>

Значением свойства должно быть имя файла APEX, который необходимо активировать.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

Версия по умолчанию также должна быть настроена с помощью bootconfig в BoardConfig.mk :

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

После загрузки устройства измените активированную версию, установив постоянный системный параметр:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

Если устройство поддерживает обновление bootconfig после прошивки (например, с помощью команд fastboot oem ), то изменение свойства bootconfig для многократно установленного APEX также меняет версию, активируемую при загрузке.

Для виртуальных эталонных устройств на базе Cuttlefish вы можете использовать команду --extra_bootconfig_args , чтобы установить свойство bootconfig непосредственно во время запуска. Например:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";
,

Вы можете использовать формат файла APEX для упаковки и установки модулей ОС Android нижнего уровня. Он позволяет независимо создавать и устанавливать такие компоненты, как собственные службы и библиотеки, реализации HAL, встроенное ПО, файлы конфигурации и т. д.

Вендорные APEX автоматически устанавливаются системой сборки в раздел /vendor и активируются apexd во время выполнения, как и APEX в других разделах.

Случаи использования

Модуляризация образов поставщиков

APEX облегчают естественное объединение и модульность реализаций функций в образах поставщиков.

Когда образы поставщиков создаются как комбинация APEX независимых поставщиков, производители устройств могут легко выбирать реализации конкретного поставщика, необходимые для их устройства. Производители могут даже создать APEX нового поставщика, если ни один из предоставленных APEX не соответствует их потребностям или у них есть совершенно новое специальное оборудование.

Например, OEM-производитель может выбрать в своем устройстве реализацию Wi-Fi AOSP APEX, реализацию Bluetooth SoC APEX и специальную реализацию OEM-телефонии APEX.

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

Итерация разработчика

Вендорные APEX помогают разработчикам быстрее выполнять итерации при разработке вендорных модулей, объединяя всю реализацию функций, например Wi-Fi HAL, внутри вендорного APEX. Затем разработчики могут создавать и индивидуально использовать APEX поставщика для тестирования изменений вместо того, чтобы перестраивать весь образ поставщика.

Это упрощает и ускоряет цикл итерации разработки для разработчиков, которые в основном работают над одной функциональной областью и хотят выполнять итерации только над этой функциональной областью.

Естественное объединение функциональной области в APEX также упрощает процесс создания, отправки и тестирования изменений для этой функциональной области. Например, при переустановке APEX автоматически обновляются все встроенные библиотеки или файлы конфигурации, входящие в состав APEX.

Объединение функциональной области в APEX также упрощает отладку или возврат в случае обнаружения плохого поведения устройства. Например, если в новой сборке телефония работает плохо, разработчики могут попробовать установить на устройство более старую реализацию телефонии APEX (без необходимости прошивать полную сборку) и посмотреть, восстановится ли хорошее поведение.

Пример рабочего процесса:

# Build the entire device and flash. OR, obtain an already-flashed device.
source build/envsetup.sh && lunch oem_device-userdebug
m
fastboot flashall -w

# Test the device.
... testing ...

# Check previous behavior using a vendor APEX from one week ago, downloaded from
# your continuous integration build.
... download command ...
adb install <path to downloaded APEX>
adb reboot
... testing ...

# Edit and rebuild just the APEX to change and test behavior.
... edit APEX source contents ...
m <apex module name>
adb install out/<path to built APEX>
adb reboot
... testing ...

Примеры

Основы

См. главную страницу формата файла APEX для получения общей информации APEX, включая требования к устройству, сведения о формате файла и этапы установки.

В Android.bp установка vendor: true делает модуль APEX APEX поставщика.

apex {
  ..
  vendor: true,
  ..
}

Двоичные файлы и общие библиотеки

APEX включает в себя транзитивные зависимости внутри полезных данных APEX, если только они не имеют стабильных интерфейсов.

Стабильные собственные интерфейсы для зависимостей APEX от поставщиков включают cc_library с stubs , ndk_library или llndk_library . Эти зависимости исключаются из упаковки и записываются в манифест APEX. Манифест обрабатывается linkerconfig , поэтому внешние собственные зависимости доступны во время выполнения.

В отличие от APEX в разделе /system , APEX поставщика обычно привязаны к конкретной версии VNDK. Библиотеки VNDK гарантируют стабильность ABI в рамках выпуска, поэтому мы можем рассматривать библиотеки VNDK как стабильные и уменьшать размер APEX поставщиков, исключая их из APEX с помощью свойства use_vndk_as_stable .

В приведенном ниже фрагменте APEX будет содержать как двоичный файл ( my_service ), так и его нестабильные зависимости (файлы *.so ). Он не будет содержать библиотеки VNDK, даже если my_service собран с использованием библиотек VNDK, таких как libbase . Вместо этого во время выполнения my_service будет использовать libbase из библиотек VNDK, предоставляемых системой.

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  binaries: ["my_service"],
  ..
}

В приведенном ниже фрагменте APEX будет содержать общую библиотеку my_standalone_lib и все ее нестабильные зависимости (как описано выше).

apex {
  ..
  vendor: true,
  use_vndk_as_stable: true,
  native_shared_libs: ["my_standalone_lib"],
  ..
}

HAL-реализации

Чтобы определить реализацию HAL, предоставьте соответствующие двоичные файлы и библиотеки внутри APEX поставщика, как показано в следующих примерах:

Чтобы полностью инкапсулировать реализацию HAL, APEX должен также указать все соответствующие фрагменты VINTF и сценарии инициализации.

Фрагменты ВИНТФ

Фрагменты VINTF могут быть предоставлены поставщиком APEX, если фрагменты расположены в каталоге etc/vintf APEX.

Используйте свойство prebuilts для встраивания фрагментов VINTF в APEX.

apex {
  ..
  vendor: true,
  prebuilts: ["fragment.xml"],
  ..
}

prebuilt_etc {
  name: "fragment.xml",
  src: "fragment.xml",
  sub_dir: "vintf",
}

Скрипты инициализации

APEX может включать сценарии инициализации двумя способами: (A) предварительно созданный текстовый файл в полезной нагрузке APEX или (B) обычный сценарий инициализации в /vendor/etc . Вы можете установить оба для одного и того же APEX.

Скрипт инициализации в APEX:

prebuilt_etc {
  name: "myinit.rc",
  src: "myinit.rc"
}

apex {
  ..
  vendor: true,
  prebuilts: ["myinit.rc"],
  ..
}

Сценарии инициализации в APEX могут иметь только определения service . Сценарии инициализации в Vendor APEX также могут иметь директивы on <property> .

Будьте осторожны при использовании директив on . Поскольку сценарии инициализации в APEX анализируются и выполняются после активации APEX, некоторые события или свойства использовать нельзя. Используйте apex.all.ready=true , чтобы запускать действия как можно раньше.

Прошивка

Пример:

Встройте прошивку в APEX поставщика с типом модуля prebuilt_firmware следующим образом.

prebuilt_firmware {
  name: "my.bin",
  src: "path_to_prebuilt_firmware",
  vendor: true,
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.bin"],  // installed inside APEX as /etc/firmware/my.bin
  ..
}

Модули prebuilt_firmware устанавливаются в каталог <apex name>/etc/firmware APEX. ueventd сканирует каталоги /apex/*/etc/firmware , чтобы найти модули прошивки.

file_contexts APEX должен правильно помечать любые записи полезной нагрузки встроенного ПО, чтобы гарантировать доступность этих файлов для ueventd во время выполнения; обычно достаточно vendor_file . Например:

(/.*)? u:object_r:vendor_file:s0

Модули ядра

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

prebuilt_etc {
  name: "my.ko",
  src: "my.ko",
  vendor: true,
  sub_dir: "modules"
}

apex {
  ..
  vendor: true,
  prebuilts: ["my.ko"],  // installed inside APEX as /etc/modules/my.ko
  ..
}

file_contexts APEX должен правильно помечать все записи полезной нагрузки модуля ядра. Например:

/etc/modules(/.*)? u:object_r:vendor_kernel_modules:s0

Модули ядра должны быть установлены явно. Следующий пример сценария инициализации в разделе поставщика показывает установку через insmod :

my_init.rc :

on early-boot
  insmod /apex/myapex/etc/modules/my.ko
  ..

Наложения ресурсов среды выполнения

Пример:

Встраивайте наложения ресурсов среды выполнения в APEX поставщика с помощью свойства rros .

runtime_resource_overlay {
    name: "my_rro",
    soc_specific: true,
}


apex {
  ..
  vendor: true,
  rros: ["my_rro"],  // installed inside APEX as /overlay/my_rro.apk
  ..
}

Другие файлы конфигурации

APEX поставщика поддерживают различные другие файлы конфигурации, которые обычно находятся в разделе поставщика в качестве предварительно созданных внутри APEX поставщика, и добавляются новые.

Примеры:

Дополнительные возможности разработки

Выбор APEX при загрузке

Пример:

Разработчики также могут установить несколько версий APEX разных производителей с одинаковым именем и ключом APEX, а затем выбирать, какая версия активируется во время каждой загрузки, используя постоянные системные свойства. В некоторых случаях использования разработчиками это может быть проще, чем установка новой копии APEX с помощью adb install .

Примеры использования:

  • Установите 3 версии поставщика Wi-Fi HAL APEX: команды контроля качества могут запускать ручное или автоматическое тестирование, используя одну версию, затем перезагрузиться в другую версию и повторно запустить тесты, а затем сравнить окончательные результаты.
  • Установите 2 версии камеры HAL поставщика APEX, текущую и экспериментальную . Разработчики Dogfoods могут использовать экспериментальную версию без загрузки и установки дополнительного файла, поэтому они могут легко заменить ее обратно.

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

Ожидаемые форматы ключа свойства:

  • Загрузочная конфигурация
    • Используется для установки значения по умолчанию в BoardConfig.mk .
    • androidboot.vendor.apex.<apex name>
  • Постоянный sysprop
    • Используется для изменения значения по умолчанию, установленного на уже загруженном устройстве.
    • Переопределяет значение bootconfig, если оно присутствует.
    • persist.vendor.apex.<apex name>

Значением свойства должно быть имя файла APEX, который необходимо активировать.

// Default version.
apex {
  name: "com.oem.camera.hal.my_apex_default",
  vendor: true,
  ..
}

// Non-default version.
apex {
  name: "com.oem.camera.hal.my_apex_experimental",
  vendor: true,
  ..
}

Версия по умолчанию также должна быть настроена с помощью bootconfig в BoardConfig.mk :

# Example for APEX "com.oem.camera.hal" with the default above:
BOARD_BOOTCONFIG += \
    androidboot.vendor.apex.com.oem.camera.hal=com.oem.camera.hal.my_apex_default

После загрузки устройства измените активированную версию, установив постоянный системный параметр:

$ adb root;
$ adb shell setprop \
    persist.vendor.apex.com.oem.camera.hal \
    com.oem.camera.hal.my_apex_experimental;
$ adb reboot;

Если устройство поддерживает обновление bootconfig после прошивки (например, с помощью команд fastboot oem ), то изменение свойства bootconfig для многократно установленного APEX также меняет версию, активируемую при загрузке.

Для виртуальных эталонных устройств на базе Cuttlefish вы можете использовать команду --extra_bootconfig_args , чтобы установить свойство bootconfig непосредственно во время запуска. Например:

launch_cvd --noresume \
  --extra_bootconfig_args "androidboot.vendor.apex.com.oem.camera.hal:=com.oem.camera.hal.my_apex_experimental";