Routage audio

Dans Android 10, car_audio_configuration.xml remplace car_volumes_groups.xml et IAudioControl.getBusForContext . Dans le nouveau fichier de configuration, une liste de zones est définie. Chaque zone possède un ou plusieurs groupes de volumes avec leurs périphériques associés, et chaque périphérique possède les contextes qui doivent être acheminés dans cette zone. Il est nécessaire que tous les contextes soient représentés dans chaque zone.

Configuration du routage audio

Les fichiers de stratégie audio, qui se trouvent généralement dans la partition du fournisseur, représentent la configuration matérielle audio de la carte. Tous les appareils référencés dans car_audio_configuration.xml doivent être définis dans audio_policy_configuration.xml .

Activation du routage AAOS

Pour utiliser le routage basé sur AAOS, vous devez définir l'indicateur audioUseDynamicRouting sur true :

<resources>
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

Lorsque false , le routage et une grande partie de CarAudioService seront désactivés et le système d'exploitation reviendra au comportement par défaut de AudioService .

Zone principale

Par défaut, tout l'audio sera acheminé vers la zone principale. Il ne peut y avoir qu'une seule zone principale, indiquée dans la configuration par l'attribut isPrimary="true" .

Exemple de configuration

À titre d’exemple, un véhicule pourrait avoir deux zones : une zone principale et un système de divertissement aux places arrière. Avec cela, un éventuel car_audio_configuration.xml serait défini comme suit :

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                       <context context="announcement"/>
                   </device>
                   <device address="bus3_call_ring_out">
                       <context context="call_ring"/>
                   </device>
                   <device address="bus6_notification_out">
                       <context context="notification"/>
                   </device>
                   <device address="bus7_system_sound_out">
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                   </device>
               </group>
               <group>
                   <device address="bus1_navigation_out">
                       <context context="navigation"/>
                   </device>
                   <device address="bus2_voice_command_out">
                       <context context="voice_command"/>
                   </device>
               </group>
               <group>
                   <device address="bus4_call_out">
                       <context context="call"/>
                   </device>
               </group>
               <group>
                   <device address="bus5_alarm_out">
                       <context context="alarm"/>
                   </device>
               </group>
           </volumeGroups>
       </zone>
        <zone name="rear seat zone" audioZoneId="1">
           <volumeGroups>
               <group>
                   <device address="bus100_rear_seat">
                       <context context="music"/>
                       <context context="navigation"/>
                       <context context="voice_command"/>
                       <context context="call_ring"/>
                       <context context="call"/>
                       <context context="alarm"/>
                       <context context="notification"/>
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                       <context context="announcement"/>
                   </device>
               </group>
           </volumeGroups>
    </zones>
</audioZoneConfiguration>

Ici, la zone principale a séparé les contextes des différents appareils. Cela permet au HAL d'appliquer différents effets de post-traitement et de mixage sur chaque sortie de périphérique à l'aide du matériel du véhicule. Les appareils ont été répartis en quatre groupes de volumes : médias, navigation, appels et alarmes. Si le système est configuré pour useFixedVolume , alors les niveaux de volume de chaque groupe seront transmis au HAL pour s'appliquer à la sortie de ces appareils.

Pour la zone secondaire, la sortie attendue se fait via un seul périphérique de sortie. Dans cet exemple, toutes les utilisations sont acheminées vers un seul périphérique et un seul groupe de volumes pour simplifier les choses.

Configuration audio de la zone occupant

Dans Android 11, car_audio_configuration.xml a été encore étendu pour introduire deux nouveaux champs, audioZoneId et occupantZoneId . Le premier, audioZoneId peut être utilisé pour mieux contrôler la gestion des zones. D'un autre côté, occupantZoneId peut être utilisé pour configurer le routage basé sur l'ID utilisateur.

Pour utiliser ces nouveaux champs, la V2 du car_audio_configuration.xml est requise. En revisitant la configuration audio ci-dessus mais en utilisant le nouveau champ pour le mappage de l'identifiant de zone d'occupant et de l'identifiant de zone audio, la nouvelle configuration sans les définitions de groupe de volumes peut être configurée comme :

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true" occupantZoneId="0">
         ...
       </zone>
       <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1">
         ...
       </zone>
    </zones>
</audioZoneConfiguration>

La configuration ci-dessus définit un mappage pour la zone principale vers la zone d'occupant 0 et audioZoneId 1 vers occupantZoneId 1. En général, tout mappage entre la zone d'occupant et la zone audio peut être configuré mais le mappage doit être un à un. Voici les règles qui ont défini les deux nouveaux champs :

  • L' audioZoneId de la zone principale est toujours nul
  • Les numéros audioZoneId et occupantZoneId ne peuvent pas se répéter
  • audioZoneId et occupantZoneId ne peuvent avoir qu'un mappage individuel

Routage via un UID d'application

Une série d'API cachées ont été introduites dans CarAudioManager en 10 pour permettre aux applications d'interroger et de définir des zones audio et de se concentrer.

int[] getAudioZoneIds();
int getZoneIdForUid(int uid);
boolean setZoneIdForUid(int zoneId, int uid);
boolean clearZoneIdForUid(int uid);

Les API ci-dessus ont permis à une application propriétaire de gérer le routage audio en fonction de l'UID d'une application. En tant que tel, l'ID de la zone audio et l'UID de l'application sont également nécessaires. Avec ces informations en main, le routage audio peut être défini à l'aide de l'API CarAudioManager#setZoneIdForUid .

Changer de zone pour une application

Par défaut, tous les fichiers audio sont acheminés vers la zone principale. Pour mettre à jour une application à acheminer vers une zone différente, utilisez CarAudioManager#setZoneIdForUid :

// Find zone to play
int zoneId = ...

// Find application's uid
Int uid = mContext.getPackageManager()
        .getApplicationInfo(mContext.getPackageName(), 0)
        .uid;

if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) {
    Log.d(TAG, "Zone successfully updated");
} else {
    Log.d(TAG, "Failed to change zone");
}

N Remarque : Les flux et le focus ne peuvent pas changer de zone de manière dynamique. Par conséquent, la lecture doit être arrêtée et la mise au point doit être redemandée pour changer de zone.

Routage avec ID utilisateur

Bien que le routage basé sur l'UID d'une application permette un contrôle précis du routage audio de chaque application, il nécessite également que le routage audio de chaque application soit défini avant que l'application ne demande réellement le focus audio et ne lise l'audio. Pour atténuer ce problème et faciliter davantage la lecture audio des applications tierces sans modification, CarAudioService utilise la zone des occupants de la voiture et le mappage de la zone audio pour définir le routage basé sur l'identifiant de l'utilisateur. De cette façon, lorsqu'un utilisateur se connecte à la zone des occupants, le service audio de la voiture en est informé. Avec ce signal, la gestion de la focalisation audio et le routage sont automatiquement configurés pour toutes les zones audio.

Le routage basé sur l'UID des applications peut toujours être utilisé mais doit être effectué indépendamment du routage de l'ID utilisateur. Cela signifie que si le mappage de la zone des occupants vers la zone audio de la voiture est défini, le routage basé sur l'UID est désactivé et la tentative d'appel CarAudioManager#setZoneidForUid générera une erreur.

Bien que le routage audio et la gestion de la mise au point aient été simplifiés grâce à la gestion des zones d'occupant, l'utilisateur doit toujours être affecté à une zone d'occupant. Cela peut être fait en utilisant CarOccupantZoneManager#assignProfileUserToOccupantZone . Cette API nécessite une autorisation pour gérer les utilisateurs. On s’attend actuellement à ce que les constructeurs OEM gèrent l’attribution des zones utilisateur à occupant via une sorte d’interface utilisateur système. Une fois cela fait, le lancement de l'application, le routage audio, la gestion du focus seront automatiquement configurés pour l'utilisateur.

Routage avec setPreferredDevice

Parallèlement aux modifications ci-dessus, Android 11 dispose également d'une nouvelle API pour interroger les périphériques de sortie associés à chaque zone, CarAudioManager#getOutputDeviceForUsage(int zoneId, int utilisation).

L'API peut être utilisée pour interroger un périphérique de sortie pour une zone particulière et l'utilisation d'un attribut audio. De cette manière, les applications propriétaires peuvent acheminer l'audio vers différentes zones en utilisant l'API setPreferredDevice du lecteur. L'API getOutputDeviceForUsage nécessite PERMISSION_CAR_CONTROL_AUDIO_SETTINGS et est une API système. Vous trouverez ci-dessous un exemple de recherche du périphérique multimédia pour une zone particulière et de routage vers ce périphérique à l'aide de l'API setPreferredDevice .

audioZoneId = ... ;
mediaDeviceInfo = mCarAudioManager
            .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA);
…
mPlayer.setPreferredDevice(mediaDeviceInfo);