Groupe d'instruments

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Utilisez l'API Instrument Cluster (une API Android) pour afficher des applications de navigation, y compris Google Maps, sur un écran secondaire dans une voiture, comme derrière le volant sur le tableau de bord. Cette page décrit comment créer un service pour contrôler cet affichage secondaire, puis intégrer le service à CarService afin que les applications de navigation puissent afficher une interface utilisateur.

Terminologie

Les termes suivants sont utilisés sur cette page :

Terme La description
CarInstrumentClusterManager Un CarManager qui permet aux applications externes de lancer une activité sur le groupe d'instruments et de recevoir des rappels lorsque le groupe d'instruments est prêt à afficher des activités.
CarManager Classe de base de tous les gestionnaires utilisés par les applications externes pour interagir avec les services spécifiques à la voiture mis en œuvre par CarService .
CarService Service de plate-forme Android qui assure la communication entre les applications externes (y compris Google Maps) et les fonctionnalités spécifiques à la voiture, telles que l'accès au groupe d'instruments.
Destination La destination finale vers laquelle le véhicule naviguera.
ETA Heure d'arrivée estimée à destination.
Unité principale (HU) Unité de calcul primaire embarquée dans une voiture. Le HU exécute tout le code Android et est connecté à l'écran central de la voiture.
Groupe d'instruments Affichage secondaire situé derrière le volant et entre les instruments de la voiture. Il peut s'agir d'une unité de calcul indépendante connectée à l'HU via le réseau interne de la voiture (bus CAN) ou d'un affichage secondaire attaché à l'HU.
InstrumentClusterRenderingService Classe de base pour le service utilisé pour s'interfacer avec l'affichage du groupe d'instruments. Les OEM doivent fournir une extension de cette classe qui interagit avec le matériel spécifique à l'OEM.
Application KitchenSink Application de test incluse avec Android Automotive.
Itinéraire Un chemin spécifique le long duquel un véhicule navigue pour arriver à une destination.
Service unique Un service Android avec l'attribut android:singleUser . À tout moment, au plus une instance du service s'exécute sur le système Android.

Conditions préalables

Pour développer l'intégration, assurez-vous d'avoir ces éléments :

  • Environnement de développement Android. Pour configurer l'environnement de développement Android, consultez Configuration requise .
  • Téléchargez le code source Android. Obtenez la dernière version du code source Android à partir de la branche pi-car-release (ou version ultérieure) sur https://android.googlesource.com .
  • Unité de tête (HU). Un appareil Android capable d'exécuter Android 9 (ou version ultérieure). Cet appareil doit avoir son propre écran et être capable de faire clignoter l'écran avec les nouvelles versions d'Android.
  • Le groupe d' instruments est l'un des suivants :
    • Affichage secondaire physique attaché à l'HU. Si le matériel et le noyau de l'appareil prennent en charge la gestion de plusieurs écrans.
    • Unité indépendante. Toute unité de calcul connectée au HU via une connexion réseau, capable de recevoir et d'afficher un flux vidéo sur son propre écran.
    • Affichage émulé. Pendant le développement, vous pouvez utiliser l'un de ces environnements émulés :
      • Affichages secondaires simulés. Pour activer un affichage secondaire simulé sur n'importe quelle distribution Android AOSP, accédez aux paramètres des options du développeur dans l'application système Paramètres, puis sélectionnez Simuler les affichages secondaires. Cette configuration équivaut à attacher un affichage secondaire physique, avec la limitation que cet affichage se superpose à l'affichage principal.
      • Combiné d'instruments émulé. L'émulateur Android inclus avec Android Automotive offre une option pour afficher un groupe d'instruments avec l' émulateur Android _qemu-pipes . Utilisez l'implémentation du groupe d'instruments de référence DirectRenderingCluster pour vous connecter à cet écran externe émulé.

Architecture d'intégration

Composants d'intégration

Toute intégration de l'API Instrument Cluster se compose de ces trois composants :

  • CarService
  • Applications de navigation
  • Service de groupe d'instruments OEM

Composants d'intégration

Service automobile

CarService assure la médiation entre les applications de navigation et la voiture, garantissant qu'une seule application de navigation est active à un moment donné et que seules les applications avec l'autorisation android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL peuvent envoyer des données à la voiture.

CarService tous les services spécifiques à la voiture et fournit l'accès à ces services via une série de gestionnaires. Pour interagir avec les services, les applications tournant dans la voiture peuvent accéder à ces gestionnaires.

Pour l'implémentation du groupe d'instruments, les équipementiers automobiles doivent créer une implémentation personnalisée d'InstrumentClusterRendererService et mettre à jour le fichier config.xml pour qu'il pointe vers cette implémentation personnalisée.

Lors du rendu d'un groupe d'instruments, pendant le processus de démarrage, CarService lit la clé InstrumentClusterRendererService du config.xml pour localiser une implémentation de InstrumentClusterService . Dans AOSP, cette entrée pointe vers l'exemple de service de rendu d'implémentation de cluster de l'API Navigation State :

<string name="instrumentClusterRendererService">
android.car.cluster/.ClusterRenderingService
</string>

Le service auquel il est fait référence dans cette entrée est initialisé et lié à CarService . Lorsque des applications de navigation, telles que Google Maps, demandent un CarInstrumentClusterManager , CarService fournit un gestionnaire qui met à jour l'état du cluster d'instruments à partir du InstrumentClusterRenderingService lié. (Dans ce cas, lié fait référence aux services Android .)

Service de groupe d'instruments

Les OEM doivent créer un package Android (APK) qui contient une sous-classe de InstrumentClusterRendererService . Voir ClusterRenderingService pour un exemple.

Cette classe a deux objectifs :

  • Fournit une interface Android et le dispositif de rendu Instrument Cluster (le but de cette page).
  • Reçoit et restitue les mises à jour de l'état de la navigation, telles que le guidage de navigation étape par étape.

Dans un premier temps, les implémentations OEM d' InstrumentClusterRendererService doivent initialiser l'affichage secondaire utilisé pour restituer les informations sur les écrans de l'habitacle de la voiture et communiquer ces informations à CarService en appelant les méthodes InstrumentClusterRendererService.setClusterActivityOptions() et InstrumentClusterRendererService.setClusterActivityState() .

Pour la seconde fonction, le service Instrument Cluster doit fournir une implémentation de l'interface NavigationRenderer qui reçoit les événements de mise à jour de l'état de navigation, qui sont encodés en tant que eventType et les données d'événement encodées dans un bundle.

Séquence d'intégration

Le schéma suivant illustre la mise en œuvre d'un état de navigation qui affiche les mises à jour :

Séquence d'intégration

Dans cette illustration, les couleurs indiquent ce qui suit :

  • Jaune. CarService et CarNavigationStatusManager fournis par la plateforme Android.
  • Cyan. InstrumentClusterRendererService mis en œuvre par l'OEM.
  • Violet. L'application de navigation mise en œuvre par Google et des développeurs tiers.
  • Vert. CarAppFocusManager .

Le flux d'informations sur l'état de la navigation suit cette séquence :

  1. CarService initialise le InstrumentClusterRenderingService .
  2. Lors de l'initialisation, InstrumentClusterRenderingService met à jour CarService avec :
    1. Propriétés d'affichage du groupe d'instruments, telles que les limites claires (voir plus de détails sur les limites claires plus tard).
    2. Options d'activité nécessaires pour lancer des activités à l'intérieur de l'affichage du groupe d'instruments (voir plus de détails sur ActivityOptions .
  3. Une application de navigation (telle que Google Maps pour Android Automotive ou toute application cartographique avec les autorisations requises) :
    1. Obtient un CarAppFocusManager en utilisant la classe Car de car-lib.
    2. Avant le démarrage des instructions détaillées, des appels à CarAppFocusManager.requestFocus() pour transmettre CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION en tant que paramètre appType .
  4. CarAppFocusManager communique cette demande à CarService . Si elle est accordée, CarService inspecte le package de l'application de navigation et localise une activité marquée avec la catégorie android.car.cluster.NAVIGATION .
  5. Si elle est trouvée, l'application de navigation utilise les ActivityOptions signalées par InstrumentClusterRenderingService pour lancer l'activité et inclut les propriétés d'affichage du groupe d'instruments en tant que suppléments dans l'intention.

Intégration de l'API

L'implémentation InstrumentClusterRenderingService doit :

  • Soyez désigné comme service singleton en ajoutant la valeur suivante à AndroidManifest.xml. Ceci est nécessaire pour s'assurer qu'une seule copie du service Instrument Cluster s'exécutera, même pendant l'initialisation et le changement d'utilisateur :
    android:singleUser="true"
  • Détenez l'autorisation système BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE . Cela garantit que seul le service de rendu du groupe d'instruments inclus dans l'image du système Android est toujours lié par le CarService :
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

Implémentation d'InstrumentClusterRenderingService

Pour créer le service :

  1. Écrivez une classe qui s'étend de InstrumentClusterRenderingService , puis ajoutez une entrée correspondante à votre fichier AndroidManifest.xml . Cette classe contrôle l'affichage du groupe d'instruments et peut ( éventuellement ) restituer les données de l'API Navigation State.
  2. Pendant onCreate() , utilisez ce service pour initialiser la communication avec le matériel de rendu. Les options incluent :
    • Déterminez l'affichage secondaire à utiliser pour le groupe d'instruments.
    • Créez un affichage virtuel afin que l'application Instrument Cluster restitue et transmette l'image rendue à une unité externe (à l'aide d'un format de diffusion vidéo, tel que H.264).
  3. Lorsque l'affichage indiqué ci-dessus est prêt, ce service doit appeler InstrumentClusterRenderingService#setClusterActivityLaunchOptions() pour définir les ActivityOptions exactes qui doivent être utilisées pour afficher une activité sur le groupe d'instruments. Utilisez ces paramètres :
    • Catégorie. CarInstrumentClusterManager#CATEGORY_NAVIGATION
    • ActivityOptions. Une instance ActivityOptions qui peut être utilisée pour lancer une activité dans le groupe d'instruments. Par exemple, à partir de l'exemple d'implémentation du groupe d'instruments sur AOSP :
      getService().setClusterActivityLaunchOptions(
         CATEGORY_NAVIGATION,
         ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
  4. Lorsque le cluster d'instruments est prêt à afficher des activités, ce service doit appeler InstrumentClusterRenderingService#setClusterActivityState() . Utilisez ces paramètres :
    • category CarInstrumentClusterManager#CATEGORY_NAVIGATION
    • state Bundle généré avec ClusterActivityState . Assurez-vous de fournir les données suivantes :
      • visible Indique que le groupe d'instruments est visible et prêt à afficher le contenu.
      • unobscuredBounds Un rectangle qui définit la zone de l'affichage du groupe d'instruments dans laquelle il est possible d'afficher du contenu en toute sécurité. Par exemple, les zones couvertes par des cadrans et des jauges.
  5. Remplacez la méthode Service#dump() et signalez les informations d'état utiles pour le débogage (voir dumpsys pour plus d'informations).

Exemple d'implémentation d'InstrumentClusterRenderingService

L'exemple suivant décrit une implémentation InstrumentClusterRenderingService , qui crée un VirtualDisplay pour présenter le contenu du groupe d'instruments sur un affichage physique distant.

Alternativement, ce code pourrait transmettre l' displayId d'affichage d'un affichage secondaire physique connecté au HU, s'il est connu qu'il est disponible.

/**
* Sample {@link InstrumentClusterRenderingService} implementation
*/
public class SampleClusterServiceImpl extends InstrumentClusterRenderingService {
   // Used to retrieve or create displays
   private final DisplayManager mDisplayManager;
   // Unique identifier for the display that will be used for instrument
   // cluster
   private final String mUniqueId = UUID.randomUUID().toString();
   // Format of the instrument cluster display
   private static final int DISPLAY_WIDTH = 1280;
   private static final int DISPLAY_HEIGHT = 720;
   private static final int DISPLAY_DPI = 320;
   // Area not covered by instruments
   private static final int DISPLAY_UNOBSCURED_LEFT = 40;
   private static final int DISPLAY_UNOBSCURED_TOP = 0;
   private static final int DISPLAY_UNOBSCURED_RIGHT = 1200;
   private static final int DISPLAY_UNOBSCURED_BOTTOM = 680;
   @Override
   public void onCreate() {
      super.onCreate();
      // Create a virtual display to render instrument cluster activities on
      mDisplayManager = getSystemService(DisplayManager.class);
      VirtualDisplay display = mDisplayManager.createVirtualDisplay(
          mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null,
          0 /* flags */, null, null);
      // Do any additional initialization (e.g.: start a video stream
      // based on this virtual display to present activities on a remote
      // display).
      onDisplayReady(display.getDisplay());
}
private void onDisplayReady(Display display) {
    // Report activity options that should be used to launch activities on
    // the instrument cluster.
    String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION;
    ActionOptions options = ActivityOptions.makeBasic()
        .setLaunchDisplayId(display.getDisplayId());
    setClusterActivityOptions(category, options);
    // Report instrument cluster state.
    Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT,
        DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT,
        DISPLAY_UNOBSCURED_BOTTOM);
    boolean visible = true;
    ClusterActivityState state = ClusterActivityState.create(visible,
       unobscuredBounds);
    setClusterActivityState(category, options);
  }
}

Utilisation de CarAppFocusManager

L'API CarAppFocusManager fournit une méthode nommée getAppTypeOwner() , qui permet au service de cluster écrit par les OEM de savoir quelle application de navigation a le focus de navigation à un moment donné. Les OEM peuvent utiliser la CarAppFocusManager#addFocusListener() existante, puis utiliser getAppTypeOwner() pour savoir quelle application a le focus. Avec ces informations, les OEM peuvent :

  • Basculez l'activité affichée dans le cluster vers l'activité de cluster fournie par l'application de navigation qui détient le focus.
  • Peut détecter si l'application de navigation ciblée a une activité de cluster ou non. Si l'application de navigation ciblée n'a pas d'activité de cluster (ou si une telle activité est désactivée), les OEM peuvent envoyer ce signal au DIM de la voiture afin que la facette de navigation du cluster soit complètement ignorée.

Utilisez CarAppFocusManager pour définir et écouter le focus actuel de l'application, comme la navigation active ou une commande vocale. Habituellement, une seule instance d'une telle application est en cours d'exécution active (ou focalisée) dans le système.

Utilisez la CarAppFocusManager#addFocusListener(..) pour écouter les changements de focus de l'application :

import android.car.CarAppFocusManager;

...

Car car = Car.createCar(this);
mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE);
mAppFocusManager.addFocusListener(this, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);

...

public void onAppFocusChanged(int appType, boolean active) {
    // Use the CarAppFocusManager#getAppTypeOwner(appType) method call
    // to retrieve a list of active package names
}

Utilisez la CarAppFocusManager#getAppTypeOwner(..) pour récupérer les noms de package du propriétaire actuel d'un type d'application donné qui est ciblé. Cette méthode peut renvoyer plusieurs noms de package si le propriétaire actuel utilise la fonctionnalité android:sharedUserId .

import android.car.CarAppFocusManager;

...

Car car = Car.createCar(this);
mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE);
List<String> focusOwnerPackageNames = mAppFocusManager.getAppTypeOwner(
              CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);

if (focusOwnerPackageNames == null || focusOwnerPackageNames.isEmpty()) {
        // No Navigation application has focus
        // OEM may choose to show their default cluster view
} else {
       // focusOwnerPackageNames
       // Use the PackageManager to retrieve the cluster activity for the package(s)
       // returned in focusOwnerPackageNames
}

...

Annexe : Utilisation de l'exemple d'application

AOSP fournit un exemple d'application qui implémente l'API Navigation State.

Pour exécuter cet exemple d'application :

  1. Créez et flashez Android Auto sur un HU pris en charge. Utilisez les instructions de construction et de clignotement d'Android spécifiques à votre appareil. Pour obtenir des instructions, reportez-vous à la section Utilisation des cartes de référence .
  2. Connectez un affichage secondaire physique au HU (si pris en charge) ou activez le HU secondaire virtuel :
    1. Sélectionnez Mode développeur dans l'application Paramètres.
    2. Accédez à Paramètres > Système > Avancé > Options pour les développeurs > Simuler les écrans secondaires .
  3. Redémarrez le HU. Le service ClusterRenderingService est connecté à l'affichage secondaire.
  4. Pour lancer l'application KitchenSink :
    1. Ouvrez le tiroir.
    2. Allez à Inst. Grappe .
    3. Cliquez sur DÉMARRER LES MÉTADONNÉES .

KitchenSink demande le focus NAVIGATION, qui demande au service DirectRenderingCluster d'afficher une interface utilisateur simulée sur le groupe d'instruments.