Multi-HAL des capteurs

Le multi-HAL des capteurs est un framework qui permet aux HAL des capteurs de s'exécuter avec d'autres HAL de capteurs. Le multi-HAL des capteurs charge dynamiquement les sous-HAL des capteurs stockés en tant que bibliothèques dynamiques sur la partition du fournisseur et leur fournit un objet de rappel capable de gérer l'envoi d'événements, 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 les uns des autres ou du code multi-HAL qui contient la fonction principale. pour le 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 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 et qui utilisent Sensors AIDL HAL, vous pouvez utiliser couche de shim multi-HAL pour permettre une fonctionnalité multi-HAL. Pour en savoir plus sur l'implémentation, voir Utiliser le système Sensors Multi-HAL avec le HAL des capteurs AIDL

Différence entre Sensors Multi-HAL 2 et Sensors HAL 2

Capteurs Multi-HAL 2, disponibles sur les appareils équipés d'Android 10 ou supérieure, introduit plusieurs abstractions en plus de l'API Sensors HAL 2 pour faciliter pour interagir 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 de l'interface V2_1/SubHal (ou V2_0/SubHal) afin de 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). l'interface de la manière suivante:

  • La méthode d'initialisation 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 bugs.
  • Les sous-HAL doivent implémenter une fonction de nom afin que le sous-HAL chargé puisse être distinguée des autres sous-HAL.

La principale différence entre les capteurs multi-HAL 2 et HAL 2 réside dans le pour initialiser des fonctions. Au lieu de fournir des FMQ, IHalProxyCallback propose deux méthodes, l'une permettant de publier les événements détectés par les capteurs framework et une méthode pour créer des wakelocks. En arrière-plan, les capteurs Multi-HAL gère toutes les interactions avec les FMQ pour garantir la livraison rapide des événements des capteurs 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 la mise à expiration des wake locks au multi-HAL Sensors et pour centraliser l'utilisation des wake locks sur un seul wake lock commun pour l'ensemble du multi-HAL Sensors, ce qui réduit au minimum les appels de verrouillage et de déverrouillage.

Sensors Multi-HAL 2 intègre également des fonctionnalités de sécurité. Il gère les situations où le FMQ du capteur est plein ou où 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é dans la classe HalProxy, mais le framework du capteur n'accepte pas les événements sont immédiatement détectés, le système Sensors Multi-HAL peut les déplacer en arrière-plan thread permettant de poursuivre le travail sur tous les sous-HAL en attendant l'appel événements à publier.

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'objet HalProxy est instancié par la fonctionnalité Sensors Multi-HAL et gère les la transmission des données des sous-HAL à la structure du capteur.
  • HalProxy.cpp: L'implémentation de HalProxy contient toute la logique nécessaire pour la communication multiplex entre les sous-HAL et la structure du capteur.
  • SubHal.h: L'interface ISensorsSubHal définit l'interface que les sous-HAL doivent suivre pour être compatible avec HalProxy. La sous-HAL met en œuvre d'initialisation 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 de HalProxy.

  • 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 le multi-HAL des capteurs dans les situations suivantes :

Utiliser le système Sensors Multi-HAL avec le HAL des capteurs AIDL

Pour autoriser la fonctionnalité multi-HAL avec le HAL AIDL des capteurs, importez le module de couche de shim multi-HAL AIDL, qui se trouve dans hardware/interfaces/sensors/aidl/default/multihal/. Le module gère la conversion entre la définition HAL des capteurs AIDL et HIDL et définit un wrapper autour de l'interface multi-HAL décrite dans Implémenter des capteurs Multi-HAL 2.1 La couche de shim multi-HAL AIDL est compatible avec les appareils qui implémentent Sensors Multi-HAL 2.1.

La couche de shim multi-HAL AIDL vous permet d'exposer le suivi de la tête et les types de capteurs IMU à axe limité dans le HAL AIDL Sensors. 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 getSensorsList_2_1(). C'est sans danger car les champs de type de capteur reposant sur des entiers des capteurs AIDL et HIDL HAL 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:

  1. Implémentez l'interface ISensorsSubHal comme décrit dans la section 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 sub-HAL que vous venez d'implémenter. Lorsque vous ajoutez la cible :

    1. Assurez-vous que la cible est transmise à un emplacement de la partition du fournisseur de l'appareil.
    2. Dans le fichier de configuration situé à l'emplacement /vendor/etc/sensors/hals.conf, ajoutez le chemin d'accès à la bibliothèque sur une nouvelle ligne. Si nécessaire, créez la classe hals.conf.

    Pour obtenir un exemple d'entrée Android.bp permettant de créer une bibliothèque de 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 compatibles sur l'appareil.

  5. Supprimez tous les fichiers de service android.hardware.sensors et service.rc du fichier device.mk, puis 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.

Migration de Sensors Multi-HAL 2.0 vers Multi-HAL 2.1

Pour passer de Multi-HAL 2.0 à 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 version 2.1 de la spécification ISensors.hal.
  • La fonction initialize() transmet une nouvelle IHalProxyCallback au lieu de celui de l'interface 2.0 SubHal
  • 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 de la version 2.1.

Port des capteurs HAL 2.0

Lorsque vous passez à Sensors Multi-HAL 2.0 à partir de Sensors HAL 2.0, assurez-vous que l'implémentation du HAL répond aux exigences suivantes.

Initialiser le HAL

Sensors HAL 2.0 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 La fonction initialize() transmet un seul rappel qui doit être utilisé pour publier les événements des capteurs, obtenir des wakelocks et une notification en cas de connexion dynamique des capteurs, les déconnexions.

Publier des événements de capteurs dans l'implémentation multi-HAL

Au lieu d'afficher des événements de capteur via le FMQ, le sous-HAL doit écrire des é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 verrouillage de réveil pour son implémentation. Dans Les capteurs multi-HAL 2.0, les sous-HAL, permettent à la mise en œuvre multi-HAL de gérer les wakelocks et demander l'acquisition d'un wakelock en appelant la méthode createScopedWakelock Un wakelock cloisonné verrouillé doit être acquis et transmis à postEvents lorsque publier des événements de wakeups 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 disponible dans le pointeur IHalProxyCallback fourni via la fonction initialize().

Port de Sensors HAL 1.0

Lors de la mise à jour de Sensors HAL vers Sensors Multi-HAL 2.0 1.0, assurez-vous que le 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 d'un seul démarrage de l'appareil, même lors des 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 le redémarrage de l'appareil.

Publier des événements de capteur dans l'implémentation multi-HAL

Dans la version 2.0 des capteurs HAL, au lieu d'attendre que poll() soit appelé, le sous-HAL doit écrire de manière proactive les événements des capteurs IHalProxyCallback dès lors que des événements de capteurs 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 Capteurs Multi-HAL 2.0, les sous-HAL permettent à l'implémentation Multi-HAL de gérer les wakelocks et demander l'acquisition d'un wakelock en appelant la méthode createScopedWakelock Un verrouillage de réveil 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 la version HAL 1.0 des capteurs, les capteurs dynamiques sont renvoyés via la fonction poll(). Sensors Multi-HAL 2.0 nécessite que onDynamicSensorsConnected et onDynamicSensorsDisconnected po IHalProxyCallback sont appelés dès que les connexions dynamiques des capteurs changent. Ces rappels sont disponible dans le pointeur IHalProxyCallback fourni via la fonction initialize().

Port de Sensors 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 elles ne sont pas compatibles avec HAL 2.0.
  3. Portez les sous-HAL comme décrit dans la section Portage à partir de Sensors HAL 1.0.
  4. 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

Si vous avez intégré une ou plusieurs sous-HAL avec la fonctionnalité Sensors Multi-Hal 2.1, utiliser la suite de test fournisseur (VTS) pour vous assurer que votre sous-HAL est installé répondent à toutes les exigences définies par l'interface HAL des capteurs.

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 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 de 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. Lorsque vous créez un sous-HAL, ces tests doivent vous servir de guide pour ajouter des tests unitaires qui vérifient que le nouveau sous-HAL est implémenté correctement.

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 sur HalProxy en fonction des intervalles spécifiés dans une requête 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 tester différents aspects du code Multi-HAL des capteurs.

Deux faux sous-HAL sont disponibles à l'adresse hardware/interfaces/sensors/common/default/2.X/multihal/tests/fake_subhal/

Pour créer des faux sub-HAL et les transférer vers un appareil, procédez comme suit:

  1. Exécutez les commandes suivantes pour créer et transférer les trois faux sous-HAL 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 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 alors sur le terminal. Vous trouverez ci-dessous un exemple de résultat de la commande Objet HalProxy et 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 un grand nombre (1 000 ou plus), cela indique que de nombreux événements sont en attente d'écriture sur les capteurs d'infrastructure. Cela indique que le service des capteurs est bloqué ou a planté. ne traite pas les événements liés aux capteurs, ou qu'un grand nombre ont récemment publié des posts depuis un 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 maintenu intentionnellement ou si des événements de réveil ont été envoyés à HalProxy et n'ont pas été traités par le framework de capteurs.

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.