Sensors Multi-HAL — это фреймворк, который позволяет HAL-ам датчиков работать вместе с другими HAL-ам датчиков. Sensors Multi-HAL динамически загружает суб-HAL-ы датчиков, хранящиеся в виде динамических библиотек в разделе поставщика, и предоставляет им объект обратного вызова, который может обрабатывать события публикации, а также получать и снимать блокировку пробуждения. Sub-HAL-ы датчиков — это HAL-ы датчиков, встроенные в общий объект в разделе поставщика и используемые фреймворком multi-HAL. Эти суб-HAL-ы не зависят друг от друга или от кода multi-HAL, который содержит основную функцию для процесса.
Sensors Multi-HAL 2.1, доступный на устройствах под управлением Android 11 или выше, представляет собой итерацию Sensors Multi-HAL 2.0, которая поддерживает загрузку sub-HAL, которые могут предоставлять тип датчика угла шарнира . Для поддержки этого типа датчика sub-HAL должны использовать API sub-HAL, определенные в заголовке 2.1 SubHal .
Для устройств под управлением Android 13 или выше, использующих Sensors AIDL HAL , можно использовать слой прокладки multi-HAL для обеспечения возможности multi-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/
: Этот пример реализации sub-HAL использует поддельные датчики для генерации поддельных данных. Полезно для тестирования того, как несколько sub-HAL взаимодействуют на устройстве.
Выполнение
В этом разделе описывается, как реализовать датчики 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 с Sensors AIDL HAL, импортируйте модуль слоя прокладки AIDL Multi-HAL, который находится в hardware/interfaces/sensors/aidl/default/multihal/ . Модуль обрабатывает преобразование между типами определения HAL датчиков AIDL и HIDL и определяет оболочку вокруг интерфейса multi-HAL, описанного в разделе Реализация датчиков Multi-HAL 2.1 . Слой прокладки AIDL multi-HAL совместим с устройствами, реализующими Sensors Multi-HAL 2.1.
Слой AIDL multi-HAL shim позволяет вам раскрыть типы датчиков head tracker и limited-axis IMU в Sensors AIDL HAL. Чтобы использовать эти типы датчиков, определенные интерфейсом AIDL HAL, установите поле type
в структуре SensorInfo
в реализации getSensorsList_2_1()
. Это безопасно, поскольку поля типа датчика с целочисленной поддержкой датчиков AIDL и HIDL HAL не перекрываются.
Датчики навесного оборудования Multi-HAL 2.1
Чтобы внедрить Sensors Multi-HAL 2.1 на новом устройстве, выполните следующие действия:
- Реализуйте интерфейс
ISensorsSubHal
, как описано вSubHal.h
. - Реализуйте метод
sensorsHalGetSubHal_2_1
вSubHal.h
. Добавьте цель
cc_library_shared
для сборки недавно реализованного sub-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 - Sub-HAL должны реализовывать
getSensorsList_2_1
иinjectSensorData_2_1
вместоgetSensorsList
иinjectSensorData
, поскольку эти методы используют новые типы, добавленные в версии 2.1 спецификацииISensors.hal
. - Sub-HAL должны предоставлять
sensorsHalGetSubHal_2_1
, а неsensorsHalGetSubHal
, чтобы Multi-HAL рассматривал их как sub-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()
должна поддерживаться для установления обратного вызова между реализацией sub-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()
.
Порт от датчиков 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 датчиков.
Два поддельных суб-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 датчиков, выполните следующую команду:
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
.