Enrutamiento de audio

En Android 10, car_audio_configuration.xml reemplaza car_volumes_groups.xml e IAudioControl.getBusForContext . En el nuevo archivo de configuración, 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 que deben enrutarse dentro de esa zona. Se requiere que todos los contextos estén representados dentro de cada zona.

Configuración de enrutamiento de audio

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

Habilitación del enrutamiento AAOS

Para usar el enrutamiento basado en AAOS, debe configurar el indicador audioUseDynamicRouting en true :

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

Cuando es false , el enrutamiento y gran parte de CarAudioService se desactivarán y el sistema operativo volverá al comportamiento predeterminado de AudioService .

zona primaria

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

Ejemplo de configuración

Por ejemplo, un vehículo podría tener dos zonas: una zona principal y un sistema de entretenimiento en el asiento trasero. Con eso, un posible car_audio_configuration.xml quedaría definido 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 tiene contextos separados para diferentes dispositivos. Esto permite que HAL aplique diferentes efectos de posprocesamiento y mezcla en la salida de cada dispositivo utilizando el hardware del vehículo. Los dispositivos se han organizado en cuatro grupos de volumen: multimedia, navegación, llamadas y alarmas. Si el sistema está configurado para usar un volumen useFixedVolume , los niveles de volumen de cada grupo se pasarán a la HAL para aplicarlos 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 único dispositivo y grupo de volúmenes para simplificar las cosas.

Configuración de audio de la zona de ocupación

En Android 11, car_audio_configuraton.xml se amplió aún más para introducir dos nuevos campos, audioZoneId y occupantZoneId . El primero, audioZoneId , se puede utilizar para controlar mejor la gestión de zonas. Por otro lado, occupantZoneId se puede usar para configurar el enrutamiento basado en ID de usuario.

Para usar estos nuevos campos, se requiere V2 de car_audio_configuration.xml . Revisando la configuración de audio anterior pero utilizando el nuevo campo para la identificación de la zona del ocupante y el mapeo de la identificación de la zona de audio, la nueva configuración sin las definiciones del grupo de volumen se puede configurar como:

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

  • El audioZoneId para la zona principal siempre es cero
  • Los números de audioZoneId y occupantZoneId no se pueden repetir
  • audioZoneId y occupantZoneId solo pueden tener un mapeo uno a uno

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

Se introdujeron una serie de API ocultas en CarAudioManager en 10 para permitir que las aplicaciones consulten y establezcan zonas de audio y enfoque.

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

Las API anteriores permitieron que una aplicación propia administrara el enrutamiento de audio en función del UID de una aplicación. Como tal, también se necesita tanto el ID de la zona de audio como el UID de la aplicación. Con esa información a mano, el enrutamiento de audio se puede configurar mediante la API CarAudioManager#setZoneIdForUid .

Cambio de zonas para una aplicación

De forma predeterminada, todas las rutas de audio a la zona principal. Para actualizar una aplicación para que se enrute a una zona diferente, use 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 secuencias y el enfoque no pueden cambiar de zona dinámicamente. Por lo tanto, se debe detener la reproducción y volver a solicitar el enfoque para cambiar de zona.

Enrutamiento con ID de usuario

Si bien el enrutamiento basado en UID de una aplicación permite un control preciso del enrutamiento de audio de cada aplicación, también requiere que se defina el enrutamiento de audio para cada aplicación antes de que la aplicación realmente solicite el enfoque de audio y reproduzca audio. Para mitigar este problema y facilitar aún más que las aplicaciones de terceros reproduzcan audio sin modificaciones, CarAudioService utiliza la zona del ocupante del automóvil y el mapeo de la zona de audio para definir el enrutamiento basado en la identificación del usuario. De esta manera, cuando un usuario inicia sesión en la zona de ocupantes, se notifica al servicio de audio del automóvil. Con esta señal, la gestión y el enrutamiento del enfoque de audio se configuran automáticamente para todas las zonas de audio.

El enrutamiento basado en UID de aplicaciones todavía se puede usar, pero debe hacerse independientemente del enrutamiento de ID de usuario. Esto significa que si se define la asignación de zona de ocupante a zona de audio del automóvil, el enrutamiento basado en UID está deshabilitado y al intentar llamar a CarAudioManager#setZoneidForUid arrojará un error.

Si bien el enrutamiento de audio y la gestión del enfoque se han simplificado con la gestión de zonas de ocupantes, el usuario aún debe estar asignado a una zona de ocupantes. Esto se puede hacer usando CarOccupantZoneManager#assignProfileUserToOccupantZone . Esta API requiere permiso para administrar usuarios. La expectativa actual es que los OEM administren la asignación de zona de usuario a ocupante a través de algún tipo de interfaz de usuario del sistema. Una vez hecho esto, el inicio de la aplicación, el enrutamiento de audio y la gestión del enfoque se configurarán automáticamente para el usuario.

Enrutamiento con setPreferredDevice

Junto con los cambios anteriores, Android 11 también tiene una nueva API para consultar los dispositivos de salida asociados con cada zona, CarAudioManager#getOutputDeviceForUsage(int zoneId, int use).

La API se puede usar para consultar un dispositivo de salida para una zona en particular y el uso de un atributo de audio. De esta manera, las aplicaciones propias pueden enrutar el audio a diferentes zonas utilizando la API setPreferredDevice del reproductor. La API getOutputDeviceForUsage requiere PERMISSION_CAR_CONTROL_AUDIO_SETTINGS y es una API del sistema. A continuación se muestra un ejemplo de cómo encontrar el dispositivo de medios para una zona en particular y enrutar a ese dispositivo usando la API setPreferredDevice .

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