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 volume com os dispositivos associados, e cada dispositivo tem os contextos que
precisam ser roteados dentro dessa zona. É necessá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 de hardware de áudio da placa. Todos os dispositivos referenciados em
car_audio_configuration.xml
precisam ser definidos no
audio_policy_configuration.xml
.
Como ativar o roteamento do AAOS
Para usar o roteamento baseado em AAOS, defina a
flag audioUseDynamicRouting
como true
:
<resources> <bool name="audioUseDynamicRouting">true</bool> </resources>
Quando false
, o roteamento e grande parte do CarAudioService
serão desativados, e
o SO vai voltar ao comportamento padrão do AudioService
.
Zona principal
Por padrão, todo o áudio será roteado para a zona principal. Só pode haver
uma zona principal, que é indicada na configuração pelo atributo
isPrimary="true"
.
Exemplo de configuração
Por exemplo, um veículo pode ter duas zonas: uma principal e um sistema de entretenimento para o banco de trás. Com isso, um possível car_audio_configuration.xml
seria definido 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 os contextos para dispositivos diferentes. Isso permite
que o HAL aplique 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 volume:
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
para o HAL para serem aplicados à saída desses dispositivos.
Para a zona secundária, a saída esperada é por um único dispositivo de saída. Neste exemplo, todos os usos são roteados para o único dispositivo e grupo de volume para simplificar as coisas.
Configuração de áudio da zona do ocupante
No Android 11, o car_audio_configuration.xml
foi expandido para
apresentar dois novos campos, audioZoneId
e occupantZoneId
.
A primeira, audioZoneId
, pode ser usada para controlar melhor o gerenciamento de zonas.
Por outro lado, occupantZoneId
pode ser usado para configurar o roteamento
com base no ID do usuário.
Para usar esses novos campos, é necessário usar a V2 do car_audio_configuration.xml
. Voltando à configuração de áudio acima, mas usando o novo campo para o mapeamento de ID da zona do ocupante e do ID da zona de áudio, a nova configuração sem as definições de grupo de volume pode ser configurada 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 principal para a zona do ocupante 0 e
audioZoneId
1 para occupantZoneId
1. Em geral, qualquer mapeamento
entre a zona do ocupante e a zona de áudio pode ser configurado, mas o mapeamento precisa ser um para um.
Confira as regras que definiram os dois novos campos:
- O
audioZoneId
da zona principal é sempre zero - Os números
audioZoneId
eoccupantZoneId
não podem ser repetidos audioZoneId
eoccupantZoneId
só podem ter um mapeamento de um para um
Roteamento por um UID do aplicativo
Uma série de APIs ocultas foi introduzida em CarAudioManager
na versão 10 para permitir que os apps
consultem e definam zonas e foco de áudio.
int[] getAudioZoneIds(); int getZoneIdForUid(int uid); boolean setZoneIdForUid(int zoneId, int uid); boolean clearZoneIdForUid(int uid);
As APIs acima permitiam que um aplicativo primário gerenciasse o roteamento de áudio com base
no UID de um aplicativo. Portanto, o ID da zona de áudio e o UID do aplicativo também são
necessários. Com essas informações, o roteamento de áudio pode ser definido usando a
API CarAudioManager#setZoneIdForUid
.
Como mudar as zonas de um app
Por padrão, todo o áudio é roteado para a zona principal. Para atualizar um aplicativo a ser
encaminhado para outra zona, 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 fluxos e o foco não podem alternar dinamicamente as zonas. Portanto, a reprodução precisa ser interrompida e o foco precisa ser solicitado novamente para mudar de zona.
Roteamento com o ID do usuário
Embora o roteamento baseado em UID de um aplicativo permita o controle fino do roteamento de áudio de
cada aplicativo, ele também exige que o roteamento de áudio de cada aplicativo seja definido antes
de o aplicativo solicitar a seleção de áudio e tocar áudio. Para atenuar esse
problema e facilitar ainda mais a reprodução de áudio sem modificações por aplicativos de terceiros,
CarAudioService
usa o mapeamento da zona de ocupantes do carro e da zona de áudio para definir
o roteamento baseado no ID do usuário. Dessa forma, quando um usuário faz login na zona de ocupantes, o serviço de áudio do carro
é notificado. Com esse sinal, o gerenciamento e o roteamento do foco de áudio são configurados automaticamente
para todas as zonas de áudio.
O roteamento baseado em UID de aplicativos ainda pode ser usado, mas precisa ser feito de forma independente do
roteamento de ID de usuário. Isso significa que, se o mapeamento da zona do ocupante para a zona de áudio do carro for
definido, o roteamento baseado em UID será desativado e a tentativa de chamar
CarAudioManager#setZoneidForUid
vai gerar um erro.
Embora o roteamento de áudio e o gerenciamento de foco tenham sido simplificados com o gerenciamento de zona
de ocupantes, o usuário ainda precisa ser atribuído a uma zona de ocupantes. Isso pode ser feito
usando o CarOccupantZoneManager#assignProfileUserToOccupantZone
. Essa
API exige permissão para gerenciar usuários. A expectativa atual é que os OEMs gerenciem
a atribuição de zonas de usuário a ocupantes por meio de algum tipo de interface do sistema. Depois disso, a inicialização
do aplicativo, o roteamento de áudio e o gerenciamento de foco serão configurados automaticamente para o usuário.
Roteamento com setPreferredDevice
Além das mudanças acima, o Android 11 também tem uma nova API para consultar dispositivos de saída associados a cada zona, CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage).
A API pode ser usada para consultar um dispositivo de saída em uma zona específica e um uso de atributo
de áudio. Dessa forma, os aplicativos próprios podem encaminhar áudio para diferentes zonas usando
a API setPreferredDevice
do player. A
API getOutputDeviceForUsage
requer
PERMISSION_CAR_CONTROL_AUDIO_SETTINGS
e é uma API do sistema. Confira abaixo 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);