Integrationsanleitung für OEMs

Auf dieser Seite wird beschrieben, wie Sie Drehknopf-Eingaben in der VHAL verarbeiten, Ihren Build so konfigurieren, dass der Drehknopf-Dienst enthalten ist, und wie Sie die Drehknopf-Funktionen in allen Apps anpassen. Informationen zu vorinstallierten OEM-Apps wie einem vom OEM bereitgestellten Launcher finden Sie unter Auto-UI-Bibliothek (car-ui-library).

VHAL

Ein Drehknopf unterstützt die folgenden Aktionen:

  • Schrittweise nach oben, unten, links und rechts bewegen
  • Im Uhrzeigersinn und gegen den Uhrzeigersinn drehen
  • Die mittlere Taste drücken
  • Die Schaltfläche „Zurück“ drücken
  • Die Schaltfläche „Startseite“ drücken
  • Andere Tasten drücken, z. B. „Telefon“ und „Medien“

Die Dokumentation zu den Systemeigenschaften und den entsprechenden int32Values finden Sie unter hardware/interfaces/automotive/vehicle/2.0/types.hal.

Die VHAL sollte diese Aktionen verarbeiten:

Schrittweise bewegen

Wenn der Nutzer den Drehknopf nach rechts drückt, sollte die VHAL die Eigenschaft HW_KEY_INPUT mit den folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Zielbildschirm

Wenn der Nutzer den Drehknopf loslässt, sollte die VHAL dieselbe Eigenschaft und denselben Tastencode mit ACTION_UP verwenden. Bei Schrittbewegungen in andere Richtungen sollten die entsprechenden Tastencodes verwendet werden.

Es gibt keine Tastencodes für Diagonalen. Die VHAL kann jedoch ein horizontales und ein vertikales Ereignis kombinieren, um eine Diagonale zu erzeugen, wenn die Hardware Diagonalen unterstützt. Wenn Sie beispielsweise nach oben und links bewegen, sollte Folgendes erzeugt werden:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

In beiden Fällen sollte das Loslassen des Drehknopfs (und anschließend) Folgendes erzeugen:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Der Nutzer kann den Drehknopf in eine senkrechte Richtung drücken, bevor er ihn loslässt. Beispiel:

Senkrechte Richtung
Abbildung 1. Senkrechte Richtung

Dadurch sollte die folgende Ereignissequenz generiert werden:

  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

Es sollten keine repeat -Ereignisse generiert werden, während der Drehknopf in einer Richtung gehalten wird.

Drehen

Wenn der Nutzer den Drehknopf um eine Rastung (Klick) im Uhrzeigersinn dreht, sollte die VHAL die Eigenschaft HW_ROTARY_INPUT mit den folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Eine (1) Rastung
  3. Zielbildschirm

Der Zeitstempel des Ereignisses sollte auf die verstrichene Zeit in Nanosekunden festgelegt werden.

Eine Drehung um eine (1) Rastung gegen den Uhrzeigersinn sollte dasselbe Ereignis generieren, aber mit -1 für die Anzahl der Rastungen.

Wenn mehrere Drehungen in derselben Richtung schnell aufeinander folgen, sollte die VHAL die Drehungen zu einem einzigen Ereignis kombinieren, um das System nicht mit Ereignissen zu überlasten. In diesem Fall sollte der Zeitstempel des Ereignisses der Zeitpunkt sein, an dem die erste Drehung erfolgt ist. Die int32Values sollten die Anzahl der Nanosekunden zwischen aufeinanderfolgenden Drehungen enthalten.

Beispiel für eine Drehsequenz:

  • Zum Zeitpunkt t0 drehte der Nutzer eine Rastung gegen den Uhrzeigersinn.
  • Zum Zeitpunkt t0 + 5 ns drehte der Nutzer eine Rastung gegen den Uhrzeigersinn.
  • Zum Zeitpunkt t0 + 8 ns drehte der Nutzer eine Rastung gegen den Uhrzeigersinn.

Dadurch sollte dieses Ereignis generiert werden:

  • Eigenschaft: HW_ROTARY_INPUT
  • Zeitstempel: t0
  • int32Values:
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (drei Drehungen gegen den Uhrzeigersinn)
    3. Zielbildschirm
    4. 5 ns zwischen der ersten und der zweiten Drehung
    5. 3 ns zwischen der zweiten und der dritten Drehung

Mittlere Taste

Wenn der Nutzer die mittlere Taste drückt, sollte die VHAL die Eigenschaft HW_KEY_INPUT mit den folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Zielbildschirm

Wenn der Nutzer den Drehknopf loslässt, sollte die VHAL dieselbe Eigenschaft und denselben Tastencode mit ACTION_UP verwenden.

Generieren Sie keine repeat -Ereignisse, wenn die mittlere Taste gedrückt wird.

Schaltfläche „Zurück“

Wenn der Nutzer die Schaltfläche „Zurück“ drückt, sollte die VHAL die Eigenschaft HW_KEY_INPUT mit den folgenden int32Values verwenden, um ein Ereignis an Android zu senden:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Zielbildschirm

Wenn der Nutzer den Drehknopf loslässt, sollte die VHAL dieselbe Eigenschaft und denselben Tastencode mit ACTION_UP verwenden.

Es sollten keine repeat -Ereignisse generiert werden, während die mittlere Taste gedrückt wird.

Schaltfläche „Startseite“

Verarbeiten Sie die Schaltfläche „Startseite“ wie die Schaltfläche „Zurück“, aber mit KEYCODE_HOME anstelle von KEYCODE_BACK.

Andere Tasten

Wenn der Drehknopf zusätzliche Tasten enthält, kann die VHAL sie beliebig verarbeiten, da sie aus Android-Sicht nicht als Teil des Drehknopfs betrachtet werden. Sie werden in der Regel wie die Schaltflächen „Zurück“ und „Startseite“ verarbeitet, aber mit anderen Tastencodes. Beispiel: KEYCODE_CALL oder KEYCODE_MUSIC.

Build-Konfiguration

Die Drehknopf-Navigation wird von einem Bedienungshilfendienst namens RotaryService bereitgestellt. Wenn Sie diesen Dienst in das Systemimage für Ihr Gerät einbeziehen möchten, fügen Sie Ihrer Makefile die folgende Zeile hinzu:

PRODUCT_PACKAGES += CarRotaryController

Außerdem sollten Sie die folgenden Pakete in Debug-Builds einbeziehen:

  • RotaryPlayground: Eine Referenz-App für den Drehknopf (siehe RotaryPlayground).
  • RotaryIME Eine Demo-IME für den Drehknopf (siehe Eingabemethoden-Editoren).
  • CarRotaryImeRRO: Das Overlay für RotaryIME.

Der Drehknopf-Dienst wird automatisch aktiviert, wenn das Gerät gestartet wird und wenn ein Nutzerwechsel erfolgt. So kann der Nutzer den Drehknopf während der Einrichtung verwenden.

Wenn Sie denselben Build für Autos mit und ohne Drehknopf verwenden, fügen Sie CarRotaryController wie oben gezeigt hinzu, damit der erforderliche Code in den Build aufgenommen wird. Damit der Drehknopf-Dienst nicht in Autos ohne Drehknopf aktiviert wird, erstellen Sie ein statisches RRO, um die String-Ressource rotaryService in packages/services/Car/service mit einem leeren String zu überlagern. Sie verwenden denselben Build, haben aber separate Produktkonfigurationen für Geräte mit und ohne Drehknopf. Nur die letztere enthält das Overlay.

Anpassung

OEMs können die Logik zum Finden des Fokus, die Fokus-Hervorhebung und einige zusätzliche Elemente über Ressourcen-Overlays an den folgenden Orten anpassen:

  • Die Auto-UI-Bibliothek befindet sich in packages/apps/Car/libs/car-ui-lib.
  • RotaryService befindet sich in packages/apps/Car/RotaryController.
  • Core befindet sich in frameworks/base/core.

Verlauf der Schrittbewegungen

Der OEM kann konfigurieren, ob jeder der beiden Arten von Schrittbewegungsverlauf aktiviert ist und wenn ja, die Cache-Größe und die Ablaufrichtlinie. Dazu werden verschiedene Ressourcen der Auto-UI-Bibliothek überschrieben.

Cache für den Fokusverlauf

(Android 11 QPR3, Android 11 Car, Android 12)
In diesem Cache pro FocusArea wird die zuletzt fokussierte Ansicht in der FocusArea gespeichert, damit sie fokussiert werden kann, wenn Sie zurück zur FocusArea bewegen. Dieser Cache kann konfiguriert werden, indem die folgenden Ressourcen der Auto-UI-Bibliothek überlagert werden:

  • car_ui_focus_history_cache_type:
    1. Der Cache ist deaktiviert.
    2. Der Cache läuft nach einiger Zeit ab (siehe unten).
    3. Der Cache läuft nie ab.
  • car_ui_focus_history_expiration_period_ms: Anzahl der Millisekunden, nach denen der Cache abläuft, wenn der Cache-Typ auf 2 festgelegt ist (siehe oben).

Cache für den FocusArea-Verlauf

(Android 11 QPR3, Android 11 Car, Android 12)
In diesem Cache wird ein Verlauf der Schrittbewegungen gespeichert, damit der Fokus durch eine Schrittbewegung in die entgegengesetzte Richtung wieder auf dieselbe FocusArea gelegt werden kann. Dieser Cache kann konfiguriert werden, indem die folgenden Ressourcen der Auto-UI-Bibliothek überlagert werden:

  • car_ui_focus_area_history_cache_type:
    1. Der Cache ist deaktiviert.
    2. Der Cache läuft nach einiger Zeit ab (siehe unten).
    3. Der Cache läuft nie ab.
  • car_ui_focus_area_history_expiration_period_ms: Anzahl der Millisekunden, nach denen der Cache abläuft, wenn der Cache-Typ auf 2 festgelegt ist (siehe oben).
  • car_ui_clear_focus_area_history_when_rotating: Gibt an, ob der Cache geleert werden soll wenn der Nutzer den Drehknopf dreht.

Drehen

(Android 11 QPR3, Android 11 Car, Android 12)
Der OEM kann zwei Ganzzahlressourcen im RotaryService überschreiben, um anzugeben, ob es eine Beschleunigung für die Drehung gibt, z. B. eine Mausbeschleunigung:

  • rotation_acceleration_3x_ms: Zeitintervall (in Millisekunden), mit dem entschieden wird, ob Google die Drehung des Drehknopfs für eine Drehung beschleunigen soll. Wenn das Intervall zwischen dieser Drehung und der vorherigen Drehung kleiner als dieser Wert ist, wird es als drei Drehungen behandelt. Legen Sie diesen Wert auf 2147483647 fest, um die 3-fache Beschleunigung zu deaktivieren.
  • rotation_acceleration_2x_ms: Ähnlich wie rotation_acceleration_3x_ms. Wird für die 2-fache Beschleunigung verwendet. Legen Sie diesen Wert auf 2147483647 fest, um die 2-fache Beschleunigung zu deaktivieren.

Die Beschleunigung funktioniert am besten, wenn für jede Drehung einzelne Zeitstempel vorhanden sind, wie von der VHAL gefordert. Wenn diese nicht verfügbar sind, geht der RotaryService davon aus, dass die Drehungen gleichmäßig verteilt sind.

/**
     * 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),

Fokus-Hervorhebung

Der OEM kann die Standard-Fokus-Hervorhebung im Android-Framework und mehrere Ressourcen für die Fokus-Hervorhebung in der Auto-UI-Bibliothek überschreiben.

Standard-Fokus-Hervorhebung

Das Android-Framework bietet eine Standard-Fokus-Hervorhebung über das Attribut selectableItemBackground. In Theme.DeviceDefault verweist dieses Attribut auf item_background.xml in Core. Der OEM kann item_background.xml überlagern, um die Standard-Fokus-Hervorhebung zu ändern.

Diese Zeichenressource sollte in der Regel ein StateListDrawable sein, das den Hintergrund basierend auf verschiedenen Kombinationen von Zuständen anpasst, darunter android:state_focused und android:state_pressed. Wenn der Nutzer den Drehknopf verwendet, um eine Ansicht zu fokussieren, ist android:state_focused auf true gesetzt, aber android:state_pressed auf false. Wenn der Nutzer dann die mittlere Taste auf dem Drehknopf drückt, sind sowohl android:state_focused als auch android:state_pressed auf true gesetzt, solange der Nutzer die Taste gedrückt hält. Wenn der Nutzer die Taste loslässt, bleibt nur android:state_focused auf true gesetzt.

Die Auto-UI-Bibliothek verwendet ein Design, das von Theme.DeviceDefault abgeleitet ist. Daher wirkt sich dieses Overlay auf Apps aus, die diese Bibliothek verwenden, und auf Apps, die ein von Theme.DeviceDefault abgeleitetes Design verwenden. Es wirkt sich nicht auf Apps aus, die ein anderes Design verwenden, z. B. Theme.Material.

Ressourcen für die Fokus-Hervorhebung in der Auto-UI-Bibliothek

Der OEM kann mehrere Ressourcen der Auto-UI-Bibliothek überschreiben, um festzulegen, wie die Fokus-Hervorhebung in Ansichten mit einer nicht rechteckigen Fokus-Hervorhebung (z. B. rund oder pillenförmig) und in Apps aussieht, die ein Design verwenden, das nicht von Theme.DeviceDefault abgeleitet ist. Diese Ressourcen sollten überlagert werden, damit die Fokus-Hervorhebung mit der Standard-Fokus-Hervorhebung übereinstimmt.

(Android 11 QPR3, Android 11 Car, Android 12)
Die folgenden Ressourcen werden verwendet, um anzugeben, wann eine Ansicht fokussiert, aber nicht gedrückt wird:

  • car_ui_rotary_focus_fill_color: Füllfarbe
  • car_ui_rotary_focus_stroke_color: Umrissfarbe
  • car_ui_rotary_focus_stroke_width: Dicke des Umrisses

(Android 11 QPR3, Android 11 Car, Android 12)
Die folgenden Ressourcen werden verwendet, um anzugeben, wann eine Ansicht fokussiert und gedrückt wird:

  • car_ui_rotary_focus_pressed_fill_color: Füllfarbe
  • car_ui_rotary_focus_pressed_stroke_color: Umrissfarbe
  • car_ui_rotary_focus_pressed_stroke_width: Dicke des Umrisses

Manchmal erhält eine Schaltfläche eine einfarbige Hintergrundfarbe, um die Aufmerksamkeit des Nutzers darauf zu lenken, wie im Beispiel gezeigt. Dadurch ist die Fokus-Hervorhebung möglicherweise schwer zu erkennen.

Button mit einfarbigem Hintergrund
Abbildung 2. Schaltfläche mit einfarbigem Hintergrund

In dieser Situation kann der Entwickler eine benutzerdefinierte Fokus-Hervorhebung mit sekundären Farben angeben:
  • (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

Alle Farben können transparent sein und beide Dimensionen können null sein, wenn Sie beispielsweise nur eine Füllung oder nur einen Umriss wünschen.

FocusArea-Hervorhebung

(Android 11 QPR3, Android 11 Car, Android 12)
FocusArea kann zwei Arten von Hervorhebung zeichnen, wenn eines seiner untergeordneten Elemente fokussiert ist. Beide können bei Bedarf zusammen verwendet werden. Diese Funktion ist in AOSP standardmäßig deaktiviert, kann aber durch Überschreiben von Ressourcen der Auto-UI-Bibliothek aktiviert werden:

  • car_ui_enable_focus_area_foreground_highlight: Zeichnet eine Hervorhebung über der FocusArea und ihren untergeordneten Elementen. In AOSP ist diese Zeichenressource ein Umriss um die FocusArea. OEMs können die car_ui_focus_area_foreground_highlight Zeichenressource überschreiben.
  • car_ui_enable_focus_area_background_highlight: Zeichnet eine Hervorhebung über der FocusArea aber hinter ihren untergeordneten Elementen. In AOSP ist diese Zeichenressource eine einfarbige Füllung. OEMs können die Zeichenressource car_ui_focus_area_background_highlight überschreiben.

Eingabemethoden-Editoren

Eingabemethoden-Editoren (Input Method Editors, IMEs) sind Eingabemethoden. Beispiel: eine Bildschirmtastatur.

(Android 11 QPR3, Android 11 Car, Android 12)
Der OEM muss die default_touch_input_method String-Ressource im RotaryService überlagern, um den ComponentName des touchbasierten IME anzugeben. Wenn der OEM beispielsweise den mit Android Automotive bereitgestellten IME verwendet, sollte er com.google.android.apps.automotive.inputmethod/.InputMethodService angeben.

(Android 11 QPR3, Android 11 Car, Android 12)
Wenn der OEM einen IME speziell für den Drehknopf erstellt hat, sollte er den ComponentName in der rotary_input_method Ressource angeben. Wenn diese Ressource überlagert wird, wird der angegebene IME verwendet, wenn der Nutzer über die Schrittbewegung, Drehung und mittlere Taste des Drehknopfs mit der Head-Unit interagiert. Wenn der Nutzer den Bildschirm berührt, wird der vorherige IME verwendet. Die Schaltfläche „Zurück“ (und andere Tasten auf dem Drehknopf) haben keine Auswirkungen auf die IME-Auswahl. Wenn diese Ressource nicht überlagert wird, erfolgt kein IME-Wechsel. Carboard unterstützt den Drehknopf nicht, daher kann der Nutzer keinen Text über den Drehknopf eingeben, wenn der OEM keinen Drehknopf-IME bereitgestellt hat.

RotaryIME ist eine Demo-IME für den Drehknopf. Sie ist zwar einfach, reicht aber aus, um den oben beschriebenen automatischen IME-Wechsel auszuprobieren. Der Quellcode für RotaryIME befindet sich in packages/apps/Car/tests/RotaryIME/.

Schrittbewegungen außerhalb des Bildschirms

Wenn der Nutzer versucht, über den Rand des Bildschirms hinaus zu bewegen, passiert standardmäßig nichts. Der OEM kann für jede der vier Richtungen konfigurieren, was geschehen soll, indem er eine beliebige Kombination aus Folgendem angibt:

  1. Eine globale Aktion, die von AccessibilityService definiert wird. Beispiel: GLOBAL_ACTION_BACK.
  2. Ein Tastencode, z. B. KEYCODE_BACK.
  3. Ein Intent zum Starten einer Aktivität, dargestellt als URL.

(Android 11 QPR3, Android 11 Car, Android 12)
Diese werden angegeben, indem die folgenden Array-Ressourcen im RotaryService überlagert werden:

  • off_screen_nudge_global_actions: Array globaler Aktionen, die ausgeführt werden sollen, wenn der Nutzer über den Rand des Bildschirms hinaus nach oben, unten, links oder rechts bewegt. Wenn das entsprechende Element dieses Arrays -1 ist, wird keine globale Aktion ausgeführt.
  • off_screen_nudge_key_codes: Array von Tastencodes für Klickereignisse, die eingefügt werden sollen wenn der Nutzer über den Rand des Bildschirms hinaus nach oben, unten, links oder rechts bewegt. Wenn das entsprechende Element dieses Arrays 0 (KEYCODE_UNKNOWN) ist, werden keine Ereignisse eingefügt.
  • off_screen_nudge_intents: Array von Intents zum Starten einer Aktivität, wenn der Nutzer über den Rand des Bildschirms hinaus nach oben, unten, links oder rechts bewegt. Wenn das entsprechende Element dieses Arrays leer ist, wird keine Aktivität gestartet.

Weitere Konfigurationen

Sie sollten die folgenden RotaryService-Ressourcen überlagern:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    config_showHeadsUpNotificationOnBottom: Boolescher Wert, der angibt, ob Heads-up-Benachrichtigungen unten anstelle von oben angezeigt werden sollen. Dieser Wert muss mit dem Wert der booleschen Ressource in übereinstimmen.config_showHeadsUpNotificationOnBottomframeworks/base/packages/CarSystemUI/res/values/config.xml
  • (Android 11 QPR3, Android 11 Car, Android 12)
    notification_headsup_card_margin_horizontal: Linker und rechter Rand für das Heads-up-Benachrichtigungsfenster. Dieser Wert muss mit dem Wert der notification_headsup_card_margin_horizontal Dimen-Ressource in packages/apps/Car/Notification/res/values/dimens.xml übereinstimmen.
  • (Android 12)
    excluded_application_overlay_window_titles: Ein Array mit Titeln von Fenstern, die nicht als Overlay-Fenster betrachtet werden sollen. Dazu sollten Titel von App-Fenstern gehören, die TaskViews oder TaskDisplayAreas darstellen. Standardmäßig enthält diese Liste nur „Maps“.

Sie können die folgende RotaryService-Ressource überlagern:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    long_press_ms: Ganzzahlwert, der angibt, wie viele Millisekunden die mittlere Taste gedrückt werden muss, um ein langes Drücken auszulösen. Null gibt an, dass das System Standard-Timeout für langes Drücken verwendet werden soll. Dies ist der Standardwert.