Le Sensors Multi-HAL est un cadre qui permet aux capteurs HAL de fonctionner aux côtés d’autres capteurs HAL. Le Sensors Multi-HAL charge dynamiquement les sous-HAL des capteurs stockés en tant que bibliothèques dynamiques sur la partition du fournisseur et leur donne un objet de rappel qui peut gérer la publication d'événements et l'acquisition et la libération du wakelock. 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 exécutant Android 11 ou version ultérieure, est une itération de Sensors Multi-HAL 2.0 qui prend en charge le chargement de sous-HAL 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 exécutant Android 13 ou version ultérieure qui utilisent les capteurs AIDL HAL , vous pouvez utiliser la couche de cale multi-HAL pour permettre la fonctionnalité multi-HAL. Pour plus de détails sur la mise en œuvre, voir Utilisation des capteurs Multi-HAL avec les capteurs AIDL HAL .
Différence entre les capteurs Multi-HAL 2 et les capteurs HAL 2
Sensors Multi-HAL 2, disponible sur les appareils fonctionnant sous Android 10 ou version ultérieure, introduit plusieurs abstractions en plus de Sensors HAL 2 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
est différente de l'interface 2.1/ISensors.hal
(ou 2.0/ISensors.hal
) des manières suivantes :
- La méthode initialize 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 bogues.
- Les sous-HAL doivent implémenter une fonction de nom afin que le sous-HAL chargé puisse être distingué des autres sous-HAL.
La principale différence entre les capteurs Multi-HAL 2 et les capteurs HAL 2 réside dans les fonctions d'initialisation. Au lieu de fournir des FMQ, l'interface IHalProxyCallback
fournit deux méthodes : une méthode pour publier les événements de capteur dans la structure des capteurs et une méthode pour créer des wakelocks. Sous le capot, le Sensors Multi-HAL gère toutes les interactions avec les FMQ pour garantir la livraison en temps opportun 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 de temporisation des wakelocks au Sensors Multi-HAL et pour centraliser l'utilisation du wakelock sur un wakelock commun pour l'ensemble des Sensors Multi-HAL, ce qui minimise le verrouillage et le déverrouillage. appels.
Les capteurs Multi-HAL 2 disposent également de fonctions de sécurité intégrées. Il gère les situations dans lesquelles le capteur FMQ est plein ou dans lesquelles le framework de capteurs Android redémarre et l'état du capteur doit être réinitialisé. De plus, lorsque des événements sont publiés dans la classe HalProxy
mais que la structure du capteur n'est pas en mesure d'accepter les événements immédiatement, le Sensors Multi-HAL peut déplacer les événements vers un thread d'arrière-plan pour permettre au travail de continuer dans tous les sous-HAL en attendant les événements. être posté.
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 indicateurs vers quelques ressources.
-
HalProxy.h
: L'objetHalProxy
est instancié par Sensors multi-HAL et gère la transmission des 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 compatible 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émentationHalProxy
.hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/
: Cet exemple d'implémentation sous-HAL utilise de faux capteurs pour générer de fausses données. Utile pour tester la façon dont plusieurs sous-HAL interagissent sur un appareil.
Mise en œuvre
Cette section décrit comment mettre en œuvre les capteurs Multi-HAL dans les situations suivantes :
- Utilisation des capteurs Multi-HAL avec les capteurs AIDL HAL
- Implémentation de capteurs Multi-HAL 2.1
- Portage des capteurs Multi-HAL 2.0 vers Multi-HAL 2.1
- Portage depuis les capteurs HAL 2.0
- Portage depuis les capteurs HAL 1.0
- Portage depuis les capteurs Multi-HAL 1.0
Utilisez les Capteurs Multi-HAL avec les Capteurs AIDL HAL
Pour permettre la fonctionnalité multi-HAL avec les capteurs AIDL HAL, importez le module de couche de cale AIDL Multi-HAL, qui se trouve 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 autour de l'interface multi-HAL décrite dans Implémentation de capteurs Multi-HAL 2.1 . La couche de cale multi-HAL AIDL est compatible avec les appareils qui implémentent les capteurs Multi-HAL 2.1.
La couche de cale multi-HAL AIDL vous permet d'exposer les types de capteurs de suivi de tête et d'IMU à axe limité dans les capteurs AIDL HAL. Pour utiliser ces types de capteurs définis par l'interface AIDL HAL, définissez le champ type
dans la structure SensorInfo
dans l'implémentation getSensorsList_2_1()
. Ceci est sûr car les champs de type de capteur à nombre entier des capteurs AIDL et HIDL HAL ne se chevauchent pas.
Mettre en œuvre des capteurs Multi-HAL 2.1
Pour implémenter Sensors Multi-HAL 2.1 sur un nouvel appareil, suivez ces étapes :
- 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 nouvellement implémenté. Lors de l'ajout de la cible :- Assurez-vous que la cible est poussée quelque part sur la partition fournisseur du périphérique.
- 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 un exemple d'entrée
Android.bp
permettant de créer une bibliothèque sous-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 pris en charge sur l'appareil.Supprimez tous les fichiers
android.hardware.sensors
service etservice.rc
du fichierdevice.mk
et 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 nouvellement implémenté et l'initialise en appelant sensorsHalGetSubHal_2_1
.
Port des capteurs Multi-HAL 2.0 vers Multi-HAL 2.1
Pour effectuer un 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()
passe 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 version 2.1.
Port des capteurs HAL 2.0
Lors de la mise à niveau vers Sensors Multi-HAL 2.0 à partir de Sensors HAL 2.0 , assurez-vous que la mise en œuvre de HAL répond aux exigences suivantes.
Initialiser le HAL
Capteurs HAL 2.0 dispose d'une fonction d'initialisation qui permet au service de capteur 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 les événements du capteur, obtenir des wakelocks et notifier la connexion et la déconnexion dynamiques du capteur.
Publier les événements du capteur dans l'implémentation Multi-HAL
Au lieu de publier les é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, le HAL peut gérer le wakelock pour sa mise en œuvre. 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 réveil dans l'implémentation Multi-HAL.
Capteurs dynamiques
Sensors Multi-HAL 2.0 nécessite que onDynamicSensorsConnected
et onDynamicSensorsDisconnected
dans IHalProxyCallback
soient appelés chaque fois que les connexions des capteurs dynamiques changent. Ces rappels sont disponibles dans le cadre du pointeur IHalProxyCallback
fourni via la fonction initialize()
.
Port des capteurs HAL 1.0
Lors de la mise à niveau vers Sensors Multi-HAL 2.0 à partir de Sensors HAL 1.0 , assurez-vous que la mise en œuvre de HAL répond aux exigences suivantes.
Initialiser le HAL
La fonction initialize()
doit être prise en charge pour établir le rappel entre l'implémentation sub-HAL et 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 périphérique, même lors des redémarrages HAL des capteurs. Cela permet à l'infrastructure 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 les événements du 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, le HAL peut gérer le wakelock pour sa mise en œuvre. 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 réveil dans l'implémentation Multi-HAL.
Capteurs dynamiques
Dans Sensors HAL 1.0, les capteurs dynamiques sont renvoyés via la fonction poll()
. Sensors Multi-HAL 2.0 nécessite que onDynamicSensorsConnected
et onDynamicSensorsDisconnected
dans IHalProxyCallback
soient appelés chaque fois que les connexions des capteurs dynamiques changent. Ces rappels sont disponibles dans le cadre du pointeur IHalProxyCallback
fourni via la fonction initialize()
.
Port des capteurs Multi-HAL 1.0
Pour porter 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 celles-ci ne sont pas prises en charge pour HAL 2.0. - Portez les sous-HAL comme décrit dans Portage à partir des capteurs Hal 1.0 .
- Définissez les capteurs Multi-HAL 2.0 comme HAL désigné en suivant les étapes 3 et 4 de la section Implémentation des capteurs Mutli-HAL 2.0 .
Validation
Exécuter VTS
Lorsque vous avez intégré un ou plusieurs sous-HAL avec Sensors Multi-Hal 2.1, utilisez 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 de calage 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
en utilisant de faux sous-HAL qui sont instanciés dans le test unitaire et ne sont pas chargés dynamiquement. Lors de la création d'un nouveau sous-HAL, ces tests doivent servir de guide sur la façon d'ajouter des tests unitaires qui vérifient que le nouveau sous-HAL est correctement implémenté.
Pour exécuter les tests, exécutez les commandes suivantes :
cd $ANDROID_BUILD_TOP/hardware/interfaces/sensors/common/default/2.X/multihal/tests
atest
Testez avec les 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 périodiquement 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 faux sous-HAL 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 souligner divers 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 et transférer les faux sous-HAL vers un appareil, effectuez les étapes suivantes :
Exécutez les commandes suivantes pour créer et transmettre 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 dans
/vendor/etc/sensors/hals.conf
avec les chemins d'accès aux 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 Sensors HAL, 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 sortie de 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 le # of events on pending write queue
est un nombre élevé (1 000 ou plus), cela indique que de nombreux événements sont en attente d'écriture dans la structure des capteurs. Cela indique que le service de capteur est bloqué ou est tombé en panne et ne traite pas les événements de capteur, ou qu'un grand lot d'événements de capteur a été récemment publié à partir d'un sous-HAL.
Si le nombre de références de wakelock est supérieur à 0
, cela signifie que HalProxy
a acquis un wakelock. Cela ne doit être supérieur à 0
que si un ScopedWakelock
est intentionnellement maintenu ou si des événements de réveil ont été envoyés à HalProxy
et n'ont pas été traités par la structure 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 le cadre de l'interface ISensorsSubHal
.