Messa a fuoco audio

Prima di avviare uno stream logico, un'app deve richiedere l'attenzione audio utilizzando gli stessi attributi audio utilizzati per lo stream logico. Sebbene l'invio di una richiesta di messa a fuoco sia consigliato, non è impostato dal sistema. Alcune app potrebbero saltare esplicitamente l'invio della richiesta per ottenere comportamenti specifici (ad esempio riprodurre intenzionalmente l'audio durante una telefonata).

Per questo motivo, dovresti considerare l'attenzione come un modo per controllare indirettamente e risolvere i conflitti di riproduzione e non come un meccanismo di controllo audio principale. Il veicolo non deve dipendere dal sistema di attenzione per il funzionamento del sottosistema audio.

Interazioni con lo stato attivo

Per supportare le esigenze di AAOS, le richieste di attenzione audio vengono gestite in base a interazioni predefinite tra il CarAudioContext della richiesta e quello dei detentori dell'attenzione attuali. Esistono tre tipi di interazioni: esclusive, di rifiuto e concorrenti.

Interazione esclusiva

Nelle interazioni esclusive, solo un'applicazione può avere il focus alla volta. Pertanto, la richiesta di messa a fuoco in arrivo viene concessa mentre il detentore della messa a fuoco esistente perde la messa a fuoco. Un esempio è quando un utente avvia una nuova applicazione musicale mentre la musica è già in riproduzione in un'applicazione esistente. Poiché entrambe riproducono contenuti multimediali, solo una delle applicazioni può avere il focus alla volta. Di conseguenza, la richiesta di attenzione dell'app appena avviata viene restituita con AUDIOFOCUS_REQUEST_GRANTED e l'app che sta attualmente riproducendo musica riceve un evento di modifica dell'attenzione con uno stato di perdita corrispondente al tipo di richiesta effettuata. Questo è il modello di interazione più comune con Android.

Rifiutare l'interazione

Con le interazioni di rifiuto, la richiesta in arrivo viene sempre rifiutata. Il tentativo di riprodurre musica mentre è in corso una chiamata è un esempio di interazione rifiutata. In questo caso, se il tastierino ha attualmente il controllo audio per una chiamata e una seconda applicazione richiede il controllo per riprodurre musica, l'applicazione musicale riceve AUDIOFOCUS_REQUEST_FAILED in risposta alla sua richiesta. Poiché la richiesta di attivazione dell'attenzione viene rifiutata, non viene inviata alcuna perdita di attenzione al proprietario dell'attenzione corrente.

Interazione simultanea

La caratteristica più unica di AAOS sono le interazioni simultanee. In questo modo, le applicazioni che richiedono il controllo audio nell'auto possono mantenere il controllo contemporaneamente ad altre applicazioni. Affinché si verifichi un'interazione simultanea, devono essere soddisfatte le seguenti condizioni. La

Se questi criteri sono soddisfatti, la richiesta di attivazione dello stato attivo viene restituita con AUDIOFOCUS_REQUEST_GRANTED, mentre lo stato attivo corrente non subisce variazioni. Tuttavia, se l'attuale detentore dell'attenzione sceglie di ricevere eventi di ducking o di mettere in pausa quando viene eseguito il ducking, perde l'attenzione, proprio come con un'interazione esclusiva.

Gestione di stream simultanei

Sebbene l'interazione simultanea abbia molte applicazioni utili, gli OEM devono occuparsi della miscelazione e del ducking a livello hardware sui dispositivi di output. Per questo motivo, è fortemente consigliato di indirizzare i CarAudioContext solo allo stesso dispositivo di output dei CarAudioContext con cui non possono essere riprodotti contemporaneamente. Avere dispositivi di output separati per gli stream simultanei consente all'HAL di disattivare uno degli stream prima di combinarli o di instradare gli stream fisici a diversi altoparlanti nel veicolo. Se gli stream logici vengono combinati in Android, i relativi guadagni non vengono alterati e vengono pubblicati all'interno dello stesso stream fisico.

Ad esempio, quando la navigazione e i contenuti multimediali vengono riprodotti contemporaneamente, l'amplificazione dello stream multimediale potrebbe essere ridotta temporaneamente (attenuata) in modo che le istruzioni di navigazione possano essere ascoltate più chiaramente. In alternativa, lo stream di navigazione potrebbe essere indirizzato agli altoparlanti lato conducente mentre i contenuti multimediali continuano a essere riprodotti nel resto dell'abitacolo.

Matrice di interazione

La tabella seguente mostra la matrice di interazione come definita da CarAudioService. Le righe rappresentano il CarAudioContext dell'elemento attualmente attivo e le colonne rappresentano quello della richiesta in arrivo.

Ad esempio, se al momento è attiva un'app di contenuti multimediali musicali e un'app di navigazione richiede l'attenzione, la matrice mostra che le due interazioni possono essere riprodotte contemporaneamente, assumendo che gli altri criteri per le interazioni simultanee siano soddisfatti.

A causa delle interazioni simultanee, è possibile che esista più di un detentore dell'attenzione. In questo caso, una richiesta di attenzione in arrivo viene confrontata con ciascuno dei detentori di attenzione attuali prima di decidere quale tipo di interazione applicare. In questo caso, vince l'interazione più conservativa (rifiuta, poi esclusiva e infine simultanea).

Nella tabella seguente sono riportate le interazioni di messa a fuoco tra CarAudioContext per una richiesta di messa a fuoco in arrivo (colonne) e il contesto dei detentori di stato attivo esistenti (righe). Ogni cella rappresenta il tipo di interazione previsto per i due contesti.

Interazioni con il focus audio

Figura 1. Interazioni con il focus audio

In Android 11 è stata introdotta una nuova impostazione utente per consentire agli utenti di modificare il comportamento di interazione tra navigazione e chiamate. Se impostato, android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL cambia l'interazione tra le richieste di attenzione NAVIGATION in arrivo e i detentori di attenzione CALL attuali da contemporanea a rifiuta. Pertanto, se un utente preferisce che la chiamata non venga interrotta dalle istruzioni di navigazione, può attivare questa impostazione. Questo valore viene mantenuto per l'utente e può essere impostato dinamicamente in modo che le richieste di messa a fuoco successive rispettino il nuovo valore dell'impostazione.

Focus audio posticipabile

In Android 11, AAOS ha aggiunto il supporto per la richiesta dell'attenzione audio posticipabile. In questo modo, le richieste di messa a fuoco non transitorie possono essere ritardate quando la loro interazione con i detentori attuali della messa a fuoco normalmente ne comporterebbe il rifiuto. Una volta che una modifica dell'attenzione genera uno stato in cui la richiesta in ritardo può acquisire l'attenzione, la richiesta viene concessa.

Regole per le richieste di messa a fuoco audio ritardate

  • Solo richieste non transitorie: come accennato in precedenza, una richiesta differita può essere effettuata solo per le origini non transitorie. Questo serve per evitare che un suono transitorio venga riprodotto molto tempo dopo che è stato pertinente.
  • È possibile ritardare una sola richiesta alla volta: se viene effettuata una richiesta ritardabile mentre è già presente una richiesta ritardata, la richiesta ritardata originale riceve un evento di modifica AUDIOFOCUS_LOSS e la nuova richiesta riceve una risposta sincrona di AUDIOFOCUS_REQUEST_DELAYED.
  • Le richieste posticipabili devono avere un OnAudioFocusChangeListener. Una volta che una richiesta viene ritardata, l'ascoltatore viene utilizzato per notificare al richiedente quando la richiesta viene finalmente concessa (AUDIOFOCUS_GAIN) o se viene rifiutata in un secondo momento (AUDIOFOCUS_LOSS).

Richiedi messa a fuoco posticipabile

Per creare una richiesta che può essere ritardata, utilizza AudioFocusRequest.Builder#setAcceptsDelayedFocusGain:

mMediaWithDelayedFocusListener = new MediaWithDelayedFocusListener();

mDelayedFocusRequest = new AudioFocusRequest
     .Builder(AudioManager.AUDIOFOCUS_GAIN)
     .setAudioAttributes(mMusicAudioAttrib)
     .setOnAudioFocusChangeListener(mMediaWithDelayedFocusListener)
     .setForceDucking(false)
     .setWillPauseWhenDucked(false)
     .setAcceptsDelayedFocusGain(true)
     .build();

Poi, quando effettui la richiesta, gestisci la risposta 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;
}

Quando la richiesta è in ritardo, l'ascoltatore dello stato attivo è responsabile della gestione delle modifiche dello stato attivo:

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

Gestione dell'attenzione multizona

Per i veicoli con più zone audio, l'attenzione audio viene gestita in modo indipendente per ogni zona. Di conseguenza, una richiesta in una zona non tiene conto di ciò che ha il controllo in altre zone né fa perdere il controllo ai detentori del controllo in altre zone. In questo modo, l'attenzione dell'abitacolo principale può essere gestita separatamente da un sistema di intrattenimento per i sedili posteriori, evitando così di interrompere la riproduzione audio in una zona a causa delle modifiche dell'attenzione in un'altra.

Per tutte le applicazioni, la gestione dell'attenzione viene gestita automaticamente dal CarAudioService. La zona audio di una richiesta di attenzione viene determinata in base al UserId o al UID associato. Per maggiori dettagli, vedi Routing audio.

Richiesta di audio da più zone contemporaneamente

Se un'app vuole riprodurre l'audio in più zone contemporaneamente, deve richiedere l'attenzione per ogni zona includendo AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID nel bundle:

// 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

Questo parametro del bundle consente all'utente che effettua la richiesta di ignorare le mappature automatiche delle zone audio per utilizzare l'ID zona specificato. Pertanto, un'app potrebbe inviare richieste separate per zone audio diverse.

HAL Audio Focus

A partire da Android 11, l'HAL è ora abilitato a richiedere lo stato attivo per conto di stream esterni. Sebbene facoltative, queste API sono vivamente consigliate per consentire ai suoni esterni di essere partecipanti migliori nell'ecosistema Android e per offrire un'esperienza utente più fluida.

Tieni presente che è ancora l'HAL a decidere quali suoni devono avere la priorità. In questo senso, gli avvisi di emergenza e di sicurezza critici devono essere riprodotti indipendentemente dal fatto che all'HAL sia stato concesso o meno il controllo audio e devono continuare a essere riprodotti in modo appropriato anche se l'HAL perde il controllo audio. Lo stesso vale per tutti i suoni richiesti dalle normative.

Nello stesso modo, l'HAL dovrebbe comunque disattivare in modo proattivo gli stream di Android, se opportuno, quando vengono riprodotti suoni di emergenza o di sicurezza critici per garantire che vengano ascoltati chiaramente.

AudioControl@2.0

La versione 2.0 dell'HAL AudioControl introduce diverse nuove API:

API Finalità
IAudioControl#registerFocusListener Registra un'istanza di IFocusListener con l'HAL AudioControl. Questo ascoltatore consente all'HAL di richiedere e abbandonare l'attenzione audio. È previsto che il componente HAl fornisca un'istanza di ICloseHandle da utilizzare da parte di Android per annullare la registrazione dell'ascoltatore.
IAudioControl#onAudioFocusChange Invia una notifica all'HAL delle modifiche dello stato per mettere a fuoco le richieste effettuate dall'HAL tramite il IFocusListener. Sono incluse le risposte alle richieste di messa a fuoco iniziale.
IFocusListener#requestAudioFocus Richiede l'attenzione per conto dell'HAL per un utilizzo, un ID zona e un tipo di guadagno di messa a fuoco specificati.
IFocusListener#abandonAudioFocus Abbandona le richieste di attenzione HAL esistenti per l'utilizzo e l'ID zona specificati.

L'HAL può avere più richieste di messa a fuoco contemporaneamente, ma è limitato a una richiesta per accoppiamento di utilizzo e ID zona. Tieni presente che Android presuppone che l'HAL inizi immediatamente a riprodurre suoni per un utilizzo dopo che è stata effettuata una richiesta e continui a farlo finché non perde lo stato attivo.

A parte registerFocusListener, tutte queste richieste sono oneway per garantire che Android non ritardi l'HAL durante l'elaborazione di una richiesta di messa a fuoco. L'HAL non deve non attendere di acquisire lo stato attivo prima di riprodurre suoni critici per la sicurezza. È facoltativo per l'HAL ascoltare e rispondere alle variazioni dell'attenzione audio tramite IAudioControl#onAudioFocusChange, anche se è consigliabile farlo se opportuno.