La structure multiHAL des capteurs permet aux capteurs de fonctionner en même temps que d'autres HAL de capteurs. La multi-HAL des capteurs charge dynamiquement les sous-HAL de capteurs stockés en tant que bibliothèques dynamiques sur la partition du fournisseur et leur fournit un objet de rappel pouvant gérer la publication d'événements, ainsi que l'acquisition et la libération du wakelock. Une sous-HAL de capteurs est une HAL de capteurs intégrée dans un objet partagé sur la partition du fournisseur et utilisée par le framework multi-HAL. Ces sous-HAL ne dépendent pas les unes des autres ni du code multi-HAL contenant la fonction principale du processus.
La version 2.1 des capteurs Multi-HAL 2.1 est disponible sur les appareils équipés d'Android 11 ou version ultérieure. Elle est une itération de la technologie Multi-HAL 2.0 des capteurs. Elle accepte les sous-HAL de chargement pouvant exposer le type de capteur d'angle de charnière. Pour prendre en charge ce type de capteur, les sous-HAL doivent utiliser les API sous-HAL définies dans l'en-tête SubHal 2.1.
Pour les appareils équipés d'Android 13 ou version ultérieure qui utilisent le HAL Sensors AIDL, vous pouvez utiliser la couche de shim multi-HAL pour autoriser la fonctionnalité multiHAL. Pour en savoir plus sur l'implémentation, consultez la page Utiliser le multi-HAL des capteurs avec le HAL des capteurs AIDL.
Différence entre les capteurs Multi-HAL 2 et HAL 2
Les capteurs Multi-HAL 2, disponibles sur les appareils équipés d'Android 10 ou version ultérieure, introduit plusieurs abstractions sur le capteurs HAL 2 pour faciliter l'interaction avec les API HAL. La multi-HAL 2 de capteurs introduit la classe HalProxy pour gérer l'implémentation de l'interface HAL 2 des capteurs et de l'interface V2_1/SubHal
(ou V2_0/SubHal
) pour permettre à HalProxy
d'interagir avec les sous-HAL.
L'interface ISensorsSubHal
diffère de l'interface 2.1/ISensors.hal
(ou 2.0/ISensors.hal
) sur les points suivants:
- La méthode d'initialisation transmet une classe
IHalProxyCallback
au lieu de deux FMQ et deISensorsCallback
. - Les sous-HAL doivent implémenter une fonction de débogage pour fournir des informations de débogage dans les rapports de bug.
- Les sous-HAL doivent implémenter une fonction de nom afin que la sous-HAL chargée se distingue des autres sous-HAL.
La principale différence entre les capteurs Multi-HAL 2 et Sensors HAL 2 réside dans les fonctions d'initialisation. Au lieu de fournir des FMQ, l'interface IHalProxyCallback
propose deux méthodes : une méthode pour publier les événements de capteurs dans le framework de capteurs et une méthode pour créer des wakelocks. En arrière-plan, le multi-HAL des capteurs gère toutes les interactions avec les FMQ afin de garantir la diffusion opportune des événements de capteurs pour tous les sous-HAL. Il est vivement recommandé aux sous-HAL d'utiliser la méthode createScopedWakelock
pour déléguer la charge du délai d'expiration des wakelocks au multi-HAL des capteurs et pour centraliser l'utilisation des wakelocks sur un wakelock commun pour l'ensemble de la multi-HAL des capteurs, ce qui minimise le verrouillage et le déverrouillage des appels.
Les capteurs Multi-HAL 2 intègrent également des fonctionnalités de sécurité. Il gère les cas où le FMQ du capteur est saturé ou où le framework du capteur Android redémarre et que l'état du capteur doit être réinitialisé. De plus, lorsque des événements sont publiés dans la classe HalProxy
, mais que le framework de capteurs ne peut pas les accepter immédiatement, le multi-HAL des capteurs peut les déplacer vers un thread d'arrière-plan pour permettre la poursuite des tâches sur toutes les sous-HAL en attendant la publication des événements.
Code source et implémentation de référence
Le code multi-HAL de tous les capteurs est disponible dans hardware/interfaces/sensors/common/default/2.X/multihal/
.
Voici des liens vers quelques ressources utiles.
HalProxy.h
: l'objetHalProxy
est instancié par la multi-HAL des capteurs et gère la transmission des données des sous-HAL au framework de capteur.HalProxy.cpp
: l'implémentation deHalProxy
contient toute la logique nécessaire à la communication multiplex entre les sous-HAL et le framework de capteur.SubHal.h
: l'interfaceISensorsSubHal
définit l'interface que les sous-HAL doivent suivre pour être compatibles avecHalProxy
. Le sous-HAL implémente la méthode d'initialisation afin que l'objetHalProxyCallback
puisse être utilisé pourpostEvents
etcreateScopedWakelock
.Pour les implémentations multi-HAL 2.0, utilisez la version 2.0 de
SubHal.h
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/
: ces tests unitaires vérifient l'implémentation deHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: cet exemple d'implémentation de sous-HAL utilise de faux capteurs pour générer de fausses données. Utile pour tester la manière dont plusieurs sous-HAL interagissent sur un appareil.
Implémentation
Cette section explique comment implémenter la fonctionnalité Multi-HAL de capteurs dans les situations suivantes:
- Utiliser le système Sensors Multi-HAL avec le HAL des capteurs AIDL
- Implémenter des capteurs Multi-HAL 2.1
- Transfert depuis Sensors Multi-HAL 2.0 vers Multi-HAL 2.1
- Transfert depuis Sensors HAL 2.0
- Transfert depuis Sensors HAL 1.0
- Transfert depuis Sensors Multi-HAL 1.0
Utiliser le système Sensors Multi-HAL avec le HAL des capteurs AIDL
Pour permettre la capacité multi-HAL avec le HAL des capteurs AIDL, importez le module de couche de shim multi-HAL AIDL, disponible dans hardware/interfaces/sensors/aidl/default/multihal/. Le module gère la conversion entre les types de définition HAL des capteurs AIDL et HIDL, et définit un wrapper pour l'interface multi-HAL décrite dans la section Implémenter Sensors Multi-HAL 2.1. La couche de shim multi-HAL AIDL est compatible avec les appareils qui implémentent les capteurs Multi-HAL 2.1.
La couche de shim multi-HAL AIDL vous permet d'exposer le head tracker et les types de capteurs IMU à axe limité dans le HAL des capteurs AIDL. Pour utiliser ces types de capteurs définis par l'interface HAL AIDL, définissez le champ type
dans la structure SensorInfo
dans l'implémentation de getSensorsList_2_1()
. Cette approche est sûre, car les champs de type de capteur AIDL et HIDL HAL des capteurs AIDL et HIDL ne se chevauchent pas.
Implémenter des capteurs Multi-HAL 2.1
Pour implémenter Sensors Multi-HAL 2.1 sur un nouvel appareil, procédez comme suit:
- Implémentez l'interface
ISensorsSubHal
comme décrit dansSubHal.h
. - Implémentez la méthode
sensorsHalGetSubHal_2_1
dansSubHal.h
. Ajoutez une cible
cc_library_shared
pour créer le sous-HAL que vous venez d'implémenter. Lorsque vous ajoutez la cible:- Assurez-vous que la cible est déplacée vers un endroit de la partition du fournisseur de l'appareil.
- Dans le fichier de configuration situé dans
/vendor/etc/sensors/hals.conf
, ajoutez le chemin d'accès à la bibliothèque sur une nouvelle ligne. Si nécessaire, créez le fichierhals.conf
.
Pour obtenir un exemple d'entrée
Android.bp
pour la création d'une bibliothèque secondaire, consultezhardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp
.Supprimez toutes les entrées
android.hardware.sensors
du fichiermanifest.xml
, qui contient la liste des HAL compatibles sur l'appareil.Supprimez tous les fichiers du service
android.hardware.sensors
etservice.rc
du fichierdevice.mk
, puis ajoutezandroid.hardware.sensors@2.1-service.multihal
etandroid.hardware.sensors@2.1-service.multihal.rc
àPRODUCT_PACKAGES
.
Au démarrage, HalProxy
démarre, recherche le sous-HAL récemment implémenté et l'initialise en appelant sensorsHalGetSubHal_2_1
.
Port des capteurs Multi-HAL 2.0 vers Multi-HAL 2.1
Pour effectuer le portage de Multi-HAL 2.0 vers Multi-HAL 2.1, implémentez l'interface SubHal
et recompilez votre sous-HAL.
Voici les différences entre les interfaces SubHal
2.0 et 2.1:
IHalProxyCallback
utilise les types créés dans la version 2.1 de la spécificationISensors.hal
.- La fonction
initialize()
transmet un nouveauIHalProxyCallback
au lieu de celui de l'interfaceSubHal
2.0. - Les sous-HAL doivent implémenter
getSensorsList_2_1
etinjectSensorData_2_1
au lieu degetSensorsList
etinjectSensorData
, car ces méthodes utilisent les nouveaux types ajoutés dans la version 2.1 de la spécificationISensors.hal
. - Les sous-HAL doivent exposer
sensorsHalGetSubHal_2_1
plutôt quesensorsHalGetSubHal
pour que le système multi-HAL les traite comme des sous-HAL de la version 2.1.
Port des capteurs HAL 2.0
Lorsque vous passez de Sensors HAL 2.0 à la version 2.0 de Sensors Multi-HAL, assurez-vous que l'implémentation de la HAL répond aux exigences suivantes.
Initialiser l'HAL
Les capteurs HAL 2.0 disposent d'une fonction d'initialisation qui permet au service des capteurs de transmettre les FMQ et un rappel dynamique du capteur. Dans Sensors Multi-HAL 2.0, la fonction initialize()
transmet un seul rappel qui doit être utilisé pour publier des événements de capteurs, obtenir des wakelocks et être averti des connexions et déconnexions dynamiques des capteurs.
Publier des événements de capteurs dans l'implémentation multi-HAL
Au lieu de publier les événements de capteurs via FMQ, le sous-HAL doit écrire les événements de capteurs dans IHalProxyCallback
lorsque les événements de capteurs sont disponibles.
Événements WAKE_UP
Dans la version 2.0 des capteurs HAL, le HAL peut gérer le wakelock pour son implémentation. Dans Sensors Multi-HAL 2.0, les sous-HAL permettent à l'implémentation Multi-HAL de gérer les wakelocks et peuvent demander l'acquisition d'un wakelock en appelant createScopedWakelock
.
Un wakelock de portée verrouillée doit être acquis et transmis à postEvents
lors de la publication d'événements de wakeups dans l'implémentation multi-HAL.
Capteurs dynamiques
Les capteurs Multi-HAL 2.0 nécessitent que onDynamicSensorsConnected
et onDynamicSensorsDisconnected
dans IHalProxyCallback
soient appelés chaque fois que les connexions dynamiques des capteurs changent. Ces rappels sont disponibles dans le pointeur IHalProxyCallback
fourni via la fonction initialize()
.
Port des capteurs HAL 1.0
Lorsque vous passez de Sensors HAL 1.0 à la version 2.0 de Sensors Multi-HAL, assurez-vous que l'implémentation de la HAL répond aux exigences suivantes.
Initialiser l'HAL
La fonction initialize()
doit être compatible pour établir le rappel entre la sous-HAL et l'implémentation multi-HAL.
Exposer les capteurs disponibles
Dans Sensors Multi-HAL 2.0, la fonction getSensorsList()
doit renvoyer la même valeur lors du démarrage d'un seul appareil, même entre les redémarrages du HAL des capteurs. Cela permet au framework de tenter de rétablir les connexions des capteurs si le serveur système redémarre. La valeur renvoyée par getSensorsList()
peut changer après un redémarrage de l'appareil.
Publier des événements de capteurs dans l'implémentation multi-HAL
Dans Sensors HAL 2.0, au lieu d'attendre que poll()
soit appelé, le sous-HAL doit écrire de manière proactive les événements de capteurs dans IHalProxyCallback
chaque fois qu'ils sont disponibles.
Événements WAKE_UP
Dans la version 1.0 des capteurs HAL, le HAL peut gérer le wakelock pour son implémentation. Dans Sensors Multi-HAL 2.0, les sous-HAL permettent à l'implémentation Multi-HAL de gérer les wakelocks et peuvent demander l'acquisition d'un wakelock en appelant createScopedWakelock
.
Un wakelock de portée verrouillée doit être acquis et transmis à postEvents
lors de la publication d'événements de wakeups dans l'implémentation multi-HAL.
Capteurs dynamiques
Dans la version HAL 1.0 des capteurs, les capteurs dynamiques sont renvoyés via la fonction poll()
.
Les capteurs Multi-HAL 2.0 nécessitent que onDynamicSensorsConnected
et onDynamicSensorsDisconnected
dans IHalProxyCallback
soient appelés chaque fois que les connexions dynamiques des capteurs changent. Ces rappels sont disponibles dans le pointeur IHalProxyCallback
fourni via la fonction initialize()
.
Port des capteurs Multi-HAL 1.0
Pour transférer une implémentation existante à partir de Sensors Multi-HAL 1.0, procédez comme suit.
- Assurez-vous que la configuration HAL des capteurs se trouve dans
/vendor/etc/sensors/hals.conf
. Cela peut impliquer de déplacer le fichier situé dans/system/etc/sensors/hals.conf
. - Supprimez toutes les références à
hardware/hardware.h
ethardware/sensors.h
, car elles ne sont pas compatibles avec HAL 2.0. - Sous-HAL de port, comme décrit dans la section Portage depuis Sensors Hal 1.0.
- Définissez Sensors Multi-HAL 2.0 comme HAL désigné en suivant les étapes 3 et 4 de la section Implementing Sensors Mutli-HAL 2.0.
Validation
Lancer un VTS
Une fois que vous avez intégré une ou plusieurs sous-HAL avec la version 2.1 des capteurs multi-Hal, utilisez la suite de test fournisseur (VTS) pour vous assurer que vos implémentations de sous-HAL répondent à toutes les exigences définies par l'interface HAL des capteurs.
Pour n'exécuter que les tests VTS des capteurs lorsque VTS est configuré sur une machine hôte, exécutez les commandes suivantes:
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 vous exécutez la couche de shim multi-HAL AIDL, exécutez VtsAidlHalSensorsTargetTest
.
vts-tradefed run commandAndExit vts \
--skip-all-system-status-check \
--primary-abi-only \
--skip-preconditions \
--module VtsAidlHalSensorsTargetTest
Exécuter des tests unitaires
Les tests unitaires dans HalProxy_test.cpp
testent HalProxy
à l'aide de faux sous-HAL instanciés dans le test unitaire et qui ne sont pas chargés dynamiquement. Lors de la création d'une sous-HAL, ces tests doivent vous servir de guide pour ajouter des tests unitaires qui vérifient que la nouvelle sous-HAL est correctement implémentée.
Pour exécuter les tests, exécutez les commandes suivantes:
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Effectuer des tests avec de faux sous-HAL
Les faux sous-HAL sont des implémentations factices de l'interface ISensorsSubHal
.
Les sous-HAL exposent différentes listes de capteurs. Lorsque les capteurs sont activés, ils publient régulièrement des événements de capteurs générés automatiquement dans HalProxy
en fonction des intervalles spécifiés dans une requête de capteur donnée.
Les fausses sous-HAL peuvent être utilisées pour tester le fonctionnement du code multi-HAL complet avec d'autres sous-HAL chargées dans le système, et pour souligner différents aspects du code multi-HAL des capteurs.
Deux faux sous-HAL sont disponibles sur hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
.
Pour créer les faux sub-HAL et les transférer vers un appareil, procédez comme suit:
Exécutez les commandes suivantes pour créer et transférer les trois faux sous-HAL différents sur l'appareil:
$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
Mettez à jour la configuration HAL des capteurs à l'emplacement
/vendor/etc/sensors/hals.conf
avec les chemins des faux sous-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
Redémarrez
HalProxy
et chargez les nouveaux sous-HAL répertoriés dans la configuration.adb shell stop
adb shell start
Débogage
Les développeurs peuvent déboguer le framework à l'aide de la commande lshal
. Pour demander la sortie de débogage du HAL des capteurs, exécutez la commande suivante:
adb root
adb shell lshal debug android.hardware.sensors@2.1::ISensors/default
Les informations sur l'état actuel de HalProxy
et de ses sous-HAL sont ensuite transmises au terminal. Vous trouverez ci-dessous un exemple de résultat de la commande pour l'objet HalProxy
et les faux sous-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
Si le nombre spécifié pour # of events on pending write queue
est un nombre élevé (1 000 ou plus), cela signifie que de nombreux événements sont en attente d'écriture dans le framework de capteurs. Cela indique que le service des capteurs est bloqué, a planté et ne traite pas les événements des capteurs, ou qu'un grand nombre d'événements de capteurs ont été récemment publiés à partir d'une sous-HAL.
Si le nombre de références du wakelock est supérieur à 0
, cela signifie que HalProxy
a acquis un wakelock. Cette valeur ne doit être supérieure à 0
que si une ScopedWakelock
est intentionnellement maintenue ou si des événements de wakeup ont été envoyés à HalProxy
et n'ont pas été traités par le framework de capteur.
Le descripteur de fichier transmis à la méthode de débogage de HalProxy
est transmis à chaque sous-HAL. Les développeurs doivent donc implémenter la méthode de débogage dans l'interface ISensorsSubHal
.