Serviço de plug-in de áudio automotivo

Os novos serviços de plug-in OEM de carro no Android 14 permitem que alguns componentes do carro sejam configurados. Especificamente para áudio, são introduzidos três novos serviços de plug-in, que permitem aos OEMs configurar de maneira flexível o gerenciamento de áudio em dispositivos AAOS:

  • Controle de foco de áudio
  • Volume de áudio e controle de mudo
  • Controle de redução de áudio

Arquitetura de serviço de plugin de carro

A figura abaixo fornece uma visão geral dos serviços automotivos e sua relação com o serviço automotivo OEM. Semelhante aos processos de aplicativos e ao processo de serviço automotivo, o processo de serviço automotivo OEM ocupa seu próprio espaço de processo.

imagem

O serviço automotivo inicia o serviço automotivo OEM localizando o componente definido em config_oemCarService . Se a configuração estiver vazia, o serviço OEM não existe e nenhum serviço será iniciado. O componente deve estender OemCarService . O serviço de áudio automotivo deve substituir as APIs para adquirir o serviço OEM de áudio automotivo:

public final class OemCarServiceImp extends OemCarService {
    @Override
    public OemCarAudioFocusService getOemAudioFocusService();

    @Override
    public OemCarAudioDuckingService getOemAudioDuckingService();

    @Override
    public OemCarAudioVolumeService getOemAudioVolumeService();
}

Por exemplo , consulte o aplicativo de teste de referência definido em packages/services/Car/tests/OemCarServiceTestApp .

Mesmo que o serviço seja iniciado pelo serviço automotivo, ele não herda automaticamente as permissões disponíveis para o serviço de áudio automotivo. Como tal, qualquer permissão exigida pelos serviços OEM deve 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 automotivo gerencia estas ações:

  • Roteamento de áudio
  • Foco de áudio
  • Esquiva de áudio
  • Volume e mudo

Antes do Android 14, esse comportamento era basicamente estático e só podia ser modificado por meio de configurações, embora em um conjunto muito limitado de casos. O Android 14 introduziu um mecanismo para que o serviço de áudio automotivo se comunique com um componente definido pelo OEM que gerencia:

  • Foco de áudio
  • Esquiva de áudio
  • Volume e mudo

A figura abaixo mostra uma arquitetura simplificada para o serviço de áudio automotivo e o serviço OEM automotivo. O serviço de áudio automotivo define diferentes ganchos que podem chamar o serviço de áudio OEM do carro para gerenciar o comportamento do áudio. Este último ocorre apenas se o componente de serviço de áudio automotivo OEM correspondente for definido. Caso contrário, o serviço de áudio automotivo usará o comportamento padrão.

imagem

Para garantir que o serviço de áudio automotivo e o serviço de áudio OEM automotivo estejam sempre sincronizados, para cada chamada, o serviço de áudio automotivo passa as partes necessárias do estado atual da pilha de áudio para o serviço de áudio OEM automotivo. Por exemplo, quando o serviço de áudio automotivo intercepta uma solicitação para avaliar o foco de áudio, ele passa o estado atual da pilha para o serviço de áudio OEM automotivo. O estado atual inclui o atual detentor do foco e os atuais perdedores do foco. Os perdedores de foco são solicitações de foco que ainda fazem parte da pilha, mas que perderam temporariamente o foco.

O serviço de áudio automotivo deve gerenciar todas as atividades de áudio no carro. Se o serviço de áudio automotivo não gerenciar algumas partes do comportamento de áudio, as informações expostas ao serviço de áudio OEM automotivo estarão incompletas. Por exemplo, se um OEM substituir o tratamento do foco de áudio no serviço automotivo registrando sua própria política de foco de áudio, o serviço de áudio automotivo não poderá fornecer informações completas ao serviço de áudio OEM automotivo. Isso pode afetar a capacidade do serviço de áudio OEM do carro de tomar decisões, uma vez que pode faltar informações não visíveis para o serviço de áudio do carro.

Para tomar medidas, o serviço de áudio automotivo liga para os serviços automotivos OEM. Essas chamadas são feitas entre processos, o que requer comunicação entre processos (IPC). IPC adiciona latência a cada chamada. É importante minimizar a latência no serviço OEM.

Como as chamadas do serviço de áudio automotivo para o serviço OEM estão bloqueadas, o serviço OEM não deve ligar para o serviço de áudio automotivo em avaliações diretas da API. Em vez disso, o serviço de áudio automotivo 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ço de áudio automotivo OEM

Serviço de foco de áudio automotivo OEM

O serviço de áudio automotivo gerencia solicitações de foco de áudio de aplicativos registrando um ouvinte de foco de política de áudio. O serviço de áudio automotivo possui um mecanismo para gerenciar o comportamento do foco baseado 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 obtém o foco do detentor do foco atual.

  • Rejeite a 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 diferir 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 a partir do serviço de áudio automotivo 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 deve retornar os resultados:

class OemCarAudioFocusResult {
    int audioZoneId;
    int audioFocusEvaluationResults;
    AudioFocusEntry focusResult;
    List<AudioFocusEntry> newLosers;
    List<AudioFocusEntry> newlyBlocked;
}

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 alterações na pilha de foco atual devem ser definidas nas entradas newLosers e newlyBlocked , dependendo da natureza da alteração na pilha.

Onde newLosers contém entradas que anteriormente mantinham o foco, mas agora devem perder o foco, de forma permanente ou transitória. Os perdedores de foco permanentes serão removidos da pilha de foco de áudio, e os perdedores de foco transitórios serão movidos para a pilha de perdedores de foco atual até que recuperem o foco ou sejam abandonados pelo solicitante de foco original. Independentemente disso, o ouvinte de foco das solicitações receberá um foco correspondente perdido.

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 foco permanente bloqueado a entrada será removida da pilha e a perda de foco será enviada para os ouvintes de foco. Para perda transitória de foco, a entrada permanecerá na pilha de perdedores de foco, mas um novo bloqueador de foco será adicionado à sua lista de bloqueadores, nenhuma perda de foco será enviada, pois uma foi enviada anteriormente quando foi bloqueada pela primeira vez. A solicitação será finalmente desbloqueada quando todos os bloqueadores atuais forem removidos ou será removida da pilha se o foco for abandonado.

A segunda API, notifyAudioFocusChange , é uma forma chamada em cada solicitação ou abandono de foco 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 automotivo OEM.

Diretrizes para avaliação de foco

No AAOS, o foco de áudio é usado para gerenciar a reprodução de áudio e determinar qual aplicativo deve aderir para fornecer uma experiência ideal para o usuário. Dessa forma, o serviço de plug-in OEM deve levar em consideração o seguinte ao gerenciar uma solicitação de foco de áudio:

  • Sem qualquer foco de áudio de alta prioridade (como uma chamada telefônica, emergência ou segurança), os aplicativos devem ser capazes de obter foco de áudio de forma transitória ou permanente.

  • Enquanto um foco de mídia está ativo, os apps solicitam:

    • O foco de uso da chamada deve ser capaz de receber foco simultaneamente ou exclusivamente.

    • O foco de uso da navegação deve ser capaz de receber foco simultânea ou exclusivamente.

    • O foco de uso do assistente deve ser capaz de receber foco simultaneamente ou exclusivamente.

  • Enquanto os aplicativos de foco 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 foco de áudio atrasada recebida deverá ser concedida ou atrasada conforme necessário.

Embora as sugestões acima não sejam exaustivas, elas podem ajudar a garantir que os aplicativos que solicitam foco sejam capazes de obter foco quando não houver sons ativos de alta prioridade. Mesmo enquanto os sons de alta prioridade estão ativos, as solicitações de foco atrasado ainda devem ser respeitadas e devem ser capazes de ganhar foco assim que o som de alta prioridade parar.

Serviço de volume de carro OEM

O serviço de áudio automotivo gerencia eventos de teclas de volume ouvindo os ajustes de volume do sistema de áudio ou ouvindo eventos de teclas de volume diretamente do serviço de entrada do carro. Em cada caso, o comportamento padrão do serviço de áudio automotivo é determinar qual grupo de volume alterar com base nos reprodutores de áudio ativos e em uma lista de prioridades de contexto de áudio.

Fornecemos duas listas de prioridade de volume. A primeira lista considera todos os contextos de áudio nesta ordem. A lista é apresentada em ordem decrescente, a prioridade mais alta no topo e a prioridade mais baixa na parte inferior. Por exemplo, se o áudio de navegação e o áudio da música estiverem ativos ao mesmo tempo, o volume de navegação será alterado durante um evento de tecla de volume.

  1. Navegação
  2. Chamar
  3. Música
  4. Anúncio
  5. Comando de voz
  6. Toque de chamada
  7. Som do sistema
  8. Segurança
  9. Alarme
  10. Notificação
  11. Estado do veículo
  12. Emergência

Para tornar o gerenciamento de eventos de teclas de volume menos complexo, o serviço de áudio automotivo tem uma segunda lista prioritária de contexto de áudio:

  1. Chamar
  2. meios de comunicação
  3. Anúncio
  4. Comando de voz

Esta lista também é apresentada em ordem decrescente. O objetivo desta segunda lista é permitir que sons mais comuns sejam alterados através de eventos importantes. Sons incomuns, talvez de duração mais curta, podem ser gerenciados apenas por meio da 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 fornecer mais flexibilidade ao gerenciamento de volume, OemCarAudioVolumeService foi introduzido no Android 14:

public interface OemCarAudioVolumeService {
    OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}

O serviço de volume de áudio automotivo OEM tem um único método, que utiliza 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 possui os atributos de áudio ativos. Os duckedAttributes são todos atributos de áudio atualmente reduzidos. O volumeGroupState possui 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 volumes deve ser alterado. Os resultados devem ser retornados em OemCarVolumeChangeInfo :

class OemCarVolumeChangeInfo {
    boolean change;
    CarVolumeGroupInfo volumeGroupChanged;
}

O booleano change indica se algum volume foi alterado, true indica que há uma alteração e o grupo de volumes deve ser atualizado. O volumeGroupChanged é o grupo de volumes real que deve ser alterado. Este grupo deve ser alterado de acordo com o parâmetro volumeAdjustment original passado para a API. Por exemplo, se os resultados indicarem que o grupo de volumes de navegação deve ser silenciado, o booleano será true e o grupo de volumes retornado deverá ser o da navegação.

Serviço de redução de carros OEM

O serviço de áudio automotivo gerencia a redução de áudio monitorando as mudanças de foco de áudio e enviando um sinal ao AudioControl HAL sobre quais dispositivos de áudio devem ser reduzidos. Quando o foco muda, todos os detentores de foco ativos são avaliados para determinar quais devem ser evitados com base neste conjunto de regras de redução estática:

  • Sons de emergência evitam tudo, exceto sons de chamada
  • A segurança evita tudo, exceto sons de emergência
  • A navegação evita tudo, exceto sons de segurança e emergência
  • Chamar evita tudo, exceto sons de segurança, emergência e navegação
  • Patos de voz chamam sons de toque
  • Música e anúncios devem ser evitados 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 é introduzido no Android 14:

class OemCarAudioDuckingService {
List<AudioAttributes>   evaluateAttributesToDuck(
        OemCarAudioVolumeRequest request);
}

Essa API é chamada a partir do serviço de áudio automotivo em alterações de foco de áudio. Ele reutiliza o OemCarAudioVolumeRequest introduzido no serviço de volume de carros OEM e contém as informações relevantes para tomar a decisão sobre quais atributos devem ser evitados. A lista de atributos de áudio a serem desviados da API é comparada ao estado de áudio atual:

  • Atributo de áudio atualmente desativado:

    • Na lista, continua a ser evitado
    • Não está na lista, esquivar-se está desativado
  • Atributo de áudio não desativado no momento:

    • Na lista, abaixou-se
    • Não está na lista, esquivar-se está desativado

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. Em última análise, isso é enviado ao AudioControl HAL 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 OEM é usado:

imagem

A sequência começa quando um aplicativo solicita Gerenciar foco de áudio por meio de APIs públicas do gerenciador de áudio. A solicitação é encaminhada ao serviço de áudio automotivo para apuração dos resultados. Quando o foco do áudio é decidido, a redução de áudio é avaliada pelo serviço de áudio do carro que chama o OemCarAudioDuckingService para avaliar quais atributos de áudio devem ser reduzidos. Depois que os resultados são retornados da evaluateAttributesToDuck , os dispositivos de áudio a serem reduzidos são calculados e, finalmente, as informações são enviadas ao AudioControl para aplicar o redução ao hardware de áudio.

Implementação de referência de serviço de áudio automotivo OEM

AAOS fornece uma implementação de referência do serviço automotivo OEM em packages/services/Car/tests/OemCarServiceTestApp , que implementa o OemCarService , junto com OemCarAudioFocusService , OemCarAudioDuckingService e o OemCarAudioVolumeService . Para este último, cada serviço utiliza um arquivo XML para carregar um comportamento estático. Por exemplo, OemCarAudioFocusServiceImp carrega oem_focus_config.xml , que contém uma matriz de interação. A matriz é usada para avaliar a solicitação de foco quando evaluateAudioFocusRequest é chamado.

Depuração de aplicativo de teste de referência

O aplicativo de teste de serviço automotivo OEM faz parte do código-fonte AOSP. Os OEMs podem fazer alterações de acordo com suas necessidades. Para depuração, use a configuração config_oemCarService para ativar o aplicativo 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 automotivo OEM usa o comando car service dump 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 ser usado, onde true indica que está pronto e false indica que não está pronto.