Service de plug-in audio pour voiture

Les nouveaux services de plug-in OEM pour voitures dans Android 14 permettent de configurer certains composants de la voiture. Pour l'audio en particulier, trois nouveaux services de plug-in sont introduits, ce qui permet aux OEM de configurer de manière flexible la gestion audio sur les appareils AAOS :

  • Contrôle de la priorité audio
  • Contrôle du volume et de la mise en sourdine
  • Contrôle de l'atténuation audio

Architecture du service de plug-in pour voitures

La figure ci-dessous présente les services pour voitures et leur relation avec le service pour voitures OEM. Comme les processus d'application et le processus de service pour voitures, le processus de service pour voitures OEM occupe son propre espace de processus.

image

Le service pour voitures démarre le service pour voitures OEM en recherchant le composant défini dans config_oemCarService. Si la configuration est vide, le service OEM n'existe pas et aucun service n'est démarré. Le composant doit étendre OemCarService. Le service audio pour voitures doit remplacer les API pour acquérir le service OEM audio pour voitures :

public final class OemCarServiceImp extends OemCarService {
    @Override
    public OemCarAudioFocusService getOemAudioFocusService();

    @Override
    public OemCarAudioDuckingService getOemAudioDuckingService();

    @Override
    public OemCarAudioVolumeService getOemAudioVolumeService();
}

Par exemple, consultez l'application de test de référence définie dans packages/services/Car/tests/OemCarServiceTestApp.

Même si le service est démarré par le service pour voitures, il n'hérite pas automatiquement des autorisations disponibles pour le service audio pour voitures. Par conséquent, toute autorisation requise par les services OEM doit être acquise avec le mécanisme approprié. Par exemple, consultez packages/services/Car/data/etc/com.android.car.oemcarservice.testapp.xml.

Architecture du service audio pour voitures avec service OEM

Dans AAOS, le service audio pour voitures gère les actions suivantes :

  • Routage audio
  • Priorité audio
  • Atténuation audio
  • Volume et mise en sourdine

Avant Android 14, ce comportement était en grande partie statique et ne pouvait être modifié que via les paramètres, bien que pour un ensemble de cas très limité. Android 14 a introduit un mécanisme permettant au service audio pour voitures de communiquer avec un composant défini par l'OEM qui gère :

  • Priorité audio
  • Atténuation audio
  • Volume et mise en sourdine

La figure ci-dessous présente une architecture simplifiée pour le service audio pour voitures et le service OEM pour voitures. Le service audio pour voitures définit différents hooks qui peuvent appeler le service audio OEM pour voitures afin de gérer le comportement audio. Cela ne se produit que si le composant de service audio pour voitures OEM correspondant est défini. Sinon, le service audio pour voitures utilise le comportement par défaut.

image

Pour s'assurer que le service audio pour voitures et le service audio OEM pour voitures sont toujours synchronisés, le service audio pour voitures transmet à chaque appel les parties requises de l'état actuel de la pile audio au service audio OEM pour voitures. Par exemple, lorsque le service audio pour voitures intercepte une requête visant à évaluer la priorité audio, il transmet l'état actuel de la pile au service audio OEM pour voitures. L'état actuel inclut le détenteur de la priorité actuel et les perdants de la priorité actuels. Les perdants de la priorité sont des requêtes de priorité qui font toujours partie de la pile, mais qui ont temporairement perdu la priorité.

Le service audio pour voitures doit gérer toutes les activités audio dans la voiture. Si le service audio pour voitures ne gère pas certaines parties du comportement audio, les informations exposées au service audio OEM pour voitures sont incomplètes. Par exemple, si un OEM remplace la gestion de la priorité audio dans le service pour voitures en enregistrant sa propre règle de priorité audio, le service audio pour voitures ne peut pas fournir d'informations complètes au service audio OEM pour voitures. Cela peut affecter la capacité du service audio OEM pour voitures à prendre des décisions, car il peut manquer d'informations non visibles pour le service audio pour voitures.

Pour effectuer des actions, le service audio pour voitures appelle les services pour voitures OEM. Ces appels sont effectués entre les processus, ce qui nécessite une communication interprocessus (IPC). L'IPC ajoute de la latence à chaque appel. Il est important de minimiser la latence dans le service OEM.

Étant donné que les appels du service audio pour voitures au service OEM sont bloquants, le service OEM ne doit pas appeler le service audio pour voitures lors des évaluations directes de l'API. Au lieu de cela, le service audio pour voitures fournit les informations nécessaires pour que les appels entre les deux processus ne doivent se déplacer que dans une seule direction.

Définitions du service audio pour voitures OEM

Service de priorité audio pour voitures OEM

Le service audio pour voitures gère les requêtes de priorité audio des applications en enregistrant un écouteur de priorité de règle audio. Le service audio pour voitures dispose d'un mécanisme permettant de gérer le comportement de la priorité en fonction d'une matrice d'interaction statique Interaction. La matrice définit trois types d'interactions différents :

  • Interaction simultanée. Les détenteurs de la priorité peuvent conserver la priorité en même temps.

  • Interactions exclusives. La requête de priorité entrante prend la priorité du détenteur de la priorité actuel.

  • Rejeter l'interaction. La requête de priorité entrante est rejetée en fonction du détenteur de la priorité actuel.

Bien que cela soit suffisant pour certains cas d'utilisation automobile, cela ne répond pas à tous les besoins d'interaction qui peuvent différer en raison des exigences des OEM. Pour cela, nous introduisons OemCarAudioFocusService :

public interface OEmCarAudioFocusService {
    OemCarAuddioFocusResults evaluateAudioFocusRequest(
        OemCarAudioFocusEvaluationRequest request);
    
    void notifyAudioFocusChange(
        List<AudioFocusEntry> holder,
        List<AudioFocusEntry> losers, int zoneId);
}

L'API evaluateAudioFocusRequest est appelée à partir du service audio pour voitures chaque fois qu'une requête de priorité audio doit être évaluée. Il s'agit d'une API bidirectionnelle qui bloque le retour des résultats. La requête contient des informations sur l'état actuel de la pile audio :

Ces informations peuvent être utilisées pour évaluer la newFocusRequest par rapport aux détenteurs de la priorité actuels dans focusHolders et aux perdants de la priorité actuels dans focusLosers. L'API doit renvoyer les résultats :

class OemCarAudioFocusResult {
    int audioZoneId;
    int audioFocusEvaluationResults;
    AudioFocusEntry focusResult;
    List<AudioFocusEntry> newLosers;
    List<AudioFocusEntry> newlyBlocked;
}

Cela contient les informations sur les résultats d'évaluation réels dans audioFocusEvaluationResults, qui indique si la requête actuelle a été accordée, retardée ou a échoué. Toute modification apportée à la pile de priorité actuelle doit être définie dans les entrées newLosers et newlyBlocked, en fonction de la nature de la modification de la pile.

newLosers contient des entrées qui détenaient auparavant la priorité, mais qui devraient désormais la perdre, de manière permanente ou temporaire. Les perdants de la priorité permanents seront supprimés de la pile de priorité audio, et les perdants de la priorité temporaires seront déplacés vers la pile des perdants de la priorité actuels jusqu'à ce qu'ils retrouvent la priorité ou soient abandonnés par le demandeur de priorité d'origine. Dans tous les cas, l'écouteur de priorité des requêtes recevra une perte de priorité correspondante.

La liste newlyBlocked contient des entrées qui figuraient auparavant dans la liste des perdants de la priorité, mais qui sont désormais bloquées par la nouvelle entrée. Le blocage peut être permanent ou temporaire. Pour le blocage permanent de la priorité, l'entrée sera supprimée de la pile et la perte de priorité sera envoyée aux écouteurs de priorité. En cas de perte de priorité temporaire, l'entrée restera dans la pile des perdants de la priorité, mais un nouveau bloqueur de priorité sera ajouté à sa liste de bloqueurs. Aucune perte de priorité ne sera envoyée, car elle a déjà été envoyée lors du premier blocage. La requête sera finalement débloquée lorsque tous les bloqueurs actuels seront supprimés, ou elle sera supprimée de la pile si la priorité est abandonnée.

La deuxième API, notifyAudioFocusChange, est unidirectionnelle et est appelée pour chaque requête de priorité audio ou abandon. L'API est principalement utilisée pour informer le service OEM des modifications de la priorité, ce qui peut affecter le comportement du service audio pour voitures OEM.

Consignes pour l'évaluation de la priorité

Dans AAOS, la priorité audio est utilisée pour gérer la lecture audio et déterminer quelle application doit adhérer pour offrir une expérience optimale à l'utilisateur. Par conséquent, le service de plug-in OEM doit tenir compte des éléments suivants lors de la gestion d'une requête de priorité audio :

  • Sans priorité audio élevée (comme un appel téléphonique, une urgence ou une sécurité), les applications doivent pouvoir obtenir la priorité audio de manière temporaire ou permanente.

  • Lorsqu'une priorité média est active, les applications demandant :

    • La priorité d'utilisation des appels doit pouvoir recevoir la priorité de manière simultanée ou exclusive.

    • La priorité d'utilisation de la navigation doit pouvoir recevoir la priorité de manière simultanée ou exclusive.

    • La priorité d'utilisation de l'assistant doit pouvoir recevoir la priorité de manière simultanée ou exclusive.

  • Lorsque des applications de priorité audio élevée (comme un appel téléphonique, une alerte d'urgence ou une alerte de sécurité) sont actives, toute requête de priorité audio différée entrante doit être accordée ou différée selon les besoins.

Bien que les suggestions ci-dessus ne soient pas exhaustives, elles peuvent garantir que les applications demandant la priorité doivent pouvoir l'obtenir lorsqu'aucun son de priorité élevée n'est actif. Même lorsque des sons de priorité élevée sont actifs, les requêtes de priorité différées doivent toujours être respectées et doivent pouvoir obtenir la priorité une fois que le son de priorité élevée s'arrête.

Service de volume pour voitures OEM

Le service audio pour voitures gère les événements de touche de volume en écoutant les ajustements de volume du système audio ou en écoutant directement les événements de touche de volume du service d'entrée de la voiture. Dans chaque cas, le comportement par défaut du service audio pour voitures consiste à déterminer le groupe de volume à modifier en fonction des lecteurs audio actifs et d'une liste de priorités de contexte audio.

Nous fournissons deux listes de priorités de volume. La première liste prend en compte tous les contextes audio dans cet ordre. La liste est présentée par ordre décroissant, la priorité la plus élevée en haut et la priorité la plus basse en bas. Par exemple, si l'audio de navigation et l'audio musical sont actifs en même temps, le volume de navigation est modifié lors d'un événement de touche de volume.

  1. Navigation
  2. Appeler
  3. Musique
  4. Annonce
  5. Commande vocale
  6. Sonnerie des appels
  7. Son du système
  8. Sécurité
  9. Alarme
  10. Notification
  11. État du véhicule
  12. Urgence

Pour simplifier la gestion des événements de touche de volume, le service audio pour voitures dispose d'une deuxième liste de priorités de contexte audio :

  1. Appeler
  2. Contenus multimédias
  3. Annonce
  4. Commande vocale

Cette liste est également présentée par ordre décroissant. L'objectif de cette deuxième liste est de permettre de modifier les sons les plus courants via des événements de touche. Les sons moins courants, peut-être de plus courte durée, ne peuvent être gérés que via l'interface utilisateur des paramètres audio.

La version réelle du volume peut être définie avec la configuration audioVolumeAdjustmentContextsVersion. La configuration peut être définie sur 1 ou 2 (2 est la valeur par défaut).

Pour offrir plus de flexibilité à la gestion du volume, OemCarAudioVolumeService est introduit dans Android 14 :

public interface OemCarAudioVolumeService {
    OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}

Le service de volume audio pour voitures OEM ne comporte qu'une seule méthode, qui prend un volumeAdjustment et un OemCarAudioVolumeRequest :

class OemCarAudioVolumeRequest {
    int audioZoneId;
    int callState;
    List<AudioAttributes> activePlaybackAttributes;
    List<AudioAttributes> duckedAttributes;
    List<CarVolumeGroupInfo> volumeGroupState;
}

Le activePlaybackAttributes de la requête comporte les attributs audio actifs. Les duckedAttributes sont tous les attributs audio actuellement atténués. Le volumeGroupState indique l'état actuel du groupe de volumes. La requête représente l'état actuel de la pile audio et peut être utilisée pour déterminer le groupe de volume à modifier. Les résultats doivent être renvoyés dans OemCarVolumeChangeInfo :

class OemCarVolumeChangeInfo {
    boolean change;
    CarVolumeGroupInfo volumeGroupChanged;
}

Le booléen change indique si un volume a été modifié. true indique qu'une modification a été apportée et que le groupe de volumes doit être mis à jour. Le volumeGroupChanged est le groupe de volumes réel qui doit être modifié. Ce groupe doit être modifié en fonction du paramètre volumeAdjustment d'origine transmis à l'API. Par exemple, si les résultats indiquent que le groupe de volumes de navigation doit être mis en sourdine, le booléen sera true et le groupe de volumes renvoyé sera celui de la navigation.

Service d'atténuation pour voitures OEM

Le service audio pour voitures gère l'atténuation audio en surveillant les modifications de la priorité audio et en envoyant un signal au HAL AudioControl concernant les appareils audio à atténuer. Lorsque la priorité change, tous les détenteurs de la priorité actifs sont évalués pour déterminer lesquels doivent être atténués en fonction de cet ensemble de règles d'atténuation statiques rules :

  • Les sons d'urgence atténuent tout, sauf les sons d'appel
  • La sécurité atténue tout, sauf les sons d'urgence
  • La navigation atténue tout, sauf les sons de sécurité et d'urgence
  • L'appel atténue tout, sauf les sons de sécurité, d'urgence et de navigation
  • La voix atténue les sons de sonnerie
  • La musique et les annonces doivent être atténuées par tout

Ces règles ne sont pas exhaustives et les OEM restent responsables de la détermination de la manière dont les sons doivent être atténués en fonction de ces consignes. Les OEM peuvent contrôler ces recommandations de manière plus active en fonction des exigences disponibles. OemCarDuckingService est introduit dans Android 14 :

class OemCarAudioDuckingService {
List<AudioAttributes>   evaluateAttributesToDuck(
        OemCarAudioVolumeRequest request);
}

Cette API est appelée à partir du service audio pour voitures lors des modifications de la priorité audio. Elle réutilise le OemCarAudioVolumeRequest introduit dans le service de volume pour voitures OEM et contient les informations pertinentes pour décider des attributs à atténuer. La liste des attributs audio à atténuer de l'API est comparée à l'état audio actuel :

  • Attribut audio actuellement atténué :

    • Dans la liste, continue d'être atténué
    • Pas dans la liste, atténuation désactivée
  • Attribut audio non atténué actuellement :

    • Dans la liste, atténué
    • Pas dans la liste, atténuation désactivée

Le service audio pour voitures détermine ensuite les appareils de sortie audio auxquels appartiennent les attributs audio et les ajoute respectivement à la liste des appareils de sortie audio atténués ou à la liste des appareils audio non atténués. Ces informations sont finalement envoyées au HAL AudioControl pour effectuer l' atténuation requise au niveau matériel.

La figure ci-dessous présente un diagramme de séquence simplifié du contrôle de l'atténuation audio pour une requête de priorité lorsque le service d'atténuation OEM est utilisé :

image

La séquence commence lorsqu'une application demande à gérer la priorité audio via des API publiques de gestionnaire audio. La requête est transmise au service audio pour voitures afin de déterminer les résultats. Lorsque la priorité audio est décidée, l'atténuation audio est évaluée par le service audio pour voitures qui appelle le OemCarAudioDuckingService afin d'évaluer les attributs audio à atténuer. Une fois les résultats renvoyés par l'API evaluateAttributesToDuck, les appareils audio à atténuer sont calculés, et enfin les informations sont envoyées à AudioControl pour appliquer l'atténuation au matériel audio.

Implémentation de référence du service audio pour voitures OEM

AAOS fournit une implémentation de référence du service pour voitures OEM dans packages/services/Car/tests/OemCarServiceTestApp, qui implémente le OemCarService, ainsi que OemCarAudioFocusService, OemCarAudioDuckingService, et le OemCarAudioVolumeService. Pour ce dernier, chaque service utilise un fichier XML pour charger un comportement statique. Par exemple, OemCarAudioFocusServiceImp charge le oem_focus_config.xml, qui contient une matrice d'interaction. La matrice est utilisée pour évaluer la requête de priorité lorsque evaluateAudioFocusRequest est appelé.

Débogage de l'application de test de référence

L'application de test du service pour voitures OEM fait partie du code source AOSP. Les OEM peuvent apporter des modifications en fonction de leurs besoins. Pour le débogage, utilisez la configuration config_oemCarService pour activer l'application de test.

<!-- This is the component name for the OEM customization service. OEM can choose to implement
this service to customize car service behavior for different policies. If OEMs choose to
implement it, they have to implement a service extending OemCarService exposed by car-lib,
and implement the required component services.
If the component name is invalid, CarService would not connect to any OEM service.
Component name can not be a third party package. It should be pre-installed -->
<string name="config_oemCarService" translatable="false">
com.android.car.oemcarservice.testapp/.OemCarServiceImpl
</string>

Pour vérifier que le service pour voitures OEM utilise la commande dump du service pour voitures pour le service OEM :

adb shell dumpsys car_service --oem-service

Les résultats peuvent être semblables à ceux ci-dessous :

***CarOemProxyService dump***
  mIsFeatureEnabled: true
  mIsOemServiceBound: true
  mIsOemServiceReady: true
  mIsOemServiceConnected: true
  mInitComplete: true
  OEM_CAR_SERVICE_CONNECTED_TIMEOUT_MS: 5000
  OEM_CAR_SERVICE_READY_TIMEOUT_MS: 5000
  mComponentName: com.android.car.oemcarservice.testapp/.OemCarServiceImpl

Chaque booléen de chaque lot d'informations dump détermine l'état de la fonctionnalité et du service. Par exemple, les informations de vidage mIsOemServiceReady spécifient si le service est prêt à être utilisé, où true indique qu'il est prêt et false indique qu'il ne l'est pas.