Dienst für Auto-Audio-Plug-ins

Mit den neuen Car OEM-Plug-in-Diensten in Android 14 können einige Fahrzeugkomponenten konfiguriert werden. Speziell für Audio werden drei neue Plug-in-Dienste eingeführt, mit denen OEMs die Audioverwaltung auf AAOS-Geräten flexibel konfigurieren können:

  • Audiofokussteuerung
  • Steuerung von Audiolautstärke und Stummschaltung
  • Steuerung von Audio-Ducking

Architektur des Car-Plug-in-Dienstes

Die folgende Abbildung bietet einen Überblick über die Car-Dienste und ihre Beziehung zum OEM-Car-Dienst. Ähnlich wie bei den App-Prozessen und dem Car-Dienstprozess hat der OEM-Car-Dienstprozess einen eigenen Prozessraum.

Bild

Der Car-Dienst startet den OEM-Car-Dienst, indem er die in config_oemCarService definierte Komponente sucht. Wenn die Konfiguration leer ist, ist der OEM-Dienst nicht vorhanden und es wird kein Dienst gestartet. Die Komponente muss OemCarService erweitern. Der Car-Audiodienst 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 Beispielfinden Sie in der Referenz-Test-App, die in packages/services/Car/tests/OemCarServiceTestAppdefiniert ist.

Obwohl der Dienst vom Car-Dienst gestartet wird, erbt er nicht automatisch die Berechtigungen, die für den Car-Audiodienst verfügbar sind. Daher sollten alle für OEM-Dienste erforderlichen Berechtigungen mit dem entsprechenden Mechanismus abgerufen werden. Ein Beispiel finden Sie unter packages/services/Car/data/etc/com.android.car.oemcarservice.testapp.xml.

Car-Audiodienst mit OEM-Dienstarchitektur

In AAOS verwaltet der Car-Audiodienst diese Aktionen:

  • Audio routing
  • Audiofokus
  • Audio-Ducking
  • Lautstärke und Stummschaltung

Vor Android 14 war dieses Verhalten weitgehend statisch und konnte nur über die Einstellungen geändert werden, allerdings nur in sehr begrenzten Fällen. Mit Android 14 wurde ein Mechanismus eingeführt, mit dem der Car-Audio dienst mit einer vom OEM definierten Komponente kommunizieren kann, die Folgendes verwaltet:

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

Die folgende Abbildung zeigt eine vereinfachte Architektur für den Car-Audiodienst und den Car-OEM-Dienst. Der Car-Audiodienst definiert verschiedene Hooks, die den Car-Audio-OEM-Dienst aufrufen können, um das Audioverhalten zu verwalten. Letzteres geschieht nur, wenn die entsprechende Car-Audio-OEM-Dienstkomponente definiert ist. Andernfalls verwendet der Car-Audiodienst das Standardverhalten.

Bild

Damit der Car-Audiodienst und der Car-Audio-OEM-Dienst immer synchron sind, übergibt der Car-Audiodienst bei jedem Aufruf die erforderlichen Teile des aktuellen Status des Audiostacks an den Car-Audio-OEM-Dienst. Wenn der Car-Audiodienst beispielsweise eine Anfrage zum Bewerten des Audiofokus abfängt, übergibt er den aktuellen Status des Stacks an den Car-Audio-OEM-Dienst. Der aktuelle Status umfasst den aktuellen Fokusinhaber und die aktuellen Fokusverlierer. Fokusverlierer sind Fokusanfragen, die noch Teil des Stacks sind, aber vorübergehend den Fokus verloren haben.

Der Car-Audiodienst muss alle Audioaktivitäten im Auto verwalten. Wenn der Car-Audiodienst einige Teile des Audioverhaltens nicht verwaltet, sind die Informationen, die dem Car-Audio-OEM-Dienst zur Verfügung gestellt werden, unvollständig. Wenn ein OEM beispielsweise die Audiofokusverwaltung im Car-Dienst überschreibt, indem er seine eigene Audiofokusrichtlinie registriert, kann der Car-Audiodienst dem Car-Audio-OEM-Dienst keine vollständigen Informationen zur Verfügung stellen. Dies kann die Entscheidungsfähigkeit des Car-Audio-OEM-Dienstes beeinträchtigen, da ihm möglicherweise Informationen fehlen, die für den Car-Audiodienst nicht sichtbar sind.

Um Aktionen auszuführen, ruft der Car-Audiodienst die OEM-Car-Dienste auf. Diese Aufrufe erfolgen über Prozesse hinweg, 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 Car-Audiodienstaufrufe an den OEM-Dienst blockierend sind, sollte der OEM-Dienst den Car-Audiodienst nicht bei direkten API-Bewertungen aufrufen. Stattdessen stellt der Car-Audiodienst die erforderlichen Informationen bereit, sodass Aufrufe zwischen den beiden Prozessen nur in eine Richtung erfolgen müssen.

Definitionen des Car-Audio-OEM-Dienstes

OEM-Audiofokusdienst für Fahrzeuge

Der Car-Audiodienst verwaltet Audiofokusanfragen von Apps, indem er einen Audiofokus-Listener registriert. Der Car-Audiodienst verfügt über einen Mechanismus zur Verwaltung des Fokusverhaltens basierend auf einer statischen Interaktionsmatrix. Die Matrix definiert drei verschiedene Arten von Interaktionen:

  • Gleichzeitige Interaktion : Fokusinhaber können den Fokus gleichzeitig beibehalten.

  • Exklusive Interaktionen : Eine eingehende Fokusanfrage nimmt dem aktuellen Fokusinhaber den Fokus ab.

  • Interaktion ablehnen : Eingehende Fokusanfrage wird basierend auf dem aktuellen Fokusinhaber abgelehnt.

Dies reicht zwar für einige Anwendungsfälle im Automobilbereich aus, erfüllt aber nicht alle Anforderungen an die Interaktion, die aufgrund von OEM-Anforderungen unterschiedlich sein können. Dazu führen wir 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-Audiodienst aufgerufen, wenn eine Audiofokusanfrage bewertet 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 Audiostacks:

Diese Informationen können verwendet werden, um die newFocusRequest mit den aktuellen Fokusinhabern in focusHolders und den aktuellen Fokusverlierern in focusLosers zu vergleichen. Die API sollte die folgenden Ergebnisse zurückgeben:

class OemCarAudioFocusResult {
    int audioZoneId;
    int audioFocusEvaluationResults;
    AudioFocusEntry focusResult;
    List<AudioFocusEntry> newLosers;
    List<AudioFocusEntry> newlyBlocked;
}

Diese Informationen enthalten die tatsächlichen Bewertungsergebnisse in audioFocusEvaluationResults. Sie geben an, ob die aktuelle Anfrage gewährt, verzögert oder fehlgeschlagen ist. Alle Änderungen am aktuellen Fokusstack 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 sollten. Dauerhafte Fokusverlierer werden aus dem Audiofokusstack entfernt und vorübergehende Fokusverlierer werden in den aktuellen Fokusverliererstack 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 eine entsprechende Benachrichtigung über den Fokusverlust.

Die Liste newlyBlocked enthält Einträge, die sich zuvor in der Liste der Fokusverlierer befanden, aber jetzt durch den neuen Eintrag blockiert werden. Die Blockierung kann dauerhaft oder vorübergehend sein. Bei einer dauerhaften Fokusblockierung wird der Eintrag aus dem Stack entfernt und eine Benachrichtigung über den Fokusverlust wird an die Fokus-Listener gesendet. Bei einem vorübergehenden Fokusverlust bleibt der Eintrag im Fokusverliererstack, aber der Liste der Blockierer wird ein neuer Fokusblockierer hinzugefügt. Es wird keine Benachrichtigung über den Fokusverlust gesendet, da dies bereits beim ersten Blockieren geschehen ist. Die Blockierung der Anfrage wird aufgehoben, wenn alle aktuellen Blockierer entfernt wurden. Wenn der Fokus aufgegeben wird, wird die Anfrage aus dem Stack entfernt.

Die zweite API, notifyAudioFocusChange, ist unidirektional und wird bei jeder Audiofokusanfrage oder -aufgabe aufgerufen. Die API wird hauptsächlich verwendet, um den OEM-Dienst über Fokusänderungen zu informieren, die sich auf das Verhalten des Car-Audio-OEM-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 verwendet werden soll, um dem Nutzer ein optimales Erlebnis 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, sollten Apps, die Folgendes anfordern:

    • Fokus auf die Anrufnutzung, den Fokus entweder gleichzeitig oder exklusiv erhalten können.

    • Fokus auf die Navigationsnutzung, den Fokus entweder gleichzeitig oder exklusiv erhalten können.

    • Fokus auf die Assistant-Nutzung, den Fokus entweder gleichzeitig oder exklusiv erhalten können.

  • Wenn Apps mit einem bestehenden 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 obigen Vorschläge sind nicht erschöpfend, können aber dazu beitragen, dass Apps, die den Fokus anfordern, ihn erhalten können, wenn keine aktiven Töne mit hoher Priorität vorhanden sind. Auch wenn Töne mit hoher Priorität aktiv sind, sollten verzögerte Fokusanfragen berücksichtigt werden und den Fokus erhalten können, sobald der Ton mit hoher Priorität beendet wird.

Car-Lautstärke-OEM-Dienst

Der Car-Audiodienst verwaltet Lautstärketastenereignisse, indem er entweder auf Lautstärkeanpassungen des Audiosystems oder direkt auf Lautstärketastenereignisse des Car-Eingabedienstes reagiert. In jedem Fall bestimmt der Car-Audiodienst standardmäßig anhand der aktiven Audioplayer und einer Prioritätsliste für Audiokontexte, welche Lautstärkegruppe geändert werden soll.

Wir bieten zwei Prioritätslisten für die Lautstärke. In der ersten Liste werden alle Audiokontexte in dieser Reihenfolge berücksichtigt. Die Liste ist in absteigender Reihenfolge dargestellt, wobei die höchste Priorität oben und die niedrigste Priorität unten steht. Wenn beispielsweise Navigationsaudio und Musikaudio gleichzeitig aktiv sind, wird die Lautstärke der Navigation bei einem Lautstärketastenereignis geändert.

  1. Navigation
  2. Anruf
  3. Musik
  4. Ankündigung
  5. Sprachbefehl
  6. Audioausgabe für Klingelton bei Anruf
  7. Systemton
  8. Sicherheit
  9. Wecker
  10. Benachrichtigung
  11. Bewegungszustand
  12. Notfall

Um die Verwaltung von Lautstärketastenereignissen zu vereinfachen, hat der Car-Audiodienst eine zweite Prioritätsliste für Audiokontexte:

  1. Anruf
  2. Medien
  3. Ankündigung
  4. Sprachbefehl

Auch diese Liste ist in absteigender Reihenfolge dargestellt. Mit dieser zweiten Liste können häufigere Töne über Tastenereignisse geändert werden. Weniger häufige Töne, die möglicherweise kürzer sind, können nur über die Benutzeroberfläche für Audioeinstellungen verwaltet werden.

Die tatsächliche Lautstärke kann mit der Konfiguration audioVolumeAdjustmentContextsVersion festgelegt werden. Die Konfiguration kann entweder auf 1 oder 2 gesetzt werden (2 ist die Standardeinstellung).

Um die Lautstärkeverwaltung flexibler zu gestalten, wird in Android 14 OemCarAudioVolumeService eingeführt:

public interface OemCarAudioVolumeService {
    OemCarvolumeChangeInfo getSuggestedGroupForVolumeChange(
OemCarAudioVolumeRequest request, int volumeAdjustment);
}

Der Car-Audio-OEM-Lautstärkedienst hat eine einzige Methode, die eine volumeAdjustment und eine OemCarAudioVolumeRequest akzeptiert:

class OemCarAudioVolumeRequest {
    int audioZoneId;
    int callState;
    List<AudioAttributes> activePlaybackAttributes;
    List<AudioAttributes> duckedAttributes;
    List<CarVolumeGroupInfo> volumeGroupState;
}

activePlaybackAttributes der Anfrage enthält die aktiven Audioattribute. duckedAttributes sind alle derzeit geduckten Audioattribute. volumeGroupState enthält den aktuellen Status der Lautstärkegruppe. Die Anfrage stellt den aktuellen Status des Audiostacks dar und kann verwendet werden, um zu bestimmen, 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 eine Lautstärke geändert hat. true bedeutet, dass eine Änderung vorliegt und die Lautstärkegruppe aktualisiert werden sollte. volumeGroupChanged ist die tatsächliche Lautstärkegruppe, die geändert werden sollte. Diese Gruppe sollte gemäß dem ursprünglichen Parameter volumeAdjustment geändert werden, der an die API übergeben wurde. Wenn die Ergebnisse beispielsweise darauf hindeuten, dass die Lautstärkegruppe der Navigation stummgeschaltet werden sollte, wäre der boolesche Wert true und die zurückgegebene Lautstärkegruppe wäre die für die Navigation.

Car-Ducking-OEM-Dienst

Der Car-Audiodienst verwaltet das Audio-Ducking, indem er Audiofokusänderungen überwacht und ein Signal an die AudioControl-HAL sendet, welche Audiogeräte geduckt werden sollen. Wenn sich der Fokus ändert, werden alle aktiven Fokusinhaber bewertet, um anhand dieser statischen Ducking Regelnzu bestimmen, welche geduckt werden sollen:

  • Notfalltöne ducken alles außer Anruftönen.
  • Sicherheit duckt alles außer Notfalltönen.
  • Navigation duckt alles außer Sicherheits- und Notfalltönen.
  • Anrufe ducken alles außer Sicherheits-, Notfall- und Navigationstönen.
  • Sprache duckt Klingeltöne.
  • Musik und Ankündigungen sollten von allem geduckt werden.

Diese Regeln sind nicht erschöpfend und OEMs sind weiterhin dafür verantwortlich, wie Töne gemäß diesen Richtlinien geduckt werden sollen. OEMs können diese Empfehlungen basierend auf den verfügbaren Anforderungen aktiver steuern. In Android 14 wird OemCarDuckingService eingeführt:

class OemCarAudioDuckingService {
List<AudioAttributes>   evaluateAttributesToDuck(
        OemCarAudioVolumeRequest request);
}

Diese API wird vom Car-Audiodienst bei Audiofokusänderungen aufgerufen. Sie verwendet die OemCarAudioVolumeRequest eingeführt in Car-Lautstärke-OEM-Dienst wieder und enthält die relevanten Informationen, um zu entscheiden, welche Attribute geduckt werden sollen. Die Liste der Audioattribute, die von der API geduckt werden sollen, wird mit dem aktuellen Audiostatus verglichen:

  • Audioattribut wird derzeit geduckt:

    • In der Liste: wird weiterhin geduckt
    • Nicht in der Liste: Ducking deaktiviert
  • Audioattribut wird derzeit nicht geduckt:

    • In der Liste: geduckt
    • Nicht in der Liste: Ducking deaktiviert

Der Car-Audiodienst bestimmt 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 Informationen werden schließlich an die AudioControl-HAL gesendet, um das erforderliche Ducking auf Hardwareebene durchzuführen.

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

Bild

Die Sequenz beginnt, wenn eine App über öffentliche Audio Manager-APIs den Audiofokus verwaltet. Die Anfrage wird an den Car-Audiodienst weitergeleitet, um die Ergebnisse zu ermitteln. Wenn der Audiofokus festgelegt ist, wird das Audio-Ducking vom Car-Audiodienst bewertet, indem er OemCarAudioDuckingService aufruft, um zu bewerten, welche Audioattribute geduckt werden sollen. Sobald die Ergebnisse von der API evaluateAttributesToDuck zurückgegeben wurden, werden die zu duckenden Audiogeräte berechnet und die Informationen werden schließlich an AudioControl gesendet, um das Ducking auf die Audiohardware anzuwenden.

Referenzimplementierung des Car-Audio-OEM-Dienstes

AAOS bietet eine Referenzimplementierung des OEM-Car-Dienstes in packages/services/Car/tests/OemCarServiceTestApp, die die OemCarService sowie OemCarAudioFocusService, OemCarAudioDuckingService und die OemCarAudioVolumeService implementiert. Für Letzteres verwendet jeder Dienst eine XML-Datei, um ein statisches Verhalten zu laden. OemCarAudioFocusServiceImp lädt beispielsweise oem_focus_config.xml, die eine Interaktionsmatrix enthält. Die Matrix wird verwendet, um die Fokusanfrage zu bewerten, wenn evaluateAudioFocusRequest aufgerufen wird.

Debugging der Referenz-Test-App

Die Test-App für den OEM-Car-Dienst ist Teil des AOSP-Quellcodes. OEMs können Änderungen nach Bedarf vornehmen. Verwenden Sie zum Debuggen die Konfiguration config_oemCarService, 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-Car-Dienst den Car-Dienstbefehl dump für den OEM-Dienst verwendet:

adb shell dumpsys car_service --oem-service

Die Ergebnisse könnten der folgenden Ausgabe ähneln:

***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. true bedeutet, dass er bereit ist, und false, dass er nicht bereit ist.