Cette section fournit des informations techniques spécifiques à l'application de référence du centre de contrôle.
Le centre de contrôle est une application non groupée, privilégiée et signée par le système qui nécessite une version minimale du SDK de 35 (Android V, niveau d'API 35). L'application est installée dans system/priv-app pour utiliser les System APIs. Pour lire les informations multimédias, l'application doit être signée par la plate-forme. Vous pouvez mettre à jour l'application Over-the-Air (OTA).
Service d'arrière-plan
L'application du centre de contrôle repose sur un service d'arrière-plan pour ses fonctionnalités.
Control Center Service est démarré à l'état user-post-unlocked du cycle de vie de l'utilisateur par Vendor ServiceController. Le centre de contrôle doit toujours être actif et communiquer en arrière-plan. L'application ne peut pas dépendre de l'ouverture de l'application par l'utilisateur.
Control Center Service se connecte à d'autres instances de
lui-même dans d'autres zones d'occupant et communique avec elles à l'aide de l'API Communication. Il est essentiel de lire le guide d'intégration pour comprendre comment les instances du centre de contrôle de chaque utilisateur établissent des connexions, et envoient et reçoivent des données.
Communication
Une fois connecté, le Control Center Service communique avec des protobuf
objets qui transmettent des informations. Pour transmettre le protobuf à une autre zone d'occupant
avec les Communication APIs, le protobuf est converti en byte array,
un payload object est créé et le Payload est envoyé via
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
}
}
//…
}
Données
Les informations sur les zones d'occupant sont stockées dans le centre de contrôle sous la forme d'objets OccupantZoneData. Les modifications apportées au OccupantZoneData local sont envoyées à d'autres instances du centre de contrôle via l'Comms API.
Lorsque le Payload reçu est analysé, les données analysées sont transmises au OccupantZoneStateRepository local qui, à son tour, notifie les vues de la modification. La plupart des
données sont transmises entre les classes avec Kotlin flows on Android.
Gérer les demandes audio des enceintes de l'habitacle
Pour que le conducteur puisse toujours recevoir des demandes de passagers pour diffuser de l'audio
sur les enceintes de l'habitacle, lorsqu'il est créé, le Control Center Service
enregistre le Primary ZoneMedia Audio RequestCallback.
Le rappel est informé des appels à
CarAudioManager#requestMediaAudioOnPrimaryZone. Le
Control Center Service du conducteur gère les demandes en créant une notification prioritaire
(HUN) qui peut être acceptée ou refusée via
CarAudioManager#allowMediaAudioOnPrimaryZone(boolean).
Regarder une vidéo à plusieurs sur différents écrans
Le visionnage à plusieurs fonctionne grâce aux Task Mirroring APIs dans CarActivityManager. Le
TaskMirroringManager recherche d'abord le package de l'application MediaSession en cours de lecture dans CarActivityManager#getVisibleTasks, puis crée un
VirtualDisplay et déplace la tâche visible vers cet écran via
CarActivityManager#moveRootTaskToDisplay.
Cela renvoie un IBinder jeton que MirroredSurfaceView peut utiliser dans une
mise en page pour afficher la tâche via MirroredSurfaceView#mirrorSurface.
L'objet Communication API Payload a transmis le jeton à d'autres zones d'occupant.
Chaque instance du centre de contrôle dans ces zones d'occupant lance une Mirroring activity et utilise ce jeton pour remplir le MirroredSurfaceView.
API de mise en miroir des tâches
Le centre de contrôle utilise les API de mise en miroir des tâches suivantes :
CarActivityManager#getVisibleTasks(int displayId)<ActivityManager.RunningTaskInfo> appelé pour l'écran de l'expéditeur.CarActivityManager#moveRootTaskToDisplay(int virtualDisplayId)CarActivityManager#createTaskMirroringToken(int taskId)IBinder et doit être appelé une fois la tâche déplacée vers l'écran virtuel.MirroredSurfaceView#mirrorSurface(IBinder token)Limites de la mise en miroir des tâches dans le centre de contrôle
Le centre de contrôle n'est compatible avec la mise en miroir des tâches que pour les applications MediaSession.
Toutefois, l'API peut mettre en miroir n'importe quelle tâche. L'écran virtuel est créé avec les dimensions de l'écran de l'expéditeur. Si l'écran du destinataire utilise des résolutions et des dimensions différentes, l'écran virtuel s'affiche au centre de l'écran.
Tâches visibles en surface
Le centre de contrôle étend le châssis Theme.CarUi.NoToolbar pour en faire une fenêtre translucide. Cela signifie que lorsque le centre de contrôle est ouvert sur une tâche, celle-ci est renvoyée dans CarActivityManager#getVisibleTasks, ce qui permet de la mettre en miroir.
Recevoir des informations de mise en miroir
Le centre de contrôle informe les autres applications des sessions de mise en miroir. Pour recevoir
des mises à jour, les applications doivent être liées au Control Center Service et envoyer une Handler
classe en tant que client, qui reçoit et gère les Messages du Control
Center Service.
Les applications clientes peuvent recevoir le nom de package de l'application mise en miroir et lancer un intent URI pour l'activité dans le centre de contrôle hébergeant l'application mise en miroir avec ces clés :
_config_msg_mirroring_pkg_name_key__config_msg_mirroring_redirect_uri_key_
Ces configurations doivent exister dans les ressources de l'application cliente et dans les ressources du centre de contrôle.
Déboguer le centre de contrôle
La classe Logger gère les journaux du centre de contrôle, qui peuvent être configurés pour forcer les journaux.
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)
}
}
...
Application système et possibilité de mise à jour
Étant donné que le centre de contrôle est une application système et qu'il est signé par la plate-forme en raison de l'utilisation d' autorisations de signature uniquement, il doit être préinstallé sur l'appareil et ne peut être mis à jour que par OTA, comme l'application Car Media.
Compiler le centre de contrôle à partir de la source
Pour obtenir le code source du centre de contrôle, consultez Intégrer des applications non groupées.
Confidentialité des utilisateurs avec plusieurs écrans
Le centre de contrôle permet à tous les passagers de la voiture de consulter les informations multimédias sur tous les écrans. Google vous recommande d'insérer un avis de confidentialité non bloquant pour informer les utilisateurs. Google vous recommande de le faire au niveau du système, lorsque vous vous connectez à un écran.