Enrutamiento de audio

En Android 10, car_audio_configuration.xml reemplaza car_volumes_groups.xml y IAudioControl.getBusForContext. En el archivo de configuración nuevo, se define una lista de zonas. Cada zona tiene uno o más grupos de volúmenes con sus dispositivos asociados, y cada dispositivo tiene los contextos se debe enrutar dentro de esa zona. Es obligatorio que todos los contextos estén representados dentro de cada zona.

Configura el enrutamiento de audio

Los archivos de políticas de audio, que suelen estar en la partición del proveedor, representan la configuración de hardware de audio de la placa. Todos los dispositivos a los que se hace referencia en car_audio_configuration.xml debe definirse dentro del audio_policy_configuration.xml

Habilita el enrutamiento de AAOS

Para utilizar el enrutamiento basado en AAOS, debe establecer el Marca audioUseDynamicRouting para true:

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

Con false, el enrutamiento y la mayor parte de CarAudioService se inhabilitarán y el SO volverá al comportamiento predeterminado de AudioService.

Zona principal

De forma predeterminada, todo el audio se enrutará a la zona principal. Solo puede haber ser una zona principal, lo que se indica en la configuración por el atributo isPrimary="true"

Configuración de ejemplo

Por ejemplo, un vehículo podría tener dos zonas: una principal y un asiento trasero. un sistema de entretenimiento. De esta forma, un posible car_audio_configuration.xml se definiría de la siguiente manera:

<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>

Aquí, la zona principal separó contextos para distintos dispositivos. Esto permite La HAL para aplicar diferentes efectos de procesamiento posterior y mezclar en cada salida del dispositivo usando el hardware del vehículo. Los dispositivos se organizaron en cuatro grupos de volúmenes: contenido multimedia, navegación, llamadas y alarmas. Si el sistema está configurado para useFixedVolume, se pasarán los niveles de volumen de cada grupo en la HAL para aplicarla a la salida de estos dispositivos.

Para la zona secundaria, la salida esperada es a través de un solo dispositivo de salida. En este ejemplo, todos los usos se enrutan al dispositivo único y al grupo de volúmenes para simplifican las cosas.

Configuración de audio de la zona ocupada

En Android 11, se amplió car_audio_configuration.xml a introducir dos campos nuevos, audioZoneId y occupantZoneId. El primero, audioZoneId, se puede usar para controlar mejor la administración de zonas. Por otro lado, se puede usar occupantZoneId para configurar un conjunto de datos basado de alto rendimiento.

Para usar estos campos nuevos, se aplica la V2 de car_audio_configuration.xml como en los productos necesarios. Revisión de la configuración de audio anterior, pero utilizando el nuevo campo para asignación de ID de zona de ocupante e ID de zona de audio, la nueva configuración sin volumen Las definiciones de grupos se pueden configurar de la siguiente manera:

<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 configuración anterior define una asignación de la zona principal a la zona de ocupación 0. audioZoneId 1 a occupantZoneId 1. En general, cualquier asignación entre la zona de ocupación y la zona de audio, pero la asignación debe ser de uno a uno. Estas son las reglas que definieron los dos campos nuevos:

  • El audioZoneId de la zona principal siempre es cero.
  • No se pueden repetir los números de audioZoneId y occupantZoneId
  • audioZoneId y occupantZoneId solo pueden tener una asignación de uno a uno

Enrutamiento a través de un UID de aplicación

Se introdujo una serie de APIs ocultas en CarAudioManager en 10 para permitir que las apps para consultar y configurar zonas de audio y foco.

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

Las APIs anteriores permitieron que una aplicación propia administrara el enrutamiento de audio en el UID de una aplicación. Tanto el ID de zona de audio como el UID de la aplicación también es necesario. Con esa información a mano, el enrutamiento de audio se puede configurar con el API de CarAudioManager#setZoneIdForUid.

Cambia las zonas de una app

De forma predeterminada, todos los audios se enrutan a la zona principal. Para actualizar una aplicación enrutado a una zona diferente, usa 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 Nota: Las transmisiones y el enfoque no pueden cambiar de zona de forma dinámica. Por lo tanto, Para cambiar de zona, se debe detener la reproducción y volver a solicitar el enfoque.

Enrutamiento con ID de usuario

Si bien el enrutamiento basado en UID de una aplicación permite el control fino de la interfaz de usuario enrutamiento de audio, también requiere que el enrutamiento de audio para cada aplicación se defina antes a la aplicación solicitando foco de audio y reproduciendo audio. Para mitigar esto y facilitan aún más que las aplicaciones de terceros reproduzcan audio sin modificaciones, CarAudioService usa la zona de ocupación del vehículo y la asignación de zonas de audio para definir el enrutamiento basado en ID de usuario. De esta forma, cuando el usuario acceda a la zona de ocupación, el audio del auto de Google Cloud. Con esta señal, el enrutamiento y la administración del foco de audio se para todas las zonas de audio.

El enrutamiento basado en UID de aplicaciones aún puede utilizarse, pero debe hacerse independientemente de enrutamiento de IDs de usuario. Esto significa que si la zona de ocupación y la asignación de zonas de audio del vehículo están definido, se inhabilita el enrutamiento basado en UID y se intenta llamar CarAudioManager#setZoneidForUid arrojará un error.

Por su parte, el enrutamiento de audio y la administración del foco se simplificó con la zona de ocupación del usuario, aún se debe asignar a una zona de ocupación. Esto se puede hacer con CarOccupantZoneManager#assignProfileUserToOccupantZone. Esta La API requiere permiso para administrar usuarios. Se espera que los OEMs administren asignación de usuario a zona de ocupación a través de algún tipo de IU del sistema. Una vez que se haya completado la aplicación el lanzamiento, el enrutamiento de audio y la administración del foco se configurarán automáticamente para el usuario.

Enrutamiento con setPreferredDevice

Además de los cambios anteriores, Android 11 también tiene una nueva API para consultar dispositivos de salida asociado a cada zona, CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage).

La API se puede usar para consultar un dispositivo de salida para una zona en particular y un atributo de audio de uso de la nube. De esta manera, las aplicaciones propias pueden enrutar el audio a diferentes zonas al con la API de setPreferredDevice del jugador. El La API de getOutputDeviceForUsage requiere PERMISSION_CAR_CONTROL_AUDIO_SETTINGS y es una API del sistema. A continuación, se incluye una ejemplo de búsqueda del dispositivo de medios para una zona en particular y enrutamiento a ese dispositivo con la API de setPreferredDevice.

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