Questa pagina descrive come elaborare gli input rotativi in VHAL, configurare la build in modo da includere il servizio rotativo e come personalizzare l'esperienza rotativa in tutte le app. Per le app OEM preinstallate, ad esempio un launcher fornito dall'OEM, vedi Libreria UI per auto (car-ui-library).
VHAL
Un controller rotativo supporta le seguenti azioni:
- Sposta verso l'alto, il basso, a sinistra e a destra.
- Ruota in senso orario e antiorario.
- Premi il pulsante centrale.
- Premi il pulsante Indietro.
- Premi il pulsante Home.
- Premi altri pulsanti, ad esempio Telefono e Media.
Consulta hardware/interfaces/automotive/vehicle/2.0/types.hal per la documentazione sulle proprietà di sistema e sui int32Values corrispondenti.
Il VHAL deve gestire queste azioni:
Colpetto di gomito
Quando l'utente spinge il controller rotativo verso destra, VHAL deve utilizzare la proprietà HW_KEY_INPUT con il seguente int32Values per inviare un evento ad Android:
ACTION_DOWNKEYCODE_SYSTEM_NAVIGATION_RIGHT- Target di visualizzazione.
Quando l'utente rilascia il controller rotativo, VHAL deve utilizzare la stessa proprietà e lo stesso
keycode con ACTION_UP. I suggerimenti in altre direzioni devono utilizzare i
codici chiave corrispondenti.
Non esistono codici chiave per le diagonali, ma l'HAL del veicolo può combinare un evento orizzontale e verticale per produrre una diagonale se l'hardware la supporta. Ad esempio, spostando leggermente verso l'alto e a sinistra si dovrebbe ottenere:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWNHW_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_UPHW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
L'utente potrebbe spingere il controller rotativo in direzione perpendicolare prima di rilasciarlo. Ad esempio, il seguente scenario:
In questo modo dovrebbe essere generata la seguente sequenza di eventi:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWNHW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWNHW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UPHW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
Non devono essere generati eventi ripetuti mentre il controller rotativo è tenuto in una direzione.
Ruota
Quando l'utente ruota il controller rotativo in senso orario di uno scatto, l'HAL
deve utilizzare la proprietà HW_ROTARY_INPUT con il seguente int32Values
per inviare un evento ad Android:
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION- Un (1) arresto.
- Target di visualizzazione.
Il timestamp dell'evento deve essere impostato sul tempo trascorso in nanosecondi.
Una rotazione di un (1) scatto in senso antiorario deve generare lo stesso evento, ma con -1 per il numero di scatti.
Se si verificano più scatti di rotazione nella stessa direzione in rapida successione, la VHAL
deve combinare gli scatti in un unico evento per non sovraccaricare il sistema con eventi.
In questo caso, il timestamp dell'evento deve corrispondere al momento in cui si è verificato il primo arresto della rotazione.
int32Values deve includere il numero di nanosecondi tra un punto di arresto e l'altro della rotazione.
Ad esempio, la seguente sequenza di rotazioni:
- Al momento t0, l'utente ha ruotato un dentello in senso antiorario.
- Al tempo t0 + 5 ns, l'utente ha ruotato un arresto in senso antiorario.
- Al tempo t0 + 8 ns, l'utente ha ruotato un arresto in senso antiorario.
dovrebbe generare questo evento:
- Proprietà:
HW_ROTARY_INPUT - Timestamp:
t0 int32Values:ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION- -3 (tre tacche in senso antiorario).
- Target di visualizzazione.
- 5 ns tra il primo e il secondo arresto.
- 3 ns tra il secondo e il terzo arresto.
Pulsante centrale
Quando l'utente preme il pulsante centrale, l'HAL del veicolo deve utilizzare la proprietà HW_KEY_INPUT con il seguente int32Values per inviare un evento ad Android:
ACTION_DOWNKEYCODE_DPAD_CENTER- Target di visualizzazione.
Quando l'utente rilascia il controller rotativo, VHAL deve utilizzare la stessa proprietà e lo stesso codice tasto con ACTION_UP.
Non generare eventi ripetuti quando il pulsante centrale è tenuto premuto.
Pulsante Indietro
Quando l'utente preme il pulsante Indietro, VHAL deve utilizzare la proprietà HW_KEY_INPUT
con il seguente int32Values per inviare un evento ad Android:
ACTION_DOWNKEYCODE_BACK- Target di visualizzazione.
Quando l'utente rilascia il controller rotativo, VHAL deve utilizzare la stessa proprietà e lo stesso codice tasto con ACTION_UP.
Non devono essere generati eventi ripetuti mentre il pulsante Centro è premuto.
pulsante Home
Gestisci il pulsante Home come faresti con il pulsante Indietro, ma con KEYCODE_HOME
anziché KEYCODE_BACK.
Altri pulsanti
Se il controller rotativo include pulsanti aggiuntivi, VHAL può gestirli come
preferisce l'OEM, in quanto non sono considerati parte del controller rotativo dal punto di vista di Android.
In genere vengono gestiti come i pulsanti Indietro e Home, ma con codici tasto diversi.
Ad esempio, KEYCODE_CALL o KEYCODE_MUSIC.
Configurazione build
La navigazione rotativa è fornita da un servizio di accessibilità chiamato RotaryService.
Per includere questo servizio nell'immagine di sistema del tuo dispositivo, aggiungi la seguente riga al
makefile:
PRODUCT_PACKAGES += CarRotaryController
Potresti anche voler includere i seguenti pacchetti nelle build di debug:
RotaryPlaygroundUn'app di riferimento per l'input rotatorio (vedi RotaryPlayground).RotaryIMEUn IME rotatorio demo (vedi Input Method Editor).CarRotaryImeRROL'overlay perRotaryIME.
Il servizio rotativo viene attivato automaticamente all'avvio del dispositivo e quando si verifica un cambio di utente. In questo modo, l'utente può utilizzare il controller rotativo durante la configurazione.
Se utilizzi la stessa build per le auto con e senza controller rotativo,
aggiungi CarRotaryController come mostrato sopra in modo che il codice necessario sia incluso
nella build. Per impedire l'attivazione del servizio rotativo su auto non rotative, crea 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 i dispositivi rotativi e non rotativi. Solo quest'ultimo
include l'overlay.
Personalizzazione
Gli OEM possono personalizzare la logica di ricerca della messa a fuoco, l'evidenziazione della messa a fuoco e alcuni elementi aggiuntivi tramite overlay delle risorse nelle seguenti posizioni:
- car-ui-library si trova in
packages/apps/Car/libs/car-ui-lib RotaryServicesi trova inpackages/apps/Car/RotaryControllerCoresi trova inframeworks/base/core
Cronologia dei Nudge
L'OEM può configurare se attivare o meno ciascuno dei due tipi di cronologia dei suggerimenti e, in caso affermativo, le dimensioni della cache e la policy di scadenza. Tutto questo viene fatto eseguendo l'override di varie risorse di car-ui-library.
Cache della cronologia della messa a fuoco
(Android 11 QPR3, Android 11 Car,
Android 12)
Questa cache per FocusArea memorizza la visualizzazione più recente all'interno del
FocusArea in modo che possa essere selezionata quando si torna al FocusArea.
Questa cache può essere configurata sovrapponendo le seguenti risorse car-ui-library:
-
car_ui_focus_history_cache_type:- La cache è disattivata.
- La cache scadrà dopo un po' di tempo (vedi sotto).
- La cache non scadrà mai.
car_ui_focus_history_expiration_period_ms: il numero di millisecondi prima della scadenza della cache se il tipo di cache è impostato su 2 (vedi sopra).
Cache della cronologia di FocusArea
(Android 11 QPR3, Android 11 Car,
Android 12)
Questa cache memorizza una cronologia dei suggerimenti in modo che i suggerimenti nella direzione opposta possano
riportare lo stato attivo sullo stesso FocusArea. Questa cache può essere configurata sovrapponendo le seguenti risorse della libreria car-ui-library:
-
car_ui_focus_area_history_cache_type:- La cache è disattivata.
- La cache scade dopo un po' di tempo (vedi sotto).
- La cache non scade mai.
car_ui_focus_area_history_expiration_period_ms: il numero di 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 invalidare la cache quando l'utente ruota il controller.
Rotazione
(Android 11 QPR3, Android 11 Car,
Android 12)
L'OEM può eseguire l'override di due risorse intere in 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 questa tacca e la tacca di rotazione precedente è inferiore a questo valore, verrà considerato come tre tacche di rotazione. Imposta questo valore su 2147483647 per disattivare l'accelerazione 3×.rotation_acceleration_2x_ms: simile arotation_acceleration_3x_ms. Utilizzato per l'accelerazione 2×. Imposta questo valore su2147483647per disattivare l'accelerazione 2x.
L'accelerazione funziona meglio quando sono presenti timestamp individuali per ogni tacca di rotazione, come
richiesto
dall'HAL del veicolo. Se non sono disponibili, RotaryService presuppone che i detent di rotazione siano equispaziati.
/** * 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ò eseguire l'override dell'evidenziazione della messa a fuoco predefinita nel framework Android e di diverse risorse di evidenziazione della messa a fuoco in car-ui-library.
Evidenziazione dello stato attivo predefinita
Il framework Android fornisce un'evidenziazione predefinita dello stato attivo 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 la risorsa disegnabile di evidenziazione della messa a fuoco predefinita.
Questo elemento disegnabile in genere deve essere un StateListDrawable, che regola lo sfondo
in base a diverse combinazioni di stati, tra cui android:state_focused
e android:state_pressed. Quando l'utente utilizza il controller rotativo per
mettere a fuoco una visualizzazione, android:state_focused sarà true, ma
android:state_pressed sarà false. Se l'utente preme
il pulsante centrale sul controller rotativo, sia android:state_focused che
android:state_pressed saranno true mentre l'utente tiene premuto il pulsante.
Quando l'utente rilascia il pulsante, rimane solo android:state_focused
true.
car-ui-library utilizza un tema derivato da Theme.DeviceDefault. Di conseguenza,
questa overlay 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.
Risorse di evidenziazione del focus in car-ui-library
L'OEM può eseguire l'override di diverse risorse della libreria car-ui per controllare l'aspetto dell'evidenziazione della messa a fuoco
nelle visualizzazioni con un'evidenziazione della messa a fuoco 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 devono essere sovrapposte in modo che l'evidenziazione dello stato attivo sia coerente con la risorsa disegnabile
dell'evidenziazione dello stato attivo predefinita.
(Android 11 QPR3, Android 11 Car,
Android 12)
Le seguenti risorse vengono utilizzate per indicare quando una visualizzazione è selezionata ma non premuta:
car_ui_rotary_focus_fill_color: colore di riempimento.car_ui_rotary_focus_stroke_color: colore contorno.car_ui_rotary_focus_stroke_width: lo spessore del contorno.
(Android 11 QPR3, Android 11 Car,
Android 12)
Le seguenti risorse vengono utilizzate per indicare quando una visualizzazione è selezionata e premuta:
car_ui_rotary_focus_pressed_fill_color: colore di riempimento.car_ui_rotary_focus_pressed_stroke_color: colore contorno.car_ui_rotary_focus_pressed_stroke_width: lo spessore del contorno.
A volte a un pulsante viene assegnato un colore di sfondo pieno per attirare l'attenzione dell'utente, come nell'esempio mostrato. Ciò potrebbe rendere difficile la visualizzazione dell'evidenziazione della messa a fuoco.
In questa situazione, lo sviluppatore può specificare un'evidenziazione personalizzata dello stato attivo utilizzando i colori secondari:
- (Android 11 QPR3, Android 11 Car,
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
Uno qualsiasi dei colori può essere trasparente e una delle dimensioni può essere zero se, ad esempio, vuoi solo un riempimento o solo un contorno.
FocusArea highlight
(Android 11 QPR3, Android 11 Car,
Android 12)
FocusArea può disegnare due tipi di evidenziazione quando uno dei suoi discendenti è
selezionato. Se vuoi, puoi utilizzarli insieme. Questa funzionalità è disattivata per impostazione predefinita in
AOSP, ma può essere attivata sostituendo le risorse della libreria car-ui:
car_ui_enable_focus_area_foreground_highlight: disegna un'evidenziazione sopra ilFocusAreae i relativi elementi secondari. In AOSP, questa risorsa disegnabile è un contorno intorno aFocusArea. Gli OEM possono eseguire l'override della risorsa disegnabilecar_ui_focus_area_foreground_highlight.car_ui_enable_focus_area_background_highlight: disegna un'evidenziazione sopraFocusAreama dietro i suoi discendenti. In AOSP, questa risorsa disegnabile è un riempimento solido. Gli OEM possono eseguire l'override del drawablecar_ui_focus_area_background_highlight.
Input Method Editors
Gli Input Method Editor (IME) sono metodi di immissione. Ad esempio, una tastiera sullo schermo.
(Android 11 QPR3, Android 11 Car,
Android 12)
L'OEM deve sovrapporre la risorsa stringa default_touch_input_method
in RotaryService per specificare ComponentName dell'IME
basato sul tocco. 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 Car,
Android 12)
Se l'OEM ha creato un IME specifico per il controllo rotativo, deve specificarne
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 il tocco, la rotazione e il pulsante centrale del controller rotativo. Quando l'utente tocca
lo schermo, viene utilizzato il metodo di input precedente. Il pulsante Indietro (e gli altri pulsanti sul controller rotativo) non hanno alcun effetto sulla selezione della IME. Se questa risorsa non viene sovrapposta, non si verifica
alcun cambio di IME. Cardboard non supporta la rotazione, quindi l'utente non può inserire testo tramite il controller rotatorio se l'OEM non ha fornito un IME rotatorio.
RotaryIME è un IME rotativo demo. Sebbene di base, è sufficiente per
provare il cambio automatico dell'IME descritto sopra. Il codice sorgente per RotaryIME
è disponibile in packages/apps/Car/tests/RotaryIME/.
Solleciti fuori dallo schermo
Per impostazione predefinita, quando l'utente tenta di spostare il contenuto fuori dallo schermo, non succede nulla. L'OEM può configurare cosa deve accadere per ciascuna delle quattro direzioni specificando una qualsiasi combinazione di:
- Un'azione globale definita da
AccessibilityService. Ad esempio,GLOBAL_ACTION_BACK. - Un codice chiave, ad esempio
KEYCODE_BACK. - Un intent per avviare un'attività rappresentata come URL.
(Android 11 QPR3, Android 11 Car,
Android 12)
Questi vengono specificati sovrapponendo le seguenti risorse di array in
RotaryService:
off_screen_nudge_global_actions: Array di azioni globali da eseguire quando l'utente scorre verso l'alto, il basso, sinistra o destra oltre il bordo dello schermo. Nessuna azione globale viene eseguita se l'elemento pertinente di questo array è -1.off_screen_nudge_key_codes: Array di codici chiave degli eventi di clic da inserire quando l'utente si sposta verso l'alto, il basso, sinistra o destra dal bordo dello schermo. Non vengono inseriti eventi se l'elemento pertinente di questo array è 0 (KEYCODE_UNKNOWN).off_screen_nudge_intents: Array di intent per avviare un'attività quando l'utente sposta il dito verso l'alto, il basso, sinistra o destra dal bordo dello schermo. Nessuna attività viene avviata se l'elemento pertinente di questo array è vuoto.
Altre configurazioni
Devi sovrapporre le seguenti risorse RotaryService:
- (Android 11 QPR3, Android 11 Car,
Android 12)
config_showHeadsUpNotificationOnBottom: valore booleano per indicare se le notifiche heads-up devono essere mostrate in basso anziché in alto. Deve avere lo stesso valore della risorsa booleanaconfig_showHeadsUpNotificationOnBottominframeworks/base/packages/CarSystemUI/res/values/config.xml - (Android 11 QPR3, Android 11 Car,
Android 12)
notification_headsup_card_margin_horizontal: Margine sinistro e destro per la finestra di notifica heads-up. Deve avere lo stesso valore della risorsanotification_headsup_card_margin_horizontaldimen inpackages/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 di overlay. Devono essere inclusi i titoli delle finestre delle app che rappresentanoTaskViewsoTaskDisplayAreas. Per impostazione predefinita, questo elenco contiene solo "Maps".
Puoi sovrapporre la seguente risorsa RotaryService:
- (Android 11 QPR3, Android 11 Car,
Android 12)
long_press_ms: valore intero che rappresenta il numero di millisecondi per cui il pulsante centrale deve essere tenuto premuto per attivare una pressione prolungata. Zero indica che deve essere utilizzato il timeout di pressione prolungata predefinito del sistema. Questo è il valore predefinito.