Sensors Multi-HAL — это фреймворк, позволяющий сенсорным HAL-модулям работать параллельно с другими сенсорными HAL-модулями. Sensors Multi-HAL динамически загружает подмодули сенсорных HAL-модулей, хранящиеся в виде динамических библиотек в разделе поставщика, и предоставляет им объект обратного вызова, который может обрабатывать отправку событий, а также получение и снятие блокировки пробуждения. Подмодуль сенсорного HAL-модуля — это сенсорный HAL-модуль, встроенный в раздел раздела поставщика и используемый фреймворком Multi-HAL. Эти подмодули не зависят друг от друга или от кода Multi-HAL, содержащего основную функцию процесса.
Sensors Multi-HAL 2.1, доступный на устройствах под управлением Android 11 или выше, является версией Sensors Multi-HAL 2.0, которая поддерживает загрузку дочерних HAL-модулей, способных предоставлять доступ к датчику угла поворота шарнира . Для поддержки этого типа датчика дочерние HAL-модули должны использовать API дочерних HAL-модулей, определенные в заголовочном файле SubHal версии 2.1 .
Для устройств под управлением 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 ) следующими способами:
- Метод initialize передает класс
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, ожидая отправки событий.
Исходный код и эталонная реализация
Весь код Multi-HAL для датчиков доступен в hardware/interfaces/sensors/common/default/2.X/multihal/ . Ниже приведены ссылки на некоторые ресурсы.
-
HalProxy.h: ОбъектHalProxyсоздается модулем multi-HAL в Sensors и обрабатывает передачу данных от дочерних 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 на устройстве.
Выполнение
В этом разделе описывается, как реализовать Sensors 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 и определяет оболочку вокруг интерфейса multi-HAL, описанного в разделе «Реализация Sensors Multi-HAL 2.1» . Модуль AIDL multi-HAL shim layer совместим с устройствами, реализующими Sensors Multi-HAL 2.1.
Слой-заглушка AIDL multi-HAL позволяет отображать типы датчиков отслеживания головы и IMU с ограниченной осью в интерфейсе AIDL Sensors. Чтобы использовать эти типы датчиков, определенные интерфейсом AIDL HAL, установите поле type в структуре SensorInfo в реализации getSensorsList_2_1() . Это безопасно, поскольку поля типов датчиков с целочисленной поддержкой в интерфейсах AIDL и HIDL Sensors HAL не перекрываются.
Внедрить датчики 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для сборки подбиблиотеки HAL можно найти в файлеhardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.Удалите все записи
android.hardware.sensorsиз файлаmanifest.xml, который содержит список поддерживаемых HAL на устройстве.Удалите все файлы
android.hardware.sensorsservice иservice.rcиз файлаdevice.mkи добавьтеandroid.hardware.sensors@2.1-service.multihalиandroid.hardware.sensors@2.1-service.multihal.rcвPRODUCT_PACKAGES.
При загрузке системы запускается HalProxy , ищет недавно реализованный подсистему HAL и инициализирует его, вызывая функцию sensorsHalGetSubHal_2_1 .
Перенос данных с Sensors 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. - Для того чтобы Multi-HAL рассматривал их как подсистемы HAL версии 2.1, дочерние HAL-модули должны предоставлять доступ
sensorsHalGetSubHal_2_1, а неsensorsHalGetSubHal.
Портировано из 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.
Динамические датчики
Для работы с Sensors Multi-HAL 2.0 требуется, чтобы onDynamicSensorsConnected и onDynamicSensorsDisconnected в IHalProxyCallback вызывались всякий раз, когда изменяются динамические соединения с датчиками. Эти методы обратного вызова доступны как часть указателя IHalProxyCallback , предоставляемого через функцию initialize() .
Порт из Sensors HAL 1.0
При обновлении с Sensors HAL 1.0 до Sensors Multi-HAL 2.0 убедитесь, что реализация HAL соответствует следующим требованиям.
Инициализация HAL
Для установления обратного вызова между подсистемой HAL и реализацией Multi-HAL необходимо поддерживать функцию initialize() .
Отобразить доступные датчики
В Sensors Multi-HAL 2.0 функция getSensorsList() должна возвращать одно и то же значение в течение одной загрузки устройства, даже при перезапуске Sensors 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 используйте набор тестов поставщика (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.
В папке hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ доступны два поддельных суб-HAL.
Для создания и загрузки поддельных суб-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-модуля Sensors, выполните следующую команду:
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 .