Antes de iniciar una transmisión lógica, una aplicación debe solicitar el enfoque de audio utilizando los mismos atributos de audio que usará para su transmisión lógica. Si bien se recomienda enviar una solicitud de enfoque de este tipo, el sistema no la impone. Algunas aplicaciones pueden omitir explícitamente el envío de la solicitud para lograr comportamientos específicos (por ejemplo, reproducir sonido intencionalmente durante una llamada telefónica).
Por este motivo, debe considerar el enfoque como una forma de controlar indirectamente la reproducción y resolver conflictos, y no como un mecanismo de control de audio principal; el vehículo no debe depender del sistema de enfoque para el funcionamiento del subsistema de audio.
Interacciones de enfoque
Para satisfacer las necesidades de AAOS, las solicitudes de enfoque de audio se manejan en función de interacciones predefinidas entre el CarAudioContext
de la solicitud y el de los titulares de enfoque actuales. Hay tres tipos de interacciones: exclusivas, de rechazo y concurrentes.
Interacción exclusiva
En las interacciones exclusivas, solo una aplicación puede mantener el foco a la vez. Por lo tanto, se concede el foco a la solicitud de foco entrante mientras que el titular del foco existente pierde el foco. Un ejemplo de esto sería cuando un usuario inicia una nueva aplicación de música mientras la música ya se está reproduciendo en una aplicación existente. Dado que ambos están reproduciendo medios, solo una de las aplicaciones puede mantener el foco a la vez. Como resultado, la solicitud de enfoque de la aplicación recién iniciada volverá con AUDIOFOCUS_REQUEST_GRANTED
y la aplicación que actualmente reproduce música recibirá un evento de cambio de enfoque con un estado de pérdida que corresponde al tipo de solicitud que se realizó. Este es el modelo de interacción más comúnmente visto con Android.
Rechazar interacción
Con las interacciones de rechazo, la solicitud entrante siempre se rechaza. Intentar reproducir música mientras una llamada está en curso es un ejemplo de una interacción rechazada. En este caso, si el marcador tiene actualmente el enfoque de audio para una llamada y una segunda aplicación solicita el enfoque para reproducir música, la aplicación de música recibirá AUDIOFOCUS_REQUEST_FAILED
en respuesta a su solicitud. Dado que se rechaza la solicitud de foco, no se envía ninguna pérdida de foco de ningún tipo al titular del foco actual.
interacción concurrente
Lo más exclusivo de AAOS son las interacciones concurrentes. Esto brinda a las aplicaciones que solicitan el enfoque de audio en el automóvil la capacidad de mantener el enfoque al mismo tiempo que otras aplicaciones. Para que tenga lugar una interacción concurrente, se deben cumplir las siguientes condiciones. Los:
- La solicitud de enfoque entrante debe solicitar
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
. - El titular del foco actual no
setPauseWhenDucked(true)
. - El titular de enfoque actual no opta por recibir eventos de pato.
Si se cumplen estos criterios, la solicitud de enfoque regresará con AUDIOFOCUS_REQUEST_GRANTED
mientras que el titular del enfoque actual no tendrá ningún cambio en el enfoque. Sin embargo, si el titular del foco actual opta por recibir eventos de agacharse o hacer una pausa cuando se agacha, el titular del foco actual perderá el foco al igual que con una interacción exclusiva.
Manejo de flujos simultáneos
Si bien la interacción concurrente tiene muchas aplicaciones útiles, los fabricantes de equipos originales deben encargarse de mezclar y atenuar a nivel de hardware en todos los dispositivos de salida. Debido a esto, se recomienda encarecidamente que los CarAudioContext
solo se enruten al mismo dispositivo de salida que los CarAudioContext
los que no se pueden reproducir simultáneamente. Al tener dispositivos de salida separados para flujos concurrentes, esto permite que el HAL elimine uno de los flujos antes de mezclarlos, o enrutar los flujos físicos a diferentes altavoces en el vehículo. Si los flujos lógicos se mezclan dentro de Android, sus ganancias no se verán alteradas y se entregarán como parte del mismo flujo físico.
Por ejemplo, cuando la navegación y los medios se entregan simultáneamente, la ganancia del flujo de medios podría reducirse (reducirse) temporalmente para que las instrucciones de navegación se escuchen con mayor claridad. Alternativamente, el flujo de navegación podría enrutarse a los altavoces del lado del conductor mientras los medios continúan reproduciéndose en el resto de la cabina.
Matriz de interacción
La siguiente tabla muestra la matriz de interacción definida por CarAudioService
. Las filas representan el CarAudioContext
del titular del foco actual y las columnas representan el de la solicitud entrante.
Mirando un ejemplo, donde una aplicación de medios de música tiene actualmente el foco y un foco de solicitud de la aplicación de navegación, la matriz muestra que las dos interacciones pueden reproducirse simultáneamente, asumiendo que se cumplen los otros criterios para las interacciones simultáneas .
Debido a las interacciones concurrentes, es posible que exista más de un portafoco. En este caso, una solicitud de enfoque entrante se comparará con cada uno de los titulares de enfoque actuales antes de decidir qué tipo de interacción aplicar. En este caso, gana la interacción más conservadora (rechazar, luego excluyente y finalmente concurrente).
En la siguiente tabla, se proporcionan las interacciones de enfoque entre CarAudioContext para una solicitud de enfoque entrante (columnas) y el contexto de los titulares de enfoque existentes (filas). Cada celda representa el tipo de interacción esperado para los dos contextos, donde:
- R: Rechazar interacción
- E: interacción exclusiva
- C: interacción concurrente
Figura 1. Interacciones de enfoque de audio
Navegación durante las llamadas telefónicas
En Android 11, se introdujo una nueva configuración de usuario para permitirles modificar el comportamiento de interacción entre la navegación y las llamadas telefónicas. Cuando se establece, android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL
cambiará la interacción entre las solicitudes de enfoque de NAVIGATION
entrantes y los titulares de enfoque de CALL
actuales de simultáneos a rechazados . Entonces, si un usuario prefiere que las instrucciones de navegación no interrumpan su llamada, puede habilitar esta configuración. Esto persiste para el usuario y se puede configurar dinámicamente para que las solicitudes de enfoque posteriores respeten el nuevo valor de configuración.
Foco de audio retardable
En Android 11, AAOS agregó soporte para solicitar enfoque de audio retrasable. Esto permite que las solicitudes de enfoque no transitorias se retrasen cuando su interacción con los titulares de enfoque actuales normalmente resultaría en su rechazo. Una vez que un cambio en el enfoque da como resultado un estado en el que la solicitud retrasada puede obtener el foco, se concederá la solicitud.
Reglas para solicitudes de enfoque de audio retrasado
- Solo solicitudes no transitorias : como se mencionó anteriormente, una solicitud retrasada solo se puede realizar para fuentes no transitorias. Esto es para evitar que se reproduzca un sonido transitorio mucho después de que sea relevante.
- Solo se puede retrasar una solicitud a la vez : si se realiza una solicitud retrasada cuando ya hay una solicitud retrasada, la solicitud retrasada original recibirá un evento de cambio
AUDIOFOCUS_LOSS
y la nueva solicitud recibirá una respuesta sincrónica deAUDIOFOCUS_REQUEST_DELAYED
. - Las solicitudes retrasables deben tener un
OnAudioFocusChangeListener
. Una vez que se retrasa una solicitud, el oyente se utilizará para notificar al solicitante cuando finalmente se conceda la solicitud (AUDIOFOCUS_GAIN
), o si se rechaza más adelante (AUDIOFOCUS_LOSS
).
Solicitar enfoque diferido
Para crear una solicitud que se pueda retrasar, use AudioFocusRequest.Builder#setAcceptsDelayedFocusGain
:
mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener(); mDelayedFocusRequest = new AudioFocusRequest .Builder(AudioManager.AUDIOFOCUS_GAIN) .setAudioAttributes(mMusicAudioAttrib) .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener) .setForceDucking(false) .setWillPauseWhenDucked(false) .setAcceptsDelayedFocusGain(true) .build();
Luego, al realizar la solicitud, maneje la respuesta 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; }
Cuando la solicitud se retrasa, el oyente de enfoque es responsable de manejar los cambios en el enfoque:
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
Gestión de enfoque multizona
Para vehículos con múltiples zonas de audio, el enfoque de audio se administrará de forma independiente para cada zona. Como tal, una solicitud a una zona no tendrá en cuenta lo que mantiene el foco en otras zonas, ni hará que los titulares de foco en otras zonas pierdan el foco. Con esto, el foco de la cabina principal se puede gestionar de forma separada de un sistema de entretenimiento de los asientos traseros, evitando así interrumpir la reproducción de audio en una zona por los cambios de foco en otra.
Para todas las aplicaciones, CarAudioService
se ocupa automáticamente de la gestión del enfoque. La zona de audio de una solicitud de enfoque se determina en función de su ID de UserId
o UID
asociado. Para obtener más información, consulte Enrutamiento de audio .
Solicitud de audio de varias zonas al mismo tiempo
Si una aplicación quiere reproducir audio en varias zonas al mismo tiempo, debe solicitar el enfoque para cada zona incluyendo AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
en el paquete:
//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
Este parámetro de paquete permite al solicitante anular las asignaciones automáticas de zona de audio para usar en su lugar la ID de zona especificada. Por lo tanto, con esto, una aplicación podría emitir solicitudes separadas para diferentes zonas de audio.
Enfoque de audio HAL
A partir de Android 11, HAL ahora está habilitado para solicitar atención en nombre de transmisiones externas. Si bien son opcionales, se recomienda encarecidamente que estas API permitan que los sonidos externos sean mejores participantes en el ecosistema de Android y brinden una experiencia de usuario más fluida.
Tenga en cuenta que HAL sigue siendo responsable de tomar la decisión final sobre qué sonidos deben tener prioridad. En este sentido, los sonidos críticos para la seguridad y emergencias deben reproducirse independientemente de si la HAL recibe o no el enfoque de audio, y deben seguir reproduciéndose según corresponda, incluso si la HAL pierde el enfoque de audio. Lo mismo es cierto para cualquier sonido requerido por las regulaciones.
Del mismo modo, HAL aún debe silenciar proactivamente las transmisiones de Android según corresponda cuando reproduzca sonidos críticos de emergencia o de seguridad para garantizar que se escuchen con claridad.
AudioControl@2.0
La versión 2.0 de AudioControl HAL presenta varias API nuevas:
API | Objetivo |
---|---|
IAudioControl#registerFocusListener | Registra una instancia de IFocusListener con AudioControl HAL. Este oyente permite que HAL solicite y abandone el enfoque de audio. Se espera que ICloseHandle para que Android la use para anular el registro del agente de escucha. |
IAudioControl#onAudioFocusChange | Notifica a la HAL de los cambios de estado para enfocar las solicitudes realizadas por la HAL a través de IFocusListener . Esto incluye las respuestas a las solicitudes de enfoque iniciales. |
IFocusListener#requestAudioFocus | Solicita el enfoque en nombre de la HAL para un uso específico, un Id. de zona y un tipo de ganancia de enfoque. |
IFocusListener#abandonAudioFocus | Abandona las solicitudes de enfoque de HAL existentes para el uso y el Id. de zona especificados. |
La HAL puede tener múltiples solicitudes de enfoque al mismo tiempo, pero está limitada a una solicitud por emparejamiento de ID de zona y uso. Tenga en cuenta que Android asume que HAL comenzará a reproducir sonidos de inmediato para un uso una vez que se haya realizado una solicitud, y continuará haciéndolo hasta que abandone el foco.
Aparte de registerFocusListener
, todas estas oneway
son una forma de garantizar que Android no retrase la HAL mientras se procesa una solicitud de enfoque. El HAL no debe esperar para enfocarse antes de reproducir sonidos críticos para la seguridad. Es opcional que HAL escuche y responda a los cambios en el foco de audio a través IAudioControl#onAudioFocusChange
, aunque se recomienda cuando sea apropiado.