Panduan integrasi untuk OEM

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

VHAL

Pengontrol alat rotasi mendukung tindakan berikut:

  • Menggeser ke atas, bawah, kiri, dan kanan.
  • Memutar searah jarum jam dan berlawanan arah jarum jam.
  • Menekan tombol Tengah.
  • Menekan tombol Kembali.
  • Menekan tombol Beranda.
  • Menekan 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 berikut:

Menggeser

Saat pengguna mendorong pengontrol alat rotasi 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.

Saat pengguna melepaskan pengontrol alat rotasi, VHAL harus menggunakan properti dan kode kunci yang sama dengan ACTION_UP. Geseran ke arah lain harus menggunakan kode kunci yang sesuai.

Tidak ada kode kunci untuk diagonal, tetapi VHAL dapat menggabungkan peristiwa horizontal dan vertikal untuk menghasilkan diagonal jika hardware mendukung diagonal. Misalnya, menggeser ke atas dan ke kiri akan menghasilkan:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

Dalam urutan apa pun (dan selanjutnya) melepaskan pengontrol alat rotasi akan menghasilkan:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Pengguna dapat mendorong pengontrol alat rotasi ke arah tegak lurus sebelum melepaskannya. Misalnya, skenario berikut:

Arah tegak lurus
Gambar 1. Arah tegak lurus

Hal 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 ulang yang akan dihasilkan saat pengontrol alat rotasi ditahan dalam satu arah.

Memutar

Saat pengguna memutar pengontrol alat rotasi searah jarum jam dengan satu detent (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) detent.
  3. Tampilan target.

Stempel waktu peristiwa harus ditetapkan ke waktu yang berlalu dalam nanodetik.

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

Jika beberapa detent rotasi ke arah yang sama terjadi secara berurutan, VHAL harus menggabungkan detent ke dalam 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 antara detent rotasi yang berurutan.

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.

akan menghasilkan peristiwa ini:

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

Tombol tengah

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

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Tampilan target.

Saat pengguna melepaskan pengontrol alat rotasi, VHAL harus menggunakan properti dan kode kunci yang sama dengan ACTION_UP.

Jangan buat peristiwa ulang saat tombol Tengah ditahan.

Tombol kembali

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

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Tampilan target.

Saat pengguna melepaskan pengontrol alat rotasi, VHAL harus menggunakan properti dan kode kunci yang sama dengan ACTION_UP.

Tidak ada peristiwa ulang yang akan dihasilkan saat tombol Tengah ditahan.

Tombol beranda

Tangani tombol Beranda seperti tombol Kembali, tetapi dengan KEYCODE_HOME, bukan KEYCODE_BACK.

Tombol lainnya

Jika pengontrol alat rotasi menyertakan tombol tambahan, VHAL dapat menanganinya sesuai keinginan OEM karena tombol tersebut tidak dianggap sebagai bagian dari alat rotasi dari perspektif Android. Tombol ini biasanya ditangani seperti tombol Kembali dan Beranda, tetapi dengan kode kunci yang berbeda. Misalnya, KEYCODE_CALL atau KEYCODE_MUSIC.

Build configuration

Navigasi alat rotasi disediakan oleh layanan aksesibilitas yang disebut RotaryService. Untuk menyertakan layanan ini dalam image sistem untuk 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 alat rotasi demo (lihat Editor Metode Input).
  • CarRotaryImeRRO Overlay untuk RotaryIME.

Layanan alat rotasi diaktifkan secara otomatis saat perangkat di-boot dan saat terjadi peralihan pengguna. Hal ini memastikan pengguna dapat menggunakan pengontrol alat rotasi selama penyiapan.

Jika Anda menggunakan build yang sama untuk mobil dengan dan tanpa pengontrol alat rotasi, tambahkan CarRotaryController seperti yang ditunjukkan di atas agar kode yang diperlukan disertakan dalam build. Untuk mencegah layanan alat rotasi diaktifkan di mobil non-alat rotasi, buat RRO statis untuk meng-overlay 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 alat rotasi dan non-alat rotasi. Hanya yang terakhir yang 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 geseran

OEM dapat mengonfigurasi apakah setiap dari dua jenis histori geseran diaktifkan atau tidak, dan jika ya, ukuran cache dan kebijakan masa berlaku. Semua ini dilakukan dengan mengganti berbagai resource car-ui-library.

Cache histori fokus

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

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

Cache histori FocusArea

(Android 11 QPR3, Android 11 Car, Android 12)
Cache ini menyimpan histori geseran sehingga geseran ke arah yang berlawanan dapat mengembalikan fokus ke FocusArea yang sama. Cache ini dapat dikonfigurasi dengan meng-overlay resource car-ui-library berikut:

  • car_ui_focus_area_history_cache_type:
    1. Cache dinonaktifkan.
    2. Cache berakhir masa berlakunya setelah beberapa waktu (lihat di bawah).
    3. Cache tidak pernah berakhir masa berlakunya.
  • car_ui_focus_area_history_expiration_period_ms: Berapa milidetik sebelum cache berakhir masa berlakunya jika jenis cache ditetapkan ke 2 (lihat di atas).
  • car_ui_clear_focus_area_history_when_rotating: Apakah akan membatalkan cache saat pengguna memutar pengontrol.

Rotasi

(Android 11 QPR3, Android 11 Car, 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 detent rotasi. Jika interval antara detent ini dan detent rotasi sebelumnya lebih kecil dari nilai ini, detent tersebut akan diperlakukan sebagai tiga detent rotasi. Tetapkan nilai ini ke 2147483647 untuk menonaktifkan akselerasi 3×.
  • rotation_acceleration_2x_ms: Mirip dengan rotation_acceleration_3x_ms. Digunakan untuk akselerasi 2×. Tetapkan nilai ini ke 2147483647 untuk menonaktifkan akselerasi 2×.

Akselerasi berfungsi paling baik jika ada stempel waktu individual untuk setiap detent of rotation, as required by the VHAL. Jika tidak tersedia, RotaryService mengasumsikan bahwa detent rotasi memiliki jarak yang sama.

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

Sorotan fokus

OEM dapat mengganti sorotan fokus default di framework Android dan beberapa resource sorotan fokus di car-ui-library.

Sorotan fokus default

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

Drawable ini biasanya harus berupa StateListDrawable, yang menyesuaikan latar belakang berdasarkan kombinasi status yang berbeda, termasuk android:state_focused dan android:state_pressed. Saat pengguna menggunakan pengontrol alat rotasi untuk memfokuskan tampilan, android:state_focused akan menjadi true, tetapi android:state_pressed akan menjadi false. Jika pengguna kemudian menekan tombol Tengah pada pengontrol alat rotasi, android:state_focused dan android:state_pressed akan menjadi true saat pengguna menahan tombol. Saat pengguna melepaskan tombol, hanya android:state_focused yang akan tetap true.

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

Resource sorotan fokus di car-ui-library

OEM dapat mengganti beberapa resource car-ui-library untuk mengontrol tampilan sorotan fokus pada tampilan dengan sorotan fokus non-persegi panjang (seperti bulat atau berbentuk pil) dan di aplikasi yang menggunakan tema yang tidak berasal dari Theme.DeviceDefault. Resource ini harus di-overlay sehingga sorotan fokus konsisten dengan drawable sorotan fokus default.

(Android 11 QPR3, Android 11 Car, 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 luar.
  • car_ui_rotary_focus_stroke_width: Ketebalan garis luar.

(Android 11 QPR3, Android 11 Car, 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 luar.
  • car_ui_rotary_focus_pressed_stroke_width: Ketebalan garis luar.

Terkadang tombol diberi warna latar belakang solid untuk menarik perhatian pengguna, seperti dalam contoh yang ditampilkan. 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 kustom menggunakan warna sekunder:
  • (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

Salah satu warna dapat transparan dan salah satu dimensi dapat nol jika, misalnya, Anda hanya menginginkan pengisi atau hanya garis luar.

Sorotan FocusArea

(Android 11 QPR3, Android 11 Car, Android 12)
FocusArea dapat menggambar dua jenis sorotan saat salah satu turunannya di fokuskan. Keduanya dapat digunakan bersamaan, jika diinginkan. Fitur ini dinonaktifkan secara default 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. Di AOSP, drawable ini adalah garis luar di sekitar FocusArea. OEM dapat mengganti drawable car_ui_focus_area_foreground_highlight.
  • car_ui_enable_focus_area_background_highlight: Menggambar sorotan di atas FocusArea tetapi di belakang turunannya. Di AOSP, drawable ini adalah pengisi solid. OEM dapat mengganti drawable car_ui_focus_area_background_highlight.

Editor Metode Input

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

(Android 11 QPR3, Android 11 Car, Android 12)
OEM harus meng-overlay resource string default_touch_input_method di RotaryService untuk menentukan ComponentName IME berbasis sentuh. 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 Car, Android 12)
Jika OEM telah membuat IME khusus untuk alat rotasi, mereka harus menentukan ComponentName di resource rotary_input_method. Jika resource ini di-overlay, IME yang ditentukan akan digunakan setiap kali pengguna berinteraksi dengan unit utama melalui geseran, rotasi, dan tombol Tengah pengontrol alat rotasi. Saat pengguna menyentuh layar, IME sebelumnya akan digunakan. Tombol Kembali (dan tombol lainnya di pengontrol alat rotasi) tidak berpengaruh pada pemilihan IME. Jika resource ini tidak di-overlay, tidak ada peralihan IME. Carboard tidak mendukung alat rotasi sehingga pengguna tidak dapat memasukkan teks melalui pengontrol alat rotasi jika OEM belum menyediakan IME alat rotasi.

RotaryIME adalah IME alat rotasi demo. Meskipun dasar, IME ini cukup untuk mencoba peralihan IME otomatis yang dijelaskan di atas. Kode sumber untuk RotaryIME dapat ditemukan di packages/apps/Car/tests/RotaryIME/.

Geseran di luar layar

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

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

(Android 11 QPR3, Android 11 Car, Android 12)
Hal ini ditentukan dengan meng-overlay resource array berikut di RotaryService:

  • off_screen_nudge_global_actions: Array tindakan global yang akan dilakukan saat pengguna menggeser 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 kunci peristiwa klik yang akan disisipkan saat pengguna menggeser ke atas, bawah, kiri, atau kanan dari tepi layar. Tidak ada peristiwa yang disisipkan jika elemen yang relevan dari array ini adalah 0 (KEYCODE_UNKNOWN).
  • off_screen_nudge_intents: Array intent untuk meluncurkan aktivitas saat pengguna menggeser ke atas, bawah, kiri, atau kanan dari tepi layar. Tidak ada aktivitas yang diluncurkan jika elemen yang relevan dari array ini kosong.

Konfigurasi lainnya

Anda harus meng-overlay resource RotaryService berikut:

  • Android 11 QPR3, Android 11 Car, Android 12)
    config_showHeadsUpNotificationOnBottom: Nilai boolean untuk menunjukkan apakah notifikasi heads-up harus ditampilkan di bagian bawah, bukan di bagian atas. Nilai ini harus memiliki nilai yang sama dengan resource Boolean config_showHeadsUpNotificationOnBottom di frameworks/base/packages/CarSystemUI/res/values/config.xml
  • (Android 11 QPR3, Android 11 Car, Android 12)
    notification_headsup_card_margin_horizontal: Margin kiri dan kanan untuk jendela notifikasi heads-up. Nilai ini harus sama dengan resource dimen notification_headsup_card_margin_horizontal di packages/apps/Car/Notification/res/values/dimens.xml
  • (Android 12)
    excluded_application_overlay_window_titles: Array judul jendela yang tidak boleh dianggap sebagai jendela overlay. Array ini harus menyertakan judul jendela aplikasi yang mewakili TaskViews atau TaskDisplayAreas. Secara default, daftar ini hanya berisi "Maps".

Anda dapat meng-overlay resource RotaryService berikut:

  • Android 11 QPR3, Android 11 Car, Android 12)
    long_press_ms: Nilai bilangan bulat untuk menunjukkan berapa milidetik tombol Tengah harus ditahan untuk memicu penekanan lama. Nol menunjukkan waktu tunggu penekanan lama default sistem harus digunakan. Nilai ini merupakan default.