Dieser Abschnitt enthält technische Details zur Referenz-App für das Steuerfeld für Smart Home.
Das Kontrollzentrum ist eine nicht gebündelte, privilegierte, systemsignierte App, für die mindestens SDK-Version 35 (Android V, API‑Level 35) erforderlich ist. Die App ist in system/priv-app installiert, um System APIs zu verwenden. Zum Lesen von Medieninformationen muss die App plattformsigniert sein. Sie können die App OTA (Over The Air) aktualisieren.
Hintergrunddienst
Die Control Center App nutzt einen Hintergrunddienst für ihre Funktionen.
Control Center Service wird im user-post-unlocked-Status im Nutzerlebenszyklus von Vendor ServiceController gestartet. Das Kontrollzentrum muss immer aktiv sein und im Hintergrund kommunizieren. Die App kann nicht darauf angewiesen sein, dass sie vom Nutzer geöffnet wird.
Control Center Service stellt mithilfe der Communication API eine Verbindung zu anderen Instanzen der App in anderen Insassenbereichen her und kommuniziert mit diesen. Es ist wichtig, den Integrationsleitfaden zu lesen, um zu verstehen, wie die Control Center-Instanzen auf den Geräten der einzelnen Nutzer Verbindungen herstellen und Daten senden und empfangen.
Kommunikation
Sobald eine Verbindung hergestellt wurde, kommuniziert das Control Center Service mit protobuf-Objekten, die Informationen vermitteln. Um die protobuf mit der Communication APIs an eine andere Belegungszone zu übergeben, wird die protobuf in eine byte array umgewandelt, eine payload object wird erstellt und die Payload wird über CarOccupantConnectionManager#sendPayload gesendet.
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
}
}
//…
}
Daten
Informationen zu Bewohnerzonen werden in der Steuerzentrale in Form von OccupantZoneData-Objekten gespeichert. Änderungen an der lokalen OccupantZoneData werden über die Comms API an andere Control Center-Instanzen gesendet.
Wenn das empfangene Payload geparst wird, werden die geparsten Daten an das lokale OccupantZoneStateRepository übergeben, das wiederum die Ansichten über die Änderung benachrichtigt. Die meisten Daten werden mit Kotlin flows on Android zwischen Klassen übergeben.
Anfragen für Lautsprecherwiedergabe verarbeiten
Damit der Fahrer immer Anfragen von Fahrgästen zum Abspielen von Audioinhalten über die Lautsprecher in der Kabine empfangen kann, wird bei der Erstellung des Fahrers Control Center Service
die Primary ZoneMedia Audio RequestCallback registriert.
Der Callback wird über Anrufe an CarAudioManager#requestMediaAudioOnPrimaryZone benachrichtigt. Der Fahrer-Control Center Service verarbeitet Anfragen, indem er eine Kurzmitteilung (Heads-up Notification, HUN) erstellt, die über CarAudioManager#allowMediaAudioOnPrimaryZone(boolean) angenommen oder abgelehnt werden kann.
Video auf mehreren Bildschirmen gemeinsam ansehen
Das gemeinsame Ansehen funktioniert aufgrund der Task Mirroring APIs in CarActivityManager. Die TaskMirroringManager sucht zuerst nach dem Paket der MediaSession-App in CarActivityManager#getVisibleTasks und erstellt dann ein VirtualDisplay. Die sichtbare Aufgabe wird über CarActivityManager#moveRootTaskToDisplay auf dieses Display verschoben.
Dadurch wird ein IBinder-Token zurückgegeben, das MirroredSurfaceView in einem Layout verwenden kann, um die Aufgabe über MirroredSurfaceView#mirrorSurface anzuzeigen.
Das Communication API Payload-Objekt hat das Token an andere Zonen mit Personen weitergegeben.
Jede Control Center-Instanz in diesen Bewohnerzonen startet ein Mirroring activity und verwendet dieses Token, um die MirroredSurfaceView zu füllen.
APIs für die Spiegelung von Aufgaben
Im Control Center werden diese APIs zur Spiegelung von Aufgaben verwendet:
CarActivityManager#getVisibleTasks(int displayId)<ActivityManager.RunningTaskInfo> wurde für die Anzeige des Absenders aufgerufen.CarActivityManager#moveRootTaskToDisplay(int virtualDisplayId)CarActivityManager#createTaskMirroringToken(int taskId)IBinder-Tokens und sollte aufgerufen werden, nachdem die Aufgabe auf das virtuelle Display verschoben wurde.MirroredSurfaceView#mirrorSurface(IBinder token)Einschränkungen der Aufgabenübertragung im Kontrollzentrum
Das Kontrollzentrum unterstützt die Spiegelung von Aufgaben nur für MediaSession-Apps.
Die API kann jedoch jede Aufgabe spiegeln. Die virtuelle Anzeige hat die Abmessungen des Senderdisplays. Wenn auf dem Display des Empfängers unterschiedliche Auflösungen und Abmessungen verwendet werden, wird das virtuelle Display in der Mitte des Bildschirms angezeigt.
Sichtbare Aufgaben anzeigen
Das Control Center erweitert das Gehäuse Theme.CarUi.NoToolbar zu einem durchscheinenden Fenster. Wenn das Kontrollzentrum über einer Aufgabe geöffnet wird, wird die Aufgabe in CarActivityManager#getVisibleTasks zurückgegeben, sodass sie gespiegelt werden kann.
Informationen zur Spiegelung erhalten
Das Kontrollzentrum benachrichtigt andere Apps über Spiegelungssitzungen. Damit Apps Updates erhalten, müssen sie an Control Center Service gebunden sein und eine Handler-Klasse als Client senden, die Messages von Control
Center Service empfängt und verarbeitet.
Client-Apps können den Paketnamen der gespiegelten App empfangen und einen intent URI für die Aktivität im Kontrollzentrum starten, in dem die gespiegelte App gehostet wird. Dazu werden die folgenden Schlüssel verwendet:
_config_msg_mirroring_pkg_name_key__config_msg_mirroring_redirect_uri_key_
Diese Konfigurationen müssen in den Ressourcen der Client-App und in den Ressourcen des Steuerzentrums vorhanden sein.
Debug-Kontrollzentrum
Die Klasse Logger verarbeitet Control Center-Logs, die so konfiguriert werden können, dass Logs erzwungen werden.
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)
}
}
...
System-App und Aktualisierbarkeit
Da das Kontrollzentrum eine System-App ist und aufgrund der Verwendung von Berechtigungen, die nur eine Signatur erfordern, plattformsigniert ist, muss das Kontrollzentrum auf dem Gerät vorinstalliert sein und kann nur OTA aktualisiert werden, ähnlich wie die Car Media App.
Control Center aus dem Quellcode erstellen
Den Quellcode für das Kontrollzentrum finden Sie unter Ungebündelte Apps einbinden.
Datenschutz bei mehreren Displays
Im Kontrollzentrum können alle Fahrzeuginsassen Medieninformationen auf allen Displays sehen. Google empfiehlt, eine nicht blockierende Datenschutzerklärung einzufügen, um Nutzer zu informieren. Google empfiehlt, dies auf Systemebene zu tun, wenn Sie sich auf einem Display anmelden.