Os novos serviços de plug-in de OEM de carro no Android 14 permitem que alguns componentes do carro sejam configurados. Especificamente para áudio, três novos serviços de plug-in foram introduzidos, o que permite que os OEMs configurem o gerenciamento de áudio de maneira flexível em dispositivos AAOS:
- Controle de seleção de áudio
- Controle de volume e silenciamento de áudio
- Controle de redução de áudio
Arquitetura de serviço de plug-in de carro
A figura abaixo oferece uma visão geral dos serviços de carro e da relação deles com o serviço de carro OEM. Semelhante aos processos de app e de serviço de carro, o processo de serviço de carro OEM ocupa o próprio espaço de processo.
O serviço de carro inicia o serviço de carro OEM encontrando o componente definido em config_oemCarService. Se a configuração estiver vazia, o serviço 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 de áudio do carro OEM:
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 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 do carro 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 silenciamento
Antes do Android 14, esse comportamento era estático e só podia ser modificado pelas 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 silenciamento
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 OEM do carro para gerenciar o comportamento de áudio. Isso só ocorre se o componente de serviço de áudio do carro OEM correspondente estiver definido. Caso contrário, o serviço de áudio do carro usa o comportamento padrão.
Para garantir que o serviço de áudio do carro e o serviço de áudio OEM do carro estejam sempre sincronizados, para 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 OEM do carro. Por exemplo, quando o serviço de áudio do carro intercepta uma solicitação para avaliar a seleção de áudio, ele transmite o estado atual da pilha para o serviço de áudio OEM do carro. O estado atual inclui o detentor de foco atual 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 carro. 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 OEM do carro ficarão incompletas. Por exemplo, se um OEM substituir o processamento de seleção de áudio no serviço de carro registrando a própria política de seleção de áudio, o serviço de áudio do carro não poderá fornecer informações completas ao serviço de áudio OEM do carro. Isso pode afetar a capacidade do serviço de áudio OEM do carro de tomar decisões, já que ele pode não ter informações que não sã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 de carro OEM. Essas chamadas são feitas em processos, o que exige comunicação entre processos (IPC, na sigla em inglês). A IPC adiciona latência a cada chamada. É importante minimizar a latência no serviço 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 de 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 só precisem viajar em uma direção.
Definições de serviço de áudio do carro 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 de seleção 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 assume o foco do detentor de foco atual.
Rejeitar interação. A solicitação de foco recebida é rejeitada com base no detentor de 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 do serviço de áudio do carro sempre que houver uma solicitação de seleção de áudio que precise 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 precisa retornar os resultados:
class OemCarAudioFocusResult {
int audioZoneId;
int audioFocusEvaluationResults;
AudioFocusEntry focusResult;
List<AudioFocusEntry> newLosers;
List<AudioFocusEntry> newlyBlocked;
}
Isso 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. Quaisquer mudanças na pilha de foco atual precisam ser definidas nas entradas newLosers e newlyBlocked, dependendo da natureza da mudança de pilha.
Em que newLosers contém entradas que estavam anteriormente com foco, mas agora precisam perder o foco, de forma permanente ou transitória. Os perdedores de foco permanentes serão removidos da pilha de seleção de áudio, e os perdedores de foco transitórios serão movidos para a pilha de perdedores de foco atuais até que recuperem o foco ou sejam abandonados pelo solicitante de foco original. De qualquer forma, o listener de foco para as solicitações vai receber uma seleção perdida correspondente.
A lista newlyBlocked contém entradas que estavam anteriormente na lista de perdedores de foco, mas agora estão bloqueadas pela nova entrada. O bloqueio pode ser permanente ou transitório. Para o foco permanente bloqueado, a entrada será removida da pilha e a perda de foco será enviada aos listeners de foco. Para a perda de foco transitória, a entrada vai permanecer na pilha de perdedores de foco, mas um novo bloqueador de foco será adicionado à lista de bloqueadores. Nenhuma perda de foco será enviada, já que uma foi enviada anteriormente quando foi bloqueada 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, é unidirecional e é chamada em cada solicitação ou abandono de seleção de áudio. A API é usada principalmente para informar o serviço OEM sobre mudanças de foco, que podem afetar o comportamento do serviço de áudio do carro OEM.
Diretrizes para avaliação de seleção
No AAOS, a seleção de áudio é usada 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 OEM precisa considerar o seguinte ao gerenciar uma solicitação de seleção de áudio:
Sem nenhuma seleção de áudio de alta prioridade (como uma chamada telefônica, emergência ou segurança), os apps precisam ser capazes de ganhar a seleção de áudio de forma transitória ou permanente.
Enquanto uma seleção de mídia estiver ativa, os apps que solicitam:
A seleção de uso de chamadas precisa ser capaz de receber a seleção de forma simultânea ou exclusiva.
A seleção de uso de navegação precisa ser capaz de receber a seleção de forma simultânea ou exclusiva.
A seleção de uso do Assistente precisa ser capaz de receber a seleção de forma simultânea ou exclusiva.
Enquanto os apps de seleção de áudio de alta prioridade (como uma chamada telefônica, alerta de emergência ou alerta de segurança) estiverem ativos, qualquer solicitação de seleção de áudio atrasada recebida precisa ser concedida ou atrasada conforme necessário.
Embora as sugestões acima não sejam exaustivas, elas podem ajudar a garantir que os apps que solicitam a seleção possam obtê-la quando não houver sons de alta prioridade ativos. Mesmo quando sons de alta prioridade estão ativos, as solicitações de seleção atrasadas ainda precisam ser respeitadas e precisam ser capazes de ganhar a seleção quando o som de alta prioridade parar.
Serviço de volume do carro OEM
O serviço de áudio do carro gerencia eventos de tecla de volume detectando ajustes de volume do sistema de áudio ou detectando 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 maior prioridade na parte de cima e a menor prioridade na parte de baixo. Por exemplo, se o áudio de navegação e o áudio 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
- Anúncio
- 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 de tecla de volume, o serviço de áudio do carro tem uma segunda lista de prioridade de contexto de áudio:
- Ligar
- Mídia
- Anúncio
- 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 de tecla. Sons incomuns, talvez de duração mais curta, só podem ser gerenciados pela interface de 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 introduzido 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 os 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 foi alterado. true indica que há uma mudança e o grupo de volume precisa ser atualizado. O volumeGroupChanged é o grupo de volume real que precisa ser alterado. Esse grupo precisa ser alterado de acordo com o parâmetro volumeAdjustment original transmitido para a 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 áudio do carro OEM
O serviço de áudio do carro gerencia a redução de áudio monitorando as mudanças de seleção de áudio e enviando um sinal para o HAL AudioControl sobre quais dispositivos de áudio reduzir.
Quando a seleção muda, todos os detentores de foco ativos são avaliados para determinar
qual precisa ser reduzido com base neste conjunto de regras de redução estáticas
de redução:
- Sons de emergência reduzem tudo, exceto sons de chamada
- Segurança reduz tudo, exceto sons de emergência
- Navegação reduz tudo, exceto sons de segurança e emergência
- Chamada reduz tudo, exceto sons de segurança, emergência e navegação
- Voz reduz 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 sendo responsáveis por determinar como os sons precisam 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 do serviço de áudio do carro em mudanças de seleção de áudio. Ela reutiliza
o OemCarAudioVolumeRequest introduzido no
serviço de volume de áudio do carro OEM, e contém as informações relevantes
para tomar a decisão sobre quais atributos reduzir. A lista de atributos de áudio a serem reduzidos da API é comparada ao estado de áudio atual:
Atributo de áudio reduzido no momento:
- Na lista, continua sendo reduzido
- Não está na lista, redução desativada
Atributo de áudio não reduzido no momento:
- Na lista, reduzido
- Não está na lista, redução desativada
O serviço de áudio do carro determina a quais dispositivos de saída de áudio os atributos de áudio pertencem e os adiciona à lista de dispositivos de saída de áudio reduzidos ou à lista de dispositivos de áudio não reduzidos, respectivamente. Isso é enviado ao HAL AudioControl para realizar a redução necessária no nível de hardware.
A figura abaixo mostra um diagrama de sequência simplificado do controle de redução de áudio para uma solicitação de seleção quando o serviço de redução OEM é usado:
A sequência começa quando um app solicita
o gerenciamento da seleção de áudio
pelas APIs públicas do gerenciador de áudio. A solicitação é encaminhada para o serviço de áudio do carro para determinar os resultados. Quando a seleção de áudio é decidida, a redução de áudio é avaliada 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 para o 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, juntamente com 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 seleção quando o evaluateAudioFocusRequest é chamado.
Depuração do app de teste de referência
O app de teste de serviço de carro OEM faz parte do código-fonte do AOSP. Os OEMs podem fazer mudanças de acordo com as necessidades. Para depuração, 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 OEM usa o comando dump do serviço de carro para o serviço 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 dump determina o estado do recurso e do serviço. Por exemplo, as informações de dump mIsOemServiceReady especificam se o serviço está pronto para uso, em que true indica que ele está pronto e false indica que não está.