Informacje techniczne

Ta sekcja zawiera szczegóły techniczne dotyczące aplikacji referencyjnej Centrum sterowania.

Centrum sterowania to odrębna, uprzywilejowana aplikacja podpisana przez system, która wymaga minimalnej wersji SDK 35 (Android V, poziom API 35). Aplikacja jest zainstalowana w system/priv-app, aby można było korzystać z System APIs. Aby odczytać informacje o multimediach, aplikacja musi być podpisana na platformie. Aplikację możesz zaktualizować bezprzewodowo (OTA).

Usługa w tle

Aplikacja Centrum sterowania korzysta z usługi działającej w tle. Control Center Service jest uruchamiana w stanie user-post-unlocked w cyklu życia użytkownika przez Vendor ServiceController. Centrum sterowania musi być zawsze aktywne i komunikować się w tle – aplikacja nie może polegać na tym, że użytkownik ją otworzy.

Control Center Service łączy się z innymi instancjami tej samej aplikacji w innych strefach pasażerów i komunikuje się z nimi za pomocą interfejsu Communication API. Zapoznanie się z przewodnikiem po integracji jest niezbędne, aby zrozumieć, jak instancje Centrum sterowania na poszczególnych urządzeniach użytkowników nawiązują połączenia oraz wysyłają i odbierają dane.

Diagram ilustrujący inicjowanie usługi Control Center przez Vendor ServiceController.
Rysunek 5. Usługa Centrum sterowania została uruchomiona przez usługę Vendor ServiceController.

Komunikacja

Po połączeniu Control Center Service komunikuje się z protobufobiektami, które przekazują informacje. Aby przekazać protobuf do innej strefy pasażera za pomocą Communication APIs, protobuf jest konwertowany na byte array, tworzony jest payload object, a Payload jest wysyłany przez CarOccupantConnectionManager#sendPayload.

message ControlCenterPayload {
    required Type messageType = 1;
    // ...
    enum Type {
       MEDIA_STATUS = 0;
       MEDIA_COMMAND = 1;
       INPUT_LOCK_COMMAND = 2;
       INPUT_LOCK_SUCCESSFUL = 3;
       CANCEL_AUDIO_REQUEST = 4;
       MIRRORING_REQUEST_RECEIVER_DECISION = 5;
       MIRRORING_SESSION_ENDED = 6;
    }
}

private fun parsePayload(
    senderZone: OccupantZoneInfo,
    payload: Payload
) {
     val parsedPayload =
         ControlCenterPayload.parseFrom(payload.bytes)
             when (parsedPayload.messageType) {
                 ControlCenterPayload.Type.MEDIA_STATUS -> {
                     // logic here
                 }
             }
             //…
}

Dane

Informacje o strefach zajmowanych są przechowywane w Centrum sterowania w postaci obiektów OccupantZoneData. Zmiany w lokalnym pliku OccupantZoneData są wysyłane do innych instancji Centrum sterowania za pomocą Comms API.

Gdy otrzymany Payload zostanie przeanalizowany, przetworzone dane są przekazywane do lokalnego OccupantZoneStateRepository, który z kolei powiadamia widoki o zmianie. Większość danych jest przekazywana między klasami za pomocą Kotlin flows on Android.

Obsługa próśb o odtwarzanie dźwięku przez głośniki

Aby kierowca zawsze otrzymywał prośby pasażerów o odtwarzanie dźwięku na głośnikach w kabinie, po utworzeniu Control Center Service rejestruje Primary ZoneMedia Audio RequestCallback.

Wywołanie zwrotne jest powiadamiane o połączeniach na numer CarAudioManager#requestMediaAudioOnPrimaryZone. Kierowca Control Center Serviceobsługuje prośby, tworząc powiadomienie (HUN), które można zaakceptować lub odrzucić za pomocą CarAudioManager#allowMediaAudioOnPrimaryZone(boolean).

Wspólne oglądanie filmu na różnych ekranach

Wspólne oglądanie działa dzięki Task Mirroring APIs w CarActivityManager. Wyszukiwanie rozpoczyna się od pakietu MediaSession aplikacji odtwarzającej w CarActivityManager#getVisibleTasks, a następnie tworzy VirtualDisplay i przenosi widoczne zadanie na ten ekran za pomocą CarActivityManager#moveRootTaskToDisplay.TaskMirroringManager

Zwraca token IBinder, którego MirroredSurfaceView może użyć w układzie, aby wyświetlić zadanie za pomocą MirroredSurfaceView#mirrorSurface. Obiekt Communication API Payload przekazał token do innych stref zajmowanych przez użytkowników.

Każde wystąpienie Centrum sterowania w tych strefach użytkowników uruchamia Mirroring activity i używa tego tokena do wypełnienia MirroredSurfaceView.

Przepływ tokena powielania w celu wyświetlenia zadania na innym ekranie.
Rysunek 6. powielać przepływ tokenów
.

Interfejsy API do dublowania zadań

Centrum sterowania korzysta z tych interfejsów API do dublowania zadań:

CarActivityManager#getVisibleTasks(int displayId)
<ActivityManager.RunningTaskInfo> wywołał wyświetlanie nadawcy.

CarActivityManager#moveRootTaskToDisplay(int virtualDisplayId)
Przenosi wybrane widoczne zadanie na utworzony wirtualny wyświetlacz.

CarActivityManager#createTaskMirroringToken(int taskId)
Tworzy zadanie, które odzwierciedla token IBinder. Należy je wywołać po przeniesieniu zadania na wirtualny wyświetlacz.

MirroredSurfaceView#mirrorSurface(IBinder token)
Obiekt niestandardowego widoku, który używa tokena do wyświetlania zawartości |wirtualnego wyświetlacza.

Ograniczenia dotyczące dublowania zadań w Centrum sterowania

Centrum sterowania obsługuje tylko dublowanie zadań w przypadku aplikacji MediaSession. Interfejs API może jednak odzwierciedlać dowolne zadanie. Wirtualny wyświetlacz ma wymiary wyświetlacza nadawcy. Jeśli wyświetlacz odbiorcy ma inne rozdzielczości i wymiary, wirtualny wyświetlacz pojawi się na środku ekranu.

Zadania widoczne na powierzchni

Centrum sterowania rozszerza obudowę Theme.CarUi.NoToolbar, tworząc półprzezroczyste okno. Oznacza to, że gdy Centrum sterowania jest otwarte nad zadaniem, zadanie jest zwracane w CarActivityManager#getVisibleTasks, co umożliwia jego odzwierciedlenie.

Otrzymywanie informacji o klonowaniu

Centrum sterowania powiadamia inne aplikacje o sesjach powielania. Aby otrzymywać aktualizacje, aplikacje muszą powiązać się z usługą Control Center Service i wysłać klasę Handler jako klienta, który odbiera i obsługuje Messages z usługi Control Center Service.

Aplikacje klienckie mogą otrzymywać nazwę pakietu odzwierciedlonej aplikacji i uruchamiać intent URI dla aktywności w Centrum sterowania, które hostuje odzwierciedloną aplikację, z tymi kluczami:

  • _config_msg_mirroring_pkg_name_key_
  • _config_msg_mirroring_redirect_uri_key_

Te konfiguracje muszą znajdować się w zasobach aplikacji klienta i w zasobach Centrum sterowania.

Aplikacje klienckie otrzymują informacje o klonowaniu z Centrum sterowania.
Rysunek 7. Otrzymywanie informacji o klonowaniu z Centrum sterowania.

Centrum sterowania debugowaniem

Klasa Logger obsługuje logi Centrum sterowania, które można skonfigurować tak, aby wymuszać logi.

class Logger(cls: Class<*>) {

   companion object {
       private const val FORCE_LOGS = false
   }

   private val tag: String

   init {
       tag = cls.simpleName
   }

   fun v(message: String) {
       if (Log.isLoggable(tag, Log.VERBOSE) || FORCE_LOGS) {
           Log.v(tag, message)
       }
   }
...

Aplikacja systemowa i możliwość jej aktualizacji

Centrum sterowania jest aplikacją systemową podpisaną przez platformę ze względu na użycie uprawnień wymagających tylko podpisu, dlatego musi być wstępnie zainstalowane na urządzeniu i może być aktualizowane tylko bezprzewodowo, podobnie jak aplikacja multimedialna w samochodzie.

Kompilowanie Centrum sterowania ze źródła

Aby uzyskać kod źródłowy Centrum sterowania, zapoznaj się z artykułem Integrowanie aplikacji bez pakietu.

Prywatność użytkowników w przypadku wielu wyświetlaczy

Centrum sterowania umożliwia wszystkim pasażerom samochodu wyświetlanie informacji o multimediach na wszystkich wyświetlaczach. Google zaleca wstawienie nieblokującego powiadomienia o prywatności, aby informować użytkowników. Google zaleca, aby robić to na poziomie systemu, gdy logujesz się na wyświetlaczu.