Das Audio Control HAL wurde in Android 9 eingeführt, um Audio-Anwendungsfälle zu unterstützen, die für die Automobilbranche relevant sind. Ab Android 14 unterstützt der Audio Control HAL Folgendes:
- Überblenden und Balance
- HAL-Anfrage für Audiofokus
- Gerät stummschalten und Ducking
- Änderungen der Verstärkung des Audiogeräts
- Änderungen an der Konfiguration des Audio-Ports
Abbildung 1 zeigt eine allgemeine Übersicht über die Architektur des Car Audio-Dienstes, in der der Car Audio-Dienst mit dem Audio Control HAL kommuniziert.
Abbildung 1: Audio für mehrere Zonen konfigurieren
Audio ausblenden und Audiobalance
HIDL-Audio-Control-HAL Version 1 wurde in Android 9 eingeführt, um Audio-Fade und ‑Balance in Automotive-Anwendungsfällen zu unterstützen. Unabhängig von den generischen Audioeffekten, die bereits in Android enthalten sind, können System-Apps mit diesem Mechanismus die Audiobalance und das Fading über CarAudioManager
-APIs festlegen:
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);
}
Nachdem diese APIs aufgerufen wurden, werden die entsprechenden Audio Control HAL-APIs vom Car Audio-Dienst aufgerufen:
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);
}
Die API ist für alle Versionen des Audio Control HAL verfügbar, einschließlich der neuen AIDL HAL-Schnittstelle.
Audiofokus-Anfrage von HAL
Ähnlich wie bei Android ist bei AAOS die aktive Teilnahme von Apps am Audiofokus erforderlich, um die Audiowiedergabe in Autos zu verwalten. Die Fokusinformationen werden verwendet, um zu verwalten, welche Streams für Lautstärke und Ducker gesteuert werden sollen. Um den Audiofokus weiter auszubauen und eine bessere Integration von fahrzeugspezifischen Sounds in Android zu ermöglichen, wurden in Android 11 die folgenden Audioattribute eingeführt:
EMERGENCY
SAFETY
VEHICLE_STATUS
ANNOUNCEMENT
Zusätzlich zu dieser Änderung wurde ein Mechanismus für Sounds hinzugefügt, die nicht von Android stammen, um an Audiofokus-Anfragen teilzunehmen. Daher wurde die HIDL-Audio-Control-HAL-Version 2 eingeführt, um Fokusanfragen zu ermöglichen, die von außerhalb von Android stammen:
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);
}
Dabei ist IFocusListener
so definiert:
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);
}
Mit den oben genannten APIs kann der Audiofokus vom HAL angefordert bzw. aufgegeben werden. Als Reaktion darauf berücksichtigt der Car Audio-Dienst die Audiofokus-Anfrage und leitet die Ergebnisse asynchron an die Methode IAudioControl#onAudioFocusChange
weiter.
Diese API kann auch verwendet werden, um Änderungen für die Audiofokus-Anfrage zu überwachen, die vom Audio Control HAL stammt. Im Allgemeinen wird jede ausstehende Audiofokusanfrage vom HAL als aktiv betrachtet. Das unterscheidet sich von einer Audiofokusanfrage von Android, bei der nur eine entsprechende aktive Audiotrackwiedergabe als aktiv gilt.
HIDL zur AIDL-Audio-Control-HAL migrieren
Mit der Einführung von AIDL und der erforderlichen Migration in Android 12 (weitere Informationen finden Sie unter AIDL für HALs) wurde die Audio Control HAL zu AIDL migriert. Bei vorhandenen HIDL-Audio-Control-Version 2-APIs waren für die Migration nur geringfügige Aktualisierungen der vorhandenen Methoden erforderlich:
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);
}
Und die entsprechende 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(in String usage, in int zoneId,
in AudioFocusChange focusGain);
}
Stummschalten von Volume-Gruppen
Mit Android 12 wurde die Stummschaltung von Lautstärkegruppen eingeführt, um eine umfassendere Stummschaltungssteuerung während der Audiointeraktionen des Nutzers zu ermöglichen. Dadurch kann das Audio Control HAL Stummschaltungsereignisse empfangen, die vom Car Audio Service abgefangen werden.
Damit OEMs die Funktion aktivieren können, müssen sie die Konfiguration audioUseCarVolumeGroupMuting
im Autoservice config.xml
auf true
festlegen:
<!-- Configuration to enable muting of individual volume groups.
If this is set to false, muting of individual volume groups is disabled,
instead muting will toggle master mute. If this is set to true, car volume
group muting is enabled and each individual volume group can be muted separately. -->
<bool name="audioUseCarVolumeGroupMuting">true</bool>
Vor Android 13 musste die Konfiguration mit einem Laufzeit-Ressourcen-Overlay für packages/services/Car/service/res/values/config.xml
überschrieben werden. Weitere Informationen finden Sie unter Build mit Ressourcen-Overlays anpassen. Ab Android 13 können Sie Laufzeit-Ressourcen-Overlays verwenden, um einen Konfigurationswert zu ändern. Weitere Informationen finden Sie unter Wert der Ressourcen einer App zur Laufzeit ändern.
System-Apps können mithilfe der CarAudioManager#isAudioFeatureEnabled
API feststellen, ob die Funktion aktiviert ist. Der übergebene Parameter muss die Konstante CarAudioManager.AUDIO_FEATURE_VOLUME_GROUP_MUTING
sein. Die Methode gibt true
zurück, wenn die Funktion auf dem Gerät aktiviert ist, andernfalls false
.
Zusätzlich zur Aktivierung des Features audioUseCarVolumeGroupMuting
muss das AIDL-Audio-Control-HAL den Stummschaltungsmechanismus für Lautstärkegruppen implementieren:
interface IAudioControl {
/**
* Notifies HAL of changes in output devices that the HAL should apply
* muting to.
*
* This will be called in response to changes in audio mute state for each
* volume group and will include a {@link MutingInfo} object per audio
* zone that experienced a mute state event.
*
* @param mutingInfos an array of {@link MutingInfo} objects for the audio
* zones where audio mute state has changed.
*/
oneway void onDevicesToMuteChange(in MutingInfo[] mutingInfos);
}
„Muting info“ enthält die relevanten Informationen zum Stummschalten für das Audiosystem:
parcelable MutingInfo {
/**
* ID of the associated audio zone
*/
int zoneId;
/**
* List of addresses for audio output devices that should be muted.
*/
String[] deviceAddressesToMute;
/**
* List of addresses for audio output devices that were previously be
* muted and should now be unmuted.
*/
String[] deviceAddressesToUnmute;
}
AAOS bietet zwei verschiedene Mechanismen zum Stummschalten, die auf Folgendem basieren:
Schlüsselereignisse mit dem Audio-KEYCODE_VOLUME_MUTE.
Direkte Aufrufe des Car Audio Service über die Car Audio Manager Mute API,
CarAudioManager#setVolumeGroupMute
.
Wenn diese Option aktiviert ist, lösen beide Mechanismen eine Stummschaltung des Anrufs an den Audio-Steuerungs-HAL aus.
Audio-Ducking im Auto
Mit Android 12 wurde die Funktion „Car Audio Ducking“ eingeführt, um die Steuerung der gleichzeitigen Wiedergabe von Audio-Streams zu optimieren. So können OEMs ihr eigenes Ducking-Verhalten basierend auf der physischen Audiokonfiguration des Fahrzeugs und dem aktuellen Wiedergabestatus implementieren, wie vom Car Audio Service bestimmt.
Der Ducker-Mechanismus basiert auf Änderungen am Audio-Fokus-Stack. Immer wenn sich der Fokus ändert (entweder durch eine Fokusanfrage oder durch das Aufgeben des Fokus), wird das Audio-Control-HAL informiert. Ähnlich wie bei der Unterstützung für das Stummschalten der Lautstärkegruppe für Autos kann die Audio-Ducking-Funktion für Autos mit dem Konfigurationsflag audioUseHalDuckingSignals
aktiviert werden:
<!-- Configuration to enable IAudioControl#onDevicesToDuckChange API to
inform HAL when to duck. If this is set to true, the API will receive signals
indicating which output devices to duck as well as what usages are currently
holding focus. If set to false, the API will not be called. -->
<bool name="audioUseHalDuckingSignals">true</bool>
Damit die Funktion aktiviert werden kann, muss das AIDL-Audio-Control-HAL die entsprechende Logik mit dem vom Car Audio Service empfangenen Signal implementieren:
interface IAudioControl {
/**
* Notifies HAL of changes in output devices that the HAL should apply
* ducking to.
*
* This will be called in response to changes in audio focus, and will
* include a {@link DuckingInfo} object per audio zone that experienced
* a change in audo focus.
*
* @param duckingInfos an array of {@link DuckingInfo} objects for the
* audio zones where audio focus has changed.
*/
oneway void onDevicesToDuckChange(in DuckingInfo[] duckingInfos);
}
Die relevanten Informationen zum Audiosystem sind in den Informationen zum Audio-Ducking enthalten:
parcelable DuckingInfo {
/**
* ID of the associated audio zone
*/
int zoneId;
/**
* List of addresses for audio output devices that should be ducked.
*/
String[] deviceAddressesToDuck;
/**
* List of addresses for audio output devices that were previously be
* ducked and should now be unducked.
*/
String[] deviceAddressesToUnduck;
/**
* List of usages currently holding focus for this audio zone.
*/
String[] usagesHoldingFocus;
}
Neben den Informationen zur Konfiguration der Audioanlage im Auto, die in den Geräteadressen zum Ein- und Ausblenden enthalten sind, enthält die Einblendung auch Informationen darüber, welche Audioattributverwendungen den Fokus haben. Diese Daten sollen das Audiosystem darüber informieren, welche Audioattributnutzungen aktiv sind.
Dies ist erforderlich, da in der Konfiguration für die Audioanlage im Auto einem einzelnen Gerät mehrere Audioattribute zugewiesen werden können. Ohne die zusätzlichen Informationen ist nicht klar, welche Verwendungen aktiv sind.
das auch Töne umfasst, die unterhalb des HAL von den Systemen eines Autos erzeugt werden.AIDL-Audio-Control-HAL 2.0
Um APIs zu aktualisieren und neue Funktionen zu ermöglichen, wurde das AIDL-Audio-Control-HAL in Android 13 auf Version 2.0 aktualisiert:
- Audiofokus mit
PlaybackTrackMetadata
- Rückruf zu Audio-Gains
Die Wiedergabemetadaten werden in android.hardware.audio.common
so definiert:
parcelable PlaybackTrackMetadata {
AudioUsage usage = INVALID;
AudioContentType contentType = UNKNOWN;
float gain;
AudioChannelLayout channelMask;
AudioDevice sourceDevice;
String[] tags;
}
Alle anderen Funktionen von AIDL-Audio-Steuerung Version 1.0 sind erhalten geblieben und können verwendet werden. Eine Ausnahme betrifft die Methode zum Ändern des Audiofokus, wie unter Methode zum Ändern des Audiofokus beschrieben.
Audio-Steuerungsfokus mit Metadaten des Wiedergabetracks
Damit dem Audiosystem unterhalb der HAL mehr Informationen zur Verfügung stehen, werden jetzt PlaybackTrackMetadata
bereitgestellt. Konkret wurde die Audio Control HAL um eine neue Methode erweitert:
interface IAudioControl {
/**
* Notifies HAL of changes in audio focus status for focuses requested
* or abandoned by the HAL.
*
* The HAL is not required to wait for a callback of AUDIOFOCUS_GAIN
* before playing audio, nor is it required to stop playing audio in the
* event of a AUDIOFOCUS_LOSS callback is received.
*
* @param playbackMetaData The output stream metadata associated with
* the focus request
* @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 onAudioFocusChangeWithMetaData(
in PlaybackTrackMetadata playbackMetaData, in int zoneId,
in AudioFocusChange focusChange);
}
Eine ähnliche entsprechende Änderung wird an IFocusListener
vorgenommen:
/**
* Called to indicate that the audio output stream associated with
* {@link android.hardware.audio.common.PlaybackTrackMetadata} is
* abandoning focus as playback has stopped.
*
* @param playbackMetaData The output stream metadata associated with
* the focus request
* @param zoneId The identifier for the audio zone that the HAL
* abandoning focus
*/
oneway void abandonAudioFocusWithMetaData(
in PlaybackTrackMetadata playbackMetaData, in int zoneId);
/**
* Called to indicate that the audio output stream associated with
* {@link android.hardware.audio.common.PlaybackTrackMetadata} has taken
* the focus as playback is starting for the corresponding stream.
*
* @param playbackMetaData The output stream metadata associated with
* the focus request
* @param zoneId The identifier for the audio zone that the HAL
* abandoning focus
* @param focusGain The focus type requested.
*/
oneway void requestAudioFocusWithMetaData(
in PlaybackTrackMetadata playbackMetaData, in int zoneId,
in AudioFocusChange focusGain);
}
Methode zum Ändern des Audiofokus
Die oben genannten Fokusvorgänge funktionieren genauso wie die in Audio-Fokus-Anfrage von HAL beschriebenen. Nur die Metadaten des Wiedergabetracks enthalten weitere Informationen sowie die Verwendung der Audioattribute. Im Allgemeinen können für das aktualisierte Android Control HAL weiterhin die bisherigen Methoden verwendet werden, es sei denn, die zusätzlichen Informationen, die durch die Metadaten des Wiedergabetracks bereitgestellt werden, sind erforderlich.
Wenn HAL-Entwickler sich entscheiden, IAudioControl#onAudioFocusChangeWithMetaData
nicht zu unterstützen, sollte die Methode Ergebnisse mit dem Fehler UNKNOWN_TRANSACTION
zurückgeben, wie unter Versionierte Schnittstellenmethoden verwenden beschrieben.
Der Audiodienst ruft zuerst onAudioFocusChangeWithMetaData
auf und wiederholt den Vorgang dann mit der Methode onAudioFocusChange
, wenn ein UNKNOWN_TRANSACTION
-Fehler auftritt.
Car Audio-Ducking mit Metadaten des Wiedergabetracks
In Version 2.0 des AIDL-Audio-Control-HAL wurden die Metadaten des Wiedergabetracks den Audio-Ducking-Informationen hinzugefügt:
parcelable DuckingInfo {
/**
* ID of the associated audio zone
*/
int zoneId;
/**
* List of addresses for audio output devices that should be ducked.
*/
String[] deviceAddressesToDuck;
/**
* List of addresses for audio output devices that were previously be
* ducked and should now be unducked.
*/
String[] deviceAddressesToUnduck;
/**
* List of usages currently holding focus for this audio zone.
*/
String[] usagesHoldingFocus;
/**
* List of output stream metadata associated with the current focus
* holder for this audio zone
*/
@nullable PlaybackTrackMetadata[] playbackMetaDataHoldingFocus;
}
usagesHoldingFocus
ist veraltet. Entwickler sollten jetzt playbackMetaDataHoldingFocus
verwenden, um die Nutzung von Audioattributen und andere Audioinformationen zu ermitteln. Der Parameter usagesHoldingFocus
enthält jedoch weiterhin die erforderlichen Informationen, bis diese Option offiziell entfernt wird.
Audio-Gain-Callback
Damit Audioänderungen unterhalb der HAL in Android 13 für AAOS besser sichtbar sind, haben wir einen Mechanismus hinzugefügt, mit dem Sie Änderungen an der Audioverstärkung vom Audiosystem des Autos an den Car Audio Service kommunizieren können. Der Mechanismus macht Änderungen des Audio-Gain-Lautstärkeindex mit einem entsprechenden Grund für die Änderung des Gains sichtbar:
- Blockierte oder stummgeschaltete Einschränkungen
- Einschränkungen
- Einschränkungen bei der Dämpfung
Durch diese Änderungen werden diese Einschränkungen unterhalb der HAL für den Car Audio Service und schließlich für eine System-UI-App verfügbar gemacht, um den Nutzer zu informieren. Der zweite Teil, die Einblendung einer möglichen System-UI, wurde in Android 14 weiter ausgebaut, damit System-UI-Apps diese Informationen leichter über einen Callback-Mechanismus für Lautstärkegruppeninformationen erhalten können.
Die Audio Control HAL API registriert den Gain-Callback so:
interface IAudioControl {
/**
* Registers callback to be used by HAL for reporting unexpected gain(s)
* changed and the reason(s) why.
*
* @param callback The {@link IAudioGainCallback}.
*/
oneway void registerGainCallback(in IAudioGainCallback callback);
}
IAudioGainCallback
ist so definiert:
interface IAudioGainCallback {
/**
* Used to indicate that one or more audio device port gains have changed,
* i.e. initiated by HAL, not by CarAudioService.
* This is the counter part of the
* {@link onDevicesToDuckChange}, {@link onDevicesToMuteChange} and,
* {@link setAudioDeviceGainsChanged} APIs.
*
* @param reasons List of reasons that triggered the given gains changed.
* @param gains List of gains affected by the change.
*/
void onAudioDeviceGainsChanged(in Reasons[] reasons,
in AudioGainConfigInfo[] gains);
}
Wie in der API-Dokumentation beschrieben, wird der Gain-Callback vom Car Audio-Dienst in der Audio Control HAL registriert. Wenn die API über die HAL für die Audio-Steuerung aufgerufen wird, antwortet der Car Audio Service mit einer entsprechenden Aktion, z. B. „block“, „limit“ oder „attenuate gain index“.
Das HAL bestimmt, wann die API aufgerufen wird, hauptsächlich um Änderungen am Status des Gain-Index zu melden. Entsprechend den behördlichen Anforderungen sollte das Audiosystem des Autos die erforderliche Maßnahme ergreifen und den Callback verwenden, um Informationen an den Car Audio-Dienst zu senden, damit Nutzer sie nutzen können. Beispielsweise, um dem Nutzer eine Benutzeroberfläche zu präsentieren.
AIDL-Audio-Control-HAL 3.0
Die Android 14 AIDL-HAL-Version für die Audiosteuerung wurde auf Version 3.0 aktualisiert, um die APIs zu aktualisieren und eine robustere Funktion für den Audioverstärkungsindex zu bieten. Die Audio Control HAL API ermöglicht es dem Audiodienst, eine IModuleChangeCallback
festzulegen und aufzuheben:
interface IAudioControl {
/**
* Sets callback with HAL for notifying changes to hardware module
* (that is: {@link android.hardware.audio.core.IModule}) configurations.
*
* @param callback The {@link IModuleChangeCallback} interface to use
* use when new updates are available for
*/
void setModuleChangeCallback(in IModuleChangeCallback callback);
/**
* Clears module change callback
*/
void clearModuleChangeCallback();
}
Der setModuleChangeCallback
wird vom Car Audio-Dienst registriert, wenn der Dienst gestartet wird oder wenn ein Fehler behoben wird. Beispiel: Eine Benachrichtigung über den Tod des Audio-Control-HAL-Binders, die vom Car Audio Service empfangen wird. Die HAL-Implementierung für die Audiosteuerung sollte alle vorhandenen Moduländerungs-Callbacks ersetzen, wenn die API aufgerufen wird.
Bei der clearModuleChangeCallback
API sollte die Implementierung den vorhandenen Callback löschen oder nichts tun, wenn kein Callback vorhanden ist. Es empfiehlt sich, für die Implementierung der Audio-Steuerung einen Death-Observer für den Callback zu registrieren und den Callback dann zu löschen, wenn „on binder death“ ausgelöst wird.
IModuleChangeCallback
ist so definiert:
oneway interface IModuleChangeCallback {
/**
* Used to indicate that one or more {@link AudioPort} configs have
* changed. Implementations MUST return at least one AudioPort.
*
* @param audioPorts list of {@link AudioPort} that are updated
*/
void onAudioPortsChanged(in AudioPort[] audioPorts);
}
Wenn der Callback für Moduländerungen vom Car Audio-Dienst registriert wird, kann er Audio-Port-Änderungen über die onAudioPortChanged
API empfangen. Die API kann verwendet werden, um die Lautstärkeanpassungen für das Audiosystem zu initialisieren, sobald der Callback registriert ist. Bei anderen dynamischen Verstärkungsänderungen kann die API jederzeit aufgerufen werden. Entsprechende Änderungen werden vorgenommen und der Car Audio-Dienst wird entsprechend aktualisiert.