Seleção de áudio

Antes de iniciar um stream lógico, um app solicita o foco de áudio usando os mesmos atributos de áudio usados para o stream lógico. O app precisa respeitar as perdas de foco para funcionar conforme o esperado nos casos de uso automotivo.

Embora o envio de uma solicitação de foco seja recomendado, ele não é aplicado pelo sistema. Portanto, considere o foco como uma forma de controlar indiretamente e evitar conflitos durante a reprodução, em vez de um mecanismo de controle de áudio principal. O veículo não pode depender do sistema de foco para operar o subsistema de áudio.

Interações de foco

Para oferecer suporte ao AAOS, as solicitações de seleção de áudio são processadas com base em interações predefinidas entre o CarAudioContext da solicitação e o dos detentores de foco atual. Há três tipos de interações:

  • Exclusivo
  • Recusar
  • Concurrent

Interação exclusiva

Esse é o modelo de interação mais usado com o Android.

Em interações exclusivas, apenas um app pode manter o foco por vez. Portanto, uma solicitação de foco recebida recebe o foco, enquanto o detentor de foco existente perde o foco. Como ambos os apps reproduzem mídia, apenas um deles pode manter o foco. Como resultado, a solicitação de foco do app recém-iniciado é retornada com AUDIOFOCUS_REQUEST_GRANTED, enquanto o app que está tocando música recebe um evento de mudança de foco com um status de perda que corresponde ao tipo de solicitação que foi feita.

Recusar interação

Com as interações de rejeição, a solicitação recebida é sempre rejeitada. Por exemplo, ao tentar tocar música enquanto uma chamada está em andamento. Nesse caso, se o discador mantiver a seleção de áudio para uma chamada e um segundo app solicitar a seleção para tocar música, o app de música vai receber AUDIOFOCUS_REQUEST_FAILED em resposta à solicitação. Como a solicitação de foco é rejeitada, nenhuma perda de foco é enviada para o detentor de foco atual.

Interação simultânea

As interações simultâneas são exclusivas do AAOS. Isso permite que os apps que solicitam o foco de áudio no carro mantenham o foco simultaneamente com outros apps. Para que uma interação simultânea ocorra, as seguintes condições precisam ser atendidas. O:

Se esses critérios forem atendidos, a solicitação de foco vai retornar com AUDIOFOCUS_REQUEST_GRANTED, enquanto o detentor de foco atual não tiver nenhuma mudança no foco. No entanto, se o detentor de foco atual optar por receber eventos de abatimento ou pausar quando abafado, o detentor de foco atual vai perder o foco, como ocorre com uma interação exclusiva.

Como lidar com streams simultâneos

Embora a interação simultânea tenha vários usos, tenha cuidado ao misturar e ocultar no nível do hardware em todos os dispositivos de saída. Recomendamos que CarAudioContexts que podem ser reproduzidos simultaneamente sejam roteados para dispositivos de saída diferentes.

Com dispositivos de saída separados para transmissões simultâneas, o HAL pode reduzir o volume de uma das transmissões antes de misturá-las ou encaminhar as transmissões físicas para diferentes alto-falantes no veículo. Se os fluxos lógicos forem misturados no Android, os ganhos serão alterados e entregues como parte do mesmo fluxo físico.

Por exemplo, quando a navegação e a mídia são transmitidas simultaneamente, o ganho do stream de mídia pode ser reduzido temporariamente (ou reduzido) para que as instruções de navegação possam ser ouvidas com mais clareza. Como alternativa, o fluxo de navegação pode ser roteado para os alto-falantes do lado do motorista enquanto a mídia continua a ser reproduzida no restante da cabine.

Matriz de interação

A tabela abaixo mostra a matriz de interação conforme definida por CarAudioService. Cada linha representa o CarAudioContext do detentor de foco atual, e cada coluna representa o da solicitação recebida.

Por exemplo, quando um app de mídia de música mantém o foco enquanto um app de navegação solicita o foco, a matriz indica que as duas interações podem ser executadas simultaneamente, supondo que os outros critérios para interações simultâneas sejam atendidos.

Devido às interações simultâneas, é possível ter mais de um detentor de foco. Nesse caso, uma solicitação de foco recebida é comparada com cada um dos detentores de foco atuais antes de determinar qual interação aplicar. Nesse caso, a interação mais conservadora vence. Rejeitar, depois exclusivo e, por fim, concorrente.

Figura 1. Matriz de interação da seleção de áudio.

No Android 11, uma nova configuração do usuário foi introduzida para permitir que os usuários alterem o comportamento de interação entre a navegação e as ligações. Quando definido, android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL muda a interação entre as solicitações de foco NAVIGATION recebidas e os detentores de foco CALL atuais de concorrente para rejeição. Se um usuário preferir que as instruções de navegação não interrompam uma chamada, ele poderá ativar a configuração. Essa persistência é mantida para o usuário e pode ser definida dinamicamente para que as solicitações de foco posteriores respeitem a nova configuração.

Seleção de áudio com atraso

No Android 11, o AAOS adicionou suporte para solicitar o foco de áudio atrasável. Isso permite que solicitações de foco não temporárias sejam adiadas quando a interação com os detentores de foco atuais normalmente resulta na rejeição delas. Quando uma mudança no foco resulta em um estado em que a solicitação atrasada pode ganhar foco, a solicitação é concedida.

Regras para solicitações de foco de áudio atrasadas

  • Somente solicitações não temporárias. Uma solicitação atrasada só pode ser feita para fontes não transitórias para evitar que um som transitório seja reproduzido muito tempo depois de ser relevante.

  • Apenas uma solicitação pode ser atrasada por vez. Se uma solicitação adiável for feita enquanto já há uma solicitação atrasada, a solicitação atrasada original receberá um evento de mudança AUDIOFOCUS_LOSS e a nova solicitação receberá uma resposta síncrona de AUDIOFOCUS_REQUEST_DELAYED.

  • As solicitações adiáveis precisam ter um OnAudioFocusChangeListener. Quando uma solicitação é adiada, o listener é usado para notificar o solicitante quando a solicitação é concedida (AUDIOFOCUS_GAIN) ou rejeitada mais tarde (AUDIOFOCUS_LOSS).

Solicitar foco adiável

Para criar uma solicitação que pode ser adiada:

  1. Use AudioFocusRequest.Builder#setAcceptsDelayedFocusGain.

    mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();
    
    mDelayedFocusRequest = new AudioFocusRequest
         .Builder(AudioManager.AUDIOFOCUS_GAIN)
         .setAudioAttributes(mMusicAudioAttrib)
         .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
         .setForceDucking(false)
         .setWillPauseWhenDucked(false)
         .setAcceptsDelayedFocusGain(true)
         .build();
    
  2. Ao fazer a solicitação, processe a resposta AUDIOFOCUS_REQUEST_DELAYED:

    int delayedFocusRequestResults = mAudioManager.requestAudioFocus(mDelayedFocusRequest);
    if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        // start audio playback
        return;
    }
    if (delayedFocusRequestResults == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
         // audio playback delayed to audio focus listener
         return;
    }
    
  3. Quando a solicitação é atrasada, o listener de foco lida com as mudanças de foco:

    private final class MediaWithDelayedFocusListener implements
    OnAudioFocusChangeListener {
           @Override
           public void onAudioFocusChange(int focusChange) {
               synchronized (mLock) {
                   switch (focusChange) {
                       case AudioManager.AUDIOFOCUS_GAIN:
                           … // Start focus playback
                       case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                           … // Pause media transiently
                       case AudioManager.AUDIOFOCUS_LOSS:
                           … // Stop media
    

Gerenciamento de foco em várias zonas

Para veículos com várias zonas de áudio, o foco de áudio é gerenciado de forma independente para cada zona. Portanto, uma solicitação para uma zona não considera o que tem o foco em outras zonas, nem faz com que os detentores de foco em outras zonas percam o foco. Com isso, o foco da cabine principal pode ser gerenciado separadamente de um sistema de entretenimento do banco traseiro, sem interromper a reprodução de áudio em uma zona por mudanças feitas no foco para outra.

Para todos os apps, o CarAudioService gerencia o foco automaticamente. A zona de áudio de uma solicitação de foco é determinada pelo UserId ou UID associado (para mais detalhes, consulte Roteamento de áudio em várias zonas).

Solicitar áudio de várias zonas ao mesmo tempo

Se um app quiser reproduzir áudio em várias zonas ao mesmo tempo, ele precisará solicitar o foco para cada zona incluindo AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID no pacote:

//Create attribute with bundle and AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID
Bundle bundle = new Bundle();
bundle.putInt(CarAudioManager.AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID,
               zoneId);

AudioAttributes attributesWithZone = new AudioAttributes.Builder()
     .setUsage(AudioAttributes.USAGE_MEDIA)
     .addBundle(bundle)
     .build();

//Create focus request using built attributesWithZone

Esse parâmetro de pacote permite que o solicitante substitua os mapeamentos automáticos de zona de áudio para usar o ID de zona especificado. Portanto, um app pode emitir solicitações separadas para diferentes zonas de áudio.

Seleção de áudio HAL

A partir do Android 11, o HAL está ativado para solicitar o foco em nome de fluxos externos. Embora opcional, o uso dessas APIs é altamente recomendado para permitir que sons externos sejam participantes ideais no ecossistema do Android e para oferecer uma experiência do usuário perfeita.

O HAL faz a determinação final sobre quais sons devem ter prioridade. Nesse sentido, os sons de emergência e de segurança críticos precisam ser reproduzidos, independentemente de o HAL receber ou não o foco de áudio, e precisam continuar sendo reproduzidos conforme apropriado, mesmo que o HAL perca o foco de áudio. O mesmo vale para qualquer som exigido por regulamentações governamentais.

O HAL precisa silenciar os streams do Android de forma proativa, conforme apropriado, ao reproduzir sons de emergência ou de segurança para garantir que eles sejam ouvidos claramente.

AudioControl@2.0

A versão 2.0 da HAL AudioControl apresenta estas novas APIs:

API Objetivo
IAudioControl#registerFocusListener Registra uma instância de IFocusListener com a HAL AudioControl. Esse listener permite que o HAL solicite e abandone o foco de áudio. O HAL fornece uma instância ICloseHandle para ser usada pelo Android para cancelar o registro do listener.
IAudioControl#onAudioFocusChange Notifica o HAL sobre mudanças de status para focar solicitações feitas pelo HAL pelo IFocusListener, incluindo respostas a solicitações de foco iniciais.
IFocusListener#requestAudioFocus As solicitações são focadas em nome do HAL para um uso, ID de zona e tipo de ganho de foco especificados.
IFocusListener#abandonAudioFocus Abandona as solicitações de foco do HAL para o uso e o ID de zona especificados.

O HAL pode ter várias solicitações de foco ao mesmo tempo, mas é limitado a uma solicitação por uso e pareamento de ID de zona. O Android assume que a HAL iniciará a reprodução de sons para um uso assim que uma solicitação for feita e continuará fazendo isso até que o foco seja abandonado.

Além de registerFocusListener, essas solicitações são oneway para garantir que o Android não atrase o HAL enquanto uma solicitação de foco é processada. O HAL não precisa esperar para receber o foco antes de reproduzir sons críticos para a segurança. É opcional para a HAL detectar e responder a mudanças no foco de áudio usando IAudioControl#onAudioFocusChange.

Serviço de seleção de áudio do carro OEM

No Android 14, o AAOS introduziu os serviços de plug-in do OEM do carro para permitir a capacidade de configuração de alguns componentes do carro. No serviço de plug-in de áudio do carro, o serviço de plug-in permite que os OEMs gerenciem solicitações de foco interceptadas pelo serviço de áudio do carro. Isso dá aos OEMs mais flexibilidade para gerenciar o foco conforme exigido por regras e regulamentos. Assim, a interação com o foco de áudio pode variar entre fabricantes e regiões. A premissa básica para o foco de áudio ainda é válida, ou seja, os apps ainda precisam solicitar o foco para um melhor gerenciamento de áudio e melhorar a experiência do usuário. Em geral, algumas regras ainda se aplicam à solicitação de foco de áudio por apps:

  • Sem nenhum foco de áudio de alta prioridade (incluindo uma ligação, um alerta de emergência ou uma notificação de segurança), os apps poderão receber o foco de áudio de forma temporária ou permanente.

  • Enquanto o foco de mídia estiver ativo:

    • Os apps que solicitam o foco de uso de chamada precisam receber a chamada simultaneamente ou exclusivamente.

    • Os apps que solicitam o foco de uso de navegação precisam receber o foco de navegação simultaneamente ou exclusivamente.

    • Os apps que solicitam o foco de uso do Assistente precisam receber o foco de uso simultaneamente ou exclusivamente.

  • Enquanto os apps de alta prioridade de foco de áudio (incluindo uma ligação, um alerta de emergência ou uma notificação de segurança) estiverem ativos, qualquer solicitação de foco de áudio atrasada recebida precisa ser concedida ou adiada conforme necessário.

Embora as sugestões acima não sejam exaustivas, elas podem ajudar os apps que solicitam foco a receber o foco se não houver sons de alta prioridade ativos. Mesmo quando sons de alta prioridade estão ativos, as solicitações de foco atrasadas ainda precisam ser respeitadas e precisam ser capazes de ganhar foco quando o som de alta prioridade parar.