Integrationsleitfaden für OEMs

Auf dieser Seite wird beschrieben, wie Sie Dreheingaben im VHAL verarbeiten, Ihren Build so konfigurieren, dass er den Drehdienst einschließt, und wie Sie das Dreherlebnis in allen Apps anpassen. Informationen zu vorinstallierten OEM-Apps, z. B. einem vom OEM bereitgestellten Launcher, finden Sie unter Car UI Library (car-ui-library) .

VHAL

Ein Drehregler unterstützt folgende Aktionen:

  • Bewegen Sie sich nach oben, unten, links und rechts.
  • Im und gegen den Uhrzeigersinn drehen.
  • Drücken Sie die mittlere Taste.
  • Drücke den Zurück-Knopf.
  • Drücken Sie die Home-Taste.
  • Drücken Sie andere Tasten, z. B. Telefon und Medien.

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

Die VHAL sollte diese Aktionen verarbeiten:

Schubs

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

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Zielanzeige.

Wenn der Benutzer den Drehregler loslässt, sollte der VHAL dieselbe Eigenschaft und denselben Schlüsselcode wie ACTION_UP verwenden. Für Stöße in andere Richtungen sollten die entsprechenden Tastencodes verwendet werden.

Es gibt keine Schlüsselcodes für Diagonalen, aber der VHAL kann ein horizontales und ein vertikales Ereignis kombinieren, um eine Diagonale zu erzeugen, wenn die Hardware Diagonalen unterstützt. Wenn Sie beispielsweise nach oben und nach links schieben, sollte dies zu Folgendem führen:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

In beiden Reihenfolgen (und anschließend) sollte das Loslassen des Drehreglers Folgendes bewirken:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Der Benutzer kann den Drehregler in eine senkrechte Richtung drücken, bevor er ihn loslässt. Beispielsweise das folgende Szenario:

Senkrechte Richtung
Abbildung 1. Senkrechte Richtung

Dies sollte die folgende Abfolge von Ereignissen erzeugen:

  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

Während der Drehregler in eine Richtung gehalten wird, sollten keine Wiederholungsereignisse generiert werden.

Drehen

Wenn der Benutzer den Drehregler um eine Rastung (Klick) im Uhrzeigersinn dreht, sollte der 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. Zielanzeige.

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

Eine Drehung um eine (1) Rastung gegen den Uhrzeigersinn sollte das gleiche Ereignis erzeugen, jedoch mit -1 für die Anzahl der Rastungen.

Wenn in schneller Folge mehrere Drehstopps in die gleiche Richtung auftreten, sollte der VHAL die Stopps zu einem einzigen Ereignis zusammenfassen, um das System nicht mit Ereignissen zu überlasten. In diesem Fall sollte der Zeitstempel des Ereignisses der Zeitpunkt sein, an dem die erste Rotationsverzögerung erfolgte. Die int32Values ​​sollten die Anzahl der Nanosekunden zwischen aufeinanderfolgenden Rotationsstopps enthalten.

Beispielsweise die folgende Abfolge von Drehungen:

  • Zum Zeitpunkt t0 drehte der Benutzer eine Raste gegen den Uhrzeigersinn.
  • Zum Zeitpunkt t0 + 5 ns drehte der Benutzer eine Raste gegen den Uhrzeigersinn.
  • Zum Zeitpunkt t0 + 8 ns drehte der Benutzer eine Raste gegen den Uhrzeigersinn.

sollte dieses Ereignis generieren:

  • Eigenschaft: HW_ROTARY_INPUT
  • Zeitstempel: t0
  • int32Values :
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (drei Rastungen gegen den Uhrzeigersinn).
    3. Zielanzeige.
    4. 5 ns zwischen erster und zweiter Rastung.
    5. 3 ns zwischen zweiter und dritter Rastung.

Mitteltaste

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

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Zielanzeige.

Wenn der Benutzer den Drehregler loslässt, sollte der VHAL dieselbe Eigenschaft und denselben Schlüsselcode wie ACTION_UP verwenden.

Generieren Sie keine Wiederholungsereignisse , wenn die mittlere Taste gedrückt gehalten wird.

Zurück-Button

Wenn der Benutzer die Schaltfläche „Zurück“ drückt, sollte der 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. Zielanzeige.

Wenn der Benutzer den Drehregler loslässt, sollte der VHAL dieselbe Eigenschaft und denselben Schlüsselcode wie ACTION_UP verwenden.

Es sollten keine Wiederholungsereignisse generiert werden, während die mittlere Taste gedrückt gehalten wird.

Home "Button

Behandeln Sie die Home-Schaltfläche wie die Zurück-Schaltfläche, jedoch mit KEYCODE_HOME anstelle von KEYCODE_BACK .

Andere Tasten

Wenn der Drehregler zusätzliche Tasten enthält, kann der VHAL diese nach Belieben des OEM verarbeiten, da sie aus Sicht von Android nicht als Teil des Drehreglers gelten. Diese werden normalerweise wie die Zurück- und Home-Tasten behandelt, verfügen jedoch über unterschiedliche Tastencodes. Zum Beispiel KEYCODE_CALL oder KEYCODE_MUSIC .

Build-Konfiguration

Die Rotationsnavigation wird von einem Barrierefreiheitsdienst namens RotaryService bereitgestellt. Um diesen Dienst in das Systemabbild Ihres Geräts aufzunehmen, fügen Sie die folgende Zeile zu Ihrem Makefile hinzu:

PRODUCT_PACKAGES += CarRotaryController

Möglicherweise möchten Sie auch die folgenden Pakete in Debug-Builds einschließen:

Der Rotationsdienst wird automatisch aktiviert, wenn das Gerät startet und wenn ein Benutzerwechsel erfolgt. Dadurch wird sichergestellt, dass der Benutzer den Drehregler während der Einrichtung verwenden kann.

Wenn Sie den gleichen Build für Autos mit und ohne Drehregler verwenden, fügen Sie CarRotaryController wie oben gezeigt hinzu, damit der erforderliche Code im Build enthalten ist. Um zu verhindern, dass der Rotationsdienst bei nicht rotierenden Fahrzeugen aktiviert wird, erstellen Sie ein statisches RRO, um die Zeichenfolgenressource „ rotaryService in packages/services/Car/service mit einer leeren Zeichenfolge zu überlagern. Sie verwenden denselben Aufbau, verfügen jedoch über unterschiedliche Produktkonfigurationen für rotierende und nicht rotierende Geräte. Nur Letzteres beinhaltet das Overlay.

Anpassung

OEMs können die Fokusfindungslogik, die Fokushervorhebung und einige zusätzliche Elemente durch Ressourcenüberlagerungen an den folgenden Stellen anpassen:

  • Die car-ui-library 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

Geschichte anstoßen

Der OEM kann konfigurieren, ob jede der beiden Arten des Nudge-Verlaufs aktiviert ist oder nicht, und, wenn ja, die Cache-Größe und die Ablaufrichtlinie. Dies geschieht alles durch Überschreiben verschiedener Ressourcen der Car-UI-Bibliothek.

Fokusverlauf-Cache

( Android 11 QPR3, Android 11 Auto, Android 12 )
Dieser Cache pro FocusArea speichert die zuletzt fokussierte Ansicht innerhalb der FocusArea , sodass sie beim Zurückschieben in die FocusArea fokussiert werden kann. Dieser Cache kann durch Überlagerung der folgenden Car-UI-Library-Ressourcen konfiguriert werden:

  • car_ui_focus_history_cache_type :
    1. 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 : Wie viele Millisekunden bevor der Cache abläuft, wenn der Cache-Typ auf zwei (2) eingestellt ist (siehe oben).

FocusArea-Verlaufscache

( Android 11 QPR3, Android 11 Auto, Android 12 )
In diesem Cache wird ein Verlauf der Anstupser gespeichert, sodass durch Anstupsen in die entgegengesetzte Richtung der Fokus wieder auf denselben FocusArea gerichtet werden kann. Dieser Cache kann durch Überlagerung der folgenden Car-UI-Library-Ressourcen konfiguriert werden:

  • car_ui_focus_area_history_cache_type :
    1. 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 : Wie viele Millisekunden bevor der Cache abläuft, wenn der Cache-Typ auf 2 gesetzt ist (siehe oben).
  • car_ui_clear_focus_area_history_when_rotating : Ob der Cache geleert werden soll, wenn der Benutzer den Controller dreht.

Drehung

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

  • rotation_acceleration_3x_ms : Zeitintervall (in Millisekunden), das verwendet wird, um zu entscheiden, ob Google die Rotation des Controllers für eine Rotationsverzögerung beschleunigen soll. Wenn der Abstand zwischen dieser Rastung und der vorherigen Drehrastung kleiner als dieser Wert ist, wird dies als drei Rastungen der Drehung behandelt. Stellen Sie dies auf 2147483647 ein, 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. Stellen Sie dies auf 2147483647 ein, um die 2-fache Beschleunigung zu deaktivieren.

Die Beschleunigung funktioniert am besten, wenn für jede Drehungsverzögerung individuelle Zeitstempel vorhanden sind, wie es von der VHAL gefordert wird . Sind diese nicht vorhanden, geht der RotaryService davon aus, dass die Drehrasten 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-Highlight

Der OEM kann die standardmäßige Fokushervorhebung im Android-Framework und mehrere Fokushervorhebungsressourcen in der Car-UI-Bibliothek überschreiben.

Standard-Fokushervorhebung

Das Android-Framework stellt über das Attribut selectableItemBackground eine Standardfokushervorhebung bereit. In Theme.DeviceDefault bezieht sich dieses Attribut auf item_background.xml in Core . Der OEM kann item_background.xml überlagern, um den standardmäßigen Fokus-Hervorhebungsmodus zu ändern.

Dieses Zeichenelement sollte normalerweise ein StateListDrawable sein, das den Hintergrund basierend auf verschiedenen Zustandskombinationen anpasst, einschließlich android:state_focused und android:state_pressed . Wenn der Benutzer den Drehregler verwendet, um eine Ansicht zu fokussieren, ist android:state_focused true , android:state_pressed jedoch false . Wenn der Benutzer dann die mittlere Taste auf dem Drehregler drückt, sind sowohl android:state_focused als auch android:state_pressed true , während der Benutzer die Taste gedrückt hält. Wenn der Benutzer die Schaltfläche loslässt, bleibt nur android:state_focused true .

car-ui-library verwendet ein von Theme.DeviceDefault abgeleitetes Thema. Daher wirkt sich dieses Overlay auf Apps aus, die diese Bibliothek verwenden, und auf Apps, die ein von Theme.DeviceDefault abgeleitetes Design verwenden. Es hat keine Auswirkungen auf Apps, die ein nicht verwandtes Thema verwenden, z. B. Theme.Material .

Fokus-Highlight-Ressourcen in der Car-UI-Bibliothek

Der OEM kann mehrere Ressourcen der Car-UI-Bibliothek überschreiben, um zu steuern, wie die Fokushervorhebung in Ansichten mit einer nicht rechteckigen (z. B. runden oder pillenförmigen) Fokushervorhebung und in Apps aussieht, die ein Design verwenden, das nicht von Theme.DeviceDefault abgeleitet ist Theme.DeviceDefault . Diese Ressourcen sollten überlagert werden, damit die Fokushervorhebung mit dem Standard-Fokushervorhebungs-Zeichnungsobjekt übereinstimmt.

( Android 11 QPR3, Android 11 Auto, Android 12 )
Die folgenden Ressourcen werden verwendet, um anzuzeigen, wenn eine Ansicht fokussiert, aber nicht gedrückt ist:

  • 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 Auto, Android 12 )
Die folgenden Ressourcen werden verwendet, um anzuzeigen, 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 Benutzers darauf zu lenken, wie im gezeigten Beispiel. Dies kann dazu führen, dass die Fokushervorhebung schwer zu erkennen ist.

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

In dieser Situation kann der Entwickler mithilfe von Sekundärfarben eine benutzerdefinierte Fokushervorhebung festlegen:
  • ( 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

Jede der Farben kann transparent sein und jede Dimension kann Null sein, wenn Sie beispielsweise nur eine Füllung oder nur einen Umriss wünschen.

FocusArea-Highlight

( Android 11 QPR3, Android 11 Auto, Android 12 )
FocusArea kann zwei Arten von Hervorhebungen zeichnen, wenn einer seiner Nachkommen fokussiert ist. Bei Bedarf können beide zusammen verwendet werden. Diese Funktion ist in AOSP standardmäßig deaktiviert, kann aber durch Überschreiben der car-ui-library-Ressourcen aktiviert werden:

  • car_ui_enable_focus_area_foreground_highlight : Zeichnen Sie eine Hervorhebung über der FocusArea und ihren Nachkommen. In AOSP ist dieses Zeichenelement ein Umriss um die FocusArea . OEMs können das Zeichenelement car_ui_focus_area_foreground_highlight überschreiben.
  • car_ui_enable_focus_area_background_highlight : Zeichnen Sie eine Hervorhebung über der FocusArea , aber hinter ihren Nachkommen. In AOSP ist dieses Zeichenelement eine feste Füllung. OEMs können das Zeichenelement car_ui_focus_area_background_highlight überschreiben.

Editoren für Eingabemethoden

Eingabemethoden-Editoren (IME) sind Eingabemethoden. Zum Beispiel eine Bildschirmtastatur.

( Android 11 QPR3, Android 11 Auto, Android 12 )
Der OEM muss die Zeichenfolgenressource default_touch_input_method im RotaryService überlagern, um den ComponentName des berührungsbasierten 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 Auto, Android 12 )
Wenn der OEM einen IME speziell für Rotary erstellt hat, sollte er dessen ComponentName in der Ressource rotary_input_method angeben. Wenn diese Ressource überlagert ist, wird der angegebene IME immer dann verwendet, wenn der Benutzer mit der Kopfeinheit über die Nudge-, Rotations- und Center-Taste des Drehreglers interagiert. Wenn der Benutzer den Bildschirm berührt, wird der vorherige IME verwendet. Die Zurück-Taste (und andere Tasten auf dem Drehregler) haben keinen Einfluss auf die IME-Auswahl. Wenn diese Ressource nicht überlagert ist, findet kein IME-Wechsel statt. Carboard unterstützt keine Rotation, sodass der Benutzer keinen Text über den Rotationsregler eingeben kann, wenn der OEM keinen Rotations-IME bereitgestellt hat.

RotaryIME ist ein Demo-Rotations-IME. Obwohl dies einfach ist, reicht es aus, die oben beschriebene automatische IME-Umschaltung auszuprobieren. Der Quellcode für RotaryIME ist unter packages/apps/Car/tests/RotaryIME/ zu finden.

Anstupser aus dem Off

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

  1. Eine globale Aktion, die von AccessibilityService definiert wird. Zum Beispiel GLOBAL_ACTION_BACK .
  2. Ein Schlüsselcode, z. B. KEYCODE_BACK .
  3. Eine Absicht, eine Aktivität zu starten, dargestellt als URL.

( Android 11 QPR3, Android 11 Auto, Android 12 )
Diese werden durch Überlagerung der folgenden Array-Ressourcen im RotaryService angegeben:

  • off_screen_nudge_global_actions : Array globaler Aktionen, die ausgeführt werden sollen, wenn der Benutzer den Bildschirmrand nach oben, unten, links oder rechts bewegt. Es wird keine globale Aktion ausgeführt, wenn das relevante Element dieses Arrays -1 ist.
  • off_screen_nudge_key_codes : Array von Tastencodes von Klickereignissen, die eingefügt werden, wenn der Benutzer den Bildschirmrand nach oben, unten, links oder rechts bewegt. Es werden keine Ereignisse eingefügt, wenn das relevante Element dieses Arrays 0 ( KEYCODE_UNKNOWN ) ist.
  • off_screen_nudge_intents : Array von Absichten zum Starten einer Aktivität, wenn der Benutzer den Bildschirmrand nach oben, unten, links oder rechts bewegt. Es wird keine Aktivität gestartet, wenn das entsprechende Element dieses Arrays leer ist.

Andere Konfigurationen

Sie sollten die folgenden RotaryService Ressourcen überlagern:

  • ( Android 11 QPR3, Android 11 Auto, Android 12 )
    config_showHeadsUpNotificationOnBottom : Boolescher Wert, der angibt, ob Heads-up-Benachrichtigungen unten und nicht oben angezeigt werden sollen. Dieser muss denselben Wert haben wie die boolesche Ressource config_showHeadsUpNotificationOnBottom in frameworks/base/packages/CarSystemUI/res/values/config.xml
  • ( Android 11 QPR3, Android 11 Auto, Android 12 )
    notification_headsup_card_margin_horizontal : Linker und rechter Rand für das Heads-up-Benachrichtigungsfenster. Dieser muss denselben Wert haben wie die Dimensionsressource notification_headsup_card_margin_horizontal “ in packages/apps/Car/Notification/res/values/dimens.xml
  • ( Android 12 )
    excluded_application_overlay_window_titles : Ein Array von Fenstertiteln, die nicht als Overlay-Fenster betrachtet werden sollten. Dies sollte Titel von App-Fenstern umfassen, die TaskViews oder TaskDisplayAreas darstellen. Standardmäßig enthält diese Liste nur „Karten“.

Sie können die folgende RotaryService Ressource überlagern:

  • ( Android 11 QPR3, Android 11 Auto, Android 12 )
    long_press_ms : Ganzzahliger Wert, der angibt, wie viele Millisekunden die mittlere Taste gedrückt gehalten werden muss, um einen langen Druck auszulösen. Null gibt an, dass das standardmäßige System-Timeout für langes Drücken verwendet werden soll. Dies ist der Standardwert.