HAL определяет стандартный интерфейс, который производители оборудования могут реализовать, чтобы Android не зависел от реализации драйверов более низкого уровня. Использование HAL позволяет реализовать функциональность, не затрагивая и не изменяя систему более высокого уровня. На этой странице описана устаревшая архитектура, которая больше не поддерживается в Android 8.0 и более поздних версиях. Для Android 8.0 и более поздних версий ознакомьтесь с обзором HAL.
Рисунок 1. Компоненты HAL
Вам необходимо реализовать соответствующий HAL (и драйвер) для определенного оборудования, которое используется в вашем продукте. Реализации HAL обычно встроены в модули общих библиотек (файлы .so), но поскольку Android не требует стандартного взаимодействия между реализацией HAL и драйверами устройств, вы можете выбрать наиболее подходящий для вас вариант. Однако, чтобы система Android правильно взаимодействовала с вашим оборудованием, вы должны соблюдать условия, определенные в каждом интерфейсе HAL для конкретного оборудования.
Чтобы гарантировать предсказуемую структуру HAL, у каждого интерфейса HAL, относящегося к определенному оборудованию, есть свойства, определенные в hardware/libhardware/include/hardware/hardware.h. Этот интерфейс позволяет системе Android загружать нужные версии модулей HAL единообразным образом. Интерфейс HAL состоит из двух компонентов: модулей и устройств.
Модули HAL
Модуль представляет собой упакованную реализацию HAL, которая хранится в виде общей библиотеки (.so file). В заголовочном файле hardware/libhardware/include/hardware/hardware.h определяется структура (hw_module_t), представляющая модуль и содержащая метаданные, такие как версия, название и автор модуля. Android использует эти метаданные для поиска и правильной загрузки модуля HAL.
Кроме того, структура hw_module_t содержит указатель на другую структуру, hw_module_methods_t, которая содержит указатель на открытую функцию для модуля. Эта открытая функция используется для инициации связи с оборудованием, для которого HAL служит абстракцией.
Каждый HAL, предназначенный для определенного оборудования, обычно расширяет общую структуру hw_module_t дополнительной информацией для этого оборудования. Например, в HAL камеры структура camera_module_t содержит структуру hw_module_t, а также указатели на другие функции, относящиеся к камере:
typedef struct camera_module {
hw_module_t common;
int (*get_number_of_cameras)(void);
int (*get_camera_info)(int camera_id, struct camera_info *info);
} camera_module_t;
При реализации HAL и создании структуры модуля необходимо присвоить ей имя
HAL_MODULE_INFO_SYM. Пример из HAL аудио для Nexus 9:
struct audio_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = AUDIO_MODULE_API_VERSION_0_1,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = AUDIO_HARDWARE_MODULE_ID,
.name = "NVIDIA Tegra Audio HAL",
.author = "The Android Open Source Project",
.methods = &hal_module_methods,
},
};
Устройства HAL
Устройство – это абстрактное представление аппаратного обеспечения вашего продукта. Например, аудиомодуль может содержать основное аудиоустройство, аудиоустройство USB или аудиоустройство Bluetooth A2DP.
Устройство представлено структурой hw_device_t. Как и в случае с модулем, каждый тип устройства определяет подробную версию общего объекта hw_device_t, содержащего указатели функций для определенных функций оборудования. Например, тип структуры audio_hw_device_t содержит указатели на функции для операций с аудиоустройствами:
struct audio_hw_device {
struct hw_device_t common;
/**
* used by audio flinger to enumerate what devices are supported by
* each audio_hw_device implementation.
*
* Return value is a bitmask of 1 or more values of audio_devices_t
*/
uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
...
};
typedef struct audio_hw_device audio_hw_device_t;
Помимо этих стандартных свойств, каждый интерфейс HAL, относящийся к определенному оборудованию, может определять собственные функции и требования. Подробную информацию можно найти в справочной документации по HAL и инструкциях для каждого HAL.
Как создать модули HAL
Реализации HAL встроены в файлы модулей (.so) и динамически связываются Android при необходимости. Вы можете создать модули, добавив Android.mk-файлы для каждой реализации HAL и указав путь к исходным файлам. В целом, ваши общие библиотеки должны быть названы в определенном формате, чтобы их можно было найти и правильно загрузить. Схема наименования немного различается от модуля к модулю, но в целом соответствует следующему шаблону: <module_type>.<device_name>.