Dienst für Auto-Audio-Plug-ins

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 Autoservice-Prozess belegt der OEM-Autoservice-Prozess einen eigenen Prozessbereich.

Bild

Der Autoservice startet den OEM-Autoservice, indem er die in config_oemCarService definierte Komponente findet. 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 Referenztest-App, die in packages/services/Car/tests/OemCarServiceTestApp definiert ist.

Auch wenn der Dienst von einem Autoservice gestartet wird, werden die Berechtigungen, die für den Car Audio-Dienst verfügbar sind, nicht automatisch übernommen. Daher sollten alle von OEM-Diensten benötigten Berechtigungen mit dem richtigen 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 Stummschalten

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 eingeführt, mit dem der Car Audio-Dienst mit einer OEM-definierten Komponente kommunizieren kann, die Folgendes verwaltet:

  • Audiofokus
  • Audio-Ducking
  • Lautstärke und Stummschalten

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.

Bild

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-Dienstanrufe an den OEM-Dienst blockierend sind, sollte der OEM-Dienst den Auto-Audio-Dienst bei direkten API-Auswertungen 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-Dienst für Audiofokus im Auto

Der Car Audio-Dienst 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 Fokus-Inhaber entfernt.

  • Interaktion ablehnen: Eingehende Fokus-Anfrage wurde vom aktuellen Fokus-Inhaber abgelehnt.

Das reicht zwar für einige Automotive-Anwendungsfälle aus, erfüllt aber nicht alle Anforderungen an die Interaktion, die aufgrund von OEM-Anforderungen unterschiedlich sein 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 im Vergleich zu den aktuellen Fokusgruppen in focusHolders und den aktuellen Fokusverlierern in focusLosers bewerten. 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. Permanente Fokusverlierer werden weiter aus dem Audiofokus-Stack entfernt und vorübergehende Fokusverlierer werden in den aktuellen Fokusverlierer-Stack verschoben, bis sie den Fokus wiedererlangen oder vom ursprünglichen Fokusanforderer aufgegeben werden. 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-Plug-in-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 entweder gleichzeitig oder exklusiv erhalten können.

    • Der Fokus sollte auf die Navigation gerichtet sein und kann entweder gleichzeitig oder exklusiv empfangen werden.

    • Assistant-Nutzungsschwerpunkt, der entweder gleichzeitig oder exklusiv den Fokus erhalten kann.

  • Wenn Apps mit Audiofokus mit hoher Priorität (z. B. Telefonanruf, Notfallbenachrichtigung oder Sicherheitsbenachrichtigung) 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-Autolautstärkedienst

Der Car Audio-Dienst verarbeitet Lautstärketastenereignisse, indem er entweder auf Lautstärkeanpassungen des Audiosystems oder direkt auf Lautstärketastenereignisse des Car Input-Dienstes wartet. In jedem Fall wird durch das Standardverhalten des Car Audio-Dienstes bestimmt, welche Lautstärkegruppe geändert werden soll. Die Entscheidung basiert auf den aktiven Audioplayern und einer Prioritätsliste für Audiokontexte.

Wir stellen zwei Prioritätenlisten für das Volumen bereit. In der ersten Liste werden alle Audiokontexte in dieser Reihenfolge berücksichtigt. Die Liste wird in absteigender Reihenfolge angezeigt, wobei die höchste Priorität oben und die niedrigste Priorität unten steht. Wenn beispielsweise sowohl Navigations- als auch Musik-Audio gleichzeitig aktiv sind, wird die Navigationslautstärke bei einem Lautstärketastenevent geändert.

  1. Navigation
  2. Anruf
  3. Musik
  4. Mitteilung
  5. Sprachbefehl
  6. Bei Anruf klingeln
  7. Systemton
  8. Sicherheit
  9. Wecker
  10. Benachrichtigung
  11. Bewegungszustand
  12. Notfall

Um die Verwaltung von Lautstärketastenevents weniger komplex zu gestalten, hat der Car Audio Service eine zweite Prioritätsliste für den Audio-Kontext:

  1. Anruf
  2. Medien
  3. Mitteilung
  4. Sprachbefehl

Diese Liste wird ebenfalls in absteigender Reihenfolge angezeigt. Mit dieser zweiten Liste können häufigere Sounds über Schlüsselereignisse geändert werden. Ungewöhnliche Geräusche, die vielleicht nur von kurzer Dauer sind, können nur über die Benutzeroberfläche für die 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 einzelne 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-Ducking-Dienst für Autos

Der Car Audio-Dienst 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.
  • Die Sicherheitsfunktion dämpft alle Töne außer Notfalltönen.
  • Bei der Navigation werden alle Töne außer Sicherheits- und Notsignalen unterdrückt.
  • Anrufe stummschalten, mit Ausnahme von Sicherheits-, Notfall- und Navigationssignalen
  • 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:

  • Aktuell gedämpftes Audioattribut:

    • Auf der Liste wird weiterhin geduckt
    • 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 oder der nicht geduckten Audioausgabegeräte hinzu. Diese wird letztendlich an die AudioControl HAL gesendet, um das erforderliche Ducking auf Hardwareebene auszuführen.

Die Abbildung unten zeigt ein vereinfachtes Sequenzdiagramm der Audio-Ducking-Steuerung für eine Fokus-Anfrage, wenn der OEM-Ducking-Dienst verwendet wird:

Bild

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 die Fehlerbehebung 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“.