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 eISensorsCallback
. - 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 objetoHalProxy
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 deHalProxy
contiene toda la lógica necesaria para multiplexar la comunicación entre las sub-HAL y el marco del sensor. SubHal.h
: la interfazISensorsSubHal
define la interfaz que deben seguir las sub-HAL para ser compatibles conHalProxy
. La sub-HAL implementa el método de inicialización para que el objetoHalProxyCallback
se pueda usar parapostEvents
ycreateScopedWakelock
.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 deHalProxy
.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
- Portabilidad de sensores Multi-HAL 2.0 a Multi-HAL 2.1
- Portar desde Sensores HAL 2.0
- Portar desde Sensores HAL 1.0
- Portar desde Sensores Multi-HAL 1.0
Implementando Sensores Multi-HAL 2.1
Para implementar Sensors Multi-HAL 2.1 en un nuevo dispositivo, siga estos pasos:
- Implemente la interfaz
ISensorsSubHal
como se describe enSubHal.h
. - Implemente el método
SubHal.h
sensorsHalGetSubHal_2_1
Agregue un objetivo
cc_library_shared
para crear la sub-HAL recién implementada. Al agregar el destino:- Asegúrese de que el objetivo se inserte en algún lugar de la partición del proveedor del dispositivo.
- 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 archivohals.conf
.
Para ver un ejemplo de entrada de
Android.bp
para crear una biblioteca sub-HAL, consultehardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Elimine todas las entradas de
android.hardware.sensors
del archivomanifest.xml
, que contiene la lista de HAL admitidas en el dispositivo.Elimine todos los archivos
android.hardware.sensors
service yservice.rc
del archivodevice.mk
y agregueandroid.hardware.sensors@2.1-service.multihal
yandroid.hardware.sensors@2.1-service.multihal.rc
aPRODUCT_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 laISensors.hal
. - La función
initialize()
pasa una nuevaIHalProxyCallback
en lugar de la de la interfaz 2.0SubHal
- Las sub-HAL deben implementar
getSensorsList_2_1
einjectSensorData_2_1
en lugar degetSensorsList
einjectSensorData
, ya que estos métodos usan los nuevos tipos agregados en la versión 2.1 de la especificaciónISensors.hal
. - Las sub-HAL deben exponer
sensorsHalGetSubHal_2_1
en lugar de lossensorsHalGetSubHal
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.
- 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
. - Elimine cualquier referencia a
hardware/hardware.h
yhardware/sensors.h
, ya que no son compatibles con HAL 2.0. - Puerto sub-HAL como se describe en Puerto desde Sensores Hal 1.0 .
- 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:
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
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
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
.