Foco de audio

Antes de iniciar una transmisión lógica, una app solicita el foco de audio con los mismos atributos de audio que se usan para la transmisión lógica. La app debe respetar las pérdidas de foco para funcionar como se espera en los casos de uso automotriz.

Si bien se recomienda enviar una solicitud de foco, el sistema no la aplica de forma forzosa. Por lo tanto, considera el foco como un medio para controlar indirectamente y evitar conflictos durante la reproducción, en lugar de como un mecanismo de control de audio principal. El vehículo no debe depender del sistema de foco para el funcionamiento del subsistema de audio.

Interacciones de enfoque

Para admitir AAOS, las solicitudes de foco de audio se controlan en función de las interacciones predefinidas entre el CarAudioContext de la solicitud y el de los titulares de foco actuales. Existen tres tipos de interacciones:

  • Exclusivo
  • Rechazar
  • Concurrent

Interacción exclusiva

Este es el modelo de interacción que se usa con más frecuencia en Android.

En las interacciones exclusivas, solo se permite que una app mantenga el foco a la vez. Por lo tanto, se otorga el foco a una solicitud de foco entrante mientras que el titular de foco existente lo pierde. Como ambas apps reproducen contenido multimedia, solo se permite que una mantenga el foco. Como resultado, la solicitud de foco de la app recién iniciada se muestra con AUDIOFOCUS_REQUEST_GRANTED, mientras que la app de música que se está reproduciendo actualmente recibe un evento de cambio de foco con un estado de pérdida que corresponde al tipo de solicitud que se realizó.

Interacción de rechazo

Con las interacciones de rechazo, la solicitud entrante siempre se rechaza. Por ejemplo, cuando se intenta reproducir música mientras hay una llamada en curso. En este caso, si el marcador mantiene el foco de audio para una llamada y una segunda app solicita el foco para reproducir música, la app de música recibe AUDIOFOCUS_REQUEST_FAILED en respuesta a la solicitud. Como se rechaza la solicitud de foco, no se envía ninguna pérdida de foco al titular de foco actual.

Interacción concurrent

Las interacciones concurrent son exclusivas de AAOS. Esto les brinda a las apps que solicitan el foco de audio en el automóvil la capacidad de mantener el foco de forma simultánea con otras apps. Para que se produzca una interacción concurrent, se deben cumplir las siguientes condiciones. La

Si se cumplen estos criterios, la solicitud de foco se muestra con AUDIOFOCUS_REQUEST_GRANTED, mientras que el titular de foco actual no tiene ningún cambio en el foco. Sin embargo, si el titular de foco actual elige recibir eventos de ducking o pausar cuando se realiza el ducking, el titular de foco actual pierde el foco, como ocurre con una interacción exclusiva.

Cómo controlar transmisiones concurrentes

Si bien la interacción concurrent tiene varios usos, ten cuidado con la mezcla y el ducking a nivel de hardware en los dispositivos de salida. Te recomendamos que las instancias de CarAudioContext que pueden reproducirse de forma simultánea se enruten a diferentes dispositivos de salida.

Al tener dispositivos de salida independientes para las transmisiones concurrentes, se permite que la HAL realice el ducking de una de las transmisiones antes de mezclarlas o que enrute las transmisiones físicas a diferentes bocinas del vehículo. Si las transmisiones lógicas se mezclan en Android, las ganancias no se modifican y se entregan como parte de la misma transmisión física.

Por ejemplo, cuando la navegación y el contenido multimedia se entregan de forma simultánea, la ganancia de la transmisión de contenido multimedia se puede reducir temporalmente (o ducking) para que las instrucciones de navegación se puedan escuchar con mayor claridad. Como alternativa, la transmisión de navegación se puede enrutar a las bocinas del lado del conductor mientras el contenido multimedia continúa reproduciéndose en el resto de la cabina.

Matriz de interacción

En esta tabla, se muestra la matriz de interacción definida por CarAudioService. Cada fila representa el CarAudioContext del titular de foco actual, y cada columna representa el de la solicitud entrante.

Por ejemplo, cuando una app de contenido multimedia de música mantiene el foco mientras una app de navegación solicita el foco, la matriz indica que las dos interacciones pueden reproducirse de forma simultánea, suponiendo que se cumplan los otros criterios para las interacciones concurrentes.

Debido a las interacciones concurrentes, es posible tener más de un titular de foco. En este caso, una solicitud de foco entrante se compara con cada uno de los titulares de foco actuales antes de determinar qué interacción aplicar. En este caso, gana la interacción más conservadora. Rechazar, luego exclusivo y, por último, concurrent.

Matriz de interacción del foco de audio

Figura 1: Matriz de interacción de foco de audio

En Android 11, se introdujo un nuevo parámetro de configuración del usuario para permitir que los usuarios modifiquen 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 cambia la interacción entre las solicitudes de foco NAVIGATION entrantes y los titulares de foco CALL actuales de concurrent a rechazos. Si un usuario prefiere que las instrucciones de navegación no interrumpan una llamada, puede habilitar el parámetro de configuración. Esto se conserva para el usuario y se puede configurar de forma dinámica para que las solicitudes de foco posteriores respeten el nuevo parámetro de configuración.

Foco de audio demorable

En Android 11, AAOS agregó compatibilidad para solicitar el foco de audio demorable. Esto permite que las solicitudes de foco no transitorias se demoren cuando su interacción con los titulares de foco actuales normalmente haría que se rechazaran. Una vez que un cambio en el foco da como resultado un estado en el que la solicitud demorada puede obtener el foco, se otorga la solicitud.

Reglas para las solicitudes de foco de audio demoradas

  • Solo solicitudes no transitorias. Solo se puede realizar una solicitud demorada para fuentes no transitorias para evitar que se reproduzca un sonido transitorio mucho después de que sea relevante.

  • Solo se puede demorar una solicitud a la vez. Si se realiza una solicitud demorable mientras ya hay una solicitud demorada, la solicitud demorada original recibe un evento de cambio AUDIOFOCUS_LOSS, y la nueva solicitud recibe una respuesta síncrona de AUDIOFOCUS_REQUEST_DELAYED.

  • Las solicitudes demorables deben tener OnAudioFocusChangeListener. Después de que se demora una solicitud, el objeto de escucha se usa para notificar al solicitante cuando finalmente se otorga la solicitud (AUDIOFOCUS_GAIN) o si se rechaza más tarde (AUDIOFOCUS_LOSS).

Solicita foco demorable

Para compilar una solicitud que se pueda demorar, haz lo siguiente:

  1. Usa AudioFocusRequest.Builder#setAcceptsDelayedFocusGain.

    mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();
    
    mDelayedFocusRequest = new AudioFocusRequest
         .Builder(AudioManager.AUDIOFOCUS_GAIN)
         .setAudioAttributes(mMusicAudioAttrib)
         .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
         .setForceDucking(false)
         .setWillPauseWhenDucked(false)
         .setAcceptsDelayedFocusGain(true)
         .build();
    
  2. Cuando realices la solicitud, controla 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;
    }
    
  3. Cuando se demora la solicitud, el objeto de escucha de foco controla los cambios en el foco:

    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
    

Fundido aplicado por el sistema

Android 15 introduce el fundido de audio aplicado por el sistema en AAOS. En Android, el sistema no aplica el foco de audio de forma forzosa. Por lo tanto, si bien se recomienda a los desarrolladores de apps que cumplan con los lineamientos de foco de audio, si una app continúa reproduciendo contenido a un volumen alto, incluso después de haber perdido el foco de audio, el sistema no puede evitarlo.

En los entornos automotrices de seguridad crítica, el cumplimiento del foco de audio es fundamental para minimizar la distracción del conductor. Con esta función, el framework de audio ahora aplica automáticamente un fundido de salida en las apps que pierden el foco de audio para brindar una experiencia de audio más controlada y predecible.

Esta mejora ayuda a garantizar que las apps cumplan con la decisión de pérdida de foco de audio según lo definido por la matriz de interacción, lo que evita conflictos de reproducción de audio.

Diseño de alto nivel

En la siguiente figura, se muestra el diseño de alto nivel y la compatibilidad con la función de pérdida de foco en los automóviles:

Diseño de alto nivel para la función de atenuación aplicada por el sistema

Figura 2: Diseño de alto nivel para la función de fundido aplicado por el sistema

  • Fundido objetivo: La aplicación forzosa del sistema del fundido en Android 15 está diseñada específicamente para situaciones en las que una app pierde el foco de audio, pero continúa reproduciendo audio.
  • Mecanismo de fundido de salida: Cuando una app pierde el foco de audio en una app nueva que lo solicita, sucede lo siguiente:
    • El framework de audio aplica automáticamente un fundido de salida en el audio de la app que pierde el foco.
    • Después del fundido de salida, el sistema silencia la transmisión de audio.
    • Luego, la app recibe una notificación de pérdida de foco de audio.
    • Las apps con comportamiento inadecuado se silencian hasta que recuperan el foco de audio.
    • La lógica predeterminada es aplicar un fundido de entrada en las apps que se desvanecen después de 2 segundos. Sin embargo, los OEMs pueden configurar esto en cualquier valor de tiempo de espera.
    • El framework de audio usa las configuraciones de OEM para las operaciones de fundido de salida y de entrada.
  • Archivo de configuración de OEM: Android 15 incluye un nuevo archivo de configuración, car_audio_fade_configuration.xml:

    • Este archivo permite que los OEMs definan criterios para cuando se aplica la aplicación forzosa del foco de audio del sistema a una app que pierde el foco.
    • El framework de audio aplica el fundido de salida y el silencio solo si la app que pierde el foco coincide con las reglas definidas por el OEM en este archivo XML.
    • Esto proporciona un mecanismo para que los OEMs personalicen el comportamiento de la función en función de las características de la app o los tipos de uso de audio.
  • Control de funciones con RRO: Se introdujo una nueva marca de función de superposición de recursos en tiempo de ejecución (RRO), audioUseFadeManagerConfiguration, para habilitar o inhabilitar esta función:

    • La función está inhabilitada de forma predeterminada.
    • Para activar la pérdida de foco de audio aplicada por el sistema, los OEMs deben establecer esta marca en true.
    • Si bien el framework de audio del automóvil espera definiciones de configuración de fundido válidas cuando la marca está habilitada, la ausencia de esas definiciones no genera automáticamente una excepción fatal.
    • Todas las apps de las configuraciones de fundido deben tener definiciones de fundido coincidentes. Es un error fatal llamar a una configuración de fundido (por su nombre) como parte de la configuración de audio del automóvil sin proporcionar una definición válida.
    • Cuando la marca está inhabilitada, se ignoran todas las definiciones de configuración de fundido y las referencias de configuración.

Configuración del administrador de fundido

El framework de audio de Android 15 introduce un FadeManagerConfiguration unificado para proporcionar a los OEMs un control detallado sobre el comportamiento de fundido de audio. Este framework se ilustra en la Figura 3:

Configuración del administrador de atenuación

Figura 3: Configuración del administrador de fundido

Esta configuración incluye lo siguiente:

  • Propiedades de transición de atenuación: Parámetros de configuración para el fundido de salida y de entrada
    • Se puede definir con usos o atributos de audio específicos.
    • Permite parámetros de configuración de duración personalizados.
    • Estos parámetros de configuración se usan para construir VolumeShaper.Configuration.
  • Políticas de fundido: Reglas que rigen cuándo se produce el fundido
    • Un botón de activación global para habilitar o inhabilitar el fundido
    • Una lista configurable de usos de audio que se pueden fundir (aptos para el fundido de salida cuando se pierde el foco)
    • Las listas de exclusión (no fundibles) evitan que se desvanezcan las fuentes de audio críticas o designadas. Estas listas pueden basarse en lo siguiente:
      • Tipos de contenido
      • Atributos de audio
      • UIDs de la app (solo se pueden configurar durante el tiempo de ejecución)

Configuraciones de OEM

En esta sección, analizamos las personalizaciones de OEM disponibles.

Archivo XML de configuración de fundido de audio del automóvil

Android 15 introduce un nuevo archivo de configuración, car_audio_fade_configuration.xml, que permite una amplia personalización de OEM del comportamiento de fundido de salida de audio durante la pérdida de foco.

  • Este archivo XML permite la definición de varias configuraciones de fundido distintas, cada una de las cuales requiere un nombre único para la referencia cruzada dentro de car_audio_configuration.xml.
  • Estas configuraciones se pueden aplicar de manera flexible en diferentes zonas de audio y configuraciones de zona.
  • En particular, cada configuración de fundido solo acepta valores de duración en milisegundos, que el sistema usa para generar internamente el correspondiente VolumeShaper.Configuration.

Para obtener orientación práctica sobre la implementación, consulta las configuraciones de ejemplo proporcionadas para el emulador ubicado en device/generic/car/emulator/audio/car_audio_fade_configuration.xml.

Archivo XML de configuración de audio del automóvil

Android 15 introduce un archivo car_audio_configuration.xml actualizado, ahora en la versión 4, que incorpora las nuevas etiquetas applyFadeConfigs y fadeConfig. La etiqueta applyFadeConfigs puede contener varias definiciones de fadeConfig, lo que permite una configuración de fundido flexible. Cada definición:

  • Debe incluir un fadeConfig predeterminado designado con isDefault = true.
  • Puede incluir varias definiciones de fadeConfig transitorias. Estas configuraciones transitorias se aplican específicamente durante las interacciones de pérdida de foco de audio y solo cuando la app que obtiene el foco de audio coincide con los criterios definidos en la configuración transitoria.

Para obtener orientación práctica sobre la implementación, consulta las configuraciones de ejemplo proporcionadas para el emulador ubicado en device/generic/car/emulator/audio/car_audio_configuration.xml.

Extensión de servicio de foco de audio del automóvil de OEM

Los OEMs que implementan un servicio de foco de audio del automóvil personalizado tienen la flexibilidad de configurar los parámetros de configuración de fundido de audio incluyéndolos en OemCarAudioFocusResult. Esto se puede lograr con el método del compilador setAudioAttributesToCarAudioFadeConfigurationMap():

/** @see OemCarAudioFocusResult#getAudioAttributesToCarAudioFadeConfigurationMap() **/
@NonNull
public Builder setAudioAttributesToCarAudioFadeConfigurationMap(@NonNull
        Map<AudioAttributes, CarAudioFadeConfiguration> attrsToCarAudioFadeConfig) {
}

En particular, los OEMs pueden elegir usar parámetros de configuración de fundido preconfigurados en el momento del arranque o aplicar configuraciones de forma dinámica a través de su servicio de foco de audio personalizado, lo que ofrece un control adaptable.

Diagrama de secuencia

En este diagrama de secuencia, se ilustra el comportamiento después de otorgar el foco de audio a App2 y la pérdida posterior del foco de audio por parte de App1:

  • Cuando el servicio de audio del automóvil envía la pérdida de foco de audio a App1, la reproducción del reproductor App1 se somete a un fundido de salida según lo definen los FadeManagerConfigurations activos. Una vez que se completa la operación de fundido de salida, App1 recibe la devolución de llamada de pérdida de foco de audio estándar.
  • De manera opcional, el audio de App1 se puede volver a fundir después de una duración configurable. Los OEMs tienen la flexibilidad de establecer esta duración a través de Builder#setFadeInDurationForUsage(int, long) según los requisitos específicos de sus productos.

Diagrama de secuencia de la función de atenuación de audio del automóvil

Figura 4: Diagrama de secuencia para la función de fundido de audio del automóvil

Administración de foco en varias zonas

En el caso de los vehículos con varias zonas de audio, el foco de audio se administra de forma independiente para cada zona. Por lo tanto, una solicitud a una zona no tiene en cuenta lo que mantiene el foco en otras zonas, ni hace que los titulares de foco en otras zonas pierdan el foco. Con esto, el foco de la cabina principal se puede administrar por separado de un sistema de entretenimiento en el asiento trasero, lo que no interrumpe la reproducción de audio en una zona por los cambios realizados en el foco de otra.

Para todas las apps, CarAudioService administra el foco automáticamente. La zona de audio de una solicitud de foco se determina por su UserId o UID asociado (para obtener más detalles, consulta Enrutamiento de audio en varias zonas).

Solicita audio de varias zonas de forma simultánea

Si una app quiere reproducir audio en varias zonas de forma simultánea, debe solicitar el foco 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 que el solicitante anule las asignaciones automáticas de zonas de audio para usar el ID de zona especificado. Por lo tanto, una app podría emitir solicitudes independientes para diferentes zonas de audio.

Foco de audio de HAL

A partir de Android 11, la HAL está habilitada para solicitar el foco en nombre de las transmisiones externas. Si bien es opcional, se recomienda usar estas APIs para permitir que los sonidos externos sean participantes óptimos en el ecosistema de Android y proporcionar una experiencia del usuario sin problemas.

La HAL toma la decisión final sobre qué sonidos deben tener prioridad. En este sentido, los sonidos de emergencia y de seguridad crítica deben reproducirse independientemente de si se otorga o no el foco de audio a la HAL, y deben seguir reproduciéndose según corresponda, incluso si la HAL pierde el foco de audio. Lo mismo sucede con los sonidos que requieren las reglamentaciones gubernamentales.

La HAL debe silenciar de forma proactiva las transmisiones de Android según corresponda cuando reproduzca sonidos de emergencia o de seguridad crítica para garantizar que se escuchen con claridad.

AudioControl@2.0

La versión 2.0 de AudioControl HAL introduce estas nuevas APIs:

API Objetivo
IAudioControl#registerFocusListener Registra una instancia de IFocusListener con la HAL de AudioControl. Este objeto de escucha permite que la HAL solicite y abandone el foco de audio. La HAL proporciona una instancia de ICloseHandle para que Android la use para cancelar el registro del objeto de escucha.
IAudioControl#onAudioFocusChange Notifica a la HAL los cambios de estado en las solicitudes de foco realizadas por la HAL a través de IFocusListener, incluidas las respuestas a las solicitudes de foco iniciales.
IFocusListener#requestAudioFocus Solicita el foco en nombre de la HAL para un uso, un ID de zona y un tipo de ganancia de foco especificados.
IFocusListener#abandonAudioFocus Abandona las solicitudes de foco de HAL existentes para el uso y el ID de zona especificados.

La HAL puede tener varias solicitudes de foco al mismo tiempo, pero se limita a una solicitud por uso y par de ID de zona. Android supone que la HAL comienza a reproducir sonidos de inmediato para un uso una vez que se realiza una solicitud y continúa haciéndolo hasta que abandona el foco.

Además de registerFocusListener, estas solicitudes son oneway para garantizar que Android no demore la HAL mientras se procesa una solicitud de foco. La HAL no debe esperar a obtener el foco antes de reproducir sonidos de seguridad crítica. Es opcional que la HAL escuche y responda a los cambios en el foco de audio a través de IAudioControl#onAudioFocusChange.

Servicio de foco de audio del automóvil de OEM

En Android 14, AAOS introdujo los servicios de complementos de OEM del automóvil para habilitar la capacidad de configuración de algunos componentes del automóvil. En el caso del servicio de complementos de audio del automóvil , el servicio de complementos permite que los OEMs administren las solicitudes de foco interceptadas por el servicio de audio del automóvil. Esto les brinda a los OEMs más flexibilidad en cuanto a la administración del foco según lo requieren las reglas y reglamentaciones. Por lo tanto, la interacción de foco de audio puede diferir entre los fabricantes y de una región a otra. La premisa básica para el foco de audio sigue siendo la misma: las apps deben solicitar el foco para administrar mejor el audio y mejorar la experiencia del usuario. En general, se siguen aplicando ciertas reglas para la solicitud de foco de audio por parte de las apps:

  • Sin ninguna prioridad, foco de audio de alta prioridad (incluida una llamada telefónica, una alerta de emergencia o una notificación de seguridad), las apps deberían poder obtener el foco de audio de forma transitoria o permanente.

  • Mientras un foco de contenido multimedia esté activo, sucederá lo siguiente:

    • Las apps que solicitan el foco de uso de llamadas deberían poder recibir la llamada de forma simultánea o exclusiva.

    • Las apps que solicitan el foco de uso de navegación deberían poder recibir el foco de navegación de forma simultánea o exclusiva.

    • Las apps que solicitan el foco de uso del Asistente deberían poder recibir el foco de uso de forma simultánea o exclusiva.

  • Mientras las apps de foco de audio de alta prioridad (incluida una llamada telefónica, una alerta de emergencia o una notificación de seguridad) estén activas, se debe otorgar o demorar cualquier solicitud de foco de audio entrante según sea necesario.

Si bien estas sugerencias no son exhaustivas, pueden ayudar a las apps que solicitan el foco a obtenerlo si no existen sonidos activos de alta prioridad. Incluso mientras los sonidos de alta prioridad estén activos, se deben respetar las solicitudes de foco demoradas y se debe poder obtener el foco cuando se detenga el sonido de alta prioridad.