Roteamento de áudio

No Android 10, car_audio_configuration.xml substitui car_volumes_groups.xml e IAudioControl.getBusForContext. No novo arquivo de configuração, uma lista de zonas é definida. Cada zona tem um ou mais grupos de volumes com os dispositivos associados, e cada dispositivo tem os contextos que precisam ser roteados dentro dessa zona. É obrigatório que todos os contextos sejam representados em cada zona.

Como configurar o roteamento de áudio

Os arquivos de política de áudio, que normalmente ficam na partição do fornecedor, representam a configuração do hardware de áudio da placa. Todos os dispositivos referenciados em car_audio_configuration.xml precisa ser definido no audio_policy_configuration.xml.

Como ativar o roteamento AAOS

Para usar o roteamento baseado no AAOS, você precisa definir a Sinalização audioUseDynamicRouting para true:

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

Quando false, o roteamento e grande parte de CarAudioService serão desabilitados e o SO vai retornar ao comportamento padrão do AudioService.

Zona principal

Por padrão, todo o áudio será roteado para a zona principal. Só é possível ser uma zona principal, o que é indicado na configuração pelo atributo isPrimary="true":

Exemplo de configuração

Por exemplo, um veículo pode ter duas zonas: uma principal e um banco traseiro no sistema de entretenimento. Com isso, um possível car_audio_configuration.xml é definida da seguinte maneira:

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

Aqui, a zona principal separou contextos para dispositivos diferentes. Isso permite a HAL para aplicar diferentes efeitos de pós-processamento e mixagem em cada saída do dispositivo. usando o hardware do veículo. Os dispositivos foram organizados em quatro grupos de volumes: mídia, navegação, chamadas e alarmes. Se o sistema estiver configurado para useFixedVolume, os níveis de volume de cada grupo serão transmitidos na HAL para aplicar à saída desses dispositivos.

Para a zona secundária, a saída esperada é de um único dispositivo de saída. Neste exemplo, todos os usos são roteados para o único dispositivo e grupo de volumes para manter as coisas simples.

Configuração de áudio da zona de ocupante

No Android 11, o car_audio_configuration.xml foi expandido ainda mais para introduzir dois novos campos, audioZoneId e occupantZoneId. A primeira, audioZoneId, pode ser usada para controlar melhor o gerenciamento das zonas. Por outro lado, occupantZoneId pode ser usado para configurar configurações de ID do usuário e roteamento de alto desempenho.

Para usar esses novos campos, a V2 do car_audio_configuration.xml é obrigatórios. Revisitando a configuração de áudio acima, mas usando o novo campo para ID da zona de ocupante e mapeamento do ID da zona de áudio, a nova configuração sem volume as definições de grupo podem ser configuradas 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>

A configuração acima define um mapeamento da zona primária para a zona de ocupantes 0 e audioZoneId 1 a occupantZoneId 1. Em geral, qualquer mapeamento entre a zona de ocupante e a zona de áudio pode ser configurado, mas o mapeamento precisa ser de um para um. Estas são as regras que definiram os dois novos campos:

  • O audioZoneId da zona principal é sempre zero.
  • Os números audioZoneId e occupantZoneId não podem se repetir
  • audioZoneId e occupantZoneId só podem ter um mapeamento de um para um

Como fazer o roteamento por um UID de aplicativo

Uma série de APIs ocultas foi introduzida ao CarAudioManager em cada 10 para permitir que os apps para consultar e definir as zonas e a seleção de áudio.

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

As APIs acima permitiram que um aplicativo próprio gerenciasse com base no roteamento de áudio no UID de um aplicativo. Dessa forma, tanto o ID da zona de áudio quanto o UID do aplicativo são necessário. Com essas informações em mãos, o roteamento de áudio pode ser definido usando o API CarAudioManager#setZoneIdForUid.

Como alterar as zonas de um app

Por padrão, todos os áudios são roteados para a zona principal. Atualizar um aplicativo para ser roteada para uma 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 Observação:os streams e o foco não podem mudar de zona dinamicamente. Portanto, a reprodução deve ser interrompida e o foco deve ser solicitado novamente para alterar as zonas.

Roteamento com User-ID

Embora o roteamento com base em UID de um aplicativo permita o controle preciso da configuração roteamento de áudio, ela também exige que o roteamento de áudio para cada aplicativo seja definido ao aplicativo, que solicita a seleção e a reprodução do áudio. Para reduzir isso problema e facilitar ainda mais a reprodução de áudio sem modificação de aplicativos de terceiros, O CarAudioService usa a zona de ocupantes do carro e o mapeamento da zona de áudio para definir do roteamento com base no ID do usuário. Dessa forma, quando um usuário faz login na zona de ocupantes, o áudio do carro ou serviço seja notificado. Com esse sinal, o gerenciamento e o roteamento da seleção de áudio são automaticamente configuradas para todas as zonas de áudio.

O roteamento com base em UID ainda pode ser usado, mas precisa ser feito de maneira independente roteamento de ID do usuário. Isso significa que, se o mapeamento da zona de ocupante para o áudio do carro for definido, o roteamento com base em UID será desativado e tentará chamar CarAudioManager#setZoneidForUid vai gerar um erro.

Embora o roteamento de áudio e o gerenciamento de foco tenham sido simplificados com a zona de ocupantes de ocupantes, ele ainda precisará ser atribuído a uma zona de ocupantes. Isso pode ser feito usando o CarOccupantZoneManager#assignProfileUserToOccupantZone. Isso A API requer permissão para gerenciar usuários. A expectativa atual é que os OEMs gerenciem atribuição de zona de ocupante por algum tipo de interface do sistema. Depois de fazer a inscrição, inicialização, roteamento de áudio e gerenciamento de foco serão configurados automaticamente para o usuário.

Roteamento com setpreferredDevice

Junto com as mudanças acima, o Android 11 também tem uma nova API para consultar dispositivos de saída associadas a cada zona, CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage).

A API pode ser usada para consultar um dispositivo de saída para uma zona específica e um atributo de áudio uso. Dessa forma, os aplicativos próprios podem rotear o áudio para zonas diferentes ao usando a API setPreferredDevice do player. A A API getOutputDeviceForUsage exige PERMISSION_CAR_CONTROL_AUDIO_SETTINGS e é uma API do sistema. Abaixo está um exemplo de como encontrar o dispositivo de mídia de uma zona específica e rotear para esse dispositivo usando a API setPreferredDevice.

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