Usługa wtyczki do samochodowego systemu audio

Usługi wtyczek OEM w Androidzie 14 umożliwiają konfigurowanie niektórych komponentów samochodu. W przypadku dźwięku wprowadzamy 3 nowe usługi wtyczek, które umożliwiają producentom OEM elastyczne konfigurowanie zarządzania dźwiękiem na urządzeniach z AAOS:

  • Sterowanie aktywnością audio
  • Sterowanie głośnością i wyciszaniem
  • Sterowanie wyciszaniem tła

Architektura usługi wtyczki samochodowej

Ilustracja poniżej przedstawia przegląd usług samochodowych i ich relacji z usługą samochodową OEM. Podobnie jak procesy aplikacji i proces usługi samochodowej, proces usługi samochodowej OEM zajmuje własną przestrzeń procesów.

obraz

Usługa samochodowa uruchamia usługę samochodową OEM, wyszukując komponent zdefiniowany w config_oemCarService. Jeśli konfiguracja jest pusta, usługa OEM nie istnieje i nie jest uruchamiana. Komponent musi być rozszerzeniem OemCarService. Usługa audio w samochodzie musi zastąpić interfejsy API do uzyskiwania usługi audio OEM w samochodzie:

public final class OemCarServiceImp extends OemCarService {
    @Override
    public OemCarAudioFocusService getOemAudioFocusService();

    @Override
    public OemCarAudioDuckingService getOemAudioDuckingService();

    @Override
    public OemCarAudioVolumeService getOemAudioVolumeService();
}

Przykład znajdziesz w aplikacji testowej zdefiniowanej w packages/services/Car/tests/OemCarServiceTestApp.

Mimo że usługa jest uruchamiana przez usługę samochodową, nie dziedziczy automatycznie uprawnień dostępnych dla usługi audio w samochodzie. W związku z tym wszystkie uprawnienia wymagane przez usługi OEM należy uzyskać za pomocą odpowiedniego mechanizmu. Przykład znajdziesz w packages/services/Car/data/etc/com.android.car.oemcarservice.testapp.xml.

Architektura usługi audio w samochodzie z usługą OEM

W AAOS usługa audio w samochodzie zarządza tymi działaniami:

  • Kierowanie dźwięku
  • Aktywność audio
  • Wyciszanie tła
  • Głośność i wyciszenie

Przed Androidem 14 to zachowanie było w dużej mierze statyczne i można je było modyfikować tylko za pomocą ustawień, ale tylko w bardzo ograniczonym zakresie. W Androidzie 14 wprowadziliśmy mechanizm umożliwiający usłudze audio w samochodzie komunikowanie się z komponentem zdefiniowanym przez producenta OEM, który zarządza:

  • Aktywność audio
  • Wyciszanie tła
  • Głośność i wyciszenie

Ilustracja poniżej przedstawia uproszczoną architekturę usługi audio w samochodzie i usługi OEM w samochodzie. Usługa audio w samochodzie definiuje różne haki, które mogą wywoływać usługę audio OEM w samochodzie, aby zarządzać zachowaniem dźwięku. Dzieje się tak tylko wtedy, gdy zdefiniowany jest odpowiedni komponent usługi audio OEM w samochodzie. W przeciwnym razie usługa audio w samochodzie używa domyślnego zachowania.

obraz

Aby usługa audio w samochodzie i usługa audio OEM w samochodzie były zawsze zsynchronizowane, usługa audio w samochodzie przekazuje do usługi audio OEM w samochodzie wymagane części bieżącego stanu stosu audio przy każdym wywołaniu. Na przykład, gdy usługa audio w samochodzie przechwytuje żądanie oceny aktywności audio, przekazuje bieżący stan stosu do usługi audio OEM w samochodzie. Bieżący stan obejmuje bieżącego posiadacza aktywności i bieżących utraconych aktywności. Utracone aktywności to żądania aktywności, które nadal są częścią stosu, ale tymczasowo utraciły aktywność.

Usługa audio w samochodzie musi zarządzać całą aktywnością audio w samochodzie. Jeśli usługa audio w samochodzie nie zarządza niektórymi częściami zachowania dźwięku, informacje udostępniane usłudze audio OEM w samochodzie są niekompletne. Jeśli na przykład producent OEM zastąpi obsługę aktywności audio w usłudze samochodowej, rejestrując własną zasadę aktywności audio, usługa audio w samochodzie nie będzie mogła przekazać pełnych informacji usłudze audio OEM w samochodzie. Może to wpłynąć na zdolność usługi audio OEM w samochodzie do podejmowania decyzji, ponieważ może ona nie mieć informacji, które nie są widoczne dla usługi audio w samochodzie.

Aby podjąć działania, usługa audio w samochodzie wywołuje usługi OEM w samochodzie. Te wywołania są wykonywane w różnych procesach, co wymaga komunikacji międzyprocesowej (IPC). IPC dodaje opóźnienie do każdego wywołania. Ważne jest, aby zminimalizować opóźnienie w usłudze OEM.

Ponieważ wywołania usługi audio w samochodzie do usługi OEM są blokujące, usługa OEM nie powinna wywoływać usługi audio w samochodzie w przypadku bezpośrednich ocen interfejsu API. Zamiast tego usługa audio w samochodzie udostępnia niezbędne informacje, dzięki czemu wywołania między tymi 2 procesami muszą odbywać się tylko w jednym kierunku.

Definicje usługi audio OEM w samochodzie

Usługa aktywności audio OEM w samochodzie

Usługa audio w samochodzie zarządza żądaniami aktywności audio z aplikacji, rejestrując odbiornik aktywności zasad audio. Usługa audio w samochodzie ma mechanizm zarządzania zachowaniem aktywności na podstawie statycznej macierzy interakcji. Macierz definiuje 3 różne rodzaje interakcji:

  • Interakcja współbieżna. Posiadacze aktywności mogą utrzymywać aktywność w tym samym czasie.

  • Interakcje wyłączne. Przychodzące żądanie aktywności przejmuje aktywność od bieżącego posiadacza aktywności.

  • Odrzucanie interakcji. Przychodzące żądanie aktywności jest odrzucane na podstawie bieżącego posiadacza aktywności.

Chociaż w niektórych przypadkach użycia w motoryzacji jest to wystarczające, nie spełnia wszystkich potrzeb interakcji, które mogą się różnić ze względu na wymagania producenta OEM. W tym celu wprowadzamy OemCarAudioFocusService:

public interface OEmCarAudioFocusService {
    OemCarAuddioFocusResults evaluateAudioFocusRequest(
        OemCarAudioFocusEvaluationRequest request);
    
    void notifyAudioFocusChange(
        List<AudioFocusEntry> holder,
        List<AudioFocusEntry> losers, int zoneId);
}

Interfejs API evaluateAudioFocusRequest jest wywoływany z usługi audio w samochodzie za każdym razem, gdy pojawia się żądanie aktywności audio, które wymaga oceny. Jest to dwukierunkowy interfejs API, który blokuje zwracanie wyników. Żądanie zawiera informacje o bieżącym stanie stosu audio:

Te informacje można wykorzystać do oceny newFocusRequest w porównaniu z bieżącymi posiadaczami aktywności w focusHolders i bieżącymi utraconymi aktywnościami w focusLosers. Interfejs API powinien zwracać te wyniki:

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

Zawiera on informacje o rzeczywistych wynikach oceny w audioFocusEvaluationResults, które wskazują, czy bieżące żądanie zostało przyznane, opóźnione czy nie powiodło się. Wszelkie zmiany w bieżącym stosie aktywności należy ustawić w pozycjach newLosers i newlyBlocked w zależności od charakteru zmiany stosu.

newLosers zawiera pozycje, które wcześniej miały aktywność, ale teraz powinny ją utracić – na stałe lub tymczasowo. Trwale utracone aktywności zostaną usunięte ze stosu aktywności audio, a tymczasowo utracone aktywności zostaną przeniesione do stosu bieżących utraconych aktywności, dopóki nie odzyskają aktywności lub nie zostaną porzucone przez pierwotnego żądającego aktywności. Niezależnie od tego odbiornik aktywności dla żądań otrzyma odpowiednią utratę aktywności.

Lista newlyBlocked zawiera pozycje, które wcześniej znajdowały się na liście utraconych aktywności, ale teraz są blokowane przez nową pozycję. Blokada może być trwała lub tymczasowa. W przypadku trwałej blokady aktywności pozycja zostanie usunięta ze stosu, a utrata aktywności zostanie wysłana do odbiorników aktywności. W przypadku tymczasowej utraty aktywności pozycja pozostanie w stosie utraconych aktywności, ale do jej listy blokujących zostanie dodany nowy blokujący aktywność. Nie zostanie wysłana żadna utrata aktywności, ponieważ została ona wysłana wcześniej, gdy pozycja została zablokowana po raz pierwszy. Żądanie zostanie ostatecznie odblokowane, gdy wszystkie bieżące blokujące zostaną usunięte, lub zostanie usunięte ze stosu, jeśli aktywność zostanie porzucona.

Drugi interfejs API, notifyAudioFocusChange, jest jednokierunkowy i jest wywoływany przy każdym żądaniu aktywności audio lub porzuceniu. Interfejs API jest używany głównie do informowania usługi OEM o zmianach aktywności, które mogą wpływać na zachowanie usługi audio OEM w samochodzie.

Wskazówki dotyczące oceny aktywności

W AAOS aktywność audio służy do zarządzania odtwarzaniem dźwięku i określania, która aplikacja powinna zapewnić użytkownikowi optymalne wrażenia. W związku z tym usługa wtyczki OEM powinna uwzględniać te kwestie podczas zarządzania żądaniem aktywności audio:

  • Bez żadnej aktywnej aktywności audio o wysokim priorytecie (np. połączenia telefonicznego, alarmu lub bezpieczeństwa) aplikacje powinny mieć możliwość uzyskania aktywności audio tymczasowo lub na stałe.

  • Gdy aktywna jest aktywność multimedialna, aplikacje żądające:

    • aktywności użycia połączeń powinny mieć możliwość uzyskania aktywności współbieżnie lub wyłącznie;

    • aktywności użycia nawigacji powinny mieć możliwość uzyskania aktywności współbieżnie lub wyłącznie;

    • aktywności użycia Asystenta powinny mieć możliwość uzyskania aktywności współbieżnie lub wyłącznie.

  • Gdy aktywne są aplikacje z aktywną aktywnością audio o wysokim priorytecie (np. połączenie telefoniczne, alert awaryjny lub alert bezpieczeństwa), każde przychodzące opóźnione żądanie aktywności audio powinno zostać przyznane lub opóźnione w zależności od potrzeb.

Powyższe sugestie nie są wyczerpujące, ale mogą pomóc zagwarantować, że aplikacje żądające aktywności będą mogły ją uzyskać, gdy nie ma aktywnych dźwięków o wysokim priorytecie. Nawet gdy aktywne są dźwięki o wysokim priorytecie, opóźnione żądania aktywności powinny być nadal respektowane i powinny mieć możliwość uzyskania aktywności po zatrzymaniu dźwięku o wysokim priorytecie.

Usługa głośności OEM w samochodzie

Usługa audio w samochodzie zarządza zdarzeniami przycisku głośności, nasłuchując korekt głośności z systemu audio lub nasłuchując zdarzeń przycisku głośności bezpośrednio z usługi wprowadzania danych w samochodzie. W każdym przypadku domyślne zachowanie usługi audio w samochodzie polega na określeniu, którą grupę głośności należy zmienić, na podstawie aktywnych odtwarzaczy audio i listy priorytetów kontekstu audio.

Udostępniamy 2 listy priorytetów głośności. Pierwsza lista uwzględnia wszystkie konteksty audio w tej kolejności. Lista jest przedstawiona w kolejności malejącej – najwyższy priorytet u góry, a najniższy u dołu. Jeśli na przykład dźwięk nawigacji i muzyka są aktywne w tym samym czasie, podczas zdarzenia klawisza głośności zmieniana jest głośność nawigacji.

  1. Nawigacja
  2. Zadzwoń
  3. Muzyka
  4. Ogłoszenie
  5. Polecenia głosowe
  6. Dzwonek połączenia
  7. Dźwięki systemowe
  8. Bezpieczeństwo
  9. Alarm
  10. Powiadomienie
  11. Stan pojazdu
  12. Awaria

Aby uprościć zarządzanie zdarzeniami klawisza głośności, usługa audio w samochodzie ma drugą listę priorytetów kontekstu audio:

  1. Zadzwoń
  2. Multimedia
  3. Ogłoszenie
  4. Polecenia głosowe

Ta lista jest również przedstawiona w kolejności malejącej. Celem tej drugiej listy jest umożliwienie zmiany częściej używanych dźwięków za pomocą zdarzeń klawiszy. Rzadko używane dźwięki, np. o krótszym czasie trwania, można zarządzać tylko za pomocą interfejsu ustawień audio.

Rzeczywistą wersję głośności można ustawić za pomocą konfiguracji audioVolumeAdjustmentContextsVersion. Konfigurację można ustawić na 1 lub 2 (2 jest wartością domyślną).

Aby zapewnić większą elastyczność zarządzania głośnością, w Androidzie 14 wprowadziliśmy OemCarAudioVolumeService:

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

Usługa głośności audio OEM w samochodzie ma jedną metodę, która przyjmuje volumeAdjustment i OemCarAudioVolumeRequest:

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

W activePlaybackAttributes żądania znajdują się aktywne atrybuty audio. duckedAttributes to wszystkie aktualnie wyciszone atrybuty audio. volumeGroupState zawiera bieżący stan grupy głośności. Żądanie reprezentuje bieżący stan stosu audio i może służyć do określenia, którą grupę głośności należy zmienić. Wyniki powinny być zwracane w OemCarVolumeChangeInfo:

class OemCarVolumeChangeInfo {
    boolean change;
    CarVolumeGroupInfo volumeGroupChanged;
}

Wartość logiczna change wskazuje, czy zmieniła się głośność. Wartość true oznacza, że nastąpiła zmiana i należy zaktualizować grupę głośności. volumeGroupChanged to rzeczywista grupa głośności, którą należy zmienić. Tę grupę należy zmienić zgodnie z pierwotnym parametrem volumeAdjustment przekazanym do interfejsu API. Jeśli na przykład wyniki wskazują, że należy wyciszyć grupę głośności nawigacji, wartość logiczna będzie true, a zwrócona grupa głośności powinna być grupą głośności nawigacji.

Usługa wyciszania OEM w samochodzie

Usługa audio w samochodzie zarządza wyciszaniem tła, monitorując zmiany aktywności audio i wysyłając sygnał do HAL AudioControl o tym, które urządzenia audio należy wyciszyć. Gdy aktywność się zmieni, wszystkie aktywne posiadacze aktywności są oceniani, aby określić które z nich należy wyciszyć na podstawie tego zestawu statycznych reguł wyciszania :

  • Dźwięki alarmowe wyciszają wszystko oprócz dźwięków połączeń.
  • Bezpieczeństwo wycisza wszystko oprócz dźwięków alarmowych.
  • Nawigacja wycisza wszystko oprócz dźwięków bezpieczeństwa i alarmowych.
  • Połączenie wycisza wszystko oprócz dźwięków bezpieczeństwa, alarmowych i nawigacji.
  • Głos wycisza dzwonek połączenia.
  • Muzyka i ogłoszenia powinny być wyciszane przez wszystko.

Te reguły nie są wyczerpujące, a producenci OEM nadal są odpowiedzialni za określenie, jak należy wyciszać dźwięki na podstawie tych wytycznych. Producenci OEM mogą aktywnie kontrolować te rekomendacje na podstawie dostępnych wymagań. W Androidzie 14 wprowadziliśmy OemCarDuckingService:

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

Ten interfejs API jest wywoływany z usługi audio w samochodzie przy zmianach aktywności audio. Ponownie używa elementu OemCarAudioVolumeRequest wprowadzonego w usłudze głośności audio OEM w samochodzie i zawiera odpowiednie informacje, aby podjąć decyzję o tym, które atrybuty należy wyciszyć. Lista atrybutów audio do wyciszenia z interfejsu API jest porównywana z bieżącym stanem audio:

  • Atrybut audio aktualnie wyciszony:

    • Na liście – nadal wyciszony.
    • Nie ma na liście – wyciszanie wyłączone.
  • Atrybut audio aktualnie niewyciszony:

    • Na liście – wyciszony.
    • Nie ma na liście – wyciszanie wyłączone.

Usługa audio w samochodzie określa następnie, do których urządzeń wyjściowych audio należą atrybuty audio, i dodaje je odpowiednio do listy wyciszonych urządzeń wyjściowych audio lub listy niewyciszonych urządzeń audio. Jest to ostatecznie wysyłane do HAL AudioControl, aby wykonać wymagane wyciszanie na poziomie sprzętu.

Ilustracja poniżej przedstawia uproszczony diagram sekwencji sterowania wyciszaniem tła w przypadku żądania aktywności, gdy używana jest usługa wyciszania OEM:

obraz

Sekwencja rozpoczyna się, gdy aplikacja żąda zarządzania aktywnością audio za pomocą publicznych interfejsów API menedżera audio. Żądanie jest przekazywane do usługi audio w samochodzie, aby określić wyniki. Gdy aktywność audio zostanie ustalona, usługa audio w samochodzie ocenia wyciszanie tła, wywołując OemCarAudioDuckingService, aby ocenić, które atrybuty audio należy wyciszyć. Gdy wyniki zostaną zwrócone z interfejsu API evaluateAttributesToDuck, obliczane są urządzenia audio do wyciszenia, a informacje są wysyłane do AudioControl, aby zastosować wyciszanie do sprzętu audio.

Implementacja referencyjna usługi audio OEM w samochodzie

AAOS udostępnia implementację referencyjną usługi OEM w samochodzie w packages/services/Car/tests/OemCarServiceTestApp, która implementuje OemCarService, a także OemCarAudioFocusService, OemCarAudioDuckingService, i OemCarAudioVolumeService. W przypadku tej ostatniej każda usługa używa pliku XML do wczytywania statycznego zachowania. Na przykład OemCarAudioFocusServiceImp wczytuje oem_focus_config.xml, który zawiera macierz interakcji. Macierz służy do oceny żądania aktywności, gdy wywoływany jest interfejs API evaluateAudioFocusRequest.

Debugowanie referencyjnej aplikacji testowej

Aplikacja testowa usługi OEM w samochodzie jest częścią kodu źródłowego AOSP. Producenci OEM mogą wprowadzać zmiany zgodnie z własnymi potrzebami. Do debugowania użyj konfiguracji config_oemCarService, aby włączyć aplikację testową.

<!-- 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>

Aby sprawdzić, czy usługa OEM w samochodzie używa polecenia dump usługi samochodowej, użyj tego polecenia:

adb shell dumpsys car_service --oem-service

Wyniki mogą być podobne do tych poniżej:

***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

Każda wartość logiczna w każdej partii informacji dump określa stan funkcji i usługi. Na przykład informacje `dump` mIsOemServiceReady określają, czy usługa jest gotowa do użycia. Wartość true oznacza, że jest gotowa, a false – że nie jest.