Sensores Multi-HAL

Sensors Multi-HAL es un marco que permite que los sensores HAL se ejecuten junto con otros sensores HAL. Sensors Multi-HAL carga dinámicamente los sensores sub-HAL 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. Una sub-HAL de sensores es una HAL de sensores integrada en un objeto compartido en la partición del proveedor y es utilizada por el marco multi-HAL. Estas sub-HAL no dependen unas de otras 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, las sub-HAL deben usar las API de sub-HAL definidas en el encabezado 2.1 SubHal .

Diferencia entre Sensores Multi-HAL 2 y Sensores HAL 2

Sensors Multi-HAL 2, disponible en dispositivos con Android 10 o superior, presenta 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 los siguientes aspectos:

  • El método de inicialización pasa una clase IHalProxyCallback en lugar de dos FMQ e ISensorsCallback .
  • Las sub-HAL deben implementar una función de depuración para proporcionar información de depuración en los informes de errores.
  • Las sub-HAL deben implementar una función de nombre para que la sub-HAL cargada pueda distinguirse de otras 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 wake locks. Debajo del capó, Sensors Multi-HAL administra todas las interacciones con los FMQ para garantizar la entrega oportuna de eventos de sensores para todos los sub-HAL. Se recomienda encarecidamente que las sub-HAL usen el método createScopedWakelock para delegar la carga de agotar el tiempo de activación de los wake locks a Sensors Multi-HAL y centralizar el uso de wake locks en un wake lock común para todo Sensors Multi-HAL, lo que minimiza el bloqueo y desbloqueo. llamadas

Sensors Multi-HAL 2 también tiene algunas funciones de seguridad integradas. Maneja situaciones en las que el FMQ del sensor 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 aceptar los eventos de inmediato, Sensors Multi-HAL puede mover los eventos a un subproceso en segundo plano para permitir que el trabajo continúe en todas las sub-HAL mientras espera 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/ . Aquí hay punteros a algunos recursos.

  • HalProxy.h : el objeto HalProxy es instanciado 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 las sub-HAL y el marco del sensor.
  • SubHal.h : la interfaz ISensorsSubHal define la interfaz que deben seguir las sub-HAL para ser compatibles con HalProxy . La sub-HAL implementa el método de inicialización para que el objeto HalProxyCallback se pueda usar para postEvents y createScopedWakelock .

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

  • hardware/interfaces/sensors/common/default/2.X/multihal/tests/ : estas pruebas unitarias verifican la implementación de 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 varias sub-HAL en un dispositivo.

Implementación

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

Implementando Sensores 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 SubHal.h sensorsHalGetSubHal_2_1
  3. Agregue un objetivo cc_library_shared para crear la sub-HAL recién implementada. Al agregar el destino:

    1. Asegúrese de que el objetivo se inserte en 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 de 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 de android.hardware.sensors del archivo manifest.xml , que contiene la lista de HAL admitidas 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 .

En el arranque, HalProxy inicia, busca el sub-HAL recién implementado y lo inicializa llamando a sensorsHalGetSubHal_2_1 .

Portabilidad 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 usa los tipos creados en la versión 2.1 de la ISensors.hal .
  • La función initialize() pasa una nueva IHalProxyCallback en lugar de la de la interfaz 2.0 SubHal
  • Las sub-HAL deben implementar getSensorsList_2_1 e injectSensorData_2_1 en lugar de getSensorsList e injectSensorData , ya que estos métodos usan los nuevos tipos agregados en la versión 2.1 de la especificación ISensors.hal .
  • Las sub-HAL deben exponer sensorsHalGetSubHal_2_1 en lugar de los sensorsHalGetSubHal para que las Multi-HAL las traten como sub-HAL de la versión 2.1.

Portar desde 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 la 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 sola devolución de llamada que debe usarse para publicar eventos de sensores, obtener bloqueos de activación y notificar sobre conexiones y desconexiones dinámicas de sensores.

Publicación de eventos de sensores en la implementación 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, el HAL puede gestionar el wake lock para su implementación. En Sensors Multi-HAL 2.0, las sub-HAL permiten que la implementación de Multi-HAL administre bloqueos de activación y puede solicitar la adquisición de un bloqueo de activación invocando createScopedWakelock . Se debe adquirir un bloqueo de activación con ámbito bloqueado y pasarlo a postEvents al publicar eventos de activación en la implementación de Multi-HAL.

Sensores dinámicos

Sensores Multi-HAL 2.0 requiere que onDynamicSensorsConnected y onDynamicSensorsDisconnected en IHalProxyCallback se llamen cada vez que cambien las conexiones de 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() .

Portar desde 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 la HAL

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

Exponer los sensores disponibles

En Sensors Multi-HAL 2.0, la función getSensorsList() debe devolver el mismo valor durante el arranque de un solo dispositivo, incluso entre reinicios 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 se reinicia.

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

En Sensors HAL 2.0, en lugar de esperar a que se llame a poll() , el sub-HAL debe escribir de manera proactiva eventos de sensor en IHalProxyCallback siempre que haya eventos de sensor disponibles.

Eventos WAKE_UP

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

Sensores dinámicos

En Sensors HAL 1.0, los sensores dinámicos se devuelven a través de la función poll() . Sensores Multi-HAL 2.0 requiere que onDynamicSensorsConnected y onDynamicSensorsDisconnected en IHalProxyCallback se llamen cada vez que cambien las conexiones de 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() .

Portar desde Sensores Multi-HAL 1.0

Para migrar 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 se encuentre 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. Puerto sub-HAL como se describe en Puerto desde Sensores Hal 1.0 .
  4. Establezca 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

Ejecutando VTS

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

Para ejecutar solo las pruebas VTS de 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

Ejecución de pruebas unitarias

Las pruebas unitarias en HalProxy_test.cpp prueban HalProxy usando sub-HAL falsas que se instancian en la prueba unitaria y no se cargan dinámicamente. Al crear una sub-HAL nueva, estas pruebas deben servir como guía sobre cómo agregar pruebas unitarias que verifiquen que la nueva 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

Pruebas con las sub-HAL falsas

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

Las sub-HAL falsas se pueden usar para probar cómo funciona el código Multi-HAL completo con otras sub-HAL cargadas en el sistema y para enfatizar varios aspectos del código Sensors Multi-HAL.

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

Para compilar y enviar las sub-HAL falsas a un dispositivo, realice los siguientes pasos:

  1. Ejecute los siguientes comandos para compilar y enviar las tres sub-HAL falsas 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 las sub-HAL falsas.

    /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 las nuevas sub-HAL enumeradas en la configuración.

    adb shell stop
    adb shell start
    

depuración

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

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

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 las sub-HAL falsas.

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 un número grande (1000 o más), esto indica que hay muchos eventos pendientes de escribir en el marco de sensores. Esto indica que el servicio del sensor está interbloqueado o se ha bloqueado y no está procesando los eventos del sensor, o que recientemente se publicó un gran lote de eventos del sensor desde una sub-HAL.

Si el recuento de referencias de bloqueo de activación es mayor que 0 , significa HalProxy ha adquirido un bloqueo de activación. Solo debe ser mayor que 0 si se retiene 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 .