Le Multi-HAL des capteurs est un framework qui permet aux HAL des capteurs de s'exécuter en parallèle d'autres HAL des capteurs. Le Multi-HAL des capteurs charge dynamiquement les sous-HAL des capteurs stockés sous forme de bibliothèques dynamiques sur la partition du fournisseur et leur fournit un objet de rappel qui peut gérer la publication d'événements, ainsi que l'acquisition et la libération du verrouillage de réveil. Un sous-HAL de capteurs est un HAL de capteurs intégré à un objet partagé sur la partition du fournisseur et utilisé par le framework multi-HAL. Ces sous-HAL ne dépendent pas les uns des autres ni du code multi-HAL qui contient la fonction principale du processus.
Sensors Multi-HAL 2.1, disponible sur les appareils équipés d'Android 11 ou version ultérieure, est une itération de Sensors Multi-HAL 2.0 qui permet de charger des sous-HAL pouvant exposer le type de capteur angle de la charnière. Pour prendre en charge ce type de capteur, les sous-HAL doivent utiliser les API de 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 la couche d'abstraction matérielle AIDL des capteurs, vous pouvez utiliser la couche shim multi-HAL pour activer la fonctionnalité multi-HAL. Pour en savoir plus sur l'implémentation, consultez Utiliser le Multi-HAL des capteurs avec le HAL AIDL des capteurs.
Différence entre Sensors Multi-HAL 2 et Sensors HAL 2
Le Multi-HAL 2 des capteurs, disponible sur les appareils équipés d'Android 10 ou version ultérieure, introduit plusieurs abstractions en plus du HAL 2 des capteurs pour faciliter l'interaction avec les API HAL. Sensors Multi-HAL 2 introduit la classe HalProxy pour gérer l'implémentation de l'interface Sensors HAL 2 et 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
) de plusieurs façons :
- La méthode d'initialisation transmet une classe
IHalProxyCallback
au lieu de deux FMQ etISensorsCallback
. - 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 nommage afin que le sous-HAL chargé puisse être distingué des autres sous-HAL.
La principale différence entre Sensors Multi-HAL 2 et Sensors HAL 2 réside dans les fonctions d'initialisation. Au lieu de fournir des FMQ, l'interface IHalProxyCallback
fournit deux méthodes : une pour publier des événements de capteur dans le framework de capteurs et une pour créer des wake locks. En interne, le Sensors Multi-HAL gère toutes les interactions avec les FMQ pour assurer la diffusion rapide des événements de capteur pour tous les sous-HAL. Il est fortement recommandé que les sous-HAL utilisent la méthode createScopedWakelock
pour déléguer la charge du délai d'expiration des wake locks au Sensors Multi-HAL et pour centraliser l'utilisation des wake locks sur un wake lock commun pour l'ensemble du Sensors Multi-HAL, ce qui minimise les appels de verrouillage et de déverrouillage.
Multi-HAL 2 pour les capteurs dispose également de fonctionnalités de sécurité intégrées. Il gère les situations où la FMQ du capteur est pleine ou lorsque le framework de 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 déplacer les événements vers un thread en arrière-plan pour permettre au travail de se poursuivre dans tous les sous-HAL en attendant que les événements soient publiés.
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 quelques ressources utiles.
HalProxy.h
: L'objetHalProxy
est instancié par Sensors multi-HAL et gère le transfert de données des sous-HAL au framework de capteurs.HalProxy.cpp
: L'implémentation deHalProxy
contient toute la logique nécessaire pour multiplexer la communication entre les sous-HAL et le framework de capteurs.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 initialize 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/
: Cette implémentation de sous-HAL d'exemple utilise de faux capteurs pour générer de fausses données. Utile pour tester l'interaction de plusieurs sous-HAL sur un appareil.
Implémentation
Cette section décrit comment implémenter Sensors Multi-HAL dans les situations suivantes :
- Utiliser le Multi-HAL des capteurs avec le HAL AIDL des capteurs
- Implémenter Sensors Multi-HAL 2.1
- Migrer de Sensors Multi-HAL 2.0 vers Multi-HAL 2.1
- Migration depuis Sensors HAL 2.0
- Portage depuis Sensors HAL 1.0
- Portage depuis Sensors Multi-HAL 1.0
Utiliser le Sensors Multi-HAL avec le Sensors AIDL HAL
Pour autoriser la fonctionnalité multi-HAL avec le HAL AIDL Sensors, importez le module de couche shim AIDL, qui se trouve dans hardware/interfaces/sensors/aidl/default/multihal/. Le module gère la conversion entre les types de définition AIDL et HIDL des HAL de capteurs, et définit un wrapper autour de l'interface multi-HAL décrite dans Implémenter Sensors Multi-HAL 2.1. La couche shim multi-HAL AIDL est compatible avec les appareils qui implémentent Sensors Multi-HAL 2.1.
La couche shim multi-HAL AIDL vous permet d'exposer les types de capteurs de suivi de la tête et d'IMU à axe limité dans le HAL AIDL des capteurs. Pour utiliser ces types de capteurs définis par l'interface AIDL HAL, définissez le champ type
dans la structure SensorInfo
de l'implémentation getSensorsList_2_1()
. Cette opération est sûre, car les champs de type de capteur à valeur entière des HAL de capteurs AIDL et HIDL ne se chevauchent pas.
Implémenter Sensors 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 compiler la sous-couche HAL nouvellement implémentée. Lorsque vous ajoutez la cible :- Assurez-vous que la cible est transférée vers une partition du fournisseur de l'appareil.
- Dans le fichier de configuration situé à l'adresse
/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 sous-bibliothèque HAL, 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 de 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 la sous-couche HAL nouvellement implémentée et l'initialise en appelant sensorsHalGetSubHal_2_1
.
Portage de Sensors Multi-HAL 2.0 vers Multi-HAL 2.1
Pour migrer 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 Multi-HAL les traite comme des sous-HAL de version 2.1.
Port depuis Sensors HAL 2.0
Lorsque vous passez de Sensors HAL 2.0 à Sensors Multi-HAL 2.0, assurez-vous que l'implémentation HAL répond aux exigences suivantes.
Initialiser le HAL
Le HAL 2.0 des capteurs dispose d'une fonction d'initialisation qui permet au service de capteur de transmettre des FMQ et un rappel de capteur dynamique. Dans Sensors Multi-HAL 2.0, la fonction initialize()
transmet un rappel unique qui doit être utilisé pour publier des événements de capteur, obtenir des verrous de réveil et notifier la connexion et la déconnexion de capteurs dynamiques.
Publier des événements de capteur dans l'implémentation Multi-HAL
Au lieu de publier des événements de capteur via le FMQ, le sous-HAL doit écrire les événements de capteur dans IHalProxyCallback
lorsque des événements de capteur sont disponibles.
Événements WAKE_UP
Dans Sensors HAL 2.0, la HAL peut gérer le verrouillage de réveil 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 verrou de réveil à portée limitée verrouillée doit être acquis et transmis à postEvents
lors de la publication d'événements de réveil dans l'implémentation Multi-HAL.
Capteurs dynamiques
Sensors Multi-HAL 2.0 exige que onDynamicSensorsConnected
et onDynamicSensorsDisconnected
dans IHalProxyCallback
soient appelés chaque fois que les connexions de capteurs dynamiques changent. Ces rappels sont disponibles dans le pointeur IHalProxyCallback
fourni par la fonction initialize()
.
Port depuis Sensors HAL 1.0
Lorsque vous passez de Sensors HAL 1.0 à Sensors Multi-HAL 2.0, assurez-vous que l'implémentation HAL répond aux exigences suivantes.
Initialiser le 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 d'un même démarrage de l'appareil, même en cas de redémarrage de Sensors HAL. 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 le redémarrage de l'appareil.
Publier des événements de capteur 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 capteur dans IHalProxyCallback
chaque fois que des événements de capteur sont disponibles.
Événements WAKE_UP
Dans Sensors HAL 1.0, la HAL peut gérer le verrouillage de réveil pour son implémentation. Dans Sensors Multi-HAL 2.0, les sous-HAL permettent à l'implémentation Multi-HAL de gérer les verrous de réveil et de demander l'acquisition d'un verrou de réveil en appelant createScopedWakelock
.
Un verrou de réveil à portée limitée verrouillée doit être acquis et transmis à postEvents
lors de la publication d'événements de réveil dans l'implémentation Multi-HAL.
Capteurs dynamiques
Dans Sensors HAL 1.0, les capteurs dynamiques sont renvoyés par le biais de la fonction poll()
.
Sensors Multi-HAL 2.0 exige que onDynamicSensorsConnected
et onDynamicSensorsDisconnected
dans IHalProxyCallback
soient appelés chaque fois que les connexions de capteurs dynamiques changent. Ces rappels sont disponibles dans le pointeur IHalProxyCallback
fourni par la fonction initialize()
.
Port depuis Sensors Multi-HAL 1.0
Pour transférer une implémentation existante depuis Sensors Multi-HAL 1.0, procédez comme suit.
- Assurez-vous que la configuration HAL des capteurs se trouve à l'adresse
/vendor/etc/sensors/hals.conf
. Cela peut impliquer de déplacer le fichier situé à l'adresse/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. - Portez les sous-HAL comme décrit dans 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 Implémenter Sensors Multi-HAL 2.0.
Validation
Exécuter VTS
Une fois que vous avez intégré un ou plusieurs sous-HAL à Sensors Multi-Hal 2.1, utilisez la Vendor Test Suite (VTS) pour vous assurer que vos implémentations de sous-HAL répondent à toutes les exigences définies par l'interface Sensors HAL.
Pour exécuter uniquement 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 shim AIDL Multi-HAL, 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 sous-HAL factices qui sont instanciés dans le test unitaire et ne sont pas chargés de manière dynamique. Lorsque vous créez une sous-couche HAL, ces tests doivent vous servir de guide pour ajouter des tests unitaires qui vérifient que la nouvelle sous-couche 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
Tester avec les faux sous-HAL
Les sous-HAL factices sont des implémentations fictives 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 capteur générés automatiquement sur HalProxy
en fonction des intervalles spécifiés dans une demande de capteur donnée.
Les sous-HAL factices peuvent être utilisés pour tester le fonctionnement du code Multi-HAL complet avec d'autres sous-HAL chargés dans le système et pour tester différents aspects du code Sensors Multi-HAL.
Deux sous-HAL fictifs sont disponibles sur hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
.
Pour créer et transférer les sous-HAL factices vers un appareil, procédez comme suit :
Exécutez les commandes suivantes pour créer et transférer les trois sous-HAL factices 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 à
/vendor/etc/sensors/hals.conf
avec les chemins d'accès aux sous-HAL factices./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 listé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 Sensors, 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 affichées dans le terminal. Vous trouverez ci-dessous un exemple de résultat de la commande pour l'objet HalProxy
et les sous-HAL fictifs.
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 élevé (1 000 ou plus), cela indique que de nombreux événements sont en attente d'être écrits dans le framework des capteurs. Cela indique que le service de capteur est bloqué ou a planté et ne traite pas les événements de capteur, ou qu'un grand nombre d'événements de capteur a récemment été publié à partir d'une sous-HAL.
Si le nombre de références de verrouillage de réveil est supérieur à 0
, cela signifie que HalProxy
a acquis un verrouillage de réveil. Cette valeur ne doit être supérieure à 0
que si un ScopedWakelock
est intentionnellement retenu ou si des événements de réveil ont été envoyés à HalProxy
et n'ont pas été traités par le framework du 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
.