Audio focus

Before starting a logical stream, an app request audio focus using the same audio attributes as is used for the logical stream. The app must respect focus losses to perform as expected in the automotive use cases.

While sending a focus request is recommended, it isn't enforced by the system. Therefore, consider focus as a means to indirectly control and avoid conflict during playback instead of as a primary audio control mechanism. The vehicle shouldn't depend on the focus system for operation of the audio subsystem.

Focus interactions

To support AAOS, audio focus requests are handled based on predefined interactions between the request’s CarAudioContext and that of current focus holders. There are three types of interactions:

  • Exclusive
  • Reject
  • Concurrent

Exclusive interaction

This is the interaction model most commonly used with Android.

In exclusive interactions, only one app is allowed to hold focus at a time. Therefore, an incoming focus request is granted focus while the existing focus holder loses focus. Since both apps play media, only one app is allowed to hold focus. As a result, the newly started app’s focus request is returned with AUDIOFOCUS_REQUEST_GRANTED while the app currently playing music receives a focus change event with a loss status that corresponds to the type of request that was made.

Reject interaction

With reject interactions, the incoming request is always rejected. For example, when attempting to play music while a call is in progress. In this case, if the Dialer holds audio focus for a call and a second app requests focus to play music, the music app receives AUDIOFOCUS_REQUEST_FAILED in response to the request. Since the focus request is rejected, no focus loss is dispatched to the current focus holder.

Concurrent interaction

Unique to AAOS are concurrent interactions. This gives apps that request audio focus in the car the ability to hold focus concurrently with other apps. For a concurrent interaction to take place, the following conditions must be met. The:

If these criteria are met, then the focus request returns with AUDIOFOCUS_REQUEST_GRANTED while the current focus holder has no change in focus. However, if the current focus holder opts to receive duck events or to pause when ducked, the current focus holder loses focus, as occurs with an exclusive interaction.

Handling concurrent streams

While the concurrent interaction has numerous uses, be careful at the mixing and ducking at the hardware level across output devices. We strongly recommend that CarAudioContext's that are allowed to play concurrently should be routed to different output devices.

By having separate output devices for concurrent streams, this enables the HAL to duck one of the streams before mixing them, or to route the physical streams to different speakers in the vehicle. If the logical streams are mixed within Android, gains are unaltered and delivered as part of the same physical stream.

For example, when navigation and media are delivered simultaneously, the gain for the media stream could temporarily be reduced (or, ducked) so that navigation instructions can be heard more clearly. Alternatively, the navigation stream could be routed to the driver side speakers while media continues to play throughout the rest of the cabin.

Interaction matrix

The table below shows the interaction matrix as defined by CarAudioService. Each row represents the current focus holder’s CarAudioContext and each column represents that of the incoming request.

For example, when a music media app holds focus as a navigation app requests focus, the matrix indicates that the two interactions can play concurrently, assuming the other criteria for concurrent interactions are fulfilled.

Because of the concurrent interactions, it's possible to have more than one focus holder. In this case, an incoming focus request is compared with each of the current focus holders before determining what interaction to apply. In this case, the most conservative interaction wins. Reject, then exclusive, and finally concurrent.

Audio focus interaction matrix

Figure 1. Audio focus interaction matrix.

In Android 11, a new user setting was introduced to allow users to alter the interaction behavior between navigation and phone calls. When set, android.car.KEY_AUDIO_FOCUS_NAVIGATION_REJECTED_DURING_CALL changes the interaction between incoming NAVIGATION focus requests and current CALL focus holders from concurrent to rejects. If a user prefers that navigation instructions not interrupt a call, they can enable the setting. This is persisted for the user, and can be set dynamically so that subsequent focus requests respect the new setting.

Delayable audio focus

In Android 11, AAOS added support for requesting delayable audio focus. This allows non-transient focus requests to be delayed when their interaction with current focus holders would normally result in them being rejected. Once a change in focus results in a state where the delayed request can gain focus, the request is granted.

Rules for delayed audio focus requests

  • Non-transient requests only. A delayed request can only be made for non-transient sources in order to avoid having a transient sound play long after it's relevant.

  • Only one request can be delayed at a time. If a delayable request is made while there is already a delayed request, the original delayed request receives a AUDIOFOCUS_LOSS change event and the new request receives a synchronous response of AUDIOFOCUS_REQUEST_DELAYED.

  • Delayable requests must have a OnAudioFocusChangeListener Once a request is delayed, the listener is used to notify the requester when the request is eventually granted (AUDIOFOCUS_GAIN), or if it’s rejected later (AUDIOFOCUS_LOSS).

Request delayable focus

To build a request that can be delayed:

  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. When making the request, handle the AUDIOFOCUS_REQUEST_DELAYED response:

    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. When the request is delayed, the focus listener handles changes in focus:

    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
    

Multi-zone focus management

For vehicles with multiple audio zones, audio focus is managed independently for each zone. As such, a request to one zone doesn't take into account what holds focus in other zones, nor does it cause focus holders in other zones to lose focus. With this, the main cabin's focus can be managed separately from a rear seat entertainment system, thereby not interrupting the audio playback in one zone by changes made in focus to another.

For all apps, the CarAudioService automatically manages focus. A focus request’s audio zone is determined by its associated UserId or UID (for details, see Audio Routing).

Request audio from multiple zones concurrently

If an app wants to play audio in multiple zones concurrently, it must request focus for each zone by including AUDIOFOCUS_EXTRA_REQUEST_ZONE_ID in the 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

This bundle parameter allows the requestor to override the automatic audio zone mappings to instead use the specified zone ID. Therefore, an app could issue separate requests for different audio zones.

HAL audio focus

Starting in Android 11, the HAL is enabled to request focus on behalf of external streams. While optional, use of these APIs is highly encouraged to enable external sounds to be optimal participants in the Android ecosystem and to provide a seamless user experience.

The HAL makes the final determination around which sounds should get priority. To this extent, emergency and safety critical sounds should be played regardless of whether or not the HAL is granted audio focus and should continue to be played as appropriate even if the HAL loses audio focus. The same is true for any sounds required by government regulations.

The HAL should proactively mute Android streams as appropriate when playing emergency or safety-critical sounds to ensure they are heard clearly.

AudioControl@2.0

Version 2.0 of AudioControl HAL introduces these new APIs:

API Purpose
IAudioControl#registerFocusListener Registers an instance of IFocusListener with the AudioControl HAL. This listener enables the HAL to request and abandon audio focus. The HAl provides an ICloseHandle instance to be used by Android to unregister the listener.
IAudioControl#onAudioFocusChange Notifies the HAL of changes in status to focus requests made by the HAL through the IFocusListener, including responses to initial focus requests.
IFocusListener#requestAudioFocus Requests focus on behalf of the HAL for a specified usage, zone Id, and focus gain type.
IFocusListener#abandonAudioFocus Abandons existing HAL focus requests for the specified usage and zone Id.

The HAL can have multiple focus requests at the same time, but is limited to one request per usage and zone Id pairing. Android assumes the HAL immediately starts playing sounds for a usage once a request has been made and continutes to do so until it abandons focus.

Other than registerFocusListener, these requests are oneway to ensure that Android doesn't delay the HAL while a focus request is processed. The HAL should not wait to gain focus before playing safety-critical sounds. It's optional for the HAL to listen for and respond to changes in audio focus through IAudioControl#onAudioFocusChange.

OEM car audio focus service

In Android 14, AAOS introduced the car OEM plugin services to enable configurability for some car components. For Car Audio Plugin Service, the plugin service allows for OEMs to manage focus requests intercepted by the car audio service. This gives OEMs more flexibility in terms of managing focus as required by rules and regulations. As such, audio focus interaction may differ between manufacturers, and from region to region. The basic premise for audio focus still holds, that apps should still request focus for better management audio to enhance user experience. In general, certain rules still apply for audio focus request by apps:

  • Without any standing, high priority audio focus (including a phone call, emergency alert, or safety notification) apps should be able to gain audio focus either transiently or permanently.

  • While a media focus is active:

    • Apps requesting call usage focus should be able to receive the call either concurrently or exclusively.

    • Apps requesting navigation usage focus should be able to receive navigation focus either concurrently or exclusively.

    • Apps requesting assistant usage focus should be able to receive usage focus either concurrently or exclusively.

  • While standing high priority audio focus (including a phone call, emergency alert, or safety notification) apps are active, any incoming delayed audio focus request should be granted or delayed as needed.

While the suggestions above are not exhaustive, they can help apps requesting focus to obtain focus if no active high priority sounds exist. Even while high priority sounds are active, delayed focus requests should still be respected and should be able to gain focus when the high priority sound stops.