Guida all'integrazione per gli OEM

Questa pagina descrive come elaborare gli input della rotazione nel VHAL, configurare la build per includere il servizio della rotazione e come personalizzare l'esperienza della rotazione su tutte le app. Per le app OEM preinstallate, come un launcher fornito dall'OEM, consulta Libreria dell'interfaccia utente dell'auto (car-ui-library) .

VHAL

Un controller rotante supporta le seguenti azioni:

  • Spingi su, giù, a sinistra e a destra.
  • Ruotare in senso orario e antiorario.
  • Premi il pulsante centrale.
  • Premi il pulsante Indietro.
  • Premi il pulsante Home.
  • Premi altri pulsanti, come Telefono e Media.

Vedi hardware/interfaces/automotive/vehicle/2.0/types.hal per la documentazione sulle proprietà del sistema e i corrispondenti int32Values ​​.

Il VHAL dovrebbe gestire queste azioni:

Spinta

Quando l'utente spinge la manopola verso destra, il VHAL dovrebbe utilizzare la proprietà HW_KEY_INPUT con i seguenti int32Values ​​per inviare un evento ad Android:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Visualizzazione dell'obiettivo.

Quando l'utente rilascia la manopola, il VHAL dovrebbe utilizzare la stessa proprietà e lo stesso codice chiave con ACTION_UP . I nudge in altre direzioni dovrebbero utilizzare i codici chiave corrispondenti.

Non ci sono codici chiave per le diagonali ma il VHAL può combinare un evento orizzontale e verticale per produrre una diagonale se l'hardware supporta le diagonali. Ad esempio, spostare verso l'alto e verso sinistra dovrebbe produrre:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

In entrambi gli ordini (e successivamente) il rilascio del controller rotativo dovrebbe produrre:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

L'utente può spingere la manopola in direzione perpendicolare prima di rilasciarla. Ad esempio, il seguente scenario:

Direzione perpendicolare
Figura 1. Direzione perpendicolare

Ciò dovrebbe generare la seguente sequenza di eventi:

  1. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  2. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
  3. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  4. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Non devono essere generati eventi ripetuti mentre la manopola viene tenuta in una direzione.

Ruotare

Quando l'utente ruota il controller rotante in senso orario di un fermo (clic), il VHAL deve utilizzare la proprietà HW_ROTARY_INPUT con i seguenti int32Values ​​per inviare un evento ad Android:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Un (1) fermo.
  3. Visualizzazione dell'obiettivo.

Il timestamp dell'evento deve essere impostato sul tempo trascorso in nanosecondi.

Una rotazione in senso antiorario di un (1) fermo dovrebbe generare lo stesso evento ma con -1 per il numero di fermi.

Se si verificano più fermi di rotazione nella stessa direzione in rapida successione, il VHAL dovrebbe combinare i fermi in un unico evento in modo da non sovraccaricare il sistema di eventi. In questo caso, il timestamp dell'evento dovrebbe essere quando si è verificato il primo arresto della rotazione. I int32Values dovrebbero includere il numero di nanosecondi tra fermi di rotazione consecutivi.

Ad esempio, la seguente sequenza di rotazioni:

  • Al momento t0, l'utente ha ruotato un fermo in senso antiorario.
  • Al tempo t0 + 5 ns, l'utente ha ruotato un fermo in senso antiorario.
  • Al tempo t0 + 8 ns, l'utente ha ruotato un fermo in senso antiorario.

dovrebbe generare questo evento:

  • Proprietà: HW_ROTARY_INPUT
  • Timestamp: t0
  • int32Values :
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (tre fermi in senso antiorario).
    3. Visualizzazione dell'obiettivo.
    4. 5 ns tra il primo e il secondo scatto.
    5. 3 ns tra il secondo e il terzo scatto.

Pulsante centrale

Quando l'utente preme il pulsante centrale, il VHAL dovrebbe utilizzare la proprietà HW_KEY_INPUT con i seguenti int32Values ​​per inviare un evento ad Android:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Visualizzazione dell'obiettivo.

Quando l'utente rilascia la manopola, il VHAL dovrebbe utilizzare la stessa proprietà e lo stesso codice chiave con ACTION_UP .

Non generare eventi ripetuti quando si tiene premuto il pulsante centrale.

Tasto indietro

Quando l'utente preme il pulsante Indietro, il VHAL dovrebbe utilizzare la proprietà HW_KEY_INPUT con i seguenti int32Values ​​per inviare un evento ad Android:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Visualizzazione dell'obiettivo.

Quando l'utente rilascia la manopola, il VHAL dovrebbe utilizzare la stessa proprietà e lo stesso codice chiave con ACTION_UP .

Non devono essere generati eventi ripetuti mentre si tiene premuto il pulsante centrale.

Pulsante Home

Gestisci il pulsante Home come faresti con il pulsante Indietro ma con KEYCODE_HOME invece di KEYCODE_BACK .

Altri pulsanti

Se il controller rotante include pulsanti aggiuntivi, il VHAL può gestirli come piace all'OEM poiché non sono considerati parte del controller rotante dal punto di vista di Android. Questi vengono generalmente gestiti come i pulsanti Indietro e Home ma con codici chiave diversi. Ad esempio, KEYCODE_CALL o KEYCODE_MUSIC .

Costruisci la configurazione

La navigazione nel Rotary è fornita da un servizio di accessibilità chiamato RotaryService . Per includere questo servizio nell'immagine di sistema del tuo dispositivo, aggiungi la seguente riga al tuo makefile:

PRODUCT_PACKAGES += CarRotaryController

Potresti anche voler includere i seguenti pacchetti nelle build di debug:

Il servizio rotativo viene abilitato automaticamente all'avvio del dispositivo e quando si verifica un cambio utente. Ciò garantisce che l'utente possa utilizzare la manopola di controllo durante la configurazione.

Se utilizzi la stessa build per auto con e senza controller rotante, aggiungi CarRotaryController come mostrato sopra in modo che il codice necessario sia incluso nella build. Per impedire che il servizio rotativo venga abilitato su auto non rotanti, creare un RRO statico per sovrapporre la risorsa stringa rotaryService in packages/services/Car/service con una stringa vuota. Utilizzerai la stessa build, ma avrai configurazioni di prodotto separate, per dispositivi rotanti e non rotanti. Solo quest'ultimo include l'overlay.

Personalizzazione

Gli OEM possono personalizzare la logica di ricerca del focus, l'evidenziazione del focus e alcuni elementi aggiuntivi tramite sovrapposizioni di risorse nelle seguenti posizioni:

  • La libreria car-ui si trova in packages/apps/Car/libs/car-ui-lib
  • RotaryService si trova in packages/apps/Car/RotaryController
  • Core si trova in frameworks/base/core

Storia della spinta

L'OEM può configurare se ciascuno dei due tipi di cronologia dei solleciti è abilitato o meno e, in tal caso, la dimensione della cache e i criteri di scadenza. Tutto questo viene fatto sovrascrivendo varie risorse car-ui-library.

Focus sulla cache della cronologia

( Android 11 QPR3, Android 11 Auto, Android 12 )
Questa cache per FocusArea memorizza la vista focalizzata più recentemente all'interno di FocusArea in modo che possa essere focalizzata quando si torna a FocusArea . Questa cache può essere configurata sovrapponendo le seguenti risorse car-ui-library:

  • car_ui_focus_history_cache_type :
    1. La cache è disabilitata.
    2. La cache scadrà dopo un po' di tempo (vedi sotto).
    3. La cache non scadrà mai.
  • car_ui_focus_history_expiration_period_ms : quanti millisecondi prima della scadenza della cache se il tipo di cache è impostato su due (2) (vedi sopra).

Cache della cronologia FocusArea

( Android 11 QPR3, Android 11 Auto, Android 12 )
Questa cache memorizza una cronologia degli spostamenti in modo che gli spostamenti nella direzione opposta possano riportare lo stato attivo sulla stessa FocusArea . Questa cache può essere configurata sovrapponendo le seguenti risorse car-ui-library:

  • car_ui_focus_area_history_cache_type :
    1. La cache è disabilitata.
    2. La cache scade dopo un po' di tempo (vedi sotto).
    3. La cache non scade mai.
  • car_ui_focus_area_history_expiration_period_ms : quanti millisecondi prima della scadenza della cache se il tipo di cache è impostato su 2 (vedi sopra).
  • car_ui_clear_focus_area_history_when_rotating : indica se svuotare la cache quando l'utente ruota il controller.

Rotazione

( Android 11 QPR3, Android 11 Auto, Android 12 )
L'OEM può sovrascrivere due risorse intere nel RotaryService per specificare se è presente un'accelerazione, ad esempio l'accelerazione del mouse, per la rotazione:

  • rotation_acceleration_3x_ms : intervallo di tempo (in millisecondi) utilizzato per decidere se Google deve accelerare la rotazione del controller per un arresto della rotazione. Se l'intervallo tra questo fermo e il precedente fermo di rotazione è inferiore a questo valore, verrà trattato come tre fermi di rotazione. Impostalo su 2147483647 per disabilitare l'accelerazione 3×.
  • rotation_acceleration_2x_ms : simile a rotation_acceleration_3x_ms . Utilizzato per l'accelerazione 2×. Impostalo su 2147483647 per disabilitare l'accelerazione 2×.

L'accelerazione funziona meglio quando sono presenti timestamp individuali per ciascun fermo di rotazione, come richiesto dal VHAL. Se questi non sono disponibili, RotaryService presuppone che i fermi di rotazione siano equidistanti.

/**
     * Property to feed H/W rotary events to android
     *
     * int32Values[0] : RotaryInputType identifying which rotary knob rotated
     * int32Values[1] : number of detents (clicks), positive for clockwise,
     *                  negative for counterclockwise
     * int32Values[2] : target display defined in VehicleDisplay. Events not
     *                  tied to specific display must be sent to
     *                  VehicleDisplay#MAIN.
     * int32values[3 .. 3 + abs(number of detents) - 2]:
     *                  nanosecond deltas between pairs of consecutive detents,
     *                  if the number of detents is > 1 or < -1
     *
     * VehiclePropValue.timestamp: when the rotation occurred. If the number of
     *                             detents is > 1 or < -1, this is when the
     *                             first detent of rotation occurred.
     *
     * @change_mode VehiclePropertyChangeMode:ON_CHANGE
     * @data_enum RotaryInputType
     * @access VehiclePropertyAccess:READ
     */
    HW_ROTARY_INPUT = (
        0x0A20
        | VehiclePropertyGroup:SYSTEM
        | VehiclePropertyType:INT32_VEC
        | VehicleArea:GLOBAL),

Evidenziazione della messa a fuoco

L'OEM può sovrascrivere l'evidenziazione del focus predefinita nel framework Android e diverse risorse di evidenziazione del focus nella libreria car-ui.

Evidenziazione della messa a fuoco predefinita

Il framework Android fornisce un'evidenziazione del focus predefinita tramite l'attributo selectableItemBackground . In Theme.DeviceDefault , questo attributo si riferisce a item_background.xml in Core . L'OEM può sovrapporre item_background.xml per modificare l'evidenziazione del focus predefinita disegnabile.

Questo drawable dovrebbe in genere essere un StateListDrawable , che regola lo sfondo in base a diverse combinazioni di stati, inclusi android:state_focused e android:state_pressed . Quando l'utente utilizza la manopola per mettere a fuoco una vista, android:state_focused sarà true , ma android:state_pressed sarà false . Se l'utente preme quindi il pulsante centrale sulla manopola di controllo, sia android:state_focused che android:state_pressed saranno true mentre l'utente tiene premuto il pulsante. Quando l'utente rilascia il pulsante, solo android:state_focused rimarrà true .

car-ui-library utilizza un tema derivato da Theme.DeviceDefault . Di conseguenza, questa sovrapposizione influisce sulle app che utilizzano questa libreria e sulle app che utilizzano qualsiasi tema derivato da Theme.DeviceDefault . Non influirà sulle app che utilizzano un tema non correlato, come Theme.Material .

Focus evidenzia le risorse nella libreria car-ui

L'OEM può sovrascrivere diverse risorse della libreria dell'interfaccia utente dell'auto per controllare l'aspetto dell'evidenziazione dello stato attivo nelle viste con un'evidenziazione dello stato attivo non rettangolare (ad esempio rotonda o a forma di pillola) e nelle app che utilizzano un tema che non deriva da Theme.DeviceDefault . Queste risorse dovrebbero essere sovrapposte in modo che l'evidenziazione del focus sia coerente con l' evidenziazione del focus predefinita disegnabile.

( Android 11 QPR3, Android 11 Auto, Android 12 )
Le seguenti risorse vengono utilizzate per indicare quando una vista è focalizzata ma non premuta:

  • car_ui_rotary_focus_fill_color : colore di riempimento.
  • car_ui_rotary_focus_stroke_color : colore del contorno.
  • car_ui_rotary_focus_stroke_width : spessore del contorno.

( Android 11 QPR3, Android 11 Auto, Android 12 )
Le seguenti risorse vengono utilizzate per indicare quando una vista è focalizzata e premuta:

  • car_ui_rotary_focus_pressed_fill_color : colore di riempimento.
  • car_ui_rotary_focus_pressed_stroke_color : colore del contorno.
  • car_ui_rotary_focus_pressed_stroke_width : spessore del contorno.

A volte a un pulsante viene assegnato un colore di sfondo a tinta unita per portarlo all'attenzione dell'utente, come nell'esempio mostrato. Ciò potrebbe rendere difficile la visualizzazione dell'evidenziazione della messa a fuoco.

Pulsante con sfondo a tinta unita
Figura 2. Pulsante con sfondo a tinta unita

In questa situazione, lo sviluppatore può specificare un'evidenziazione del focus personalizzata utilizzando i colori secondari :
  • ( Android 11 QPR3, Android 11 Auto, Android 12 )
    car_ui_rotary_focus_fill_secondary_color
    car_ui_rotary_focus_stroke_secondary_color
  • ( Android 12 )
    car_ui_rotary_focus_pressed_fill_secondary_color
    car_ui_rotary_focus_pressed_stroke_secondary_color

Qualsiasi colore può essere trasparente e ciascuna dimensione può essere zero se, ad esempio, si desidera solo un riempimento o solo un contorno.

Evidenziazione dell'area di messa a fuoco

( Android 11 QPR3, Android 11 Auto, Android 12 )
FocusArea può disegnare due tipi di evidenziazione quando uno dei suoi discendenti è focalizzato. Entrambi possono essere utilizzati insieme, se lo si desidera. Questa funzione è disabilitata per impostazione predefinita in AOSP, ma può essere abilitata sovrascrivendo le risorse car-ui-library:

  • car_ui_enable_focus_area_foreground_highlight : disegna un'evidenziazione sopra FocusArea e i suoi discendenti. In AOSP, questo drawable è un contorno attorno a FocusArea . Gli OEM possono sovrascrivere il drawable car_ui_focus_area_foreground_highlight .
  • car_ui_enable_focus_area_background_highlight : disegna un'evidenziazione sopra la FocusArea ma dietro i suoi discendenti. In AOSP, questo elemento disegnabile è un riempimento solido. Gli OEM possono sovrascrivere il drawable car_ui_focus_area_background_highlight .

Editor del metodo di input

Gli Input Method Editor (IME) sono metodi di input. Ad esempio, una tastiera su schermo.

( Android 11 QPR3, Android 11 Auto, Android 12 )
L'OEM deve sovrapporre la risorsa stringa default_touch_input_method nel RotaryService per specificare il ComponentName dell'IME basato su touch. Ad esempio, se l'OEM utilizza l'IME fornito con Android Automotive, deve specificare com.google.android.apps.automotive.inputmethod/.InputMethodService .

( Android 11 QPR3, Android 11 Auto, Android 12 )
Se l'OEM ha creato un IME appositamente per il Rotary, deve specificarne il ComponentName nella risorsa rotary_input_method . Se questa risorsa è sovrapposta, l'IME specificato viene utilizzato ogni volta che l'utente interagisce con l'unità principale tramite la spinta, la rotazione e il pulsante centrale del controller rotante. Quando l'utente tocca lo schermo, verrà utilizzato l'IME precedente. Il pulsante Indietro (e gli altri pulsanti sulla manopola) non hanno effetto sulla selezione IME. Se questa risorsa non è sovrapposta, non si verifica alcun cambio IME. Carboard non supporta la rotazione, quindi l'utente non può inserire testo tramite la manopola se l'OEM non ha fornito un IME rotativo.

RotaryIME è un IME rotativo demo. Anche se di base, è sufficiente provare la commutazione automatica dell'IME descritta sopra. Il codice sorgente per RotaryIME può essere trovato in packages/apps/Car/tests/RotaryIME/ .

Solleciti fuori schermo

Per impostazione predefinita, quando l'utente tenta di spostarsi dal bordo dello schermo, non accade nulla. L'OEM può configurare cosa dovrebbe accadere per ciascuna delle quattro direzioni specificando qualsiasi combinazione di:

  1. Un'azione globale definita da AccessibilityService . Ad esempio, GLOBAL_ACTION_BACK .
  2. Un codice chiave, ad esempio KEYCODE_BACK .
  3. Un intento di avviare un'attività rappresentata come un URL.

( Android 11 QPR3, Android 11 Auto, Android 12 )
Questi vengono specificati sovrapponendo le seguenti risorse dell'array nel RotaryService :

  • off_screen_nudge_global_actions : serie di azioni globali da eseguire quando l'utente sposta verso l'alto, verso il basso, a sinistra o a destra oltre il bordo dello schermo. Non viene eseguita alcuna azione globale se l'elemento rilevante di questo array è -1.
  • off_screen_nudge_key_codes : matrice di codici chiave degli eventi di clic da inserire quando l'utente sposta verso l'alto, verso il basso, a sinistra o a destra oltre il bordo dello schermo. Nessun evento viene inserito se l'elemento rilevante di questo array è 0 ( KEYCODE_UNKNOWN ).
  • off_screen_nudge_intents : array di intenti per avviare un'attività quando l'utente sposta verso l'alto, verso il basso, a sinistra o a destra oltre il bordo dello schermo. Nessuna attività viene avviata se l'elemento rilevante di questo array è vuoto.

Altre configurazioni

Dovresti sovrapporre le seguenti risorse RotaryService :

  • ( Android 11 QPR3, Android 11 Auto, Android 12 )
    config_showHeadsUpNotificationOnBottom : valore booleano per indicare se le notifiche heads-up devono essere visualizzate in basso anziché in alto. Deve avere lo stesso valore della risorsa booleana config_showHeadsUpNotificationOnBottom in frameworks/base/packages/CarSystemUI/res/values/config.xml
  • ( Android 11 QPR3, Android 11 Auto, Android 12 )
    notification_headsup_card_margin_horizontal : margine sinistro e destro per la finestra di notifica heads-up. Deve avere lo stesso valore della risorsa notification_headsup_card_margin_horizontal dimen in packages/apps/Car/Notification/res/values/dimens.xml
  • ( Android 12 )
    excluded_application_overlay_window_titles : un array di titoli di finestre che non devono essere considerate finestre sovrapposte. Dovrebbero includere i titoli delle finestre dell'app che rappresentano TaskViews o TaskDisplayAreas . Per impostazione predefinita, questo elenco contiene solo "Mappe".

Puoi sovrapporre la seguente risorsa RotaryService :

  • ( Android 11 QPR3, Android 11 Auto, Android 12 )
    long_press_ms : valore intero per rappresentare quanti millisecondi è necessario tenere premuto il pulsante centrale per attivare una pressione prolungata. Lo zero indica che è necessario utilizzare il timeout di pressione prolungata predefinito del sistema. Questo è il valore predefinito.