Вы должны использовать HIDL для описания всех флагов сборки, используемых для условной компиляции фреймворка. Соответствующие флаги сборки должны быть сгруппированы и включены в один файл .hal
. Использование HIDL для указания элементов конфигурации дает следующие преимущества:
- Поддержка версий (для добавления новых элементов конфигурации поставщики / OEM-производители должны явно расширить HAL)
- Хорошо задокументированы
- Контроль доступа с помощью SELinux
- Проверка работоспособности элементов конфигурации с помощью Vendor Test Suite (проверка диапазона, проверка взаимозависимости между элементами и т. Д.)
- Автоматически сгенерированные API на C ++ и Java
Определение флагов сборки, используемых платформой
Начните с определения конфигураций сборки, используемых для условной компиляции фреймворка, затем откажитесь от устаревших конфигураций, чтобы уменьшить набор. Например, для surfaceflinger
определен следующий набор флагов сборки:
-
TARGET_USES_HWC2
-
TARGET_BOARD_PLATFORM
-
TARGET_DISABLE_TRIPLE_BUFFERING
-
TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS
-
NUM_FRAMEBUFFER_SURFACE_BUFFERS
-
TARGET_RUNNING_WITHOUT_SYNC_FRAMEWORK
-
VSYNC_EVENT_PHASE_OFFSET_NS
-
SF_VSYNC_EVENT_PHASE_OFFSET_NS
-
PRESENT_TIME_OFFSET_FROM_VSYNC_NS
-
MAX_VIRTUAL_DISPLAY_DIMENSION
Создание интерфейса HAL
Доступ к конфигурациям сборки для подсистемы осуществляется через интерфейс HAL, а интерфейсы для предоставления значений конфигурации сгруппированы в пакете HAL android.hardware.configstore
(в настоящее время версия 1.0). Например, чтобы создать файл интерфейса HAL для surfaceflinger
, в hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
:
package android.hardware.configstore@1.0; interface ISurfaceFlingerConfigs { // TO-BE-FILLED-BELOW };
После создания файла .hal
запустите hardware/interfaces/update-makefiles.sh
чтобы добавить новый файл .hal
файлы Android.bp
и Android.mk
.
Добавление функций для флагов сборки
Для каждого флага сборки добавьте новую функцию в интерфейс. Например, в hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
:
interface ISurfaceFlingerConfigs { disableTripleBuffering() generates(OptionalBool ret); forceHwcForVirtualDisplays() generates(OptionalBool ret); enum NumBuffers: uint8_t { USE_DEFAULT = 0, TWO = 2, THREE = 3, }; numFramebufferSurfaceBuffers() generates(NumBuffers ret); runWithoutSyncFramework() generates(OptionalBool ret); vsyncEventPhaseOffsetNs generates (OptionalUInt64 ret); presentTimeOffsetFromSyncNs generates (OptionalUInt64 ret); maxVirtualDisplayDimension() generates(OptionalInt32 ret); };
При добавлении функции:
- Будьте краткими с именами. Избегайте преобразования имен переменных make-файла в имена функций и помните, что
TARGET_
иBOARD_
больше не нужны. - Добавляйте комментарии. Помогите разработчикам понять назначение элемента конфигурации, то, как он изменяет поведение платформы, допустимые значения и другую важную информацию.
Типы возвращаемых функций могут быть Optional[Bool|String|Int32|UInt32|Int64|UInt64]
. Типы определены в types.hal
в том же каталоге и types.hal
в себя примитивные значения с полем, которое указывает, задано ли значение HAL; в противном случае используется значение по умолчанию.
struct OptionalString { bool specified; string value; };
При необходимости определите перечисление, которое наилучшим образом представляет тип элемента конфигурации, и используйте это перечисление в качестве возвращаемого типа. В приведенном выше NumBuffers
перечисление NumBuffers
определено для ограничения количества допустимых значений. При определении таких настраиваемых типов данных добавьте поле или значение перечисления (например, USE_DEFAULT
) для обозначения того, указано ли значение / не указано в HAL.
Необязательно, чтобы один флаг сборки стал отдельной функцией в HIDL. В качестве альтернативы владельцы модулей могут агрегировать тесно связанные флаги сборки в структуру и иметь функцию, которая возвращает эту структуру (это может уменьшить количество вызовов функций).
Например, вариант объединения двух флагов сборки в одну структуру в hardware/interfaces/configstore/1.0/ISurfaceFlingerConfigs.hal
:
interface ISurfaceFlingerConfigs { // other functions here struct SyncConfigs { OptionalInt64 vsyncEventPhaseoffsetNs; OptionalInt64 presentTimeoffsetFromSyncNs; }; getSyncConfigs() generates (SyncConfigs ret); // other functions here };
Альтернативы одной функции HAL
В качестве альтернативы использованию одной функции HAL для всех флагов сборки интерфейс HAL также предоставляет простые функции, такие как getBoolean(string key)
и getInteger(string key)
. Фактические пары key=value
хранятся в отдельных файлах, и служба HAL предоставляет значения путем чтения / анализа этих файлов.
Хотя этот подход легко определить, он не включает преимуществ, предоставляемых HIDL (принудительное управление версиями, простота документации, контроль доступа), и поэтому не рекомендуется.
Один и несколько интерфейсов
Дизайн интерфейса HAL для элементов конфигурации предлагает два варианта:
- Единый интерфейс, охватывающий все элементы конфигурации
- Несколько интерфейсов, каждый из которых охватывает набор связанных элементов конфигурации
Единый интерфейс проще, но может стать недоступным для обслуживания по мере добавления дополнительных элементов конфигурации в один файл. Кроме того, управление доступом не является детализированным, поэтому процесс, которому предоставлен доступ к интерфейсу, может читать все элементы конфигурации (доступ к частичному набору элементов конфигурации не может быть предоставлен). В качестве альтернативы, если доступ не предоставлен, элементы конфигурации не могут быть прочитаны.
Из-за этих проблем Android использует несколько интерфейсов с одним интерфейсом HAL для группы связанных элементов конфигурации. Например, ISurfaceflingerConfigs
для surfaceflinger
о связанных конфигурации элементов и IBluetoothConfigs
для Bluetooth-связанных элементов конфигурации.