El Multi-HAL de sensores es un framework que permite que las HAL de sensores se ejecuten junto con otras HAL de sensores. El Multi-HAL de sensores carga de forma dinámica las sub-HAL de sensores almacenadas como bibliotecas dinámicas en la partición del proveedor y les proporciona un objeto de devolución de llamada que puede controlar la publicación de eventos, la adquisición y la 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 que usa el framework de Multi-HAL. Estas sub-HAL no dependen entre sí ni del código de Multi-HAL que contiene la función principal del proceso.
Los sensores Multi-HAL 2.1, disponibles en dispositivos con Android 11 o versiones posteriores, son una iteración de los sensores 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 subHAL deben usar las APIs de subHAL definidas en el encabezado SubHal 2.1.
En dispositivos con Android 13 o versiones posteriores que usan la HAL de sensores AIDL, puedes usar la capa de shim de Multi-HAL para permitir la capacidad de Multi-HAL. Para obtener detalles de la implementación, consulta Cómo usar el Multi-HAL de sensores con la HAL de sensores AIDL.
Diferencia entre el Multi-HAL de sensores 2 y la HAL de sensores 2
El Multi-HAL de sensores 2, disponible en dispositivos con Android
10 o versiones posteriores,
presenta varias abstracciones sobre la HAL de sensores
2 para facilitar
la interacción con las APIs de HAL. El Multi-HAL de sensores 2 presenta la
clase HalProxy
para controlar la implementación de la interfaz de la HAL de sensores 2 y la
V2_1/SubHal
(o
V2_0/SubHal)
interfaz para permitir que HalProxy interactúe con las sub-HAL.
La interfaz ISensorsSubHal difiere de la interfaz
2.1/ISensors.hal
(o
2.0/ISensors.hal)
de las siguientes maneras:
- El método initialize pasa una clase
IHalProxyCallbacken lugar de dos FMQ yISensorsCallback. - 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 se pueda distinguir de otras sub-HAL.
La principal diferencia entre el Multi-HAL de sensores 2 y la HAL de sensores 2 está en las funciones de inicialización. En lugar de proporcionar FMQ, la interfaz IHalProxyCallback proporciona dos métodos: uno para publicar eventos de sensores en el framework de sensores y otro para crear bloqueos de activación. En segundo plano, el Multi-HAL de sensores administra todas las interacciones con las FMQ para garantizar la entrega oportuna de eventos de sensores para todas las sub-HAL. Se recomienda que las sub-HAL usen el método createScopedWakelock para delegar la carga de los bloqueos de activación de tiempo de espera al Multi-HAL de sensores y centralizar el uso del bloqueo de activación en un bloqueo de activación común para todo el Multi-HAL de sensores, lo que minimiza las llamadas de bloqueo y desbloqueo.
El Multi-HAL de sensores 2 también tiene algunas funciones de seguridad integradas. Controla situaciones en las que la FMQ del sensor está llena o cuando se reinicia el framework de sensores de Android y se debe restablecer el estado del sensor. Además, cuando los eventos se publican en la clase HalProxy, pero el framework de sensores no puede aceptarlos de inmediato, el Multi-HAL de sensores puede mover los eventos a un subproceso en segundo plano para permitir que el trabajo continúe en todas las sub-HAL mientras se espera que se publiquen los eventos.
Código fuente y referencia de implementación
Todo el código del Multi-HAL de sensores está disponible en
hardware/interfaces/sensors/common/default/2.X/multihal/.
Aquí encontrarás punteros a algunos recursos.
HalProxy.h: El objetoHalProxyse instancia con el Multi-HAL de sensores y controla el paso de datos de las sub-HAL al framework de sensores.HalProxy.cpp: La implementación deHalProxycontiene toda la lógica necesaria para multiplexar la comunicación entre las sub-HAL y el framework de sensores.SubHal.h: La interfazISensorsSubHaldefine la interfaz que deben seguir las sub-HAL para ser compatibles conHalProxy. La sub-HAL implementa el método initialize para que el objetoHalProxyCallbackse pueda usar parapostEventsycreateScopedWakelock.Para las implementaciones de Multi-HAL 2.0, usa la versión 2.0 de
SubHal.h.hardware/interfaces/sensors/common/default/2.X/multihal/tests/: Estas pruebas de unidades verifican la implementación deHalProxy.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/: Esta implementación de sub-HAL de ejemplo usa sensores falsos para generar datos falsos. Es útil para probar cómo interactúan varias sub-HAL en un dispositivo.
Implementación
En esta sección, se describe cómo implementar el Multi-HAL de sensores en las siguientes situaciones:
- Cómo usar el Multi-HAL de sensores con la HAL de sensores AIDL
- Cómo implementar el Multi-HAL de sensores 2.1
- Cómo migrar del Multi-HAL de sensores 2.0 al Multi-HAL 2.1
- Cómo migrar desde la HAL de sensores 2.0
- Cómo migrar desde la HAL de sensores 1.0
- Cómo migrar desde el Multi-HAL de sensores 1.0
Usa el Multi-HAL de sensores con la HAL de sensores AIDL
Para permitir la capacidad de Multi-HAL con la HAL de sensores AIDL, importa el módulo de capa de shim de Multi-HAL AIDL, que se encuentra en hardware/interfaces/sensors/aidl/default/multihal/. El módulo controla la conversión entre los tipos de definición de HAL de sensores AIDL y HIDL y define un wrapper alrededor de la interfaz de Multi-HAL que se describe en Cómo implementar el Multi-HAL de sensores 2.1. La capa de shim de Multi-HAL AIDL es compatible con dispositivos que implementan el Multi-HAL de sensores 2.1.
La capa de shim de Multi-HAL AIDL te permite exponer el seguimiento de cabeza y los tipos de sensores de IMU de eje limitado en la HAL de sensores AIDL. Para usar estos tipos de sensores definidos por la interfaz de la HAL de AIDL, establece el campo type en el struct SensorInfo en la implementación getSensorsList_2_1(). Esto es seguro porque los campos de tipo de sensor respaldados por números enteros de la HAL de sensores AIDL y HIDL no se superponen.
Implementa el Multi-HAL de sensores 2.1
Para implementar el Multi-HAL de sensores 2.1 en un dispositivo nuevo, sigue estos pasos:
- Implementa la interfaz
ISensorsSubHalcomo se describe enSubHal.h. - Implementa el
sensorsHalGetSubHal_2_1método enSubHal.h. Agrega un destino
cc_library_sharedpara compilar la sub-HAL recién implementada. Cuando agregues el destino, haz lo siguiente:- Asegúrate de que el destino se envíe a algún lugar de la partición del proveedor del dispositivo.
- En el archivo de configuración ubicado en
/vendor/etc/sensors/hals.conf, agrega la ruta de acceso a la biblioteca en una línea nueva. Si es necesario, crea el archivohals.conf.
Para obtener un ejemplo de entrada
Android.bppara compilar una biblioteca de sub-HAL, consultahardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp.Quita todas las entradas
android.hardware.sensorsdelmanifest.xmlarchivo, que contiene la lista de HAL compatibles en el dispositivo.Quita todos los archivos de servicio
android.hardware.sensorsyservice.rcde el archivodevice.mky agregaandroid.hardware.sensors@2.1-service.multihalyandroid.hardware.sensors@2.1-service.multihal.rcaPRODUCT_PACKAGES.
Durante el arranque, HalProxy se inicia, busca la sub-HAL recién implementada y
la inicializa llamando a
sensorsHalGetSubHal_2_1.
Migra del Multi-HAL de sensores 2.0 al Multi-HAL 2.1
Para migrar del Multi-HAL 2.0 al Multi-HAL 2.1, implementa la
SubHal
interfaz y vuelve a compilar tu sub-HAL.
Estas son las diferencias entre las interfaces SubHal 2.0 y 2.1:
IHalProxyCallbackusa los tipos creados en la versión 2.1 de la especificaciónISensors.hal.- La función
initialize()pasa un nuevoIHalProxyCallbacken lugar del de la interfazSubHal2.0. - Las sub-HAL deben implementar
getSensorsList_2_1yinjectSensorData_2_1en lugar degetSensorsListyinjectSensorData, 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_1en lugar desensorsHalGetSubHalpara que el Multi-HAL las trate como sub-HAL de la versión 2.1.
Migra desde la HAL de sensores 2.0
Cuando actualices al Multi-HAL de sensores 2.0 desde la HAL de sensores 2.0, asegúrate de que la implementación de HAL cumpla con los siguientes requisitos.
Inicializa la HAL
La HAL de sensores 2.0 tiene una función de inicialización que permite que el servicio de sensores pase FMQ y una devolución de llamada de sensor dinámico. En el Multi-HAL de sensores 2.0, la función initialize() pasa una sola devolución de llamada que se debe usar para publicar eventos de sensores, obtener bloqueos de activación y notificar la conexión y desconexión de sensores dinámicos.
Publica eventos de sensores en la implementación de Multi-HAL
En lugar de publicar eventos de sensores a través de la FMQ, la sub-HAL debe escribir eventos de sensores
en el
IHalProxyCallback
cuando estén disponibles.
Eventos WAKE_UP
En la HAL de sensores 2.0, la HAL puede administrar el bloqueo de activación para su implementación. En
el Multi-HAL de sensores 2.0, las sub-HAL permiten que la implementación de Multi-HAL
administre los 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 de alcance bloqueado y pasarlo a postEvents cuando se publiquen eventos de activación en la implementación de Multi-HAL.
Sensores dinámicos
El Multi-HAL de sensores 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().
Migra desde la HAL de sensores 1.0
Cuando actualices al Multi-HAL de sensores 2.0 desde la HAL de sensores 1.0, asegúrate de que la implementación de HAL cumpla con los siguientes requisitos.
Inicializa la HAL
Se debe admitir la función initialize() para establecer la devolución de llamada entre la sub-HAL y la implementación de Multi-HAL.
Expón los sensores disponibles
En el Multi-HAL de sensores 2.0, la función getSensorsList() debe mostrar el mismo valor durante un solo arranque del dispositivo, incluso en los reinicios de la HAL de sensores. Esto permite que el framework intente restablecer las conexiones de sensores si se reinicia el servidor del sistema. El valor que muestra getSensorsList() puede cambiar después de que el dispositivo realice un reinicio.
Publica eventos de sensores en la implementación de Multi-HAL
En la HAL de sensores 2.0, en lugar de esperar a que se llame a poll(), la sub-HAL
debe escribir de forma proactiva eventos de sensores en
IHalProxyCallback
cada vez que estén disponibles.
Eventos WAKE_UP
En la HAL de sensores 1.0, la HAL puede administrar el bloqueo de activación para su implementación. En
el Multi-HAL de sensores 2.0, las sub-HAL permiten que la implementación de Multi-HAL
administre los 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 de alcance bloqueado y pasarlo a postEvents cuando se publiquen eventos de activación en la implementación de Multi-HAL.
Sensores dinámicos
En la HAL de sensores 1.0, los sensores dinámicos se muestran a través de la función poll().
El Multi-HAL de sensores 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().
Migra desde el Multi-HAL de sensores 1.0
Para migrar una implementación existente desde el Multi-HAL de sensores 1.0, sigue estos pasos.
- Asegúrate de que la configuración de la HAL de sensores se encuentre en
/vendor/etc/sensors/hals.conf. Esto podría implicar mover el archivo ubicado en/system/etc/sensors/hals.conf. - Quita todas las referencias a
hardware/hardware.hyhardware/sensors.h, ya que no son compatibles con la HAL 2.0. - Migra las sub-HAL como se describe en Cómo migrar desde la HAL de sensores 1.0.
- Establece el Multi-HAL de sensores 2.0 como la HAL designada siguiendo los pasos 3 y 4 de la sección Cómo implementar el Multi-HAL de sensores 2.0.
Validación
Ejecuta VTS
Cuando hayas integrado una o más sub-HAL con el Multi-HAL de sensores 2.1, usa el Paquete de pruebas del proveedor (VTS) para asegurarte de que las implementaciones de sub-HAL cumplan con todos los requisitos establecidos por la interfaz de la HAL de sensores.
Para ejecutar solo las pruebas de VTS de sensores cuando VTS está configurado en una máquina anfitrión, ejecuta 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 ejecutas la capa de shim de Multi-HAL AIDL, ejecuta VtsAidlHalSensorsTargetTest.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Ejecutar pruebas de unidades
Las pruebas de unidades en HalProxy_test.cpp prueban HalProxy con sub-HAL falsas que
se instancian en la prueba de unidades y no se cargan de forma dinámica. Cuando crees una sub-HAL nueva, estas pruebas deben servir como guía para agregar pruebas de unidades que verifiquen que la nueva sub-HAL se implemente correctamente.
Para ejecutar las pruebas, ejecuta los siguientes comandos:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/testsatest
Prueba con las sub-HAL falsas
Las sub-HAL falsas son implementaciones ficticias de la interfaz ISensorsSubHal.
Las sub-HAL exponen diferentes listas de sensores. Cuando se activan los sensores, publican periódicamente eventos de sensores generados automáticamente en HalProxy según los intervalos especificados en una solicitud de sensor determinada.
Las sub-HAL falsas se pueden usar para probar cómo funciona el código completo de Multi-HAL con otras sub-HAL cargadas en el sistema y para destacar varios aspectos del código de Multi-HAL de sensores.
Hay dos sub-HAL falsas disponibles en
hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/.
Para compilar y enviar las sub-HAL falsas a un dispositivo, sigue estos pasos:
Ejecuta 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/mmaadb 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.soadb 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.soadb 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.soActualiza la configuración de la HAL de sensores en
/vendor/etc/sensors/hals.confcon las rutas de acceso de 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.soReinicia
HalProxyy carga las nuevas sub-HAL que aparecen en la configuración.adb shell stopadb shell start
Depuración
Los desarrolladores pueden depurar el framework con el comando lshal. Para solicitar el resultado de depuración de la HAL de sensores, ejecuta el siguiente comando:
adb rootadb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Luego, se muestra información sobre el estado actual de HalProxy y sus sub-HAL en la terminal. A continuación, se muestra un ejemplo del resultado 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 grande (1,000 o más), indica que hay muchos eventos pendientes para escribir en el framework de sensores. Esto indica que el servicio de sensores está bloqueado o falló y no procesa eventos de sensores, o que se publicó recientemente un lote grande de eventos de sensores desde una sub-HAL.
Si el recuento de referencias del bloqueo de activación es mayor que 0, significa que HalProxy adquirió un bloqueo de activación. Esto solo debe ser mayor que 0 si se mantiene un ScopedWakelock de forma intencional o si se enviaron eventos de activación a HalProxy y el framework de sensores no los procesó.
El descriptor de archivo que se pasa 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.