Датчики Multi-HAL

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

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

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

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

    Пример записи Android.bp для создания библиотеки sub-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 , ищет недавно реализованный 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 , выполните следующие действия.

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

  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 датчиков, выполните следующую команду:

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 .