Os novos serviços de plug-in de OEM de carro no Android 14 permitem configurar alguns componentes do veículo. Especificamente para áudio, três novos serviços de plug-in foram introduzidos, permitindo que os OEMs configurem de maneira flexível o gerenciamento de áudio em dispositivos AAOS:
- Controle de seleção de áudio
- Controle de volume e desativação do som
- Controle de redução de áudio
Arquitetura de serviço do plug-in de carro
A figura abaixo mostra uma visão geral dos serviços automotivos e da relação deles com o serviço automotivo do OEM. Assim como os processos de apps e de serviços automotivos, o processo de serviços automotivos do OEM ocupa um espaço próprio.
O serviço de carro inicia o serviço de carro do OEM encontrando o componente definido em
config_oemCarService
. Se a configuração estiver vazia, o serviço do OEM não vai existir
e nenhum serviço será iniciado. O componente precisa estender
OemCarService.
O serviço de áudio do carro precisa substituir as APIs para adquirir o serviço OEM
de áudio do carro:
public final class OemCarServiceImp extends OemCarService {
@Override
public OemCarAudioFocusService getOemAudioFocusService();
@Override
public OemCarAudioDuckingService getOemAudioDuckingService();
@Override
public OemCarAudioVolumeService getOemAudioVolumeService();
}
Por
exemplo, consulte
o app de teste de referência definido em
packages/services/Car/tests/OemCarServiceTestApp
.
Embora o serviço seja iniciado pelo serviço de carro, ele não herda automaticamente as permissões disponíveis para o serviço de áudio do carro. Assim, qualquer
permissão exigida pelos serviços do OEM precisa ser adquirida com o mecanismo
adequado. Por exemplo, consulte
packages/services/Car/data/etc/com.android.car.oemcarservice.testapp.xml
.
Serviço de áudio automotivo com arquitetura de serviço OEM
No AAOS, o serviço de áudio do carro gerencia estas ações:
- Roteamento de áudio
- Seleção de áudio
- Redução de áudio
- Volume e desativar som
Antes do Android 14, esse comportamento era basicamente estático e só podia ser modificado nas configurações, embora para um conjunto muito limitado de casos. O Android 14 introduziu um mecanismo para que o serviço de áudio do carro se comunique com um componente definido pelo OEM que gerencia:
- Seleção de áudio
- Redução de áudio
- Volume e desativar som
A figura abaixo mostra uma arquitetura simplificada para o serviço de áudio do carro e o serviço OEM do carro. O serviço de áudio do carro define diferentes hooks que podem chamar o serviço de áudio do OEM do carro para gerenciar o comportamento do áudio. Isso só acontece se o componente de serviço de áudio do carro OEM correspondente estiver definido. Caso contrário, o serviço de áudio do carro usará o comportamento padrão.
Para garantir que o serviço de áudio do carro e o serviço de áudio do OEM do carro estejam sempre sincronizados, em cada chamada, o serviço de áudio do carro transmite as partes necessárias do estado atual da pilha de áudio para o serviço de áudio do OEM do carro. Por exemplo, quando o serviço de áudio do carro intercepta uma solicitação para avaliar o foco de áudio, ele transmite o estado atual da pilha para o serviço de áudio do OEM do carro. O estado atual inclui o detentor e os perdedores de foco atuais. Os perdedores de foco são solicitações de foco que ainda fazem parte da pilha, mas que perderam o foco temporariamente.
O serviço de áudio do carro precisa gerenciar toda a atividade de áudio no veículo. Se o serviço de áudio do carro não gerenciar algumas partes do comportamento de áudio, as informações expostas ao serviço de áudio do OEM do carro vão estar incompletas. Por exemplo, se um OEM substituir o processamento de foco de áudio no serviço de carro registrando a própria política de foco de áudio, o serviço de áudio do carro não poderá fornecer informações completas ao serviço de áudio do OEM do carro. Isso pode afetar a capacidade do serviço de áudio do OEM do carro de tomar decisões, já que ele pode não ter informações não visíveis para o serviço de áudio do carro.
Para realizar ações, o serviço de áudio do carro chama os serviços do carro do OEM. Essas chamadas são feitas entre processos, o que exige comunicação entre processos (IPC). A IPC adiciona latência a cada chamada. É importante minimizar a latência no serviço do OEM.
Como as chamadas de serviço de áudio do carro para o serviço OEM são de bloqueio, o serviço OEM não deve chamar o serviço de áudio do carro em avaliações diretas da API. Em vez disso, o serviço de áudio do carro fornece as informações necessárias para que as chamadas entre os dois processos precisem viajar apenas em uma direção.
Definições de serviços de áudio automotivo do OEM
Serviço de seleção de áudio do carro OEM
O serviço de áudio do carro gerencia solicitações de seleção de áudio de apps registrando um listener de seleção de política de áudio. O serviço de áudio do carro tem um mecanismo para gerenciar o comportamento do foco com base em uma matriz de interação estática. A matriz define três tipos diferentes de interações:
Interação simultânea. Os detentores de foco podem manter o foco ao mesmo tempo.
Interações exclusivas. A solicitação de foco recebida tira o foco do detentor atual.
Rejeitar interação. Solicitação de foco recebida rejeitada com base no detentor do foco atual.
Embora isso seja suficiente para alguns casos de uso automotivo, não atende a todas as necessidades de interação, que podem variar devido aos requisitos do OEM. Para isso, apresentamos o OemCarAudioFocusService
:
public interface OEmCarAudioFocusService {
OemCarAuddioFocusResults evaluateAudioFocusRequest(
OemCarAudioFocusEvaluationRequest request);
void notifyAudioFocusChange(
List<AudioFocusEntry> holder,
List<AudioFocusEntry> losers, int zoneId);
}
A API evaluateAudioFocusRequest
é chamada pelo serviço de áudio do carro sempre que
há uma solicitação de foco de áudio que precisa ser avaliada. É uma API
bidirecional que bloqueia o retorno dos resultados. A solicitação contém informações sobre o estado atual da pilha de áudio:
Essas informações podem ser usadas para avaliar o newFocusRequest
em comparação com os
detentores de foco atuais em focusHolders
e os perdedores de foco atuais em
focusLosers
. A API retorna os resultados:
class OemCarAudioFocusResult {
int audioZoneId;
int audioFocusEvaluationResults;
AudioFocusEntry focusResult;
List<AudioFocusEntry> newLosers;
List<AudioFocusEntry> newlyBlocked;
}
Ele contém as informações sobre os resultados reais da avaliação em
audioFocusEvaluationResults
, que indica se a solicitação atual foi
concedida, atrasada ou falhou. Todas as mudanças na pilha de foco atual
devem ser definidas nas entradas newLosers
e newlyBlocked
, dependendo da natureza
da mudança na pilha.
Em que o newLosers
contém entradas que estavam em foco anteriormente, mas
agora precisam perder o foco, de forma permanente ou temporária. Os perdedores de seleção permanente
serão removidos da pilha de seleção de áudio, e os perdedores de seleção temporária
serão movidos para a pilha atual de perdedores de seleção até que recuperem a seleção ou sejam
abandonados pelo solicitante de seleção original. De qualquer forma, o listener de foco para
as solicitações vai receber uma perda de foco correspondente.
A lista newlyBlocked
contém entradas que estavam na lista de perdedores de foco, mas agora estão bloqueadas pela nova entrada. O bloqueio pode ser permanente ou
temporário. No caso de um bloqueio permanente, a entrada será removida da pilha
e a perda de foco será enviada aos listeners de foco. Para perda de foco temporária, a entrada vai permanecer na pilha de perdedores de foco, mas um novo bloqueador de foco será adicionado à lista. Nenhuma perda de foco será enviada, já que uma foi enviada anteriormente quando o foco foi bloqueado pela primeira vez. A solicitação será desbloqueada quando todos os bloqueadores atuais forem removidos ou será removida da pilha se o foco for abandonado.
A segunda API, notifyAudioFocusChange
, é uma via única chamada em cada
solicitação ou abandono de foco de áudio. A API é usada principalmente para informar o serviço do OEM sobre mudanças de foco, que podem afetar o comportamento do serviço de áudio do carro do OEM.
Diretrizes para avaliação de foco
No AAOS, o foco de áudio é usado para gerenciar a reprodução de áudio e determinar qual app precisa aderir para oferecer uma experiência ideal ao usuário. Assim, o serviço de plug-in do OEM precisa considerar o seguinte ao gerenciar uma solicitação de foco de áudio:
Sem nenhum foco de áudio de alta prioridade (como uma ligação, emergência ou segurança), os apps precisam conseguir o foco de áudio de forma temporária ou permanente.
Enquanto um foco de mídia estiver ativo, os apps que solicitarem:
Chame o foco de uso, que precisa receber o foco simultânea ou exclusivamente.
O foco no uso da navegação precisa ser capaz de receber o foco simultânea ou exclusivamente.
O foco do uso do Google Assistente. Ele precisa ser capaz de receber foco simultânea ou exclusivamente.
Enquanto apps com foco de áudio de alta prioridade (como uma ligação, um alerta de emergência ou um alerta de segurança) estão ativos, qualquer solicitação de foco de áudio atrasada recebida deve ser concedida ou adiada conforme necessário.
As sugestões acima não são exaustivas, mas podem ajudar a garantir que os apps que pedem foco consigam isso quando não houver sons ativos de alta prioridade. Mesmo quando sons de alta prioridade estão ativos, as solicitações de foco atrasado ainda precisam ser respeitadas e podem ganhar foco quando o som de alta prioridade para.
Serviço de volume de carros OEM
O serviço de áudio do carro gerencia eventos de tecla de volume ouvindo ajustes de volume do sistema de áudio ou eventos de tecla de volume diretamente do serviço de entrada do carro. Em cada caso, o comportamento padrão do serviço de áudio do carro é determinar qual grupo de volume mudar com base nos players de áudio ativos e em uma lista de prioridade de contexto de áudio.
Oferecemos duas listas de prioridade de volume. A primeira lista considera todos os contextos de áudio nesta ordem. A lista é apresentada em ordem decrescente, com a prioridade mais alta na parte de cima e a mais baixa na parte de baixo. Por exemplo, se o áudio de navegação e o de música estiverem ativos ao mesmo tempo, o volume de navegação será alterado durante um evento de tecla de volume.
- Navegação
- Ligar
- Música
- Aviso
- Comando de voz
- Toque da chamada
- Som do sistema
- Segurança
- Alarme
- Notificação
- Status do veículo
- Emergência
Para simplificar o gerenciamento de eventos da tecla de volume, o serviço de áudio do carro tem uma segunda lista de prioridade de contexto de áudio:
- Ligar
- Mídia
- Aviso
- Comando de voz
Essa lista também é apresentada em ordem decrescente. O objetivo dessa segunda lista é permitir que sons mais comuns sejam alterados por eventos principais. Sons incomuns, talvez de duração mais curta, só podem ser gerenciados pela interface do usuário das configurações de áudio.
A versão real do volume pode ser definida com a configuração audioVolumeAdjustmentContextsVersion
. A configuração pode ser definida como 1
ou 2
(2
é o padrão).
Para oferecer mais flexibilidade ao gerenciamento de volume, o
OemCarAudioVolumeService
foi lançado no Android 14:
public interface OemCarAudioVolumeService {
OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}
O serviço de volume de áudio do carro OEM tem um único método, que recebe um
volumeAdjustment
e um OemCarAudioVolumeRequest
:
class OemCarAudioVolumeRequest {
int audioZoneId;
int callState;
List<AudioAttributes> activePlaybackAttributes;
List<AudioAttributes> duckedAttributes;
List<CarVolumeGroupInfo> volumeGroupState;
}
O activePlaybackAttributes
da solicitação tem os atributos de áudio ativos. Os
duckedAttributes
são todos atributos de áudio reduzidos no momento. O
volumeGroupState
tem o estado atual do grupo de volumes. A solicitação representa o estado atual da pilha de áudio e pode ser usada para determinar qual grupo de volume precisa ser alterado. Os resultados precisam ser retornados em
OemCarVolumeChangeInfo
:
class OemCarVolumeChangeInfo {
boolean change;
CarVolumeGroupInfo volumeGroupChanged;
}
O booleano change
indica se algum volume mudou, e true
indica que
há uma mudança e que o grupo de volume precisa ser atualizado. O
volumeGroupChanged
é o grupo de volumes real que precisa ser mudado. Esse grupo precisa ser alterado de acordo com o parâmetro volumeAdjustment
original transmitido à API. Por exemplo, se os resultados indicarem que o grupo de volume de navegação precisa ser silenciado, o booleano será true
e o grupo de volume retornado será o de navegação.
Serviço de redução de volume de carro OEM
O serviço de áudio do carro gerencia a redução de áudio monitorando as mudanças de foco e
enviando um sinal para a HAL AudioControl
sobre quais dispositivos de áudio reduzir.
Quando o foco muda, todos os detentores de foco ativos são avaliados para determinar
qual deles deve ser reduzido com base neste conjunto de regras
estáticas de redução:
- Os sons de emergência diminuem tudo, exceto os sons de chamada
- A segurança silencia tudo, exceto sons de emergência
- A navegação reduz o volume de tudo, exceto os sons de segurança e emergência
- Chamar patos tudo, exceto sons de segurança, emergência e navegação
- O Voice reduz os sons de toque de chamada
- Músicas e anúncios precisam ser reduzidos por tudo
Essas regras não são exaustivas, e os OEMs continuam responsáveis por determinar como os sons devem ser reduzidos com base nessas diretrizes. Os OEMs podem controlar essas recomendações de forma mais ativa com base nos requisitos disponíveis. O
OemCarDuckingService
foi introduzido no Android 14:
class OemCarAudioDuckingService {
List<AudioAttributes> evaluateAttributesToDuck(
OemCarAudioVolumeRequest request);
}
Essa API é chamada pelo serviço de áudio do carro em mudanças de seleção de áudio. Ele reutiliza o OemCarAudioVolumeRequest
apresentado no serviço de volume de carros OEM e contém as informações relevantes para decidir quais atributos ocultar. A lista de atributos de áudio a serem reduzidos da API é comparada ao estado atual do áudio:
Atributo de áudio atualmente reduzido:
- Na lista, continua sendo evitado
- Não está na lista, a ação de abaixar foi desativada
Atributo de áudio não reduzido no momento:
- Na lista, com redução
- Não está na lista, a ação de abaixar foi desativada
Em seguida, o serviço de áudio do carro determina a quais dispositivos de saída de áudio os atributos pertencem e os adiciona à lista de dispositivos de saída de áudio reduzidos ou não reduzidos, respectivamente. Isso é enviado para a HAL AudioControl para realizar a redução necessária no nível do hardware.
A figura abaixo mostra um diagrama de sequência simplificado do controle de redução de áudio para uma solicitação de foco quando o serviço de redução do OEM é usado:
A sequência começa quando um app solicita
Gerenciar seleção de áudio
usando APIs públicas do gerenciador de áudio. A solicitação é encaminhada ao serviço de áudio do carro para determinar os resultados. Quando o foco de áudio é decidido, o ducking de áudio
é avaliado pelo serviço de áudio do carro que chama o OemCarAudioDuckingService
para
avaliar quais atributos de áudio precisam ser reduzidos. Depois que os resultados são retornados
da API evaluateAttributesToDuck
, os dispositivos de áudio a serem reduzidos são calculados
e, por fim, as informações são enviadas ao AudioControl
para aplicar a redução
ao hardware de áudio.
Implementação de referência do serviço de áudio do carro OEM
O AAOS oferece uma implementação de referência do serviço de carro OEM em
packages/services/Car/tests/OemCarServiceTestApp
, que implementa o
OemCarService
, além de OemCarAudioFocusService
,
OemCarAudioDuckingService
e o OemCarAudioVolumeService
. Para o último,
cada serviço usa um arquivo XML para carregar um comportamento estático. Por exemplo, OemCarAudioFocusServiceImp
carrega o oem_focus_config.xml
, que contém uma matriz de interação. A matriz é usada para avaliar a solicitação de foco quando o evaluateAudioFocusRequest
é chamado.
Depuração do app de teste de referência
O app de teste de serviço de carro do OEM faz parte do código-fonte do AOSP. Os OEMs podem fazer mudanças de acordo com as necessidades deles. Para depurar, use a configuração config_oemCarService
para ativar o app de teste.
<!-- This is the component name for the OEM customization service. OEM can choose to implement
this service to customize car service behavior for different policies. If OEMs choose to
implement it, they have to implement a service extending OemCarService exposed by car-lib,
and implement the required component services.
If the component name is invalid, CarService would not connect to any OEM service.
Component name can not be a third party package. It should be pre-installed -->
<string name="config_oemCarService" translatable="false">
com.android.car.oemcarservice.testapp/.OemCarServiceImpl
</string>
Para verificar se o serviço de carro do OEM usa o comando dump
do serviço de carro para o
serviço do OEM:
adb shell dumpsys car_service --oem-service
Os resultados podem ser semelhantes à saída abaixo:
***CarOemProxyService dump***
mIsFeatureEnabled: true
mIsOemServiceBound: true
mIsOemServiceReady: true
mIsOemServiceConnected: true
mInitComplete: true
OEM_CAR_SERVICE_CONNECTED_TIMEOUT_MS: 5000
OEM_CAR_SERVICE_READY_TIMEOUT_MS: 5000
mComponentName: com.android.car.oemcarservice.testapp/.OemCarServiceImpl
Cada booleano em cada lote de informações de dump
determina o estado do recurso
e do serviço. Por exemplo, as informações de despejo mIsOemServiceReady
especificam se o
serviço está pronto para uso. true
indica que está pronto, e false
indica que não está.