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 current playing music app 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:
Incoming focus request must ask for AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
Current focus holder doesn't setPauseWhenDucked(true)
Current focus holder opts not to receive duck events
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.
Handle 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
instances of CarAudioContext
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
This table 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.
Figure 1. Audio focus interaction matrix.
Navigation during phone calls
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 ofAUDIOFOCUS_REQUEST_DELAYED
.Delayable requests must have
OnAudioFocusChangeListener
. After 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:
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();
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; }
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
System enforced fade
Android 15 introduces system-enforced audio fade in AAOS. In Android, the audio focus isn't enforced by the system. So, while app developers are encouraged to comply with the audio focus guidelines, if an app continues to play loudly even after losing audio focus, the system can't prevent it.
In safety-critical automotive environments, adherence to audio focus is vital for minimizing driver distraction. With this feature, the audio framework now automatically fades apps that lose audio focus, for a more controlled and predictable audio experience.
This enhancement helps ensure that apps adhere to audio focus loss decision as defined by the interaction matrix, preventing audio playback conflicts.
High-level design
The following figure shows the high-level design and support for focus loss feature in the cars:
Figure 2. High-level design for system-enforced fade feature.
- Targeted fading: System enforcement of fading in Android 15 is specifically designed for situations where an app loses audio focus but continues to play audio.
- Fade-out mechanism: When an app loses audio focus to a new
requesting app:
- The audio framework automatically fades out the losing app audio.
- Following the fade-out, the audio stream is silenced by the system.
- The app then receives an audio focus loss notification.
- Misbehaving apps are silenced until they regain the audio focus.
- The default logic is to fade in the apps that are faded out after 2 seconds. However, OEMs can configure this to any timeout value.
- The audio framework uses the OEM configs for both fade-out and fade-in operations.
OEM configuration file: Android 15 includes a new configuration file,
car_audio_fade_configuration.xml
:- This file allows OEMs to define criteria for when the system's audio focus enforcement is applied to a losing app.
- The audio framework enforces fade-out and silencing only if the losing app matches the OEM-defined rules in this XML file.
- This provides a mechanism for OEMs to customize the feature's behavior based on app characteristics or audio usage types.
Feature control with RRO: A new runtime resource overlay (RRO) feature flag,
audioUseFadeManagerConfiguration
, has been introduced to enable or disable this feature:- The feature is disabled by default.
- To activate system-enforced audio focus loss, OEMs must
set this flag to
true
. - Although car audio framework expects valid fade config definitions when the flag is enabled, the absence of the such definitions does not automatically result in a fatal exception.
- All apps of fade configs must have matching fade definitions. It's a fatal error to call out a fade config (by its name) as part of car audio configuration without providing a valid definition.
- When the flag is disabled, all fade config definitions and any config references are ignored.
Fade manager configuration
The Android 15 audio framework introduces a unified FadeManagerConfiguration
to provide OEMs with granular control over audio fading behavior. This framework
is illustrated in Figure 3:
Figure 3. Fade manager configuration.
This configuration includes:
- Fade transition properties: Settings for both fade-out and fade-in.
- Can be defined with specific audio usages or attributes.
- Allows for custom duration settings.
- These settings are used to construct
VolumeShaper.Configuration
.
- Fading policies: Rules governing when fading occurs.
- A global toggle to enable or disable fading.
- A configurable list of fadeable audio usages (eligible for fade-out upon losing focus).
- Exclusion lists (unfadeable) prevent critical or designated audio sources
from being faded. These lists can be based on:
- Content types
- Audio attributes
- App UIDs (can be set during runtime only)
OEM configurations
In this section, we look at available OEM customizations.
Car audio fade configuration XML file
Android 15 introduces a new configuration file,
car_audio_fade_configuration.xml
, enabling extensive OEM customization of
audio fade-out behavior during focus loss.
- This XML file allows for the definition of multiple distinct fade
configurations, each requiring a unique name for cross-referencing within
car_audio_configuration.xml
. - These configurations can be flexibly applied across different audio zones and zone configs.
- Notably, each fade configuration solely accepts duration values in
milliseconds, which the system then uses to internally generate the
corresponding
VolumeShaper.Configuration
.
For practical implementation guidance, consult the example configurations
provided for the emulator located at
device/generic/car/emulator/audio/car_audio_fade_configuration.xml
.
Car audio configuration XML file
Android 15 introduces an updated car_audio_configuration.xml
file, now at
version 4, which incorporates new applyFadeConfigs
and fadeConfig
tags.
The applyFadeConfigs
tag can contain multiple fadeConfig
definitions,
allowing for flexible fade configuration. Each definition:
- Must include one default
fadeConfig
designated withisDefault = true
. - Can include several transient
fadeConfig
definitions. These transient configurations are applied specifically during audio focus loss interactions, and only when the audio focus gaining app matches the criteria defined within the transient config.
For practical implementation guidance, consult the example configurations
provided for the emulator located at
device/generic/car/emulator/audio/car_audio_configuration.xml
.
OEM audio focus service extension
OEMs who implement a custom car audio focus service have the flexibility to
configure audio fade settings by including them within OemCarAudioFocusResult
.
This can be achieved using the
setAudioAttributesToCarAudioFadeConfigurationMap()
builder method:
/** @see OemCarAudioFocusResult#getAudioAttributesToCarAudioFadeConfigurationMap() **/
@NonNull
public Builder setAudioAttributesToCarAudioFadeConfigurationMap(@NonNull
Map<AudioAttributes, CarAudioFadeConfiguration> attrsToCarAudioFadeConfig) {
}
Notably, OEMs can choose to use either preconfigured boot-time fade settings or dynamically apply configurations through their custom audio focus service, offering adaptable control.
Sequence diagram
This sequence diagram illustrates the behavior following audio focus grant to
App2
and the subsequent loss of audio focus by App1
:
- Upon the car audio service dispatching audio focus loss to
App1
, the playback fromApp1
player undergoes a fade-out as defined by the activeFadeManagerConfiguration
s. Once the fade-out operation is complete,App1
receives the standard audio focus loss callback. - Optionally, the audio for
App1
can be faded back in after a configurable duration. OEMs have the flexibility to set this duration throughBuilder#setFadeInDurationForUsage(int, long)
according to their specific product requirements.
Figure 4. Sequence diagram for car audio fade feature.
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 Multi-zone 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 these suggestions 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.