Neue OEM-Plug-in-Dienste für Autos in Android 14 ermöglichen die Konfiguration einiger Fahrzeugkomponenten. Speziell für Audio werden drei neue Plug-in-Dienste eingeführt, mit denen OEMs die Audiowiedergabe auf AAOS-Geräten flexibel konfigurieren können:
- Audiofokus steuern
- Lautstärke und Stummschaltung steuern
- Audio-Ducking-Steuerung
Architektur des Car-Plug-in-Dienstes
Die Abbildung unten bietet einen Überblick über die Autoservices und ihre Beziehung zum OEM-Autoservice. Ähnlich wie bei den App-Prozessen und dem Prozess für Autoservices belegt der Prozess für OEM-Autoservices einen eigenen Prozessbereich.
„Car service“ startet den OEM-Autodienst, indem die in config_oemCarService definierte Komponente gesucht wird. Wenn die Konfiguration leer ist, ist der OEM-Dienst nicht vorhanden und es wird kein Dienst gestartet. Die Komponente muss OemCarService erweitern.
Der Car Audio-Dienst muss die APIs zum Abrufen des Car Audio-OEM-Dienstes überschreiben:
public final class OemCarServiceImp extends OemCarService {
@Override
public OemCarAudioFocusService getOemAudioFocusService();
@Override
public OemCarAudioDuckingService getOemAudioDuckingService();
@Override
public OemCarAudioVolumeService getOemAudioVolumeService();
}
Ein Beispiel finden Sie in der Referenz-Test-App, die in packages/services/Car/tests/OemCarServiceTestApp definiert ist.
Auch wenn der Dienst vom Car Service gestartet wird, werden die Berechtigungen, die für den Car Audio Service verfügbar sind, nicht automatisch übernommen. Daher sollten alle Berechtigungen, die für OEM-Dienste erforderlich sind, mit dem entsprechenden Mechanismus eingeholt werden. Beispiele finden Sie unter packages/services/Car/data/etc/com.android.car.oemcarservice.testapp.xml.
Car Audio-Dienst mit OEM-Dienstarchitektur
In AAOS werden diese Aktionen vom Car Audio Service verwaltet:
- Audio routing
- Audiofokus
- Audio-Ducking
- Lautstärke und Stummschaltung
Vor Android 14 war dieses Verhalten weitgehend statisch und konnte nur in sehr wenigen Fällen über die Einstellungen geändert werden. In Android 14 wurde ein Mechanismus für den Car Audio-Dienst eingeführt, mit dem er mit einer vom OEM definierten Komponente kommunizieren kann, die Folgendes verwaltet:
- Audiofokus
- Audio-Ducking
- Lautstärke und Stummschaltung
Die Abbildung unten zeigt eine vereinfachte Architektur für den Car Audio-Dienst und den Dienst des Automobilherstellers. Der Car Audio-Dienst definiert verschiedene Hooks, die den Audio-Dienst des Auto-OEM aufrufen können, um das Audioverhalten zu verwalten. Letzteres tritt nur auf, wenn die entsprechende OEM-Komponente für den Car Audio-Dienst definiert ist. Andernfalls verwendet der Car Audio-Dienst das Standardverhalten.
Damit der Car Audio-Dienst und der Audio-Dienst des Auto-OEM immer synchronisiert sind, übergibt der Car Audio-Dienst bei jedem Aufruf die erforderlichen Teile des aktuellen Status des Audio-Stacks an den Audio-Dienst des Auto-OEM. Wenn der Car Audio-Dienst beispielsweise eine Anfrage zum Bewerten des Audiofokus abfängt, übergibt er den aktuellen Status des Stacks an den Audio-Dienst des Auto-OEM. Der aktuelle Status umfasst den aktuellen Fokusinhaber und die aktuellen Fokusverlierer. Fokusverlierer sind Fokusanfragen, die weiterhin Teil des Stapels sind, aber vorübergehend den Fokus verloren haben.
Der Car Audio-Dienst muss alle Audioaktivitäten im Auto verwalten. Wenn der Audio-Dienst für Autos einige Aspekte des Audioverhaltens nicht verwaltet, sind die Informationen, die dem Audio-Dienst des Auto-OEM zur Verfügung gestellt werden, unvollständig. Wenn ein OEM beispielsweise die Verarbeitung des Audiofokus im Fahrzeugdienst überschreibt, indem er seine eigene Audiofokusrichtlinie registriert, kann der Fahrzeugaudiodienst dem Fahrzeug-OEM-Audiodienst keine vollständigen Informationen zur Verfügung stellen. Dies kann die Entscheidungsfindung des Audio-Dienstes des Auto-OEM beeinträchtigen, da ihm möglicherweise Informationen fehlen, die für den Audio-Dienst des Autos nicht sichtbar sind.
Um Aktionen auszuführen, ruft der Car Audio-Dienst die OEM-Car-Dienste auf. Diese Aufrufe erfolgen prozessübergreifend, was eine prozessübergreifende Kommunikation (Inter-Process Communication, IPC) erfordert. IPC erhöht die Latenz bei jedem Aufruf. Es ist wichtig, die Latenz im OEM-Dienst zu minimieren.
Da Auto-Audio-Dienstaufrufe an den OEM-Dienst blockierend sind, sollte der OEM-Dienst den Auto-Audio-Dienst bei direkten API-Bewertungen nicht aufrufen. Stattdessen stellt der Car Audio-Dienst die erforderlichen Informationen bereit, sodass Anrufe zwischen den beiden Prozessen nur in eine Richtung erfolgen müssen.
OEM-Dienstdefinitionen für Auto-Audioanlagen
OEM-Autofokusdienst für Audio
Der Car Audio Service verwaltet Audiofokusanfragen von Apps, indem er einen Audio Policy Focus Listener registriert. Der Car Audio-Dienst verfügt über einen Mechanismus zur Verwaltung des Fokusverhaltens basierend auf einer statischen Interaktionsmatrix. In der Matrix werden drei verschiedene Arten von Interaktionen definiert:
Gleichzeitige Interaktion: Fokusinhaber können den Fokus gleichzeitig beibehalten.
Exklusive Interaktionen: Bei einer eingehenden Fokus-Anfrage wird der Fokus vom aktuellen Fokusinhaber entfernt.
Interaktion ablehnen: Eingehende Fokus-Anfrage wurde vom aktuellen Fokus-Inhaber abgelehnt.
Für einige Automotive-Anwendungsfälle reicht das aus, aber nicht für alle Interaktionsanforderungen, die sich aufgrund von OEM-Anforderungen unterscheiden können. Dazu führen wir die OemCarAudioFocusService ein:
public interface OEmCarAudioFocusService {
OemCarAuddioFocusResults evaluateAudioFocusRequest(
OemCarAudioFocusEvaluationRequest request);
void notifyAudioFocusChange(
List<AudioFocusEntry> holder,
List<AudioFocusEntry> losers, int zoneId);
}
Die API evaluateAudioFocusRequest wird vom Car Audio Service aufgerufen, wenn eine Anfrage für den Audiofokus vorliegt, die ausgewertet werden muss. Es handelt sich um eine bidirektionale API, die blockiert, bis die Ergebnisse zurückgegeben werden. Die Anfrage enthält Informationen zum aktuellen Status des Audio-Stacks:
Anhand dieser Informationen lässt sich die newFocusRequest mit den aktuellen Fokusinhabern in focusHolders und den aktuellen Fokusverlierern in focusLosers vergleichen. Die API sollte die Ergebnisse zurückgeben:
class OemCarAudioFocusResult {
int audioZoneId;
int audioFocusEvaluationResults;
AudioFocusEntry focusResult;
List<AudioFocusEntry> newLosers;
List<AudioFocusEntry> newlyBlocked;
}
Dieser enthält die Informationen zu den tatsächlichen Bewertungsergebnissen in audioFocusEvaluationResults, die angeben, ob die aktuelle Anfrage genehmigt, verzögert oder fehlgeschlagen ist. Alle Änderungen am aktuellen Fokus-Stack sollten in den Einträgen newLosers und newlyBlocked festgelegt werden, je nach Art der Stack-Änderung.
newLosers enthält Einträge, die zuvor den Fokus hatten, ihn aber jetzt dauerhaft oder vorübergehend verlieren sollen. Dauerhafte Fokusverlierer werden weiter aus dem Audiofokus-Stack entfernt. Vorübergehende Fokusverlierer werden in den aktuellen Fokusverlierer-Stack verschoben, bis sie den Fokus wiedererlangen oder der ursprüngliche Fokusanforderer sie nicht mehr berücksichtigt. Unabhängig davon erhält der Fokus-Listener für die Anfragen einen entsprechenden Fokusverlust.
Die Liste newlyBlocked enthält Einträge, die sich zuvor in der Liste der Fokusverlierer befanden, jetzt aber durch den neuen Eintrag blockiert werden. Die Blockierung kann dauerhaft oder vorübergehend sein. Bei einer dauerhaften Blockierung des Fokus wird der Eintrag aus dem Stapel entfernt und der Fokusverlust wird an die Fokus-Listener gesendet. Bei vorübergehendem Fokusverlust bleibt der Eintrag im Stapel der Fokusverlierer, aber seiner Liste von Blockern wird ein neuer Fokusblocker hinzugefügt. Es wird kein Fokusverlust gesendet, da bereits einer gesendet wurde, als der Eintrag zum ersten Mal blockiert wurde. Die Anfrage wird schließlich entsperrt, wenn alle aktuellen Blockierungen entfernt wurden. Wenn der Fokus aufgegeben wird, wird sie aus dem Stapel entfernt.
Die zweite API, notifyAudioFocusChange, ist eine Einbahnstraße, die bei jeder Audiofokus-Anfrage oder jedem Audiofokus-Verzicht aufgerufen wird. Die API wird hauptsächlich verwendet, um den OEM-Dienst über Fokusänderungen zu informieren, die sich auf das Verhalten des OEM-Car-Audio-Dienstes auswirken können.
Richtlinien für die Fokusbewertung
In AAOS wird der Audiofokus verwendet, um die Audiowiedergabe zu verwalten und zu bestimmen, welche App sich daran halten sollte, um dem Nutzer eine optimale Erfahrung zu bieten. Daher sollte der OEM-Plugin-Dienst bei der Verwaltung einer Audiofokusanfrage Folgendes berücksichtigen:
Ohne einen bestehenden Audiofokus mit hoher Priorität (z. B. Telefonanruf, Notfall oder Sicherheit) sollten Apps den Audiofokus entweder vorübergehend oder dauerhaft erhalten können.
Wenn ein Media-Fokus aktiv ist, werden für Apps, die Folgendes anfordern:
Der Anruf muss den Fokus erhalten können, entweder gleichzeitig oder exklusiv.
Der Fokus sollte entweder gleichzeitig oder exklusiv auf die Navigationsnutzung gerichtet sein.
Assistant-Nutzungsschwerpunkt, der entweder gleichzeitig oder exklusiv den Fokus erhalten kann.
Wenn Apps mit Audiofokus mit hoher Priorität (z. B. Telefonanruf, Notfallbenachrichtigung oder Sicherheitswarnung) aktiv sind, sollte jede eingehende verzögerte Audiofokusanfrage nach Bedarf entweder gewährt oder verzögert werden.
Die oben genannten Vorschläge sind nicht vollständig, können aber dazu beitragen, dass Apps, die den Fokus anfordern, ihn auch erhalten, wenn keine aktiven Sounds mit hoher Priorität vorhanden sind. Auch wenn Sounds mit hoher Priorität aktiv sind, sollten verzögerte Fokusanfragen berücksichtigt werden und der Fokus sollte möglich sein, sobald der Sound mit hoher Priorität beendet wird.
OEM-Autovolumendienst
Der Car Audio-Dienst verwaltet Lautstärketastenereignisse, indem er entweder auf Lautstärkeanpassungen des Audiosystems oder direkt auf Lautstärketastenereignisse des Car Input-Dienstes reagiert. In jedem Fall wird durch das Standardverhalten des Car Audio-Dienstes anhand der aktiven Audioplayer und einer Prioritätsliste für Audiokontexte bestimmt, welche Lautstärkegruppe geändert werden soll.
Wir stellen zwei Prioritätenlisten für das Volumen bereit. In der ersten Liste werden alle Audiokontexte in dieser Reihenfolge berücksichtigt. Die Liste ist in absteigender Reihenfolge sortiert, mit der höchsten Priorität oben und der niedrigsten Priorität unten. Wenn beispielsweise sowohl Navigations- als auch Musik-Audio gleichzeitig aktiv sind, wird die Navigationslautstärke bei einem Lautstärketastenevent geändert.
- Navigation
- Anruf
- Musik
- Ankündigung
- Sprachbefehl
- Audioausgabe für Klingelton bei Anruf
- Systemton
- Sicherheit
- Wecker
- Benachrichtigung
- Bewegungszustand
- Notfall
Um die Verwaltung von Lautstärketastenevents weniger komplex zu gestalten, hat der Car Audio Service eine zweite Prioritätsliste für Audiokontexte:
- Anruf
- Medien
- Ankündigung
- Sprachbefehl
Diese Liste wird ebenfalls in absteigender Reihenfolge angezeigt. Der Zweck dieser zweiten Liste besteht darin, häufigere Sounds über Tastaturereignisse ändern zu können. Ungewöhnliche Geräusche, die vielleicht nur von kurzer Dauer sind, können nur über die Benutzeroberfläche der Audioeinstellungen verwaltet werden.
Die tatsächliche Version des Volumes kann mit der audioVolumeAdjustmentContextsVersion-Konfiguration festgelegt werden. Die Konfiguration kann entweder auf 1 oder 2 festgelegt werden (2 ist die Standardeinstellung).
Um die Lautstärkeregelung flexibler zu gestalten, wird in Android 14 OemCarAudioVolumeService eingeführt:
public interface OemCarAudioVolumeService {
OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}
Der OEM-Dienst für die Lautstärke der Audioanlage im Auto hat eine einzige Methode, die einen volumeAdjustment und einen OemCarAudioVolumeRequest akzeptiert:
class OemCarAudioVolumeRequest {
int audioZoneId;
int callState;
List<AudioAttributes> activePlaybackAttributes;
List<AudioAttributes> duckedAttributes;
List<CarVolumeGroupInfo> volumeGroupState;
}
Das activePlaybackAttributes der Anfrage enthält die aktiven Audioattribute. Die duckedAttributes sind alle aktuell gedämpften Audioattribute. volumeGroupState enthält den aktuellen Status der Volumegruppe. Die Anfrage stellt den aktuellen Status des Audio-Stacks dar und kann verwendet werden, um zu ermitteln, welche Lautstärkegruppe geändert werden soll. Die Ergebnisse sollten in OemCarVolumeChangeInfo zurückgegeben werden:
class OemCarVolumeChangeInfo {
boolean change;
CarVolumeGroupInfo volumeGroupChanged;
}
Der boolesche Wert change gibt an, ob sich die Lautstärke geändert hat. true gibt an, dass eine Änderung vorliegt und die Lautstärkegruppe aktualisiert werden sollte. volumeGroupChanged ist die tatsächliche Lautstärkegruppe, die geändert werden soll. Diese Gruppe sollte entsprechend dem ursprünglichen volumeAdjustment-Parameter geändert werden, der an die API übergeben wurde. Wenn die Ergebnisse beispielsweise darauf hindeuten, dass die Lautstärkegruppe für die Navigation stummgeschaltet werden sollte, wäre der boolesche Wert true und die zurückgegebene Lautstärkegruppe die für die Navigation.
OEM-Autoducking-Dienst
Der Car Audio Service verwaltet das Ducking von Audioinhalten, indem er Änderungen des Audiofokus überwacht und ein Signal an den AudioControl HAL sendet, in dem angegeben wird, welche Audiogeräte geduckt werden sollen.
Wenn sich der Fokus ändert, werden alle aktiven Fokushalter ausgewertet, um anhand dieser statischen Regeln für die Dämpfung zu bestimmen, welche gedämpft werden sollen:
- Bei Notfalltönen werden alle Töne außer Anruftönen gedämpft.
- „Sicherheit“ stummschaltet alles außer Notfallsignalen
- Bei der Navigation werden alle Töne außer Sicherheits- und Notsignalen unterdrückt.
- Anrufe für alles außer Sicherheits-, Notfall- und Navigationsgeräuschen
- Sprache unterdrückt Klingeltöne bei Anrufen
- Musik und Ansagen sollten durch alles unterbrochen werden
Diese Regeln sind nicht vollständig und OEMs sind weiterhin dafür verantwortlich, wie Sounds auf Grundlage dieser Richtlinien geduckt werden sollen. OEMs können diese Empfehlungen anhand der verfügbaren Anforderungen aktiver steuern. Die OemCarDuckingService wird in Android 14 eingeführt:
class OemCarAudioDuckingService {
List<AudioAttributes> evaluateAttributesToDuck(
OemCarAudioVolumeRequest request);
}
Diese API wird vom Car Audio-Dienst bei Änderungen des Audiofokus aufgerufen. Dabei wird die in OEM car volume service eingeführte OemCarAudioVolumeRequest wiederverwendet. Sie enthält die relevanten Informationen, um zu entscheiden, welche Attribute geduckt werden sollen. Die Liste der Audioattribute, die über die API geduckt werden sollen, wird mit dem aktuellen Audiostatus verglichen:
Audioattribut, das derzeit unterdrückt wird:
- Auf der Liste wird weiterhin unterdrückt
- Nicht auf der Liste, Ducking deaktiviert
Audioattribut wird derzeit nicht unterdrückt:
- Auf der Liste, ausgeblendet
- Nicht auf der Liste, Ducking deaktiviert
Der Car Audio-Dienst ermittelt dann, zu welchen Audioausgabegeräten die Audioattribute gehören, und fügt sie der Liste der geduckten Audioausgabegeräte bzw. der Liste der nicht geduckten Audiogeräte hinzu. Diese wird letztendlich an die AudioControl-HAL gesendet, um das erforderliche Ducking auf Hardwareebene auszuführen.
Die folgende Abbildung zeigt ein vereinfachtes Sequenzdiagramm der Audio-Ducking-Steuerung für eine Fokusanfrage, wenn der OEM-Ducking-Dienst verwendet wird:
Die Sequenz beginnt, wenn eine App über öffentliche Audio-Manager-APIs Manage audio focus anfordert. Die Anfrage wird an den Car Audio-Dienst weitergeleitet, um die Ergebnisse zu ermitteln. Wenn der Audiofokus festgelegt ist, wird das Audio-Ducking vom Car Audio-Dienst ausgewertet, indem OemCarAudioDuckingService aufgerufen wird, um zu ermitteln, welche Audioattribute geduckt werden sollen. Sobald die Ergebnisse von der evaluateAttributesToDuck API zurückgegeben werden, werden die Audio-Geräte berechnet, die stummgeschaltet werden sollen. Schließlich werden die Informationen an die AudioControl gesendet, um die Stummschaltung auf die Audio-Hardware anzuwenden.
Referenzimplementierung des OEM-Car-Audio-Dienstes
AAOS bietet eine Referenzimplementierung des OEM-Autodienstes in packages/services/Car/tests/OemCarServiceTestApp, die die OemCarService zusammen mit OemCarAudioFocusService, OemCarAudioDuckingService und der OemCarAudioVolumeService implementiert. Im letzteren Fall verwendet jeder Dienst eine XML-Datei, um ein statisches Verhalten zu laden. Beispiel: OemCarAudioFocusServiceImp lädt oem_focus_config.xml, das eine Interaktionsmatrix enthält. Die Matrix wird verwendet, um die Fokusanfrage zu bewerten, wenn evaluateAudioFocusRequest aufgerufen wird.
Fehlerbehebung bei der Referenztest-App
Die OEM-Test-App für Autodienste ist Teil des AOSP-Quellcodes. OEMs können Änderungen nach Bedarf vornehmen. Verwenden Sie für das Debugging die config_oemCarService-Konfiguration, um die Test-App zu aktivieren.
<!-- This is the component name for the OEM customization service. OEM can choose to implement
this service to customize car service behavior for different policies. If OEMs choose to
implement it, they have to implement a service extending OemCarService exposed by car-lib,
and implement the required component services.
If the component name is invalid, CarService would not connect to any OEM service.
Component name can not be a third party package. It should be pre-installed -->
<string name="config_oemCarService" translatable="false">
com.android.car.oemcarservice.testapp/.OemCarServiceImpl
</string>
So prüfen Sie, ob der OEM-Autodienst den Autodienstbefehl dump für den OEM-Dienst verwendet:
adb shell dumpsys car_service --oem-service
Die Ergebnisse könnten etwa so aussehen:
***CarOemProxyService dump***
mIsFeatureEnabled: true
mIsOemServiceBound: true
mIsOemServiceReady: true
mIsOemServiceConnected: true
mInitComplete: true
OEM_CAR_SERVICE_CONNECTED_TIMEOUT_MS: 5000
OEM_CAR_SERVICE_READY_TIMEOUT_MS: 5000
mComponentName: com.android.car.oemcarservice.testapp/.OemCarServiceImpl
Jeder boolesche Wert in jedem Batch von dump-Informationen bestimmt den Status der Funktion und des Dienstes. Die Dump-Informationen mIsOemServiceReady geben beispielsweise an, ob der Dienst verwendet werden kann. Dabei steht true für „bereit“ und false für „nicht bereit“.