Partage de l'entrée audio

L'entrée audio provient généralement du micro intégré, d'un micro externe ou d'une interface audio connectée à l'appareil. L'entrée audio peut également provenir d'une conversation téléphonique.

Il arrive que plusieurs applications souhaitent "capturer" la même entrée audio. Ils peuvent effectuer différentes tâches. Par exemple, certaines applications qui reçoivent de l'audio peuvent être en mode "enregistrement", comme un simple enregistreur vocal, tandis que d'autres applications peuvent être en mode "écoute", comme l'Assistant Google ou un service d'accessibilité qui répond aux commandes vocales.

Dans les deux cas, ces applications souhaitent recevoir des entrées audio. Sur cette page, nous utilisons le terme "capture" pour désigner l'enregistrement ou l'écoute par une application.

Si plusieurs applications souhaitent capturer de l'audio en même temps, il peut y avoir un problème de diffusion du signal audio de la même source à toutes les applications. Cette page décrit comment le système Android partage l'entrée audio entre plusieurs applications qui capturent l'audio.

Comportement avant Android 10

Avant Android 10, le flux audio d'entrée ne pouvait être capturé que par une seule application à la fois. Si une autre application enregistrait ou écoutait déjà de l'audio, votre application pouvait créer un objet AudioRecord, mais une erreur était renvoyée lorsque vous appeliez AudioRecord.startRecording() et l'enregistrement ne démarrait pas.

Une exception à cette règle était lorsqu'une application privilégiée (comme l'Assistant Google ou un service d'accessibilité) disposait de l'autorisation android.permission.CAPTURE_AUDIO_HOTWORD et utilisait une source audio de type HOTWORD. Dans ce cas, une autre application peut commencer à enregistrer. Lorsque cela s'est produit, l'application privilégiée s'est arrêtée et la nouvelle application a capturé l'entrée.

Une autre modification a été ajoutée dans Android 9 : seules les applications exécutées au premier plan (ou un service de premier plan) pouvaient capturer l'entrée audio. Lorsqu'une application sans service de premier plan ni composant d'UI de premier plan commençait à enregistrer, elle continuait de fonctionner, mais ne recevait aucun son, même si elle était la seule application à enregistrer de l'audio à ce moment-là.

Comportement d'Android 10

Avant Android 10, le comportement était "premier arrivé, premier servi". Une fois qu'une application commence à enregistrer du contenu audio, aucune autre application ne peut accéder à l'entrée audio tant que l'application qui enregistre le contenu audio ne s'arrête pas.

Android 10 impose un système de priorité qui peut basculer le flux audio d'entrée entre les applications en cours d'exécution. Dans la plupart des cas, si une nouvelle application acquiert l'entrée audio, l'application qui capturait l'audio précédemment continue de s'exécuter, mais reçoit le silence. Dans certains cas, le système peut continuer à diffuser l'audio dans les deux applications. Les différents scénarios de partage sont expliqués ci-dessous.

Ce schéma est semblable à la façon dont la mise au point audio gère plusieurs applications qui se disputent l'utilisation de la sortie audio. Toutefois, la priorité audio est gérée par des requêtes programmatiques pour obtenir et libérer la priorité, tandis que le schéma de commutation d'entrée décrit ici est basé sur une règle de priorisation qui est appliquée automatiquement chaque fois qu'une nouvelle application commence à capturer l'audio.

Pour la capture audio, Android distingue deux types d'applications :

  • Les applications "ordinaires" sont installées par l'utilisateur.
  • Les applications "privilégiées" sont préinstallées sur l'appareil. Cela inclut l'Assistant Google et tous les services d'accessibilité.

De plus, une application est traitée différemment si elle utilise une source audio "sensible à la confidentialité" :CAMCORDER ou VOICE_COMMUNICATION.

Voici les règles de priorité pour l'utilisation et le partage des entrées audio :

  • Les applications privilégiées ont une priorité plus élevée que les applications ordinaires.
  • Les applications dont les UI de premier plan sont visibles ont une priorité plus élevée que les applications en arrière-plan.
  • Les applications qui capturent de l'audio à partir d'une source sensible en termes de confidentialité ont une priorité plus élevée que celles qui ne le font pas.
  • Deux applications ordinaires ne peuvent jamais enregistrer de l'audio en même temps.
  • Dans certains cas, une application privilégiée peut partager l'entrée audio avec une autre application.
  • Si deux applications en arrière-plan de même priorité capturent de l'audio, la dernière lancée a la priorité.

Scénarios de partage

Lorsque deux applications tentent de capturer de l'audio, elles peuvent toutes les deux recevoir le signal d'entrée, ou l'une d'elles peut recevoir le silence.

Il existe quatre scénarios principaux :

  • Assistant + application ordinaire
  • Service d'accessibilité + application ordinaire
  • Deux applications ordinaires
  • Appel vocal + application ordinaire

Assistant + application ordinaire

L'Assistant est une application privilégiée, car il est préinstallé et possède le rôle RoleManager.ROLE_ASSISTANT. Toute autre application préinstallée avec ce rôle est traitée de la même manière.

Android partage l'entrée audio selon les règles suivantes :

  • L'Assistant peut recevoir de l'audio (au premier plan ou en arrière-plan), sauf si une autre application utilisant une source audio sensible en termes de confidentialité est déjà en train de capturer du son.

  • L'application reçoit l'audio, sauf si l'Assistant comporte un composant d'interface utilisateur visible en haut de l'écran.

Notez que les deux applications ne reçoivent l'audio que lorsque l'Assistant est en arrière-plan et que l'autre application ne capture pas l'audio à partir d'une source audio sensible en termes de confidentialité.

Service d'accessibilité + application ordinaire

Un AccessibilityService nécessite une déclaration stricte.

Android partage l'entrée audio selon les règles suivantes :

  • Si l'UI du service est au premier plan, le service et l'application reçoivent tous deux l'entrée audio. Ce comportement offre des fonctionnalités telles que le contrôle d'un appel vocal ou de la capture vidéo avec des commandes vocales.

  • Si le service n'est pas en haut de la pile, ce cas est traité comme le cas ordinaire à deux applications ci-dessous.

Deux applications ordinaires

Lorsque deux applications capturent simultanément, une seule reçoit l'audio et l'autre reçoit le silence.

Android partage l'entrée audio selon les règles suivantes :

  • Si aucune des deux applications n'est sensible à la confidentialité, l'application dont l'UI est au premier plan reçoit l'audio. Si aucune des applications ne possède d'UI, celle qui a lancé la capture reçoit l'audio en dernier.
  • Si l'une des applications est sensible à la confidentialité, elle reçoit l'audio et l'autre application n'entend rien, même si elle dispose d'une UI au-dessus ou a commencé à capturer plus récemment.
  • Si les deux applications sont sensibles à la confidentialité, celle qui a commencé la capture le plus récemment reçoit l'audio et l'autre reçoit le silence.

Appel vocal + application ordinaire

Un appel vocal est actif si le mode audio renvoyé par AudioManager.getMode() est MODE_IN_CALL ou MODE_IN_COMMUNICATION.

Android partage l'entrée audio selon les règles suivantes :

Comportement d'Android 11

Android 11 (niveau d'API 30) respecte le système de priorité d'Android 10 décrit ci-dessus. Il fournit également de nouvelles méthodes dans AudioRecord, MediaRecorder et AAudioStream qui permettent d'activer et de désactiver la possibilité de capturer l'audio simultanément, quel que soit le cas d'utilisation sélectionné.

Voici les nouvelles méthodes :

Lorsque setPrivacySensitive() est défini sur true, le cas d'utilisation de la capture est privé et même un Assistant privilégié ne peut pas effectuer de capture simultanément. Ce paramètre remplace le comportement par défaut qui dépend de la source audio. Par exemple, VOICE_COMMUNICATION est privé par défaut, mais UNPROCESSED ne l'est pas.

Modifications de configuration

Lorsque plusieurs applications capturent de l'audio simultanément, une ou deux d'entre elles seulement sont "actives" (reçoivent de l'audio), tandis que les autres sont mises en sourdine (reçoivent du silence). Lorsque les applications actives changent, le framework audio peut reconfigurer les chemins audio selon les règles suivantes :

  • Le périphérique d'entrée audio de chaque application active peut changer (par exemple, du micro intégré à un casque Bluetooth connecté).
  • Le prétraitement associé à l'application active ayant la priorité la plus élevée est activé. Tout autre prétraitement est ignoré.

Étant donné qu'une application active peut être mise en sourdine lorsqu'une application de priorité supérieure devient active, vous pouvez enregistrer un AudioManager.AudioRecordingCallback sur l'objet AudioRecord ou MediaRecorder pour être averti lorsque la configuration change. Voici les modifications possibles :

  • Capture avec ou sans son
  • Appareil modifié
  • Prétraitement modifié
  • Les propriétés du flux ont été modifiées (taux d'échantillonnage, masque de canal, format d'échantillon).

Vous devez appeler AudioRecord.registerAudioRecordingCallback() avant le début de la capture. Le rappel n'est exécuté que lorsque l'application reçoit de l'audio et qu'un changement se produit.

La méthode onRecordingConfigChanged() renvoie un AudioRecordingConfiguration contenant l'état actuel de la capture audio. Pour en savoir plus sur ce changement, utilisez les méthodes suivantes :

isClientSilenced()
Renvoie la valeur "true" si l'audio renvoyé au client est actuellement mis en sourdine en raison de la règle de capture.
getAudioDevice()
Renvoie le périphérique audio actif.
getEffects()
Renvoie l'effet de prétraitement actif. Notez que l'effet actif peut ne pas être le même que celui renvoyé par getClientEffects() si le client n'est pas l'application active ayant la priorité la plus élevée.
getFormat()
Renvoie les propriétés du flux. Notez que les données audio réelles reçues par le client respectent toujours le format requis renvoyé par getClientFormat(). Le framework effectue automatiquement le rééchantillonnage, la conversion de canal et de format nécessaires, du format utilisé au niveau de l'interface matérielle vers le format spécifié par le client.
AudioRecord.getActiveRecordingConfiguration().
Renvoie la configuration de l'enregistrement actif.

Vous pouvez obtenir une vue générale de tous les enregistrements actifs sur l'appareil en appelant AudioManager.getActiveRecordingConfigurations().