Capteurs Multi-HAL

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 et ISensorsCallback .
  • 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'objet HalProxy 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 de HalProxy contient toute la logique nécessaire pour multiplexer la communication entre les sous-HAL et le framework de capteurs.
  • SubHal.h : L'interface ISensorsSubHal définit l'interface que les sous-HAL doivent suivre pour être compatible avec HalProxy . Le sous-HAL implémente la méthode initialize afin que l'objet HalProxyCallback puisse être utilisé pour postEvents et createScopedWakelock .

    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 HalProxy .

  • 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 :

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 :

  1. Implémentez l'interface ISensorsSubHal comme décrit dans SubHal.h .
  2. Implémentez la méthode sensorsHalGetSubHal_2_1 dans SubHal.h .
  3. Ajoutez une cible cc_library_shared pour créer le sous-HAL nouvellement implémenté. Lors de l'ajout de la cible :

    1. Assurez-vous que la cible est poussée quelque part sur la partition fournisseur du périphérique.
    2. 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 fichier hals.conf .

    Pour un exemple d'entrée Android.bp permettant de créer une bibliothèque sous-HAL, consultez hardware/interfaces/sensors/common/default/2.X/multihal/tests/Android.bp .

  4. Supprimez toutes les entrées android.hardware.sensors du fichier manifest.xml , qui contient la liste des HAL pris en charge sur l'appareil.

  5. Supprimez tous les fichiers android.hardware.sensors service et service.rc du fichier device.mk et ajoutez android.hardware.sensors@2.1-service.multihal et android.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écification ISensors.hal .
  • La fonction initialize() passe un nouveau IHalProxyCallback au lieu de celui de l'interface SubHal 2.0
  • Les sous-HAL doivent implémenter getSensorsList_2_1 et injectSensorData_2_1 au lieu de getSensorsList et injectSensorData car ces méthodes utilisent les nouveaux types ajoutés dans la version 2.1 de la spécification ISensors.hal .
  • Les sous-HAL doivent exposer sensorsHalGetSubHal_2_1 plutôt que sensorsHalGetSubHal 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.

  1. 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 .
  2. Supprimez toutes les références à hardware/hardware.h et hardware/sensors.h car celles-ci ne sont pas prises en charge pour HAL 2.0.
  3. Portez les sous-HAL comme décrit dans Portage à partir des capteurs Hal 1.0 .
  4. 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 :

  1. 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
    
  2. 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
    
  3. 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 .