Датчики Multi-HAL

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.

Для обеспечения возможности работы с несколькими 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 на новое устройство выполните следующие действия:

  1. Реализуйте интерфейс ISensorsSubHal , как описано в SubHal.h .
  2. Реализуйте метод sensorsHalGetSubHal_2_1 в SubHal.h .
  3. Добавьте цель cc_library_shared для сборки недавно реализованного подсистемы HAL. При добавлении цели:

    1. Убедитесь, что целевое устройство загружено в раздел, относящийся к производителю.
    2. В конфигурационном файле, расположенном по адресу /vendor/etc/sensors/hals.conf , добавьте путь к библиотеке на новой строке. При необходимости создайте файл hals.conf .

    Пример записи в файле Android.bp для сборки подбиблиотеки HAL можно найти в файле hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp .

  4. Удалите все записи android.hardware.sensors из файла manifest.xml , который содержит список поддерживаемых HAL на устройстве.

  5. Удалите все файлы 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 , ищет недавно реализованный подсистему 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 выполните следующие шаги.

  1. Убедитесь, что конфигурация HAL для датчиков находится по адресу /vendor/etc/sensors/hals.conf . Возможно, для этого потребуется переместить файл, расположенный по адресу /system/etc/sensors/hals.conf .
  2. Удалите все ссылки на hardware/hardware.h и hardware/sensors.h поскольку они не поддерживаются для HAL 2.0.
  3. Переносите подсистемы HAL, как описано в разделе «Перенос из Sensors HAL 1.0» .
  4. Установите 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/tests
atest

Протестируйте с помощью поддельных суб-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 на устройство выполните следующие шаги:

  1. Выполните следующие команды, чтобы собрать и загрузить на устройство три различных поддельных суб-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
  2. Обновите конфигурацию 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
    
  3. Перезапустите 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 .