API del quadro strumenti

Utilizza l'API Instrument Cluster (un'API Android) per visualizzare le app di navigazione, incluso Google Maps, su un display secondario in un'auto, ad esempio dietro il volante sul quadro strumenti. Questa pagina descrive come creare un servizio per controllare il display secondario e quindi integrare il servizio con CarService in modo che le app di navigazione possano visualizzare un'interfaccia utente.

Terminologia

In questa pagina vengono utilizzati i seguenti termini:

Termine Descrizione
CarInstrumentClusterManager Un'istanza CarManager che consente alle app esterne di avviare un'attività sul quadro strumenti e ricevere richiamate quando il quadro strumenti è pronto per visualizzare le attività.
CarManager Classe base di tutti i gestori utilizzati dalle app esterne per interagire con i servizi specifici dell'auto implementati da CarService .
CarService Servizio della piattaforma Android che fornisce la comunicazione tra app esterne (incluso Google Maps) e funzionalità specifiche dell'auto, come l'accesso al quadro strumenti.
Destinazione La destinazione finale verso la quale navigherà il veicolo.
ETA Ora prevista di arrivo a destinazione.
Unità principale (HU) Unità computazionale primaria incorporata in un'auto. L'HU esegue tutto il codice Android ed è collegato al display centrale dell'auto.
Strumentazione Display secondario situato dietro al volante e tra gli strumenti della vettura. Può trattarsi di un'unità di calcolo indipendente collegata all'HU tramite la rete interna dell'auto (bus CAN) o di un display secondario collegato all'HU.
InstrumentClusterRenderingService Classe base per il servizio utilizzato per interfacciarsi con il display del quadro strumenti. Gli OEM devono fornire un'estensione di questa classe che interagisca con l'hardware specifico dell'OEM.
Applicazione Lavello da cucina App di prova inclusa con Android Automotive.
Itinerario Un percorso specifico lungo il quale un veicolo naviga per arrivare a destinazione.
Servizio Singleton Un servizio Android con l'attributo android:singleUser . In ogni momento, sul sistema Android viene eseguita al massimo un'istanza del servizio.

Prerequisiti

Per sviluppare l'integrazione, assicurati di avere questi elementi:

  • Ambiente di sviluppo Android. Per configurare l'ambiente di sviluppo Android, consulta Requisiti di creazione .
  • Scarica il codice sorgente di Android. Ottieni la versione più recente del codice sorgente Android dal ramo pi-car-release (o successivo) su https://android.googlesource.com .
  • Unità principale (HU). Un dispositivo Android in grado di eseguire Android 9 (o versioni successive). Questo dispositivo deve avere il proprio display ed essere in grado di lampeggiare il display con le nuove build di Android.
  • Il quadro strumenti è uno dei seguenti:
    • Display secondario fisico collegato all'HU. Se l'hardware e il kernel del dispositivo supportano la gestione di più display.
    • Unità indipendente. Qualsiasi unità di calcolo connessa all'HU tramite una connessione di rete, in grado di ricevere e visualizzare un flusso video sul proprio display.
    • Visualizzazione emulata. Durante lo sviluppo, puoi utilizzare uno di questi ambienti emulati:
      • Display secondari simulati. Per abilitare un display secondario simulato su qualsiasi distribuzione Android AOSP, vai alle impostazioni Opzioni sviluppatore nell'app di sistema Impostazioni e quindi seleziona Simula display secondari. Questa configurazione equivale a collegare un display secondario fisico, con la limitazione che questo display è sovrapposto al display principale.
      • Quadro strumenti emulato. L'emulatore Android incluso con Android Automotive offre un'opzione per visualizzare un quadro strumenti con il servizio ClusterRenderingService connesso al display secondario.
      • emulatore _qemu-pipes . Il servizio ClusterRenderingService è connesso al display secondario. implementazione del quadro strumenti di riferimento per connettersi a questo display esterno emulato.

Architettura di integrazione

Componenti di integrazione

Qualsiasi integrazione dell'API Instrument Cluster è costituita da questi tre componenti:

  • CarService
  • App di navigazione
  • Servizio quadro strumenti OEM

Componenti di integrazione

CarService

CarService funge da intermediario tra le app di navigazione e l'auto, garantendo che sia attiva solo un'app di navigazione alla volta e che solo le app con l'autorizzazione android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL possano inviare dati all'auto.

CarService avvia tutti i servizi specifici dell'auto e fornisce l'accesso a questi servizi attraverso una serie di gestori. Per interagire con i servizi, le app in esecuzione nell'auto possono accedere a questi gestori.

Per l'implementazione del quadro strumenti, gli OEM automobilistici devono creare un'implementazione personalizzata di InstrumentClusterRendererService e aggiornare il servizio ClusterRenderingService connesso al display secondario.

Durante il rendering di un quadro strumenti, durante il processo di avvio CarService legge la chiave InstrumentClusterRendererService del servizio ClusterRenderingService connesso al display secondario. per individuare un'implementazione di InstrumentClusterService . In AOSP, questa voce punta al servizio di rendering dell'implementazione del cluster di esempio dell'API Navigation State:

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

Il servizio a cui si fa riferimento in questa voce è inizializzato e associato a CarService . Quando le app di navigazione, come Google Maps, richiedono un CarInstrumentClusterManager , CarService fornisce un gestore che aggiorna lo stato del cluster strumento InstrumentClusterRenderingService associato. (In questo caso, bound si riferisce ai servizi Android .)

Servizio quadro strumenti

Gli OEM devono creare un pacchetto Android (APK) che contenga una sottoclasse del servizio ClusterRenderingService connessa al display secondario. Il servizio ClusterRenderingService è connesso al display secondario. per un campione.

Questa classe ha due scopi:

  • Fornisce un'interfaccia Android e il dispositivo di rendering del quadro strumenti (scopo di questa pagina).
  • Riceve ed esegue il rendering degli aggiornamenti sullo stato della navigazione, come le indicazioni di navigazione passo passo.

Per il primo scopo, le implementazioni OEM di InstrumentClusterRendererService devono inizializzare il display secondario utilizzato per visualizzare le informazioni sugli schermi nell'abitacolo dell'auto e comunicare queste informazioni a CarService chiamando i metodi InstrumentClusterRendererService.setClusterActivityOptions() e InstrumentClusterRendererService.setClusterActivityState() .

Per la seconda funzione, il servizio Instrument Cluster deve fornire un'implementazione del servizio ClusterRenderingService collegata al display secondario. interfaccia che riceve gli eventi di aggiornamento dello stato di navigazione, che sono codificati come eventType e dati evento codificati in un bundle.

Sequenza di integrazione

Il diagramma seguente illustra l'implementazione di uno stato di navigazione che esegue il rendering degli aggiornamenti:

Sequenza di integrazione

In questa illustrazione, i colori indicano quanto segue:

  • Giallo. CarService e CarNavigationStatusManager forniti dalla piattaforma Android. Per ulteriori informazioni, consulta Auto e CAR_NAVIGATION_SERVICE .
  • Ciano. InstrumentClusterRendererService implementato dall'OEM.
  • Viola. L'app di navigazione implementata da Google e sviluppatori di terze parti.
  • Verde. CarAppFocusManager . Per ulteriori informazioni, consulta Utilizzo dell'API CarAppFocusManager di seguito e CarAppFocusManager .

Il flusso di informazioni sullo stato della navigazione segue questa sequenza:

  1. CarService inizializza InstrumentClusterRenderingService .
  2. Durante l'inizializzazione, InstrumentClusterRenderingService aggiorna CarService con:
    1. Proprietà di visualizzazione del quadro strumenti, come i confini non oscuri (vedere ulteriori dettagli sui confini non oscuri più avanti).
    2. Opzioni di attività necessarie per avviare attività all'interno del display del quadro strumenti (vedere maggiori dettagli in ActivityOptions .
  3. Un'app di navigazione (come Google Maps per Android Automotive o qualsiasi app di mappe con le autorizzazioni richieste):
    1. Ottiene un CarAppFocusManager utilizzando la classe Car da car-lib.
    2. Prima dell'inizio delle indicazioni stradali dettagliate, le chiamate a CarAppFocusManager.requestFocus() per passare CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION come parametro appType .
  4. CarAppFocusManager comunica questa richiesta a CarService . Se concesso, CarService ispeziona il pacchetto dell'app di navigazione e individua un'attività contrassegnata con la categoria android.car.cluster.NAVIGATION .
  5. Se trovata, l'app di navigazione utilizza ActivityOptions segnalate da InstrumentClusterRenderingService per avviare l'attività e include le proprietà di visualizzazione del cluster dello strumento come extra nell'intento.

Integra l'API

L'implementazione InstrumentClusterRenderingService deve:

  • Essere designato come servizio singleton aggiungendo il valore seguente ad AndroidManifest.xml. Ciò è necessario per garantire che venga eseguita un'unica copia del servizio Instrument Cluster, anche durante l'inizializzazione e il cambio utente:
    android:singleUser="true"
  • Mantieni l'autorizzazione di sistema BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE . Ciò garantisce che solo il servizio di rendering del quadro strumenti incluso come parte dell'immagine del sistema Android sia mai vincolato da CarService :
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

Implementare InstrumentClusterRenderingService

Per costruire il servizio:

  1. Scrivi una classe che si estende dal servizio ClusterRenderingService connesso al display secondario.
  2. e quindi aggiungi una voce corrispondente al tuo file AndroidManifest.xml . Questa classe controlla la visualizzazione del quadro strumenti e può ( facoltativamente ) eseguire il rendering dei dati API dello stato di navigazione.
  3. Durante onCreate() , utilizzare questo servizio per inizializzare la comunicazione con l'hardware di rendering. Le opzioni includono:
    • Determinare il display secondario da utilizzare per il quadro strumenti.
    • Crea un display virtuale in modo che l'app Instrument Cluster esegua il rendering e trasmetta l'immagine renderizzata a un'unità esterna (utilizzando un formato di streaming video, come H.264).
  4. Quando il display sopra indicato è pronto, questo servizio deve chiamare InstrumentClusterRenderingService#setClusterActivityLaunchOptions() per definire le esatte ActivityOptions che devono essere utilizzate per visualizzare un'Attività sullo Instrument Cluster. Utilizza questi parametri:
    • categoria. Il servizio ClusterRenderingService è connesso al display secondario.
    • ActivityOptions. Un'istanza ActivityOptions che può essere utilizzata per avviare un'attività nel cluster dello strumento. Ad esempio, dall'implementazione di esempio del quadro strumenti su AOSP:
      getService().setClusterActivityLaunchOptions(
         CATEGORY_NAVIGATION,
         ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
      
  5. Quando il cluster dello strumento è pronto per visualizzare le attività, questo servizio deve richiamare InstrumentClusterRenderingService#setClusterActivityState() . Utilizza questi parametri:
    • Il servizio category ClusterRenderingService è connesso al display secondario.
    • state Il bundle generato con il servizio ClusterRenderingService è connesso al display secondario.
    • Assicurati di fornire i seguenti dati:
      • visible Specifica il quadro strumenti come visibile e pronto per visualizzare il contenuto.
      • unobscuredBounds Un rettangolo che definisce l'area all'interno del display del quadro strumenti in cui è sicuro visualizzare il contenuto. Ad esempio, aree coperte da quadranti e indicatori.
  6. Sostituisci il metodo Service#dump() e riporta informazioni sullo stato utili per il debug (vedi dumpsys per ulteriori informazioni).

Esempio di implementazione di InstrumentClusterRenderingService

L'esempio seguente descrive un'implementazione InstrumentClusterRenderingService , che crea un VirtualDisplay per presentare il contenuto del cluster strumento su un display fisico remoto.

In alternativa, questo codice potrebbe trasmettere il displayId di un display secondario fisico collegato all'HU, se ne è disponibile uno.

/**
* Sample {@link InstrumentClusterRenderingService} implementation
*/
public class SampleClusterServiceImpl extends InstrumentClusterRenderingService {
   // Used to retrieve or create displays
   private final DisplayManager mDisplayManager;
   // Unique identifier for the display to 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);
  }
}

Utilizza l'API CarAppFocusManager

L'API CarAppFocusManager fornisce un metodo denominato getAppTypeOwner() , che consente al servizio cluster scritto dagli OEM di sapere quale app di navigazione ha il focus sulla navigazione in un dato momento. Gli OEM possono utilizzare il metodo CarAppFocusManager#addFocusListener() esistente e quindi utilizzare getAppTypeOwner() per sapere quale app è attiva. Con queste informazioni, gli OEM possono:

  • Cambia l'attività mostrata nel cluster con l'attività del cluster fornita dall'app di navigazione mantenendo il focus.
  • Può rilevare se l'app di navigazione focalizzata ha un'attività cluster o meno. Se l'app di navigazione focalizzata non ha un'attività del cluster (o se tale attività è disabilitata), gli OEM possono inviare questo segnale al DIM dell'auto in modo che l'aspetto di navigazione del cluster venga saltato del tutto.

Utilizza CarAppFocusManager per impostare e ascoltare il focus corrente dell'app, come la navigazione attiva o un comando vocale. Di solito solo un'istanza di tale app è attivamente in esecuzione (o focalizzata) nel sistema.

Utilizza il metodo CarAppFocusManager#addFocusListener(..) per ascoltare le modifiche al focus dell'app:

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
}

Utilizza il metodo CarAppFocusManager#getAppTypeOwner(..) per recuperare i nomi dei pacchetti dell'attuale proprietario di un determinato tipo di app attivo. Questo metodo può restituire più di un nome di pacchetto se il proprietario attuale utilizza la funzionalità 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 app 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
}

...

Appendice: utilizzare l'app di esempio

AOSP fornisce un'app di esempio che implementa l'API Navigation State.

Per eseguire questa app di esempio:

  1. Crea ed esegui il flashing di Android Auto su un HU supportato. Utilizza le istruzioni per la creazione e il flashing di Android specifiche per il tuo dispositivo. Per istruzioni, vedere Utilizzo delle schede di riferimento .
  2. Collega un display secondario fisico all'HU (se supportato) o attiva l'HU secondario virtuale:
    1. Seleziona Modalità sviluppatore nell'app Impostazioni.
    2. Vai a Impostazioni > Sistema > Avanzate > Opzioni sviluppatore > Simula display secondari .
  3. Riavviare l'HU. Il servizio ClusterRenderingService è connesso al display secondario.
  4. Per avviare l'app KitchenSink:
    1. Apri il cassetto.
    2. Vai a Ist. Grappolo .
    3. Fare clic su INIZIA METADATI .

KitchenSink richiede il focus NAVIGATION, che indica al servizio DirectRenderingCluster di visualizzare un'interfaccia utente simulata sul quadro strumenti.