Cette page explique comment traiter les entrées rotatives dans le VHAL, comment configurer votre compilation pour inclure le service rotatif et comment personnaliser l'expérience rotative dans toutes les applications. Pour les applications OEM préinstallées, telles qu'un lanceur fourni par l'OEM, consultez la bibliothèque Car UI (car-ui-library).
VHAL
Un contrôleur rotatif est compatible avec les actions suivantes :
- Déplacer vers le haut/bas, vers la gauche/droite
- Rotation dans le sens des aiguilles d'une montre et dans le sens inverse
- Appuyer sur le bouton central
- Appuyer sur le bouton Retour
- Appuyer sur le bouton Accueil
- Appuyer sur d'autres boutons, tels que Téléphone et Multimédia
Consultez hardware/interfaces/automotive/vehicle/2.0/types.hal pour obtenir de la documentation sur les propriétés système et les int32Values correspondants.
Le VHAL doit gérer les actions suivantes :
Déplacer
Lorsque l'utilisateur pousse le contrôleur rotatif vers la droite, le VHAL doit utiliser la propriété HW_KEY_INPUT avec les int32Values suivants pour envoyer un événement à Android :
ACTION_DOWNKEYCODE_SYSTEM_NAVIGATION_RIGHT- Affichage cible
Lorsque l'utilisateur relâche le contrôleur rotatif, le VHAL doit utiliser la même propriété et le même code de touche avec ACTION_UP. Les déplacements dans d'autres directions doivent utiliser les codes de touche correspondants.
Il n'existe pas de codes de touche pour les diagonales, mais le VHAL peut combiner un événement horizontal et vertical pour produire une diagonale si le matériel est compatible avec les diagonales. Par exemple, un déplacement vers le haut et vers la gauche doit produire :
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWNHW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
Dans n'importe quel ordre (et par la suite), le fait de relâcher le contrôleur rotatif doit produire :
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UPHW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
L'utilisateur peut pousser le contrôleur rotatif dans une direction perpendiculaire avant de le relâcher. Par exemple, le scénario suivant :
Cela doit générer la séquence d'événements suivante :
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
Aucun événement repeat ne doit être généré lorsque le contrôleur rotatif est maintenu dans une direction.
Faire pivoter
Lorsque l'utilisateur fait pivoter le contrôleur rotatif dans le sens des aiguilles d'une montre d'un cran (clic), le VHAL doit utiliser la propriété HW_ROTARY_INPUT avec les int32Values suivants pour envoyer un événement à Android :
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION- Un (1) cran
- Affichage cible
L'horodatage de l'événement doit être défini sur le temps écoulé en nanosecondes.
Une rotation d'un (1) cran dans le sens inverse des aiguilles d'une montre doit générer le même événement, mais avec -1 pour le nombre de crans.
Si plusieurs crans de rotation dans la même direction se produisent rapidement, le VHAL doit combiner les crans en un seul événement afin de ne pas surcharger le système avec des événements.
Dans ce cas, l'horodatage de l'événement doit correspondre au moment où le premier cran de rotation s'est produit.
Les int32Values doivent inclure le nombre de nanosecondes entre les crans de rotation consécutifs.
Par exemple, la séquence de rotations suivante :
- À l'heure t0, l'utilisateur a fait pivoter d'un cran dans le sens inverse des aiguilles d'une montre.
- À l'heure t0 + 5 ns, l'utilisateur a fait pivoter d'un cran dans le sens inverse des aiguilles d'une montre.
- À l'heure t0 + 8 ns, l'utilisateur a fait pivoter d'un cran dans le sens inverse des aiguilles d'une montre.
doit générer cet événement :
- Propriété :
HW_ROTARY_INPUT - Horodatage :
t0 int32Values:ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION- -3 (trois crans dans le sens inverse des aiguilles d'une montre)
- Affichage cible
- 5 ns entre le premier et le deuxième cran
- 3 ns entre le deuxième et le troisième cran
Bouton central
Lorsque l'utilisateur appuie sur le bouton central, le VHAL doit utiliser la propriété HW_KEY_INPUT avec les int32Values suivants pour envoyer un événement à Android :
ACTION_DOWNKEYCODE_DPAD_CENTER- Affichage cible
Lorsque l'utilisateur relâche le contrôleur rotatif, le VHAL doit utiliser la même propriété et le même code de touche avec ACTION_UP.
Ne générez pas d'événements repeat lorsque le bouton central est maintenu enfoncé.
Bouton Retour
Lorsque l'utilisateur appuie sur le bouton Retour, le VHAL doit utiliser la propriété HW_KEY_INPUT avec les int32Values suivants pour envoyer un événement à Android :
ACTION_DOWNKEYCODE_BACK- Affichage cible
Lorsque l'utilisateur relâche le contrôleur rotatif, le VHAL doit utiliser la même propriété et le même code de touche avec ACTION_UP.
Aucun événement repeat ne doit être généré lorsque le bouton central est maintenu enfoncé.
Bouton Accueil
Gérez le bouton Accueil comme vous le feriez pour le bouton Retour, mais avec KEYCODE_HOME au lieu de KEYCODE_BACK.
Autres boutons
Si le contrôleur rotatif inclut des boutons supplémentaires, le VHAL peut les gérer comme l'OEM le souhaite, car ils ne sont pas considérés comme faisant partie du rotatif du point de vue d'Android.
Ils sont généralement gérés comme les boutons Retour et Accueil, mais avec des codes de touche différents.
Par exemple, KEYCODE_CALL ou KEYCODE_MUSIC.
Configuration de la compilation
La navigation rotative est fournie par un service d'accessibilité appelé RotaryService.
Pour inclure ce service dans l'image système de votre appareil, ajoutez la ligne suivante à votre fichier makefile :
PRODUCT_PACKAGES += CarRotaryController
Vous pouvez également inclure les packages suivants dans les compilations de débogage :
RotaryPlayground: application de référence pour le rotatif (voir RotaryPlayground)RotaryIME: IME rotatif de démonstration (voir Éditeurs de mode de saisie)CarRotaryImeRRO: superposition pourRotaryIME
Le service rotatif est activé automatiquement au démarrage de l'appareil et lorsqu'un utilisateur change. Cela permet à l'utilisateur d'utiliser le contrôleur rotatif lors de la configuration.
Si vous utilisez la même compilation pour les voitures avec et sans contrôleur rotatif, ajoutez CarRotaryController comme indiqué ci-dessus afin que le code nécessaire soit inclus dans la compilation. Pour empêcher l'activation du service rotatif sur les voitures non rotatives, créez un RRO statique pour superposer la ressource de chaîne rotaryService dans packages/services/Car/service avec une chaîne vide. Vous utiliserez la même compilation, mais vous aurez des configurations de produit distinctes pour les appareils rotatifs et non rotatifs. Seule la dernière inclut la superposition.
Personnalisation
Les OEM peuvent personnaliser la logique de recherche de focus, la mise en surbrillance du focus et certains éléments supplémentaires via des superpositions de ressources aux emplacements suivants :
- car-ui-library se trouve dans
packages/apps/Car/libs/car-ui-lib RotaryServicese trouve danspackages/apps/Car/RotaryControllerCorese trouve dansframeworks/base/core
Historique des déplacements
L'OEM peut configurer si chaque type d'historique de déplacement est activé ou non, et si c'est le cas, la taille du cache et la règle d'expiration. Pour ce faire, il suffit de remplacer différentes ressources de la bibliothèque Car UI.
Cache de l'historique du focus
(Android 11 QPR3, Android 11 Car,
Android 12)
Ce cache par FocusArea stocke la vue la plus récemment ciblée dans le
FocusArea, afin qu'elle puisse être ciblée lors d'un déplacement vers le FocusArea.
Ce cache peut être configuré en superposant les ressources suivantes de la bibliothèque Car UI :
-
car_ui_focus_history_cache_type:- Le cache est désactivé.
- Le cache expirera après un certain temps (voir ci-dessous).
- Le cache n'expirera jamais.
car_ui_focus_history_expiration_period_ms: nombre de millisecondes avant l' expiration du cache si le type de cache est défini sur deux (2) (voir ci-dessus).
Cache de l'historique de FocusArea
(Android 11 QPR3, Android 11 Car,
Android 12)
Ce cache stocke un historique des déplacements afin que le déplacement dans la direction opposée puisse
renvoyer le focus au même FocusArea. Ce cache peut être configuré en superposant les ressources suivantes de la bibliothèque Car UI :
-
car_ui_focus_area_history_cache_type:- Le cache est désactivé.
- Le cache expire après un certain temps (voir ci-dessous).
- Le cache n'expire jamais.
car_ui_focus_area_history_expiration_period_ms: nombre de millisecondes avant l'expiration du cache si le type de cache est défini sur 2 (voir ci-dessus).car_ui_clear_focus_area_history_when_rotating: indique s'il faut vider le cache lorsque l'utilisateur fait pivoter le contrôleur.
Rotation
(Android 11 QPR3, Android 11 Car,
Android 12)
L'OEM peut remplacer deux ressources entières dans le RotaryService pour spécifier s'il existe
une accélération, telle que l'accélération de la souris, pour la rotation :
rotation_acceleration_3x_ms: intervalle de temps (en millisecondes) utilisé pour déterminer si Google doit accélérer la rotation du contrôleur pour un cran de rotation. Si l' intervalle entre ce cran et le cran de rotation précédent est inférieur à cette valeur, il sera traité comme trois crans de rotation. Définissez cette valeur sur 2147483647 pour désactiver l'accélération 3x.rotation_acceleration_2x_ms: semblable àrotation_acceleration_3x_ms. Utilisé pour l'accélération 2x. Définissez cette valeur sur2147483647pour désactiver l'accélération 2x.
L'accélération fonctionne mieux lorsqu'il existe des horodatages individuels pour chaque cran de
rotation, comme
l'exige
le VHAL. Si ces informations ne sont pas disponibles, le RotaryService suppose que les crans de rotation sont espacés de manière uniforme.
/** * 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),
Mise en surbrillance du focus
L'OEM peut remplacer la mise en surbrillance du focus par défaut dans le framework Android et plusieurs ressources de mise en surbrillance du focus dans la bibliothèque Car UI.
Mise en surbrillance du focus par défaut
Le framework Android fournit une mise en surbrillance du focus par défaut via l'attribut selectableItemBackground. Dans Theme.DeviceDefault, cet attribut fait référence à item_background.xml dans Core. L'OEM peut superposer item_background.xml pour modifier le drawable de mise en surbrillance du focus par défaut.
Ce drawable doit généralement être un StateListDrawable, qui ajuste l'arrière-plan en fonction de différentes combinaisons d'états, y compris android:state_focused et android:state_pressed. Lorsque l'utilisateur utilise le contrôleur rotatif pour cibler une vue, android:state_focused est true, mais android:state_pressed est false. Si l'utilisateur appuie ensuite sur le bouton central du contrôleur rotatif, android:state_focused et android:state_pressed seront true tant que l'utilisateur maintiendra le bouton enfoncé.
Lorsque l'utilisateur relâche le bouton, seul android:state_focused restera true.
La bibliothèque Car UI utilise un thème dérivé de Theme.DeviceDefault. Par conséquent, cette superposition affecte les applications qui utilisent cette bibliothèque et celles qui utilisent un thème dérivé de Theme.DeviceDefault. Elle n'affectera pas les applications qui utilisent un thème non lié, tel que Theme.Material.
Ressources de mise en surbrillance du focus dans la bibliothèque Car UI
L'OEM peut remplacer plusieurs ressources de la bibliothèque Car UI pour contrôler l'apparence de la mise en surbrillance du focus sur les vues avec une mise en surbrillance du focus non rectangulaire (par exemple, ronde ou en forme de pilule) et dans les applications qui utilisent un thème qui ne dérive pas de Theme.DeviceDefault. Ces
ressources doivent être superposées afin que la mise en surbrillance du focus soit cohérente avec le
drawable de mise en surbrillance du focus par défaut.
(Android 11 QPR3, Android 11 Car,
Android 12)
Les ressources suivantes sont utilisées pour indiquer qu'une vue est ciblée, mais pas enfoncée :
car_ui_rotary_focus_fill_color: couleur de remplissage.car_ui_rotary_focus_stroke_color: couleur du contour.car_ui_rotary_focus_stroke_width: épaisseur du contour.
(Android 11 QPR3, Android 11 Car,
Android 12)
Les ressources suivantes sont utilisées pour indiquer qu'une vue est ciblée et enfoncée :
car_ui_rotary_focus_pressed_fill_color: couleur de remplissage.car_ui_rotary_focus_pressed_stroke_color: couleur du contour.car_ui_rotary_focus_pressed_stroke_width: épaisseur du contour.
Parfois, un bouton reçoit une couleur d'arrière-plan unie pour attirer l'attention de l'utilisateur, comme dans l'exemple illustré. Cela peut rendre la mise en surbrillance du focus difficile à voir.
Dans ce cas, le développeur peut spécifier une mise en surbrillance du focus personnalisée à l'aide de couleurs secondaires :
- (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
N'importe quelle couleur peut être transparente et l'une ou l'autre dimension peut être nulle si, par exemple, vous ne souhaitez qu'un remplissage ou qu'un contour.
Mise en surbrillance de FocusArea
(Android 11 QPR3, Android 11 Car,
Android 12)
FocusArea peut dessiner deux types de mise en surbrillance lorsque l'un de ses descendants est
ciblé. Les deux peuvent être utilisés conjointement, si vous le souhaitez. Cette fonctionnalité est désactivée par défaut dans AOSP, mais peut être activée en remplaçant les ressources de la bibliothèque Car UI :
car_ui_enable_focus_area_foreground_highlight: dessine une mise en surbrillance au-dessus deFocusAreaet de ses descendants. Dans AOSP, ce drawable est un contour autour duFocusArea. Les OEM peuvent remplacer lecar_ui_focus_area_foreground_highlightdrawable.car_ui_enable_focus_area_background_highlight: dessine une mise en surbrillance au-dessus duFocusAreamais derrière ses descendants. Dans AOSP, ce drawable est un remplissage uni. Les OEM peuvent remplacer le drawablecar_ui_focus_area_background_highlight.
Éditeurs de mode de saisie
Les éditeurs de mode de saisie (IME) sont des méthodes de saisie. Par exemple, un clavier à l'écran.
(Android 11 QPR3, Android 11 Car,
Android 12)
L'OEM doit superposer la ressource de chaîne default_touch_input_method
dans le RotaryService pour spécifier le ComponentName de l'IME
tactile. Par exemple, si l'OEM utilise l'IME fourni avec Android Automotive, il doit spécifier com.google.android.apps.automotive.inputmethod/.InputMethodService.
(Android 11 QPR3, Android 11 Car,
Android 12)
Si l'OEM a créé un IME spécifiquement pour le rotatif, il doit spécifier son
ComponentName dans la rotary_input_method ressource. Si cette ressource est superposée, l'IME spécifié est utilisé chaque fois que l'utilisateur interagit avec l'unité principale via le déplacement, la rotation et le bouton central du contrôleur rotatif. Lorsque l'utilisateur touche l'écran, l'IME précédent est utilisé. Le bouton Retour (et les autres boutons du contrôleur rotatif) n'ont aucun effet sur la sélection de l'IME. Si cette ressource n'est pas superposée, aucun changement d'IME ne se produit. Carboard n'est pas compatible avec le rotatif. L'utilisateur ne peut donc pas saisir de texte via le contrôleur rotatif si l'OEM n'a pas fourni d'IME rotatif.
RotaryIME est un IME rotatif de démonstration. Bien que basique, il suffit d'essayer le changement automatique d'IME décrit ci-dessus. Le code source de RotaryIME
se trouve dans packages/apps/Car/tests/RotaryIME/.
Déplacements hors écran
Par défaut, lorsque l'utilisateur tente de déplacer le curseur hors de l'écran, rien ne se passe. L'OEM peut configurer ce qui doit se produire pour chacune des quatre directions en spécifiant n'importe quelle combinaison des éléments suivants :
- Une action globale définie par
AccessibilityService. Par exemple,GLOBAL_ACTION_BACK. - Un code de touche, tel que
KEYCODE_BACK. - Un intent pour lancer une activité représentée sous forme d'URL.
(Android 11 QPR3, Android 11 Car,
Android 12)
Ces éléments sont spécifiés en superposant les ressources de tableau suivantes dans le
RotaryService :
off_screen_nudge_global_actions: tableau des actions globales à effectuer lorsque l'utilisateur déplace le curseur vers le haut, le bas, la gauche ou la droite hors de l'écran. Aucune action globale n'est effectuée si l'élément pertinent de ce tableau est -1.off_screen_nudge_key_codes: tableau des codes de touche des événements de clic à injecter lorsque l'utilisateur déplace le curseur vers le haut, le bas, la gauche ou la droite hors de l'écran. Aucun événement n'est injecté si l'élément pertinent de ce tableau est 0 (KEYCODE_UNKNOWN).off_screen_nudge_intents: tableau des intents pour lancer une activité lorsque l'utilisateur déplace le curseur vers le haut, le bas, la gauche ou la droite hors de l'écran. Aucune activité n'est lancée si l'élément pertinent de ce tableau est vide.
Autres configurations
Vous devez superposer les ressources RotaryService suivantes :
- (Android 11 QPR3, Android 11 Car,
Android 12)
config_showHeadsUpNotificationOnBottom: valeur booléenne indiquant si les notifications heads-up doivent s'afficher en bas plutôt qu'en haut. Cette valeur doit être identique à celle de la ressource booléenne dansframeworks/base/packages/CarSystemUI/res/values/config.xml.config_showHeadsUpNotificationOnBottom - (Android 11 QPR3, Android 11 Car,
Android 12)
notification_headsup_card_margin_horizontal: marge gauche et droite de la fenêtre de notification heads-up. Cette valeur doit être identique à celle de la ressource dimennotification_headsup_card_margin_horizontaldanspackages/apps/Car/Notification/res/values/dimens.xml. - (Android 12)
excluded_application_overlay_window_titles: tableau des titres des fenêtres qui ne doivent pas être considérées comme des fenêtres de superposition. Cela doit inclure les titres des fenêtres d'application qui représententTaskViewsouTaskDisplayAreas. Par défaut, cette liste ne contient que "Maps".
Vous pouvez superposer la ressource RotaryService suivante :
- Android 11 QPR3, Android 11 Car,
Android 12)
long_press_ms: valeur entière représentant le nombre de millisecondes pendant lesquelles le bouton central doit être maintenu enfoncé pour déclencher une pression longue. La valeur zéro indique que le délai d'inactivité par défaut du système doit être utilisé. Il s'agit de la valeur par défaut.