Routing dell'audio

In Android 10, car_audio_configuration.xml sostituisce car_volumes_groups.xml e IAudioControl.getBusForContext. Nel nuovo file di configurazione è definito un elenco di zone. Ogni zona ha uno o più gruppi di volumi con i relativi dispositivi associati e ogni dispositivo ha i contesti che devono essere instradati all'interno della zona. È obbligatorio che tutti i contesti siano rappresentati all'interno di ogni zona.

Configurazione del routing audio

I file di criteri audio, che in genere si trovano nella partizione del fornitore, rappresentano la configurazione dell'hardware audio della scheda. Tutti i dispositivi a cui viene fatto riferimento in car_audio_configuration.xml devono essere definiti all'interno di audio_policy_configuration.xml.

Attivazione del routing di AAOS

Per utilizzare il routing basato su AAOS, devi impostare il audioUseDynamicRouting flag su true:

<resources>
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

Quando false, il routing e gran parte di CarAudioService verranno disattivati e il sistema operativo tornerà al comportamento predefinito del AudioService.

Zona principale

Per impostazione predefinita, tutto l'audio verrà indirizzato alla zona principale. Può esserci soltanto una zona principale, indicata nella configurazione dall'attributo isPrimary="true".

Configurazione di esempio

Ad esempio, un veicolo potrebbe avere due zone: una principale e un sistema di intrattenimento per i sedili posteriori. Di conseguenza, un possibile car_audio_configuration.xml viene definito come segue:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                       <context context="announcement"/>
                   </device>
                   <device address="bus3_call_ring_out">
                       <context context="call_ring"/>
                   </device>
                   <device address="bus6_notification_out">
                       <context context="notification"/>
                   </device>
                   <device address="bus7_system_sound_out">
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                   </device>
               </group>
               <group>
                   <device address="bus1_navigation_out">
                       <context context="navigation"/>
                   </device>
                   <device address="bus2_voice_command_out">
                       <context context="voice_command"/>
                   </device>
               </group>
               <group>
                   <device address="bus4_call_out">
                       <context context="call"/>
                   </device>
               </group>
               <group>
                   <device address="bus5_alarm_out">
                       <context context="alarm"/>
                   </device>
               </group>
           </volumeGroups>
       </zone>
        <zone name="rear seat zone" audioZoneId="1">
           <volumeGroups>
               <group>
                   <device address="bus100_rear_seat">
                       <context context="music"/>
                       <context context="navigation"/>
                       <context context="voice_command"/>
                       <context context="call_ring"/>
                       <context context="call"/>
                       <context context="alarm"/>
                       <context context="notification"/>
                       <context context="system_sound"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                       <context context="announcement"/>
                   </device>
               </group>
           </volumeGroups>
    </zones>
</audioZoneConfiguration>

Qui la zona principale ha separato i contesti in dispositivi diversi. In questo modo, l'HAL può applicare diversi effetti di post-elaborazione e di mixing su ogni uscita del dispositivo utilizzando l'hardware del veicolo. I dispositivi sono stati suddivisi in quattro gruppi di volume: contenuti multimediali, navigazione, chiamate e sveglie. Se il sistema è configurato su useFixedVolume, i livelli di volume per ciascun gruppo verranno trasmessi all'HAL per essere applicati all'uscita di questi dispositivi.

Per la zona secondaria, l'output previsto è tramite un singolo dispositivo di output. In questo esempio, tutti gli utilizzi vengono indirizzati al singolo dispositivo e al gruppo di volumi per mantenere la semplicità.

Configurazione audio della zona passeggeri

In Android 11, car_audio_configuration.xml è stato ulteriormente ampliato per introdurre due nuovi campi, audioZoneId e occupantZoneId. Il primo, audioZoneId, può essere utilizzato per controllare meglio la gestione delle zone. D'altra parte, occupantZoneId può essere utilizzato per configurare il routing in base allo User-ID.

Per utilizzare questi nuovi campi, è obbligatoria la versione 2 di car_audio_configuration.xml. Se esaminiamo la configurazione audio riportata sopra, ma utilizziamo il nuovo campo per la mappatura dell'ID zona occupante e dell'ID zona audio, la nuova configurazione senza le definizioni dei gruppi di volume può essere impostata come segue:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true" occupantZoneId="0">
         ...
       </zone>
       <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1">
         ...
       </zone>
    </zones>
</audioZoneConfiguration>

La configurazione riportata sopra definisce una mappatura per la zona principale alla zona occupante 0 e per audioZoneId 1 a occupantZoneId 1. In generale, è possibile configurare qualsiasi mappatura tra la zona occupanti e la zona audio, ma la mappatura deve essere uno a uno. Ecco le regole che hanno definito i due nuovi campi:

  • audioZoneId per la zona principale è sempre pari a zero
  • I numeri audioZoneId e occupantZoneId non possono essere ripetuti
  • audioZoneId e occupantZoneId possono avere solo una mappatura uno a uno

Routing tramite un UID dell'applicazione

In CarAudioManager 10 è stata introdotta una serie di API nascoste per consentire alle app di eseguire query e impostare zone audio e messa a fuoco.

int[] getAudioZoneIds();
int getZoneIdForUid(int uid);
boolean setZoneIdForUid(int zoneId, int uid);
boolean clearZoneIdForUid(int uid);

Le API sopra indicate consentivano a un'applicazione proprietaria di gestire il routing audio in base all'UID di un'applicazione. Di conseguenza, sono necessari anche l'ID zona audio e l'UID dell'applicazione. Una volta acquisite queste informazioni, puoi impostare il routing audio utilizzando l'API CarAudioManager#setZoneIdForUid.

Modificare le zone per un'app

Per impostazione predefinita, tutto l'audio viene indirizzato alla zona principale. Per aggiornare un'applicazione in modo che venga indirizzata a una zona diversa, utilizza CarAudioManager#setZoneIdForUid:

// Find zone to play
int zoneId = ...

// Find application's uid
Int uid = mContext.getPackageManager()
        .getApplicationInfo(mContext.getPackageName(), 0)
        .uid;

if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) {
    Log.d(TAG, "Zone successfully updated");
} else {
    Log.d(TAG, "Failed to change zone");
}

N Nota:gli stream e lo stato di concentrazione non possono cambiare dinamicamente le zone. Pertanto, per cambiare zona è necessario interrompere la riproduzione e richiedere nuovamente il controllo.

Routing con User-ID

Sebbene il routing basato su UID di un'applicazione consenta il controllo fine del routing audio di ogni applicazione, richiede anche che il routing audio di ogni applicazione sia definito prima che l'applicazione richieda effettivamente l'attenzione audio e riproduca l'audio. Per attenuare questo problema e facilitare ulteriormente la riproduzione di audio da parte di applicazioni di terze parti senza modifiche, CarAudioService utilizza la mappatura della zona degli occupanti dell'auto e della zona audio per definire il routing in base all'ID utente. In questo modo, quando un utente accede alla zona occupanti, il servizio audio della vettura viene informato. Con questo indicatore, la gestione e il routing dell'attenzione audio vengono configurati automaticamente per tutte le zone audio.

Il routing basato su UID delle applicazioni può comunque essere utilizzato, ma deve essere eseguito indipendentemente dal routing dell'ID utente. Ciò significa che se è definita la mappatura della zona degli occupanti alla zona audio dell'auto, il routing basato su UID viene disattivato e il tentativo di chiamare CarAudioManager#setZoneidForUid genera un errore.

Sebbene il routing audio e la gestione dell'attenzione siano stati semplificati con la gestione della zona degli occupanti, l'utente deve comunque essere assegnato a una zona degli occupanti. Per farlo, usa CarOccupantZoneManager#assignProfileUserToOccupantZone. Questa API richiede l'autorizzazione per gestire gli utenti. Attualmente, si prevede che gli OEM gestiscano l'assegnazione dell'utente alla zona occupante tramite una sorta di interfaccia utente di sistema. Al termine, l'avvio delle applicazioni, il routing audio e la gestione dell'attenzione verranno configurati automaticamente per l'utente.

Routing con setPreferredDevice

Oltre alle modifiche sopra indicate, Android 11 dispone anche di una nuova API per eseguire query sui dispositivi di output associati a ogni zona, CarAudioManager#getOutputDeviceForUsage(int zoneId, int usage).

L'API può essere utilizzata per eseguire query su un dispositivo di output per una determinata zona e un utilizzo dell'attributo audio. In questo modo, le applicazioni proprietarie possono instradare l'audio in zone diverse utilizzando l'API setPreferredDevice del player. L'getOutputDeviceForUsage API richiedePERMISSION_CAR_CONTROL_AUDIO_SETTINGS ed è un'API di sistema. Di seguito è riportato un esempio di ricerca del dispositivo multimediale per una determinata zona e di indirizzamento a quel dispositivo utilizzando l'API setPreferredDevice.

audioZoneId = ... ;
mediaDeviceInfo = mCarAudioManager
            .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA);
…
mPlayer.setPreferredDevice(mediaDeviceInfo);