Многоуровневый HAL датчиков (Sensors Multi-HAL) — это фреймворк, позволяющий HAL датчиков работать параллельно с другими HAL датчиков. Многоуровневый HAL датчиков (Sensors Multi-HAL) динамически загружает подуровневые HAL датчиков, хранящиеся в виде динамических библиотек в разделе поставщика, и предоставляет им объект обратного вызова, который может обрабатывать события отправки, а также получать и снимать блокировку пробуждения. Подуровневый HAL датчиков — это HAL датчиков, встроенный в общий объект в разделе поставщика и используемый фреймворком многоуровневого HAL. Эти подуровневые HAL не зависят друг от друга и от кода многоуровневого HAL, содержащего основную функцию процесса.
Sensors Multi-HAL 2.1, доступный на устройствах под управлением Android 11 и выше, представляет собой итерацию Sensors Multi-HAL 2.0, которая поддерживает загрузку подсистем HAL, предоставляющих доступ к данным о датчике угла поворота шарнира . Для поддержки этого типа датчиков подсистемы HAL должны использовать API подсистем HAL, определённые в заголовке 2.1 SubHal .
Для устройств под управлением Android 13 и выше, использующих Sensors AIDL HAL , можно использовать слой-прокладку multi-HAL для поддержки поддержки нескольких HAL. Подробности реализации см. в разделе «Использование Sensors Multi-HAL с Sensors AIDL HAL» .
Разница между датчиками Multi-HAL 2 и датчиками HAL 2
Sensors Multi-HAL 2, доступный на устройствах под управлением Android 10 и выше, представляет несколько абстракций поверх Sensors HAL 2 для упрощения взаимодействия с API HAL. Sensors Multi-HAL 2 представляет класс HalProxy для реализации интерфейса Sensors HAL 2 и интерфейса V2_1/SubHal
(или V2_0/SubHal
), позволяющего HalProxy
взаимодействовать с подинтерфейсами HAL.
Интерфейс ISensorsSubHal
отличается от интерфейса 2.1/ISensors.hal
(или 2.0/ISensors.hal
) следующими особенностями:
- Метод инициализации передает класс
IHalProxyCallback
вместо двух FMQ иISensorsCallback
. - Подсистемы HAL должны реализовывать функцию отладки для предоставления отладочной информации в отчетах об ошибках.
- Подсистемы HAL должны реализовывать функцию имени, чтобы загруженную подсистему HAL можно было отличить от других подсистем HAL.
Основное различие между Sensors Multi-HAL 2 и Sensors HAL 2 заключается в функциях инициализации. Вместо предоставления FMQ интерфейс IHalProxyCallback
предоставляет два метода: один для отправки событий датчиков в фреймворк датчиков, а другой для создания блокировок пробуждения. Под капотом Sensors Multi-HAL управляет всеми взаимодействиями с FMQ, обеспечивая своевременную доставку событий датчиков на все подчинённые HAL. Настоятельно рекомендуется, чтобы подчинённые HAL использовали метод createScopedWakelock
для делегирования нагрузки по тайм-ауту блокировок пробуждения Sensors Multi-HAL и централизации использования блокировок пробуждения в одной общей блокировке пробуждения для всего Sensors Multi-HAL, что минимизирует количество вызовов блокировки и разблокировки.
Sensors Multi-HAL 2 также обладает рядом встроенных функций безопасности. Он обрабатывает ситуации, когда FMQ датчика заполнен или когда фреймворк сенсора Android перезапускается и требуется сброс состояния датчика. Кроме того, когда события отправляются в класс HalProxy
, но фреймворк сенсора не может принять их немедленно, Sensors Multi-HAL может переместить события в фоновый поток, чтобы работа могла продолжаться во всех подуровневых HAL в ожидании отправки событий.
Исходный код и эталонная реализация
Код All Sensors Multi-HAL доступен в hardware/interfaces/sensors/common/default/2.X/multihal/
. Ниже приведены ссылки на некоторые ресурсы.
-
HalProxy.h
: ОбъектHalProxy
создается с помощью нескольких HAL датчиков и обрабатывает передачу данных из под-HAL в структуру датчиков. -
HalProxy.cpp
: РеализацияHalProxy
содержит всю логику, необходимую для мультиплексной связи между под-HAL и структурой датчиков. SubHal.h
: ИнтерфейсISensorsSubHal
определяет интерфейс, которому должны соответствовать подсистемы HAL для совместимости сHalProxy
. Подсистема HAL реализует метод инициализации, чтобы объектHalProxyCallback
можно было использовать дляpostEvents
иcreateScopedWakelock
.Для реализаций Multi-HAL 2.0 используйте версию 2.0
SubHal.h
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: Эти модульные тесты проверяют реализациюHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: В этом примере реализации подсистемы HAL используются поддельные датчики для генерации поддельных данных. Полезно для тестирования взаимодействия нескольких подсистем HAL на устройстве.
Выполнение
В этом разделе описывается, как реализовать функцию Sensors Multi-HAL в следующих ситуациях:
- Использование датчиков Multi-HAL с датчиками AIDL HAL
- Реализация датчиков Multi-HAL 2.1
- Портирование с датчиков Multi-HAL 2.0 на Multi-HAL 2.1
- Портирование с датчиков HAL 2.0
- Портирование с датчиков HAL 1.0
- Портирование с датчиков Multi-HAL 1.0
Используйте датчики Multi-HAL с датчиками AIDL HAL
Чтобы реализовать поддержку нескольких HAL с помощью HAL-модуля Sensors AIDL, импортируйте модуль слоя-прокладки AIDL Multi-HAL, который находится в папке hardware/interfaces/sensors/aidl/default/multihal/ . Этот модуль выполняет преобразование между типами определения HAL датчиков AIDL и HIDL и определяет оболочку для интерфейса multi-HAL, описанного в разделе «Реализация датчиков Multi-HAL 2.1» . Слой-прокладка AIDL multi-HAL совместим с устройствами, реализующими Multi-HAL 2.1.
Слой-прокладка AIDL multi-HAL позволяет отображать типы датчиков слежения за головой и инерциальных измерительных блоков с ограниченной осью в HAL-системе датчиков AIDL. Чтобы использовать эти типы датчиков, определяемые интерфейсом AIDL HAL, задайте поле type
в структуре SensorInfo
в реализации getSensorsList_2_1()
. Это безопасно, поскольку целочисленные поля типа датчика в HAL-системах датчиков AIDL и HIDL не перекрываются.
Датчики навесного оборудования Multi-HAL 2.1
Чтобы внедрить Sensors Multi-HAL 2.1 на новое устройство, выполните следующие действия:
- Реализуйте интерфейс
ISensorsSubHal
, как описано вSubHal.h
. - Реализуйте метод
sensorsHalGetSubHal_2_1
вSubHal.h
. Добавьте целевой объект
cc_library_shared
для сборки нового реализованного под-HAL. При добавлении целевого объекта:- Убедитесь, что цель помещена куда-то в раздел поставщика устройства.
- В конфигурационном файле
/vendor/etc/sensors/hals.conf
добавьте путь к библиотеке в новой строке. При необходимости создайте файлhals.conf
.
Пример записи
Android.bp
для создания библиотеки sub-HAL см. в разделеhardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Удалите все записи
android.hardware.sensors
из файлаmanifest.xml
, который содержит список поддерживаемых HAL на устройстве.Удалите все файлы
android.hardware.sensors
service иservice.rc
из файлаdevice.mk
и добавьтеandroid.hardware.sensors@2.1-service.multihal
иandroid.hardware.sensors@2.1-service.multihal.rc
вPRODUCT_PACKAGES
.
При загрузке запускается HalProxy
, ищет недавно реализованный sub-HAL и инициализирует его, вызывая sensorsHalGetSubHal_2_1
.
Порт с датчиков Multi-HAL 2.0 на Multi-HAL 2.1
Для переноса из Multi-HAL 2.0 в Multi-HAL 2.1 реализуйте интерфейс SubHal
и перекомпилируйте свой sub-HAL.
Различия между интерфейсами SubHal
2.0 и 2.1:
-
IHalProxyCallback
использует типы, созданные в версии 2.1 спецификацииISensors.hal
. - Функция
initialize()
передает новыйIHalProxyCallback
вместо того, чтобы использовать интерфейсSubHal
2.0. - Подклассы HAL должны реализовывать
getSensorsList_2_1
иinjectSensorData_2_1
вместоgetSensorsList
иinjectSensorData
, поскольку эти методы используют новые типы, добавленные в версии 2.1 спецификацииISensors.hal
. - Подчиненные HAL должны предоставлять
sensorsHalGetSubHal_2_1
, а неsensorsHalGetSubHal
, чтобы Multi-HAL рассматривал их как подчинённые HAL версии 2.1.
Порт из Sensors HAL 2.0
При обновлении с Sensors HAL 2.0 до Sensors Multi-HAL 2.0 убедитесь, что реализация HAL соответствует следующим требованиям.
Инициализируйте HAL
В Sensors HAL 2.0 есть функция инициализации, которая позволяет службе датчиков передавать запросы FMQ и динамический обратный вызов датчика. В Sensors Multi-HAL 2.0 функция initialize()
передаёт один обратный вызов, который необходимо использовать для публикации событий датчика, получения блокировок пробуждения и уведомления о подключении и отключении динамического датчика.
События датчиков передаются в реализацию Multi-HAL
Вместо отправки событий датчика через FMQ, под-HAL должен записывать события датчика в IHalProxyCallback
, когда события датчика доступны.
События WAKE_UP
В Sensors HAL 2.0 HAL может управлять блокировкой пробуждения для своей реализации. В Sensors Multi-HAL 2.0 подуровневые HAL позволяют реализации Multi-HAL управлять блокировками пробуждения и могут запросить получение блокировки пробуждения, вызвав createScopedWakelock
. Заблокированная блокировка пробуждения с заданной областью действия должна быть получена и передана в postEvents
при отправке событий пробуждения в реализацию Multi-HAL.
Динамические датчики
Датчики Multi-HAL 2.0 требуют, чтобы onDynamicSensorsConnected
и onDynamicSensorsDisconnected
в IHalProxyCallback
вызывались при каждом изменении подключений динамических датчиков. Эти обратные вызовы доступны как часть указателя IHalProxyCallback
, предоставляемого функцией initialize()
.
Порт от Sensors HAL 1.0
При обновлении с Sensors HAL 1.0 до Sensors Multi-HAL 2.0 убедитесь, что реализация HAL соответствует следующим требованиям.
Инициализируйте HAL
Функция initialize()
должна поддерживаться для установления обратного вызова между под-HAL и реализацией Multi-HAL.
Выставить доступные датчики
В Sensors Multi-HAL 2.0 функция getSensorsList()
должна возвращать одно и то же значение при загрузке одного устройства, даже при перезапуске HAL датчиков. Это позволяет фреймворку попытаться восстановить соединения с датчиками после перезапуска системного сервера. Значение, возвращаемое функцией getSensorsList()
может измениться после перезагрузки устройства.
События датчиков передаются в реализацию Multi-HAL
В Sensors HAL 2.0 вместо ожидания вызова poll()
под-HAL должен заблаговременно записывать события датчика в IHalProxyCallback
всякий раз, когда доступны события датчика.
События WAKE_UP
В Sensors HAL 1.0 HAL может управлять блокировкой пробуждения для своей реализации. В Sensors Multi-HAL 2.0 подсистемы HAL позволяют реализации Multi-HAL управлять блокировками пробуждения и могут запросить получение блокировки пробуждения, вызвав createScopedWakelock
. Заблокированная блокировка пробуждения с заданной областью действия должна быть получена и передана в postEvents
при отправке событий пробуждения в реализацию Multi-HAL.
Динамические датчики
В Sensors HAL 1.0 динамические датчики возвращаются через функцию poll()
. Sensors Multi-HAL 2.0 требует, чтобы onDynamicSensorsConnected
и onDynamicSensorsDisconnected
в IHalProxyCallback
вызывались при каждом изменении подключений динамических датчиков. Эти обратные вызовы доступны как часть указателя IHalProxyCallback
, предоставляемого функцией initialize()
.
Порт от Sensors Multi-HAL 1.0
Чтобы перенести существующую реализацию из Sensors Multi-HAL 1.0 , выполните следующие действия.
- Убедитесь, что конфигурация HAL датчиков находится в
/vendor/etc/sensors/hals.conf
. Для этого может потребоваться переместить файл, расположенный в/system/etc/sensors/hals.conf
. - Удалите все ссылки на
hardware/hardware.h
иhardware/sensors.h
так как они не поддерживаются в HAL 2.0. - Подключите суб-HAL, как описано в разделе Портирование с датчиков HAL 1.0 .
- Установите Sensors Multi-HAL 2.0 в качестве назначенного HAL, выполнив шаги 3 и 4 в разделе «Реализация Sensors Multi-HAL 2.0» .
Проверка
Запустить СУДС
После интеграции одного или нескольких дополнительных HAL с Sensors Multi-Hal 2.1 используйте Vendor Test Suite (VTS), чтобы убедиться, что ваши реализации дополнительных HAL соответствуют всем требованиям, установленным интерфейсом Sensors HAL.
Чтобы запустить только тесты датчиков VTS, когда VTS настроен на хост-компьютере, выполните следующие команды:
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_0Target && \
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsHalSensorsV2_1Target
Если вы используете слой прокладки AIDL Multi-HAL, запустите VtsAidlHalSensorsTargetTest
.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Выполнение модульных тестов
Модульные тесты в HalProxy_test.cpp
проверяют HalProxy
, используя поддельные подсистемы HAL, которые создаются в рамках модульного теста и не загружаются динамически. При создании нового подсистемы HAL эти тесты должны служить руководством по добавлению модульных тестов, проверяющих корректность реализации нового подсистемы HAL.
Для запуска тестов выполните следующие команды:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Тест с поддельными суб-HAL
Поддельные подсистемы HAL представляют собой фиктивные реализации интерфейса ISensorsSubHal
. Подсистемы HAL предоставляют различные списки датчиков. При активации датчики периодически отправляют автоматически сгенерированные события датчиков в HalProxy
с интервалами, указанными в запросе датчика.
Поддельные суб-HAL можно использовать для проверки того, как работает полный код Multi-HAL с другими суб-HAL, загруженными в систему, а также для проверки различных аспектов кода Multi-HAL датчиков.
Два поддельных sub-HAL доступны в hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
.
Чтобы создать и загрузить поддельные суб-HAL на устройство, выполните следующие действия:
Выполните следующие команды для создания и отправки трех различных поддельных суб-HAL на устройство:
$ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests/
mma
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so
adb push \ $ANDROID_BUILD_TOP/out/target/product/<device>/symbols/vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so \ /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
Обновите конфигурацию HAL датчиков в
/vendor/etc/sensors/hals.conf
, указав пути для поддельных дополнительных HAL./vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config1.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config2.so /vendor/lib64/android.hardware.sensors@2.X-fakesubhal-config3.so
Перезапустите
HalProxy
и загрузите новые под-HAL, указанные в конфигурации.adb shell stop
adb shell start
Отладка
Разработчики могут отлаживать фреймворк с помощью команды lshal
. Чтобы запросить отладочный вывод HAL-компонента Sensors, выполните следующую команду:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Информация о текущем состоянии HalProxy
и его подсистем HAL выводится на терминал. Ниже представлен пример вывода команды для объекта HalProxy
и поддельных подсистем HAL.
Internal values:
Threads are running: true
Wakelock timeout start time: 200 ms ago
Wakelock timeout reset time: 73208 ms ago
Wakelock ref count: 0
# of events on pending write queue: 0
# of non-dynamic sensors across all subhals: 8
# of dynamic sensors across all subhals: 0
SubHals (2):
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Name: FakeSubHal-OnChange
Debug dump:
Available sensors:
Name: Ambient Temp Sensor
Min delay: 40000
Flags: 2
Name: Light Sensor
Min delay: 200000
Flags: 2
Name: Proximity Sensor
Min delay: 200000
Flags: 3
Name: Relative Humidity Sensor
Min delay: 40000
Flags: 2
Если указанное число # of events on pending write queue
велико (1000 или более), это означает, что в фреймворк датчиков ожидающих записи много событий. Это указывает на то, что служба датчиков заблокирована, аварийно завершилась и не обрабатывает события датчиков, или на то, что из подуровнего уровня HAL недавно был отправлен большой пакет событий датчиков.
Если счётчик ссылок на пробуждение больше 0
, это означает, что HalProxy
получил пробуждение. Значение больше 0
может быть только в том случае, если ScopedWakelock
удерживается намеренно или если события пробуждения были отправлены в HalProxy
и не были обработаны фреймворком сенсора.
Дескриптор файла, переданный в метод отладки HalProxy
, передается в каждый под-HAL, поэтому разработчики должны реализовать метод отладки как часть интерфейса ISensorsSubHal
.