Dettagli tecnici

Questa sezione fornisce dettagli tecnici specifici dell'app di riferimento Control Center.

Il Centro di controllo è un'app privilegiata, firmata dal sistema e non raggruppata che richiede una versione minima dell'SDK 35 (Android V (livello API 35)). L'app è installata in system/priv-app per utilizzare System APIs. Per leggere le informazioni sui contenuti multimediali, l'app deve essere firmata dalla piattaforma. Puoi aggiornare l'app Over-the-Air (OTA).

Servizio in background

L'app Control Center si basa su un servizio in background per il suo funzionamento. Control Center Service viene avviato nello stato user-post-unlocked del ciclo di vita dell'utente da Vendor ServiceController. Il Centro di controllo deve essere sempre attivo e comunicare in background. L'app non può fare affidamento sull'apertura da parte dell'utente.

Control Center Service si connette e comunica con altre istanze di se stessa in altre zone degli occupanti utilizzando l'API Communication. La lettura della guida all'integrazione è essenziale per comprendere in che modo le istanze del Centro di controllo di ogni utente stabiliscono connessioni e inviano e ricevono dati.

Diagramma che illustra l'avvio del servizio Control Center da parte di Vendor ServiceController.
Figura 5. Control Center Service avviato da Vendor ServiceController.

Comunicazione

Una volta collegato, Control Center Service comunica con gli oggetti protobuf che trasmettono informazioni. Per passare il protobuf a un'altra zona occupante con il Communication APIs, il protobuf viene convertito in un byte array, viene creato un payload object e il Payload viene inviato tramite 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
                 }
             }
             //…
}

Dati

Le informazioni sulle zone occupanti vengono archiviate nel Centro di controllo sotto forma di oggetti OccupantZoneData. Le modifiche all'OccupantZoneData locale vengono inviate ad altre istanze di Control Center tramite Comms API.

Quando il Payload ricevuto viene analizzato, i dati analizzati vengono passati al OccupantZoneStateRepository locale, che a sua volta notifica le modifiche alle visualizzazioni. La maggior parte dei dati viene trasferita tra le classi con Kotlin flows on Android.

Gestire le richieste audio dell'altoparlante dell'abitacolo

Affinché l'autista possa sempre ricevere richieste di riproduzione audio da parte dei passeggeri tramite gli altoparlanti dell'abitacolo, al momento della creazione, l'Control Center Service dell'autista registra Primary ZoneMedia Audio RequestCallback.

Il callback viene informato delle chiamate a CarAudioManager#requestMediaAudioOnPrimaryZone. Il conducente Control Center Service gestisce le richieste creando una notifica di avviso (HUN) che può essere accettata o rifiutata tramite CarAudioManager#allowMediaAudioOnPrimaryZone(boolean).

Guardare un video insieme su più schermi

La funzionalità Guarda insieme funziona grazie a Task Mirroring APIs in CarActivityManager. TaskMirroringManager cerca prima il pacchetto dell'app MediaSession in CarActivityManager#getVisibleTasks, poi crea un VirtualDisplay e sposta l'attività visibile in questo display tramite CarActivityManager#moveRootTaskToDisplay.

Viene restituito un token IBinder che MirroredSurfaceView può utilizzare in un layout per visualizzare l'attività tramite MirroredSurfaceView#mirrorSurface. L'oggetto Communication API Payload ha passato il token ad altre zone occupanti.

Ogni istanza di Control Center in queste zone per occupanti avvia un Mirroring activity e utilizza questo token per compilare MirroredSurfaceView.

Flusso di un token di mirroring per visualizzare un'attività su un altro schermo.
Figura 6. Duplicare un flusso di token.

API di mirroring delle attività

Control Center utilizza le seguenti API di mirroring delle attività:

CarActivityManager#getVisibleTasks(int displayId)
<ActivityManager.RunningTaskInfo> ha chiamato per la visualizzazione del mittente.

CarActivityManager#moveRootTaskToDisplay(int virtualDisplayId)
Sposta l'attività visibile selezionata in un display virtuale creato.

CarActivityManager#createTaskMirroringToken(int taskId)
Crea un'attività per eseguire il mirroring del token IBinder e deve essere chiamata dopo che l'attività viene spostata sul display virtuale.

MirroredSurfaceView#mirrorSurface(IBinder token)
Un oggetto di visualizzazione personalizzato che utilizza il token per visualizzare i contenuti del |display virtuale.

Limitazioni del mirroring delle attività nel Centro di controllo

Il Centro di controllo supporta il mirroring delle attività solo per le app MediaSession. Tuttavia, l'API può eseguire il mirroring di qualsiasi attività. Il display virtuale viene creato con le dimensioni del display del mittente. Se il display del ricevitore utilizza risoluzioni e dimensioni diverse, il display virtuale viene visualizzato al centro dello schermo.

Attività visibili sulla superficie

Il Centro di controllo estende il telaio Theme.CarUi.NoToolbar per creare una finestra traslucida. Ciò significa che quando il Centro di controllo viene aperto su un'attività, questa viene restituita in CarActivityManager#getVisibleTasks, il che consente di eseguirne il mirroring.

Ricevere informazioni sul mirroring

Il Centro di controllo invia notifiche alle altre app relative alle sessioni di mirroring. Per ricevere aggiornamenti, le app devono essere associate a Control Center Service e inviare una classe Handler come client, che riceve e gestisce Messages da Control Center Service.

Le app client possono ricevere il nome pacchetto dell'app sottoposta a mirroring e avviare un intent URI per l'attività nel Centro di controllo che ospita l'app sottoposta a mirroring con queste chiavi:

  • _config_msg_mirroring_pkg_name_key_
  • _config_msg_mirroring_redirect_uri_key_

Queste configurazioni devono esistere nelle risorse dell'app client e in quelle del Control Center.

Le app client ricevono le informazioni di mirroring dal Centro di controllo.
Figura 7. Ricevi le informazioni sul mirroring dal Centro di controllo.

Centro di controllo del debug

La classe Logger gestisce i log del Centro di controllo, che possono essere configurati per forzare i log.

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)
       }
   }
...

App di sistema e aggiornabilità

Poiché il Centro di controllo è un'app di sistema e firmata dalla piattaforma a causa dell'utilizzo di autorizzazioni solo per la firma, il Centro di controllo deve essere preinstallato sul dispositivo e può essere aggiornato solo OTA, in modo simile all'app Car Media.

Creare Control Center dal codice sorgente

Per ottenere il codice sorgente del Centro di controllo, vedi Integrare app non raggruppate.

Privacy dell'utente con più display

Il Centro di controllo consente a tutti i passeggeri dell'auto di visualizzare le informazioni sui contenuti multimediali su tutti i display. Google consiglia di inserire un'informativa sulla privacy non bloccante per informare gli utenti. Google consiglia di farlo a livello di sistema, quando accedi a un display.