Multi-HAL датчиков – это фреймворк, который позволяет HAL датчиков работать вместе с другими HAL датчиков. Многофункциональный HAL датчиков динамически загружает вспомогательные HAL датчиков, хранящиеся в виде динамических библиотек в разделе поставщика, и предоставляет им объект обратного вызова, который может обрабатывать отправку событий, а также получение и освобождение блокировки пробуждения. Суб-HAL датчиков – это HAL датчиков, встроенный в общий объект в разделе поставщика и используемый фреймворком multi-HAL. Эти вложенные HAL не зависят друг от друга или от кода многомодульного HAL, который содержит основную функцию для процесса.
Multi-HAL 2.1 для датчиков, доступный на устройствах с Android 11 или более поздней версией, – это итерация Multi-HAL 2.0 для датчиков, которая поддерживает загрузку дополнительных HAL, способных предоставлять тип датчика угла шарнира. Чтобы поддерживать этот тип датчика, вложенные HAL должны использовать API вложенных HAL, определенные в заголовке SubHal версии 2.1.
На устройствах с Android 13 или более поздней версии, на которых используется HAL-интерфейс AIDL для датчиков, можно использовать многоуровневую прокладку HAL, чтобы разрешить многоуровневую работу HAL. Подробнее о реализации многофункционального HAL датчиков с помощью HAL датчиков AIDL…
Различия между Sensors Multi-HAL 2 и Sensors HAL 2
В Multi-HAL 2 для датчиков, доступном на устройствах с Android 10 или более поздней версии, реализовано несколько абстракций поверх 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) следующим образом:
- Метод initialize передает класс
IHalProxyCallbackвместо двух FMQ иISensorsCallback. - Вложенные HAL должны реализовывать функцию отладки, которая предоставляет информацию для отладки в отчетах об ошибках.
- Вложенные HAL должны реализовывать функцию имени, чтобы загруженный вложенный HAL можно было отличить от других вложенных HAL.
Основное различие между Sensors Multi-HAL 2 и Sensors HAL 2 заключается в функциях инициализации. Вместо FMQ интерфейс IHalProxyCallback предоставляет два метода: один для отправки событий датчиков в фреймворк датчиков, а другой – для создания блокировок пробуждения. Внутри Sensors Multi-HAL управляет всеми взаимодействиями с FMQ, чтобы обеспечить своевременную доставку событий датчиков для всех суб-HAL. Мы настоятельно рекомендуем использовать вложенные HAL-модули метод createScopedWakelock, чтобы делегировать задачу отслеживания времени ожидания запретов блокировки многомодульному HAL датчиков и централизовать использование запретов блокировки в одном общем запрете блокировки для всего многомодульного HAL датчиков. Это позволит свести к минимуму вызовы блокировки и разблокировки.
В Sensors Multi-HAL 2 также встроены некоторые функции безопасности. Он обрабатывает ситуации, когда очередь сообщений FMQ датчика заполнена или когда платформа датчиков Android перезапускается и состояние датчика необходимо сбросить. Кроме того, если события отправляются в класс HalProxy, но фреймворк датчиков не может принять их немедленно, многокомпонентный HAL датчиков может переместить события в фоновый поток, чтобы позволить продолжить работу во всех суб-HAL, пока события не будут отправлены.
Исходный код и пример реализации
Весь код 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 реализует метод initialize, чтобы объект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 на устройстве.
Реализация
В этом разделе описано, как реализовать Multi-HAL датчиков в следующих ситуациях:
- Использование Sensors Multi-HAL с Sensors AIDL HAL
- Реализация Multi-HAL 2.1 для датчиков
- Перенос с Sensors Multi-HAL 2.0 на Multi-HAL 2.1
- Перенос из Sensors HAL 2.0
- Перенос из Sensors HAL 1.0
- Перенос данных из Sensors Multi-HAL 1.0
Использовать Sensors Multi-HAL с Sensors AIDL HAL
Чтобы разрешить использование нескольких HAL с Sensors AIDL HAL, импортируйте модуль AIDL Multi-HAL shim layer, который находится в hardware/interfaces/sensors/aidl/default/multihal/. Модуль обрабатывает преобразование между типами определений HAL сенсоров AIDL и HIDL и определяет оболочку для многоуровневого интерфейса HAL, описанного в разделе Реализация многоуровневого HAL сенсоров 2.1. Промежуточный слой AIDL multi-HAL совместим с устройствами, на которых реализован Sensors Multi-HAL 2.1.
Многоуровневая прослойка AIDL HAL позволяет предоставлять доступ к датчикам отслеживания движений головы и ограниченной оси IMU в Sensors AIDL HAL. Чтобы использовать типы датчиков, определенные интерфейсом AIDL HAL, задайте поле type в структуре SensorInfo в реализации getSensorsList_2_1(). Это безопасно, поскольку целочисленные поля типа датчика в HAL датчиков AIDL и HIDL не пересекаются.
Как реализовать Sensors 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.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.
Перенос с Sensors Multi-HAL 2.0 на Multi-HAL 2.1
Чтобы перенести данные из Multi-HAL 2.0 в Multi-HAL 2.1, реализуйте интерфейс SubHal и перекомпилируйте свой суб-HAL.
Ниже перечислены различия между интерфейсами SubHal версий 2.0 и 2.1.
- В
IHalProxyCallbackиспользуются типы, созданные в версии 2.1 спецификацииISensors.hal. - Функция
initialize()передает новый объектIHalProxyCallbackвместо объекта из интерфейсаSubHalверсии 2.0. - Вместо
getSensorsListиinjectSensorDataв суб-HAL должны быть реализованыgetSensorsList_2_1иinjectSensorData_2_1, поскольку в этих методах используются новые типы, добавленные в спецификациюISensors.halверсии 2.1. - Вложенные HAL должны предоставлять
sensorsHalGetSubHal_2_1, а неsensorsHalGetSubHal, чтобы Multi-HAL воспринимал их как вложенные HAL версии 2.1.
Перенос из Sensors HAL 2.0
При переходе на Sensors Multi-HAL 2.0 с Sensors HAL 2.0 убедитесь, что реализация HAL соответствует следующим требованиям.
Инициализация HAL
В 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 портов, как описано в разделе Перенос из Sensors HAL 1.0.
- Назначьте Sensors Multi-HAL 2.0 в качестве HAL по умолчанию, выполнив шаги 3 и 4 в разделе Реализация Sensors Multi-HAL 2.0.
Проверка
Как запустить VTS
После интеграции одного или нескольких дополнительных 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/testsatest
Тестирование с использованием подсистем HAL
Поддельные вложенные HAL – это фиктивные реализации интерфейса ISensorsSubHal.
Вложенные HAL-модули предоставляют разные списки датчиков. Когда датчики активированы, они периодически отправляют автоматически сгенерированные события датчиков в HalProxy на основе интервалов, указанных в запросе датчика.
Имитированные суб-HAL можно использовать для тестирования того, как полный код Multi-HAL работает с другими суб-HAL, загруженными в систему, и для стресс-тестирования различных аспектов кода Sensors 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/mmaadb 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.soadb 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.soadb 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 stopadb shell start
Отладка
Разработчики могут отлаживать фреймворк с помощью команды lshal. Чтобы запросить вывод отладочной информации из HAL датчиков, выполните следующую команду:
adb rootadb 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.