Датчики Multi-HAL

Многоуровневый HAL датчиков (Sensors Multi-HAL) — это фреймворк, позволяющий HAL датчиков работать параллельно с другими HAL датчиков. Многоуровневый HAL датчиков (Sensors Multi-HAL) динамически загружает подуровневые HAL датчиков, хранящиеся в виде динамических библиотек в разделе поставщика, и предоставляет им объект обратного вызова, который может обрабатывать события отправки, а также получать и снимать блокировку пробуждения. Подуровневый HAL датчиков — это HAL датчиков, встроенный в общий объект в разделе поставщика и используемый фреймворком многоуровневого HAL. Эти подуровневые HAL не зависят друг от друга и от кода многоуровневого HAL, содержащего основную функцию процесса.

Sensors Multi-HAL 2.1, доступный на устройствах под управлением Android 11 и выше, представляет собой итерацию Sensors Multi-HAL 2.0, которая поддерживает загрузку подсистем HAL, предоставляющих доступ к данным о датчике угла поворота шарнира . Для поддержки этого типа датчиков подсистемы HAL должны использовать API подсистем HAL, определённые в заголовке 2.1 SubHal .

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

  • Метод инициализации передает класс 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/ : В этом примере реализации подсистемы HAL используются поддельные датчики для генерации поддельных данных. Полезно для тестирования взаимодействия нескольких подсистем HAL на устройстве.

Выполнение

В этом разделе описывается, как реализовать функцию Sensors Multi-HAL в следующих ситуациях:

Используйте датчики Multi-HAL с датчиками AIDL HAL

Чтобы реализовать поддержку нескольких HAL с помощью HAL-модуля Sensors AIDL, импортируйте модуль слоя-прокладки AIDL Multi-HAL, который находится в папке hardware/interfaces/sensors/aidl/default/multihal/ . Этот модуль выполняет преобразование между типами определения HAL датчиков AIDL и HIDL и определяет оболочку для интерфейса multi-HAL, описанного в разделе «Реализация датчиков Multi-HAL 2.1» . Слой-прокладка AIDL multi-HAL совместим с устройствами, реализующими Multi-HAL 2.1.

Слой-прокладка AIDL multi-HAL позволяет отображать типы датчиков слежения за головой и инерциальных измерительных блоков с ограниченной осью в HAL-системе датчиков AIDL. Чтобы использовать эти типы датчиков, определяемые интерфейсом AIDL HAL, задайте поле type в структуре SensorInfo в реализации getSensorsList_2_1() . Это безопасно, поскольку целочисленные поля типа датчика в HAL-системах датчиков AIDL и HIDL не перекрываются.

Датчики навесного оборудования 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 для создания библиотеки 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.
  • Подклассы HAL должны реализовывать getSensorsList_2_1 и injectSensorData_2_1 вместо getSensorsList и injectSensorData , поскольку эти методы используют новые типы, добавленные в версии 2.1 спецификации ISensors.hal .
  • Подчиненные HAL должны предоставлять sensorsHalGetSubHal_2_1 , а не sensorsHalGetSubHal , чтобы Multi-HAL рассматривал их как подчинённые 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() должна поддерживаться для установления обратного вызова между под-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 , выполните следующие действия.

  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 датчиков.

Два поддельных sub-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-компонента 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 .