Panduan integrasi untuk OEM

Halaman ini menjelaskan cara memproses input dari tombol putar di VHAL, mengonfigurasi build Anda untuk menyertakan layanan putar, dan cara menyesuaikan pengalaman putar di semua aplikasi. Untuk aplikasi OEM bawaan, seperti peluncur yang disediakan OEM, lihat Library UI Mobil (car-ui-library).

VHAL

rotary controller mendukung tindakan berikut:

  • Geser ke atas, bawah, kiri, dan kanan.
  • Putar searah jarum jam dan berlawanan arah jarum jam.
  • Tekan tombol Tengah.
  • Tekan tombol Kembali.
  • Tekan tombol Layar utama.
  • Tekan tombol lain, seperti Telepon dan Media.

Lihat hardware/interfaces/automotive/vehicle/2.0/types.hal untuk dokumentasi tentang properti sistem dan int32Values yang sesuai.

VHAL harus menangani tindakan ini:

Senggol

Ketika pengguna mendorong rotary controller ke kanan, VHAL harus menggunakan Properti HW_KEY_INPUT dengan int32Values berikut untuk mengirim peristiwa ke Android:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Tampilan target.

Ketika pengguna melepaskan {i>rotary controller<i}, VHAL harus menggunakan properti dan kode tombol dengan ACTION_UP. Dorongan ke arah lain harus menggunakan kode tombol yang sesuai.

Tidak ada kode tombol untuk diagonal, tetapi VHAL dapat menggabungkan garis horizontal dan vertikal untuk menghasilkan diagonal jika hardware mendukung diagonal. Misalnya, mendorong dan di sebelah kiri akan menghasilkan:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

Dalam urutan mana pun (dan selanjutnya) melepaskan rotary controller akan menghasilkan:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Pengguna dapat mendorong rotary controller dalam arah tegak lurus sebelum melepaskannya. Misalnya, skenario berikut:

Arah tegak lurus
Gambar 1. Arah tegak lurus

Tindakan ini akan menghasilkan urutan peristiwa berikut:

  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

Tidak ada peristiwa repeat yang harus dibuat saat rotary controller ditahan dalam satu arah.

Putar

Ketika pengguna memutar rotary controller searah jarum jam sebanyak satu penahan (klik), VHAL harus menggunakan properti HW_ROTARY_INPUT dengan int32Values berikut untuk mengirim peristiwa ke Android:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Satu (1) tahanan.
  3. Tampilan target.

Stempel waktu peristiwa harus disetel ke waktu berlalu dalam nanodetik.

Rotasi satu (1) detent berlawanan arah jarum jam akan menghasilkan peristiwa yang sama tetapi dengan -1 untuk jumlah detent.

Jika beberapa penahanan rotasi pada arah yang sama terjadi secara berurutan dengan cepat, VHAL harus menggabungkan detent menjadi satu peristiwa agar tidak membebani sistem dengan peristiwa. Dalam hal ini, stempel waktu peristiwa harus saat detent rotasi pertama terjadi. int32Values harus menyertakan jumlah nanodetik di antara detent berturut-turut rotasi.

Misalnya, urutan rotasi berikut:

  • Pada waktu t0, pengguna memutar satu detent berlawanan arah jarum jam.
  • Pada waktu t0 + 5 ns, pengguna memutar satu detent berlawanan arah jarum jam.
  • Pada waktu t0 + 8 ns, pengguna memutar satu detent berlawanan arah jarum jam.

harus menghasilkan peristiwa ini:

  • Properti: HW_ROTARY_INPUT
  • Stempel waktu: t0
  • int32Values:
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (tiga deten berlawanan arah jarum jam).
    3. Tampilan target.
    4. 5 ns antara penahan pertama dan kedua.
    5. 3 ns antara penahanan kedua dan ketiga.

Tombol tengah

Saat pengguna menekan tombol Center, VHAL harus menggunakan HW_KEY_INPUT dengan int32Values berikut untuk mengirim peristiwa ke Android:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Tampilan target.

Saat pengguna melepaskan rotary controller, VHAL harus menggunakan properti yang sama dan kode tombol dengan ACTION_UP.

Jangan buat peristiwa repeat saat tombol Tengah ditahan.

Tombol kembali

Saat pengguna menekan tombol Kembali, VHAL harus menggunakan HW_KEY_INPUT dengan int32Values berikut untuk mengirim peristiwa ke Android:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Tampilan target.

Saat pengguna melepaskan rotary controller, VHAL harus menggunakan properti yang sama dan kode tombol dengan ACTION_UP.

Tidak ada peristiwa repeat yang harus dibuat saat tombol Tengah ditahan.

Tombol beranda

Tangani tombol Beranda seperti yang Anda lakukan dengan tombol Kembali, tetapi dengan KEYCODE_HOME sebagai gantinya dari KEYCODE_BACK.

Tombol lainnya

Jika rotary controller menyertakan tombol tambahan, VHAL dapat menanganinya OEM suka karena mereka tidak dianggap sebagai bagian dari alat rotasi dari perspektif Android. Ini biasanya ditangani seperti tombol Back dan Home tetapi dengan kode tombol yang berbeda. Misalnya, KEYCODE_CALL atau KEYCODE_MUSIC.

Konfigurasi build

Navigasi putar disediakan oleh layanan aksesibilitas yang disebut RotaryService. Untuk menyertakan layanan ini dalam image sistem perangkat Anda, tambahkan baris berikut ke makefile:

PRODUCT_PACKAGES += CarRotaryController

Anda mungkin juga ingin menyertakan paket berikut dalam build debug:

  • RotaryPlayground Aplikasi referensi untuk alat rotasi (lihat RotaryPlayground).
  • RotaryIME IME putar demo (lihat Editor Metode Input).
  • CarRotaryImeRRO Overlay untuk RotaryIME.

Layanan putar diaktifkan secara otomatis saat perangkat melakukan booting dan saat pengguna terjadi peralihan. Hal ini memastikan bahwa pengguna dapat menggunakan rotary controller selama penyiapan.

Jika Anda menggunakan {i>build<i} yang sama untuk mobil dengan dan tanpa {i>rotary controller<i}, tambahkan CarRotaryController seperti yang ditunjukkan di atas sehingga kode yang diperlukan disertakan dalam build. Untuk mencegah layanan putar tidak diaktifkan pada mobil non-rotary, buat RRO statis untuk menempatkan resource string rotaryService di packages/services/Car/service dengan string kosong. Anda akan menggunakan build yang sama, tetapi memiliki konfigurasi produk yang terpisah, untuk perangkat putar dan non-putar. Hanya yang terakhir menyertakan overlay.

Penyesuaian

OEM dapat menyesuaikan logika pencarian fokus, sorotan fokus, dan beberapa item tambahan melalui overlay resource di lokasi berikut:

  • car-ui-library terletak di packages/apps/Car/libs/car-ui-lib
  • RotaryService terletak di packages/apps/Car/RotaryController
  • Core terletak di frameworks/base/core

Histori dorongan

OEM dapat mengonfigurasi apakah kedua jenis histori dorongan diaktifkan atau tidak, dan jika ya, yaitu ukuran cache dan kebijakan masa berlaku. Ini semua dilakukan dengan mengganti berbagai library car-ui-library Google Cloud Platform.

Memfokuskan cache histori

(Android 11 QPR3, Android 11 Mobil, Android 12)
Cache per-FocusArea ini menyimpan tampilan yang difokuskan baru-baru ini dalam FocusArea sehingga dapat difokuskan saat mendorong kembali ke FocusArea. Cache ini dapat dikonfigurasi dengan menempatkan resource car-ui-library berikut:

  • car_ui_focus_history_cache_type:
    1. Cache dinonaktifkan.
    2. Masa berlaku cache akan berakhir setelah beberapa waktu (lihat di bawah).
    3. Cache tidak akan pernah habis masa berlakunya.
  • car_ui_focus_history_expiration_period_ms: Berapa milidetik sebelum kedaluwarsa jika jenis cache disetel ke dua (2) (lihat di atas).

Cache histori FocusArea

(Android 11 QPR3, Android 11 Mobil, Android 12)
Cache ini menyimpan riwayat saran tindak lanjut sehingga mendorong ke arah yang berlawanan dapat mengembalikan fokus ke FocusArea yang sama. Cache ini dapat dikonfigurasi dengan menempatkan resource car-ui-library berikut:

  • car_ui_focus_area_history_cache_type:
    1. Cache dinonaktifkan.
    2. Cache akan kedaluwarsa setelah beberapa waktu (lihat di bawah).
    3. Cache tidak memiliki batas waktu.
  • car_ui_focus_area_history_expiration_period_ms: Berapa milidetik sebelumnya cache akan kedaluwarsa jika jenis cache disetel ke 2 (lihat di atas).
  • car_ui_clear_focus_area_history_when_rotating: Apakah cache akan dibatalkan atau tidak saat pengguna memutar pengontrol.

Rotasi

(Android 11 QPR3, Android 11 Mobil, Android 12)
OEM dapat mengganti dua resource bilangan bulat di RotaryService untuk menentukan apakah ada akselerasi, seperti akselerasi mouse, untuk rotasi:

  • rotation_acceleration_3x_ms: Interval waktu (dalam milidetik) yang digunakan untuk memutuskan apakah Google harus mempercepat rotasi pengontrol untuk deten rotasi. Jika interval antara detent ini dan detent rotasi sebelumnya lebih kecil dari nilai ini, ini akan diperlakukan sebagai tiga deten rotasi. Setel ini ke 2147483647 untuk menonaktifkan 3× dan percepatan.
  • rotation_acceleration_2x_ms: Mirip dengan rotation_acceleration_3x_ms. Digunakan untuk akselerasi 2×. Setel ke 2147483647 untuk menonaktifkan akselerasi 2×.

Akselerasi berfungsi optimal jika ada stempel waktu individu untuk setiap penahanan seperti rotasi wajib oleh VHAL. Jika tidak tersedia, RotaryService mengasumsikan bahwa penahanan rotasi ditempatkan secara merata.

/**
     * 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 sorotan

OEM dapat mengganti sorotan fokus default dalam framework Android dan beberapa resource sorotan fokus di {i>car-ui-library<i}.

Sorotan fokus default

Framework Android menyediakan sorotan fokus default melalui atribut selectableItemBackground. Pada Theme.DeviceDefault, ini merujuk ke item_background.xml di Core. OEM dapat menempatkan item_background.xml untuk mengubah drawable sorotan fokus default.

Drawable ini biasanya harus berupa StateListDrawable, yang menyesuaikan latar belakang berdasarkan berbagai kombinasi status, termasuk android:state_focused dan android:state_pressed. Ketika pengguna menggunakan rotary controller untuk memfokuskan tampilan, android:state_focused akan menjadi true, tapi android:state_pressed akan menjadi false. Jika pengguna kemudian menekan tombol Tengah pada rotary controller, baik android:state_focused maupun android:state_pressed akan menjadi true saat pengguna menahan tombol. Jika pengguna melepaskan tombol, hanya android:state_focused yang akan tetap ada true.

car-ui-library menggunakan tema yang berasal dari Theme.DeviceDefault. Hasilnya, overlay ini memengaruhi aplikasi yang menggunakan library ini dan aplikasi yang menggunakan tema apa pun yang berasal dari Theme.DeviceDefault. Setelan ini tidak akan memengaruhi aplikasi yang menggunakan tema yang tidak terkait, misalnya Theme.Material.

Memfokuskan resource sorotan di car-ui-library

OEM dapat mengganti beberapa resource car-ui-library untuk mengontrol cara sorotan fokus terlihat pada tampilan dengan sorotan fokus non-persegi panjang (seperti bulat atau berbentuk pil) dan dalam aplikasi yang menggunakan tema yang bukan berasal dari Theme.DeviceDefault. Ini harus dihamparkan sehingga sorotan fokus konsisten dengan drawable highlight fokus default.

(Android 11 QPR3, Android 11 Mobil, Android 12)
Resource berikut digunakan untuk menunjukkan kapan tampilan difokuskan, tetapi tidak ditekan:

  • car_ui_rotary_focus_fill_color: Warna pengisi.
  • car_ui_rotary_focus_stroke_color: Warna garis batas.
  • car_ui_rotary_focus_stroke_width: Ketebalan garis batas.

(Android 11 QPR3, Android 11 Mobil, Android 12)
Resource berikut digunakan untuk menunjukkan kapan tampilan difokuskan dan ditekan:

  • car_ui_rotary_focus_pressed_fill_color: Warna pengisi.
  • car_ui_rotary_focus_pressed_stroke_color: Warna garis batas.
  • car_ui_rotary_focus_pressed_stroke_width: Ketebalan garis batas.

Terkadang sebuah tombol diberi warna latar belakang yang solid untuk menarik perhatian pengguna, seperti dalam contoh yang ditunjukkan. Hal ini dapat membuat sorotan fokus sulit dilihat.

Tombol dengan latar belakang solid
Gambar 2. Tombol dengan latar belakang solid

Dalam situasi ini, developer dapat menentukan sorotan fokus khusus menggunakan sekunder:
  • (Android 11 QPR3, Android 11 Mobil, 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

Setiap warna bisa transparan dan salah satu dimensi bisa nol jika, misalnya, Anda hanya ingin isian atau garis besar.

Sorotan FocusArea

(Android 11 QPR3, Android 11 Mobil, Android 12)
FocusArea dapat menggambar dua jenis sorotan jika salah satu turunannya adalah tetap fokus. Keduanya dapat digunakan bersamaan, jika diinginkan. Fitur ini dinonaktifkan secara {i>default<i} di AOSP, tetapi dapat diaktifkan dengan mengganti resource car-ui-library:

  • car_ui_enable_focus_area_foreground_highlight: Menggambar sorotan di atas FocusArea dan turunannya. Dalam AOSP, drawable ini adalah garis besar di sekitar FocusArea. OEM dapat mengganti Drawable car_ui_focus_area_foreground_highlight.
  • car_ui_enable_focus_area_background_highlight: Gambar sorotan di atas FocusArea tetapi di belakang turunannya. Dalam AOSP, drawable ini merupakan isian yang solid. OEM dapat mengganti drawable car_ui_focus_area_background_highlight.

Editor Metode Masukan

Editor Metode Input (IME) adalah metode input. Misalnya, keyboard virtual.

(Android 11 QPR3, Android 11 Mobil, Android 12)
OEM harus menempatkan resource string default_touch_input_method di RotaryService untuk menentukan ComponentName IME berbasis sentuhan. Misalnya, jika OEM menggunakan IME yang disediakan dengan Android Automotive, mereka harus menentukan com.google.android.apps.automotive.inputmethod/.InputMethodService.

(Android 11 QPR3, Android 11 Mobil, Android 12)
Jika OEM telah membuat IME khusus untuk alat rotasi, OEM harus menentukan ComponentName dalam resource rotary_input_method. Jika sumber daya ini ditempatkan sebagai overlay, IME yang ditentukan digunakan setiap kali pengguna berinteraksi dengan head unit melalui dorongan, rotasi, dan tombol Center dari rotary controller. Saat pengguna menyentuh layar, IME sebelumnya akan digunakan. Tombol Kembali (dan tombol lain pada tombol putar pengontrol) tidak memengaruhi pemilihan IME. Jika resource ini tidak dihamparkan, pengalihan IME tidak akan terjadi apa yang terjadi. Carboard tidak mendukung tombol putar sehingga pengguna tidak dapat memasukkan teks melalui tombol putar jika OEM belum menyediakan IME putar.

RotaryIME adalah IME putar demo. Meskipun sederhana, Anda dapat melakukan cobalah beralih IME otomatis seperti yang dijelaskan di atas. Kode sumber untuk RotaryIME dapat ditemukan di packages/apps/Car/tests/RotaryIME/.

Pengingat di luar layar

Secara default, saat pengguna mencoba menggeser tepi layar, tidak ada yang terjadi. OEM dapat mengonfigurasi apa yang harus dilakukan untuk masing-masing dari keempat arah tersebut dengan menentukan kombinasi dari:

  1. Tindakan global yang ditentukan oleh AccessibilityService. Contoh: GLOBAL_ACTION_BACK.
  2. Kode tombol, seperti KEYCODE_BACK.
  3. Intent untuk meluncurkan aktivitas yang direpresentasikan sebagai URL.

(Android 11 QPR3, Android 11 Mobil, Android 12)
Ini ditetapkan dengan menempatkan sumber daya array berikut dalam RotaryService:

  • off_screen_nudge_global_actions: Array tindakan global yang akan dilakukan saat pengguna mendorong ke atas, bawah, kiri, atau kanan dari tepi layar. Tidak ada tindakan global yang dilakukan jika elemen yang relevan dari array ini adalah -1.
  • off_screen_nudge_key_codes: Array kode tombol peristiwa klik yang akan dimasukkan ketika pengguna menggeser ke atas, bawah, kiri, atau kanan dari tepi layar. Tidak ada peristiwa yang dimasukkan jika elemen yang relevan dari array ini adalah 0 (KEYCODE_UNKNOWN).
  • off_screen_nudge_intents: Array intent untuk meluncurkan aktivitas saat pengguna mendorong ke atas, bawah, kiri, atau kanan dari tepi layar. Tidak ada aktivitas diluncurkan jika elemen yang relevan dari array ini kosong.

Konfigurasi lainnya

Anda harus menempatkan resource RotaryService berikut:

  • (Android 11 QPR3, Android 11 Mobil, Android 12)
    config_showHeadsUpNotificationOnBottom: Nilai Boolean untuk mewakili apakah notifikasi peringatan dini harus ditampilkan di bagian bawah, bukan di bagian atas. Ini harus memiliki nilai yang sama dengan config_showHeadsUpNotificationOnBottom Resource Boolean di frameworks/base/packages/CarSystemUI/res/values/config.xml
  • (Android 11 QPR3, Android 11 Mobil, Android 12)
    notification_headsup_card_margin_horizontal: Margin kiri dan kanan untuk jendela notifikasi peringatan dini. Nilai ini harus sama dengan notification_headsup_card_margin_horizontal resource dimensi di packages/apps/Car/Notification/res/values/dimens.xml
  • (Android 12)
    excluded_application_overlay_window_titles: Array dari judul jendela yang seharusnya tidak dianggap sebagai jendela {i>overlay<i}. Ini harus mencakup judul jendela aplikasi yang mewakili TaskViews atau TaskDisplayAreas. Secara default, daftar ini hanya berisi "Maps".

Anda dapat menempatkan resource RotaryService berikut:

  • (Android 11 QPR3, Android 11 Mobil, Android 12)
    long_press_ms: Nilai bilangan bulat untuk mewakili berapa milidetik saat Tombol tengah harus ditahan untuk memicu penekanan lama. Nol menunjukkan sistem waktu tunggu tekan lama default harus digunakan. Nilai ini merupakan default.