Avant de démarrer un flux logique, une application doit demander la sélection audio à l'aide des mêmes attributs audio que ceux utilisés pour son flux logique. Bien qu'il soit recommandé d'envoyer une telle requête de sélection, elle n'est pas appliquée par le système. Certaines applications peuvent ignorer explicitement l'envoi de la requête pour obtenir des comportements spécifiques (par exemple, pour diffuser intentionnellement du son pendant un appel téléphonique).
Pour cette raison, vous devez considérer la mise au point comme un moyen de contrôler indirectement et de dénouer les conflits de lecture, et non comme un mécanisme de contrôle audio principal. Le véhicule ne doit pas dépendre du système de mise au point pour le fonctionnement du sous-système audio.
Interactions de sélection
Pour répondre aux besoins de l'AAOS, les requêtes de priorité audio sont gérées en fonction d'interactions prédéfinies entre le CarAudioContext
de la requête et celui des détenteurs de priorité actuels. Il existe trois types d'interactions: exclusive, rejet et simultanée.
Interaction exclusive
Dans les interactions exclusives, une seule application est autorisée à conserver la sélection à la fois.
Par conséquent, la requête de mise au point entrante reçoit la mise au point, tandis que le détenteur de la mise au point existante perd la mise au point. Par exemple, lorsqu'un utilisateur démarre une nouvelle application musicale alors que de la musique est déjà en cours de lecture dans une application existante. Comme les deux applications diffusent des contenus multimédias, une seule d'entre elles est autorisée à conserver la sélection à la fois. Par conséquent, la requête de focus de l'application nouvellement démarrée est renvoyée avec AUDIOFOCUS_REQUEST_GRANTED
, et l'application qui lit actuellement de la musique reçoit un événement de changement de focus avec un état de perte correspondant au type de requête effectuée. Il s'agit du modèle d'interaction le plus courant avec Android.
Refuser l'interaction
Avec les interactions de refus, la requête entrante est toujours refusée. La tentative de lecture de musique pendant un appel est un exemple d'interaction refusée. Dans ce cas, si le clavier détient actuellement la priorité audio pour un appel et qu'une deuxième application demande la priorité pour lire de la musique, l'application de musique reçoit AUDIOFOCUS_REQUEST_FAILED
en réponse à sa requête. Étant donné que la requête de mise au point est rejetée, aucune perte de focus n'est envoyée au détenteur actuel de la mise au point.
Interaction simultanée
Les interactions simultanées sont la caractéristique la plus spécifique à l'AAOS. Cela permet aux applications qui demandent la priorité audio dans la voiture de conserver la priorité en même temps que d'autres applications. Pour qu'une interaction simultanée puisse avoir lieu, les conditions suivantes doivent être remplies. La
- La requête de sélection entrante doit demander
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
. - Le détenteur actuel du focus ne
setPauseWhenDucked(true)
pas. - Le détenteur actuel du focus ne choisit pas de recevoir des événements de canard.
Si ces critères sont remplis, la requête de sélection renvoie AUDIOFOCUS_REQUEST_GRANTED
, tandis que le détenteur actuel de la sélection ne change pas de sélection. Toutefois, si le détenteur actuel du focus choisit de recevoir des événements de masquage ou de suspendre son activité en cas de masquage, il perd le focus, comme pour une interaction exclusive.
Gérer les flux simultanés
Bien que l'interaction simultanée ait de nombreuses applications utiles, les OEM doivent s'occuper du mixage et du masquage au niveau matériel sur les appareils de sortie. C'est pourquoi nous vous recommandons vivement de ne router les CarAudioContext
que vers le même appareil de sortie que les CarAudioContext
avec lesquels ils ne peuvent pas être lus simultanément. En disposant de périphériques de sortie distincts pour les flux simultanés, le HAL peut couper l'un des flux avant de les mélanger ou de router les flux physiques vers différents haut-parleurs du véhicule. Si les flux logiques sont mélangés dans Android, leurs gains ne sont pas modifiés et sont diffusés dans le même flux physique.
Par exemple, lorsque la navigation et les contenus multimédias sont diffusés simultanément, le gain du flux multimédia peut être temporairement réduit (masqué) afin que les instructions de navigation soient plus audibles. Le flux de navigation peut également être acheminé vers les haut-parleurs du côté conducteur, tandis que les contenus multimédias continuent de se diffuser dans le reste de l'habitacle.
Matrice d'interaction
Le tableau ci-dessous présente la matrice d'interaction telle que définie par CarAudioService
.
Les lignes représentent le CarAudioContext
du détenteur actuel du focus, et les colonnes celui de la requête entrante.
Prenons un exemple : une application multimédia musicale détient actuellement la sélection et une application de navigation demande la sélection. La matrice montre que les deux interactions peuvent se produire simultanément, à condition que les autres critères des interactions simultanées soient remplis.
En raison des interactions simultanées, il est possible qu'il existe plusieurs détenteurs de focus. Dans ce cas, une requête de focus entrante est comparée à chacun des détenteurs de focus actuels avant de décider du type d'interaction à appliquer. Dans ce cas, l'interaction la plus conservatrice l'emporte (rejet, puis exclusive, puis simultanée).
Dans le tableau suivant, les interactions de mise au point entre le CarAudioContext pour une requête de mise au point entrante (colonnes) et le contexte des détenteurs de mise au point existants (lignes) sont fournies. Chaque cellule représente le type d'interaction attendu pour les deux contextes.
Figure 1. Interactions avec la priorité audio
Navigation pendant les appels téléphoniques
Dans Android 11, un nouveau paramètre utilisateur a été introduit pour permettre aux utilisateurs de modifier le comportement d'interaction entre la navigation et les appels téléphoniques. Lorsqu'il est défini, android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL
modifie l'interaction entre les requêtes de focus NAVIGATION
entrantes et les détenteurs de focus CALL
actuels, passant de concurrent à reject.
Par conséquent, si un utilisateur préfère que les instructions de navigation n'interrompent pas son appel, il peut activer ce paramètre. Cette valeur est conservée pour l'utilisateur et peut être définie de manière dynamique afin que les requêtes de mise au point ultérieures respectent la nouvelle valeur du paramètre.
Priorité audio retardable
Dans Android 11, AAOS a ajouté la possibilité de demander un focus audio retardable. Cela permet de retarder les requêtes de focus non temporaires lorsque leur interaction avec les détenteurs actuels du focus les ferait normalement rejeter. Une fois qu'un changement de focus entraîne un état dans lequel la requête retardée peut être mise en avant, la requête est accordée.
Règles concernant les requêtes de mise au point audio différée
- Requêtes non temporaires uniquement : comme indiqué précédemment, une requête différée ne peut être effectuée que pour des sources non temporaires. Cela permet d'éviter qu'un son transitoire ne soit diffusé longtemps après qu'il n'est plus pertinent.
- Une seule requête peut être retardée à la fois : si une requête retardable est envoyée alors qu'une requête retardée est déjà en cours, la requête retardée d'origine reçoit un événement de modification
AUDIOFOCUS_LOSS
et la nouvelle requête reçoit une réponse synchrone deAUDIOFOCUS_REQUEST_DELAYED
. - Les requêtes retardables doivent comporter un
OnAudioFocusChangeListener
. Une fois qu'une requête est retardée, l'écouteur est utilisé pour avertir le demandeur lorsque la requête est finalement accordée (AUDIOFOCUS_GAIN
) ou si elle est refusée plus tard (AUDIOFOCUS_LOSS
).
Demander un focus retardable
Pour créer une requête pouvant être retardée, utilisez AudioFocusRequest.Builder#setAcceptsDelayedFocusGain
:
mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener(); mDelayedFocusRequest = new AudioFocusRequest .Builder(AudioManager.AUDIOFOCUS_GAIN) .setAudioAttributes(mMusicAudioAttrib) .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener) .setForceDucking(false) .setWillPauseWhenDucked(false) .setAcceptsDelayedFocusGain(true) .build();
Ensuite, lorsque vous effectuez la requête, gérez la réponse AUDIOFOCUS_REQUEST_DELAYED
:
int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest); if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // start audio playback return; } if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) { // audio playback delayed to audio focus listener return; }
Lorsque la requête est retardée, l'écouteur de focus est chargé de gérer les modifications de focus:
private final class MediaWithDelayedFocusListener implements OnAudioFocusChangeListener { @Override public void onAudioFocusChange(int focusChange) { synchronized (mLock) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: … // Start focus playback case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: … // Pause media transiently case AudioManager.AUDIOFOCUS_LOSS: … // Stop media
Gestion du ciblage multizone
Pour les véhicules dotés de plusieurs zones audio, la sélection audio est gérée indépendamment pour chaque zone. Par conséquent, une requête envoyée à une zone ne tient pas compte de ce qui maintient la sélection dans d'autres zones, ni ne fait perdre la sélection aux détenteurs de la sélection dans d'autres zones. Ainsi, le focus de la cabine principale peut être géré séparément d'un système de divertissement pour les sièges arrière, ce qui évite d'interrompre la lecture audio dans une zone en raison des changements de focus dans une autre.
Pour toutes les applications, la gestion du focus est gérée automatiquement par CarAudioService
. La zone audio d'une requête de mise au point est déterminée en fonction de son UserId
ou UID
associé. Pour en savoir plus, consultez la section Routage audio.
Demander de l'audio à partir de plusieurs zones simultanément
Si une application souhaite lire de l'audio dans plusieurs zones simultanément, elle doit demander la sélection pour chaque zone en incluant AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
dans le bundle:
// Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID Bundle bundle = new Bundle(); bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID, zoneId); AudioAttributes attributesWithZone = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .addBundle(bundle) .build(); // Create focus request using built attributesWithZone
Ce paramètre de lot permet à l'auteur de la requête de remplacer les mappages automatiques des zones audio pour utiliser l'ID de zone spécifié. Par conséquent, une application peut envoyer des requêtes distinctes pour différentes zones audio.
Priorité audio HAL
À partir d'Android 11, le HAL est désormais autorisé à demander la sélection au nom de flux externes. Bien que facultatives, ces API sont vivement recommandées pour permettre aux sons externes de mieux participer à l'écosystème Android et de fournir une expérience utilisateur plus fluide.
N'oubliez pas que le HAL est toujours responsable de la prise de décision finale concernant les sons qui doivent avoir la priorité. À cet égard, les sons d'urgence et de sécurité critique doivent être diffusés, que le HAL dispose ou non de la priorité audio, et doivent continuer à être diffusés si nécessaire, même si le HAL perd la priorité audio. Il en va de même pour tous les sons requis par la réglementation.
Dans le même ordre d'idées, le HAL doit toujours couper de manière proactive les flux Android, le cas échéant, lorsqu'il diffuse des sons d'urgence ou essentiels à la sécurité pour s'assurer qu'ils sont entendus clairement.
AudioControl@2.0
La version 2.0 de l'HAL AudioControl introduit plusieurs nouvelles API:
API | Objectif |
---|---|
IAudioControl#registerFocusListener |
Enregistre une instance de IFocusListener avec le HAL AudioControl.
Cet écouteur permet au HAL de demander et d'abandonner la priorité audio. Le HAl doit fournir une instance ICloseHandle à utiliser par Android pour annuler l'enregistrement de l'écouteur.
|
IAudioControl#onAudioFocusChange |
Informe le HAL des modifications d'état pour concentrer les requêtes effectuées par le HAL via le IFocusListener . Cela inclut les réponses aux requêtes de mise au point initiales.
|
IFocusListener#requestAudioFocus |
Les requêtes sont ciblées au nom du HAL pour une utilisation, un ID de zone et un type de gain de mise au point spécifiés. |
IFocusListener#abandonAudioFocus |
Abandonne les requêtes de mise au point HAL existantes pour l'utilisation et l'ID de zone spécifiés. |
Le HAL peut recevoir plusieurs requêtes de mise au point en même temps, mais il est limité à une seule requête par utilisation et association d'ID de zone. Notez qu'Android suppose que le HAL commence immédiatement à diffuser des sons pour une utilisation une fois une requête envoyée, et qu'il continue de le faire jusqu'à ce qu'il abandonne la mise au point.
À l'exception de registerFocusListener
, toutes ces requêtes sont oneway
pour s'assurer qu'Android ne retarde pas le HAL pendant le traitement d'une requête de mise au point. Le HAL ne doit pas attendre d'être en mode actif avant de diffuser des sons critiques pour la sécurité. Il est facultatif pour le HAL d'écouter et de répondre aux modifications de la sélection audio via IAudioControl#onAudioFocusChange
, bien que cela soit recommandé le cas échéant.