Sensores Multi-HAL

Sensors Multi-HAL es un marco que permite que los sensores HAL funcionen junto con otros sensores HAL. Sensors Multi-HAL carga dinámicamente sub-HAL de sensores almacenados como bibliotecas dinámicas en la partición del proveedor y les proporciona un objeto de devolución de llamada que puede manejar la publicación de eventos y la adquisición y liberación del bloqueo de activación. Un sub-HAL de sensores es un HAL de sensores que está integrado en un objeto compartido en la partición del proveedor y es utilizado por el marco multi-HAL. Estos sub-HAL no dependen unos de otros ni del código multi-HAL que contiene la función principal del proceso.

Sensors Multi-HAL 2.1, disponible en dispositivos con Android 11 o superior, es una iteración de Sensors Multi-HAL 2.0 que admite la carga de sub-HAL que pueden exponer el tipo de sensor de ángulo de bisagra . Para admitir este tipo de sensor, los sub-HAL deben utilizar las API sub-HAL definidas en el encabezado 2.1 SubHal .

Para dispositivos con Android 13 o superior que usan sensores AIDL HAL , puede usar la capa de cuña multi-HAL para permitir la capacidad multi-HAL. Para obtener detalles de implementación, consulte Uso de los sensores Multi-HAL con los sensores AIDL HAL .

Diferencia entre Sensores Multi-HAL 2 y Sensores HAL 2

Sensors Multi-HAL 2, disponible en dispositivos con Android 10 o superior, introduce varias abstracciones además de Sensors HAL 2 para facilitar la interacción con las API de HAL. Sensors Multi-HAL 2 presenta la clase HalProxy para manejar la implementación de la interfaz Sensors HAL 2 y la interfaz V2_1/SubHal (o V2_0/SubHal ) para permitir que HalProxy interactúe con sub-HAL.

La interfaz ISensorsSubHal es diferente de la interfaz 2.1/ISensors.hal (o 2.0/ISensors.hal ) en las siguientes formas:

  • El método de inicialización pasa una clase IHalProxyCallback en lugar de dos FMQ e ISensorsCallback .
  • Los Sub-HAL deben implementar una función de depuración para proporcionar información de depuración en los informes de errores.
  • Los sub-HAL deben implementar una función de nombre para que el sub-HAL cargado pueda distinguirse de otros sub-HAL.

La principal diferencia entre Sensors Multi-HAL 2 y Sensors HAL 2 está en las funciones de inicialización. En lugar de proporcionar FMQ, la interfaz IHalProxyCallback proporciona dos métodos, un método para publicar eventos de sensores en el marco de sensores y un método para crear bloqueos de activación. Debajo del capó, Sensors Multi-HAL gestiona todas las interacciones con los FMQ para garantizar la entrega oportuna de eventos de sensores para todos los sub-HAL. Se recomienda encarecidamente que los sub-HAL utilicen el método createScopedWakelock para delegar la carga de cronometrar los bloqueos de activación al Sensors Multi-HAL y centralizar el uso del bloqueo de activación en un bloqueo de activación común para todos los Sensores Multi-HAL, lo que minimiza el bloqueo y desbloqueo. llamadas.

Sensores Multi-HAL 2 también tiene algunas características de seguridad integradas. Maneja situaciones en las que el sensor FMQ está lleno o en las que el marco del sensor de Android se reinicia y es necesario restablecer el estado del sensor. Además, cuando los eventos se publican en la clase HalProxy pero el marco del sensor no puede aceptarlos inmediatamente, Sensors Multi-HAL puede mover los eventos a un subproceso en segundo plano para permitir que el trabajo continúe en todos los sub-HAL mientras se esperan los eventos. para ser publicado.

Código fuente e implementación de referencia.

El código Multi-HAL de todos los sensores está disponible en hardware/interfaces/sensors/common/default/2.X/multihal/ . A continuación se ofrecen sugerencias sobre algunos recursos.

  • HalProxy.h : el objeto HalProxy es creado por Sensors multi-HAL y maneja el paso de datos desde los sub-HAL al marco del sensor.
  • HalProxy.cpp : la implementación de HalProxy contiene toda la lógica necesaria para multiplexar la comunicación entre los sub-HAL y el marco del sensor.
  • SubHal.h : la interfaz ISensorsSubHal define la interfaz que los sub-HAL deben seguir para ser compatibles con HalProxy . El sub-HAL implementa el método de inicialización para que el objeto HalProxyCallback pueda usarse para postEvents y createScopedWakelock .

    Para implementaciones Multi-HAL 2.0, utilice la versión 2.0 de SubHal.h .

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/ : estas pruebas unitarias verifican la implementación HalProxy .

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ : este ejemplo de implementación sub-HAL utiliza sensores falsos para generar datos falsos. Útil para probar cómo interactúan varios sub-HAL en un dispositivo.

Implementación

Esta sección describe cómo implementar Sensores Multi-HAL en las siguientes situaciones:

Utilice los Sensores Multi-HAL con los Sensores AIDL HAL

Para permitir la capacidad multi-HAL con los sensores AIDL HAL, importe el módulo de capa de cuña AIDL Multi-HAL, que se encuentra en hardware/interfaces/sensors/aidl/default/multihal/ . El módulo maneja la conversión entre los tipos de definición HAL de sensores AIDL y HIDL y define un contenedor alrededor de la interfaz multi-HAL descrita en Implementación de sensores Multi-HAL 2.1 . La capa de cuña AIDL multi-HAL es compatible con dispositivos que implementan Sensores Multi-HAL 2.1.

La capa de cuña AIDL multi-HAL le permite exponer los tipos de sensores IMU de eje limitado y rastreador de cabeza en los sensores AIDL HAL. Para utilizar estos tipos de sensores definidos por la interfaz AIDL HAL, configure el campo type en la estructura SensorInfo en la implementación getSensorsList_2_1() . Esto es seguro porque los campos de tipo de sensor respaldados por números enteros de los sensores HAL AIDL y HIDL no se superponen.

Sensores de implementos Multi-HAL 2.1

Para implementar Sensors Multi-HAL 2.1 en un nuevo dispositivo, siga estos pasos:

  1. Implemente la interfaz ISensorsSubHal como se describe en SubHal.h .
  2. Implemente el método sensorsHalGetSubHal_2_1 en SubHal.h .
  3. Agregue un objetivo cc_library_shared para construir el sub-HAL recién implementado. Al agregar el objetivo:

    1. Asegúrese de que el objetivo se envíe a algún lugar de la partición del proveedor del dispositivo.
    2. En el archivo de configuración ubicado en /vendor/etc/sensors/hals.conf , agregue la ruta a la biblioteca en una nueva línea. Si es necesario, cree el archivo hals.conf .

    Para ver un ejemplo de entrada Android.bp para crear una biblioteca sub-HAL, consulte hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp .

  4. Elimine todas las entradas android.hardware.sensors del archivo manifest.xml , que contiene la lista de HAL admitidos en el dispositivo.

  5. Elimine todos los archivos android.hardware.sensors service y service.rc del archivo device.mk y agregue android.hardware.sensors@2.1-service.multihal y android.hardware.sensors@2.1-service.multihal.rc a PRODUCT_PACKAGES .

Al arrancar, HalProxy se inicia, busca el sub-HAL recién implementado y lo inicializa llamando sensorsHalGetSubHal_2_1 .

Puerto de Sensores Multi-HAL 2.0 a Multi-HAL 2.1

Para migrar de Multi-HAL 2.0 a Multi-HAL 2.1, implemente la interfaz SubHal y vuelva a compilar su sub-HAL.

Estas son las diferencias entre las interfaces SubHal 2.0 y 2.1:

  • IHalProxyCallback utiliza los tipos creados en la versión 2.1 de la especificación ISensors.hal .
  • La función initialize() pasa un nuevo IHalProxyCallback en lugar del de la interfaz SubHal 2.0
  • Los sub-HAL deben implementar getSensorsList_2_1 e injectSensorData_2_1 en lugar de getSensorsList e injectSensorData , ya que estos métodos utilizan los nuevos tipos agregados en la versión 2.1 de la especificación ISensors.hal .
  • Los sub-HAL deben exponer sensorsHalGetSubHal_2_1 en lugar de sensorsHalGetSubHal para que Multi-HAL los trate como sub-HAL de la versión 2.1.

Puerto de Sensores HAL 2.0

Al actualizar a Sensors Multi-HAL 2.0 desde Sensors HAL 2.0 , asegúrese de que la implementación de HAL cumpla con los siguientes requisitos.

Inicializar el HAL

Sensores HAL 2.0 tiene una función de inicialización que permite que el servicio del sensor pase FMQ y una devolución de llamada dinámica del sensor. En Sensors Multi-HAL 2.0, la función initialize() pasa una única devolución de llamada que debe usarse para publicar eventos de sensores, obtener bloqueos de activación y notificar conexiones y desconexiones dinámicas de sensores.

Publicar eventos de sensores en la implementación de Multi-HAL

En lugar de publicar eventos de sensores a través de FMQ, el sub-HAL debe escribir eventos de sensores en IHalProxyCallback cuando los eventos de sensores estén disponibles.

Eventos WAKE_UP

En Sensors HAL 2.0, HAL puede gestionar el wake lock para su implementación. En Sensors Multi-HAL 2.0, los sub-HAL permiten que la implementación de Multi-HAL administre bloqueos de activación y puede solicitar que se adquiera un bloqueo de activación invocando createScopedWakelock . Se debe adquirir un bloqueo de activación con alcance bloqueado y pasarlo a postEvents al publicar eventos de activación en la implementación Multi-HAL.

Sensores dinámicos

Sensors Multi-HAL 2.0 requiere que se llame a onDynamicSensorsConnected y onDynamicSensorsDisconnected en IHalProxyCallback cada vez que cambian las conexiones de los sensores dinámicos. Estas devoluciones de llamada están disponibles como parte del puntero IHalProxyCallback que se proporciona a través de la función initialize() .

Puerto de sensores HAL 1.0

Al actualizar a Sensors Multi-HAL 2.0 desde Sensors HAL 1.0 , asegúrese de que la implementación de HAL cumpla con los siguientes requisitos.

Inicializar el HAL

La función initialize() debe ser compatible para establecer la devolución de llamada entre la implementación sub-HAL y Multi-HAL.

Exponer los sensores disponibles

En Sensors Multi-HAL 2.0, la función getSensorsList() debe devolver el mismo valor durante el inicio de un solo dispositivo, incluso entre reinicios de HAL de sensores. Esto permite que el marco intente restablecer las conexiones de los sensores si el servidor del sistema se reinicia. El valor devuelto por getSensorsList() puede cambiar después de que el dispositivo realiza un reinicio.

Publicar eventos de sensores en la implementación de Multi-HAL

En Sensors HAL 2.0, en lugar de esperar a que se llame a poll() , el sub-HAL debe escribir de forma proactiva los eventos del sensor en IHalProxyCallback siempre que los eventos del sensor estén disponibles.

Eventos WAKE_UP

En Sensors HAL 1.0, HAL puede gestionar el wake lock para su implementación. En Sensors Multi-HAL 2.0, los sub-HAL permiten que la implementación de Multi-HAL administre bloqueos de activación y puede solicitar que se adquiera un bloqueo de activación invocando createScopedWakelock . Se debe adquirir un bloqueo de activación con alcance bloqueado y pasarlo a postEvents al publicar eventos de activación en la implementación Multi-HAL.

Sensores dinámicos

En Sensors HAL 1.0, los sensores dinámicos se devuelven a través de la función poll() . Sensors Multi-HAL 2.0 requiere que se llame a onDynamicSensorsConnected y onDynamicSensorsDisconnected en IHalProxyCallback cada vez que cambian las conexiones de los sensores dinámicos. Estas devoluciones de llamada están disponibles como parte del puntero IHalProxyCallback que se proporciona a través de la función initialize() .

Puerto de Sensores Multi-HAL 1.0

Para portar una implementación existente de Sensors Multi-HAL 1.0 , siga estos pasos.

  1. Asegúrese de que la configuración HAL de los sensores esté ubicada en /vendor/etc/sensors/hals.conf. Esto podría implicar mover el archivo ubicado en /system/etc/sensors/hals.conf .
  2. Elimine cualquier referencia a hardware/hardware.h y hardware/sensors.h , ya que no son compatibles con HAL 2.0.
  3. Port sub-HAL como se describe en Porting from Sensors Hal 1.0 .
  4. Configure Sensors Multi-HAL 2.0 como el HAL designado siguiendo los pasos 3 y 4 en la sección Implementación de sensores Mutli-HAL 2.0 .

Validación

Ejecutar VTS

Cuando haya integrado uno o más sub-HAL con Sensors Multi-Hal 2.1, utilice Vendor Test Suite (VTS) para garantizar que sus implementaciones sub-HAL cumplan con todos los requisitos establecidos por la interfaz Sensors HAL.

Para ejecutar solo las pruebas VTS de los sensores cuando VTS está configurado en una máquina host, ejecute los siguientes comandos:

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

Si está ejecutando la capa de cuña AIDL Multi-HAL, ejecute VtsAidlHalSensorsTargetTest .

vts-tradefed run commandAndExit vts \
    --skip-all-system-status-check \
    --primary-abi-only \
    --skip-preconditions \
    --module VtsAidlHalSensorsTargetTest

Ejecutar pruebas unitarias

Las pruebas unitarias en HalProxy_test.cpp prueban HalProxy utilizando sub-HAL falsos que se crean instancias en la prueba unitaria y no se cargan dinámicamente. Al crear un nuevo sub-HAL, estas pruebas deben servir como guía sobre cómo agregar pruebas unitarias que verifiquen que el nuevo sub-HAL se implemente correctamente.

Para ejecutar las pruebas, ejecute los siguientes comandos:

cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest

Prueba con los sub-HAL falsos

Los sub-HAL falsos son implementaciones ficticias de la interfaz ISensorsSubHal . Los sub-HAL exponen diferentes listas de sensores. Cuando los sensores se activan, publican periódicamente eventos de sensores generados automáticamente en HalProxy en función de los intervalos especificados en una solicitud de sensor determinada.

Los sub-HAL falsos se pueden utilizar para probar cómo funciona el código Multi-HAL completo con otros sub-HAL cargados en el sistema y para enfatizar varios aspectos del código Multi-HAL de sensores.

Hay dos sub-HAL falsos disponibles en hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/ .

Para crear y enviar sub-HAL falsos a un dispositivo, realice los siguientes pasos:

  1. Ejecute los siguientes comandos para compilar y enviar los tres sub-HAL falsos diferentes al dispositivo:

    $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. Actualice la configuración HAL de los sensores en /vendor/etc/sensors/hals.conf con las rutas para los sub-HAL falsos.

    /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. Reinicie HalProxy y cargue los nuevos sub-HAL enumerados en la configuración.

    adb shell stop
    adb shell start
    

Depuración

Los desarrolladores pueden depurar el marco utilizando el comando lshal . Para solicitar la salida de depuración de Sensors HAL, ejecute el siguiente comando:

adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default

Luego, la información sobre el estado actual de HalProxy y sus sub-HAL se envía al terminal. A continuación se muestra un ejemplo de la salida del comando para el objeto HalProxy y sub-HAL falsos.

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

Si el número especificado para # of events on pending write queue es grande (1000 o más), esto indica que hay muchos eventos pendientes de escribir en el marco de sensores. Esto indica que el servicio de sensores está bloqueado o se ha bloqueado y no está procesando eventos de sensores, o que recientemente se publicó un gran lote de eventos de sensores desde un sub-HAL.

Si el recuento de referencias de bloqueo de activación es mayor que 0 , esto significa que HalProxy ha adquirido un bloqueo de activación. Esto solo debe ser mayor que 0 si se realiza intencionalmente un ScopedWakelock o si los eventos de activación se enviaron a HalProxy y el marco del sensor no los procesó.

El descriptor de archivo pasado al método de depuración de HalProxy se pasa a cada sub-HAL, por lo que los desarrolladores deben implementar el método de depuración como parte de la interfaz ISensorsSubHal .