Audio control HAL was introduced in Android 9 to support audio use cases relevant to automotive. As of Android 14, Audio control HAL supports:
- Fade and balance
- HAL audio focus request
- Device muting and ducking
- Audio device gain changes
- Audio port configuration changes
Figure 1 shows a high-level overview of the car audio service architecture, in which the car audio service communicates with the audio control HAL.
Figure 1. Configure multi-zone audio.
Audio fade and balance
HIDL audio control HAL version 1 was introduced in Android
9 to support audio fade and balance in automotive use
cases. Separate from the generic audio effects already provided in Android, this
mechanism allows for system apps to set the audio balance and fade through
CarAudioManager APIs:
class CarAudioManager {
/**
* Adjust the relative volume in the front vs back of the vehicle cabin.
*
* @param value in the range -1.0 to 1.0 for fully toward the back through
* fully toward the front. 0.0 means evenly balanced.
*/
@SystemApi
@RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
public void setFadeTowardFront(float value);
/**
* Adjust the relative volume on the left vs right side of the vehicle cabin.
*
* @param value in the range -1.0 to 1.0 for fully toward the left through
* fully toward the right. 0.0 means evenly balanced.
*/
@SystemApi
@RequiresPermission(Car.PERMISSION_CAR_CONTROL_AUDIO_VOLUME)
public void setBalanceTowardRight(float value);
}
Once these APIs are called, the respective audio control HAL APIs are called from the car audio service:
interface IAudioControl {
/**
* Control the right/left balance setting of the car speakers.
*/
oneway setBalanceTowardRight(float value);
/**
* Control the fore/aft fade setting of the car speakers.
*/
oneway setFadeTowardFront(float value);
}
The API is available on all versions of the audio control HAL, including the new AIDL HAL interface.
Audio focus request from HAL
AAOS, similar to Android, relies on the active participation of apps on audio focus to manage audio playback in cars. The focus information is used to manage which streams to control for volume and ducking. As such, to further expand on the audio focus and to provide a better integration of car specific sounds into the Android experience, the following audio attributes were introduced in Android 11:
EMERGENCYSAFETYVEHICLE_STATUSANNOUNCEMENT
In addition to this change, a mechanism was added for sounds that originate from outside Android to participate in audio focus requests. Thus, the HIDL audio control HAL version 2 was introduced to allow for focus requests that originate from outside Android:
interface IAudioControl {
/**
* Registers focus listener to be used by HAL for requesting and
* abandoning audio focus.
* @param listener the listener interface
* @return closeHandle A handle to unregister observer.
*/
registerFocusListener(IFocusListener listener)
generates (ICloseHandle closeHandle);
/**
* Notifies HAL of changes in audio focus status for focuses requested
* or abandoned by the HAL.
*
* @param usage The audio usage associated with the focus change
* @param zoneId The identifier for the audio zone that the HAL is
* playing the stream in
* @param focusChange the AudioFocusChange that has occurred
*/
oneway onAudioFocusChange(bitfield<AudioUsage> usage, int32_t zoneId,
bitfield<AudioFocusChange> focusChange);
}
Where the IFocusListener is defined as:
interface IFocusListener {
/**
* Called whenever HAL is requesting focus as it is starting to play
* audio of a given usage in a specified zone.
*
* @param usage The audio usage associated with the focus request
* {@code AttributeUsage}
* @param zoneId The identifier for the audio zone where the HAL is
* requesting focus
* @param focusGain The AudioFocusChange associated with this request.
*/
oneway requestAudioFocus(bitfield<AudioUsage> usage,
int32_t zoneId, bitfield<AudioFocusChange> focusGain);
/**
* Called whenever HAL is abandoning focus as it is finished playing audio
* of a given usage in a specific zone.
*
* @param usage The audio usage for which the HAL is abandoning focus
* {@code AttributeUsage}
* @param zoneId The identifier for the audio zone that the HAL
* abandoning focus
*/
oneway abandonAudioFocus(bitfield<AudioUsage> usage, int32_t zoneId);
}
The APIs above can be used to request and abandon audio focus from the HAL,
respectively. In response, the car audio service considers the audio focus
request and forwards the results asynchronously to the
IAudioControl#onAudioFocusChange method.
This API can also be used to monitor changes for the audio focus request that originates from the audio control HAL. In general, any standing audio focus request from the HAL is considered active, which differs from an audio focus request from Android, in which only a corresponding active audio track playback is regarded as active.
Migrate HIDL to AIDL audio control HAL
With the advent of AIDL and the required migration in Android 12 (to learn more, see AIDL for HALs), the audio control HAL was migrated to AIDL. For existing HIDL audio control version 2 APIs, the migration required minor updates to the existing methods:
interface IAudioControl {
/**
* Notifies HAL of changes in audio focus status for focuses requested
* or abandoned by the HAL.
*
* @param usage The audio usage associated with the focus change
* {@code AttributeUsage}. See {@code audioUsage} in
* audio_policy_configuration.xsd for the list of allowed values.
* @param zoneId The identifier for the audio zone that the HAL is
* playing the stream in
* @param focusChange the AudioFocusChange that has occurred.
*/
oneway void onAudioFocusChange(in String usage, in int zoneId,
in AudioFocusChange focusChange);
/**
* Registers focus listener to be used by HAL for requesting and
* abandoning audio focus.
* @param listener the listener interface.
*/
oneway void registerFocusListener(in IFocusListener listener);
/**
* Control the right/left balance setting of the car speakers.
*/
oneway void setBalanceTowardRight(in float value);
/**
* Control the fore/aft fade setting of the car speakers.
*/
oneway void setFadeTowardFront(in float value);
}
And the corresponding IFocusListener:
interface IFocusListener {
/**
* Called whenever HAL is abandoning focus as it is finished playing audio
* of a given usage in a specific zone.
*
* @param usage The audio usage for which the HAL is abandoning focus
* {@code AttributeUsage}. See {@code audioUsage} in
* audio_policy_configuration.xsd for the list of allowed values.
* @param zoneId The identifier for the audio zone that the HAL
* abandoning focus
*/
oneway void abandonAudioFocus(in String usage, in int zoneId);
/**
* Called whenever HAL is requesting focus as it is starting to play audio
* of a given usage in a specified zone.
*
* @param usage The audio usage associated with the focus request
* {@code AttributeUsage}. See {@code audioUsage} in
* audio_policy_configuration.xsd for the list of allowed values.
* @param zoneId The identifier for the audio zone where the HAL is
* requesting focus
* @param focusGain The AudioFocusChange associated with this request.
*/
oneway void requestAudioFocus