Panduan Integrasi untuk OEM

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

VHAL

Kontroler putar 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 Beranda.
  • 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:

Dorongan

Saat pengguna mendorong pengontrol putar 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 sasaran.

Saat pengguna melepaskan pengontrol putar, VHAL harus menggunakan properti dan kode kunci yang sama dengan ACTION_UP . Dorongan 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 perangkat keras mendukung diagonal. Misalnya, menyenggol ke atas dan ke kiri harus menghasilkan:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

Dalam kedua urutan (dan selanjutnya) melepaskan pengontrol putar harus menghasilkan:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

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

Arah tegak lurus
Gambar 1. Arah tegak lurus

Ini harus 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 kejadian berulang yang harus dihasilkan saat pengontrol putar ditahan dalam satu arah.

Memutar

Saat pengguna memutar pengontrol putar searah jarum jam dengan 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. 1 (satu) orang tahanan.
  3. Tampilan sasaran.

Stempel waktu acara harus disetel ke waktu yang telah berlalu dalam nanodetik.

Rotasi satu (1) penahan berlawanan arah jarum jam harus menghasilkan kejadian yang sama tetapi dengan -1 untuk jumlah penahan.

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

Misalnya, urutan rotasi berikut:

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

harus menghasilkan acara ini:

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

tombol tengah

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

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Tampilan sasaran.

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

Jangan membuat acara berulang saat tombol Tengah ditekan.

Tombol kembali

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

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Tampilan sasaran.

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

Tidak ada acara berulang yang harus dibuat saat tombol Tengah ditekan.

Tombol Home

Tangani tombol Beranda seperti yang Anda lakukan pada tombol Kembali tetapi dengan KEYCODE_HOME alih-alih KEYCODE_BACK .

Tombol lainnya

Jika pengontrol putar menyertakan tombol tambahan apa pun, VHAL dapat menanganinya sesuai keinginan OEM karena tidak dianggap sebagai bagian dari putaran dari perspektif Android. Ini biasanya ditangani seperti tombol Kembali dan Beranda tetapi dengan kode kunci yang berbeda. Misalnya, KEYCODE_CALL atau KEYCODE_MUSIC .

Bangun konfigurasi

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

PRODUCT_PACKAGES += CarRotaryController

Anda mungkin juga ingin menyertakan paket berikut dalam build debug:

  • RotaryPlayground Sebuah aplikasi referensi untuk rotary (lihat RotaryPlayground ).
  • RotaryIME Sebuah demo rotary IME (lihat Editor Metode Input ).
  • CarRotaryImeRRO Hamparan untuk RotaryIME .

Layanan putar diaktifkan secara otomatis saat perangkat melakukan booting dan saat terjadi peralihan pengguna. Ini memastikan bahwa pengguna dapat menggunakan pengontrol putar selama pengaturan.

Jika Anda menggunakan build yang sama untuk mobil dengan dan tanpa pengontrol putar, tambahkan CarRotaryController seperti yang ditunjukkan di atas agar kode yang diperlukan disertakan dalam build. Untuk mencegah layanan putar diaktifkan pada mobil non-putar, buat RRO statis untuk melapisi sumber daya string rotaryService dalam packages/services/Car/service dengan string kosong. Anda akan menggunakan build yang sama, tetapi memiliki konfigurasi produk terpisah, untuk perangkat putar dan non-putar. Hanya yang terakhir yang mencakup overlay.

Kustomisasi

OEM dapat menyesuaikan logika pencarian fokus, sorotan fokus, dan beberapa item tambahan melalui hamparan sumber daya 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

Sejarah dorongan

OEM dapat mengonfigurasi apakah masing-masing dari dua jenis riwayat dorongan diaktifkan atau tidak dan, jika demikian, ukuran cache dan kebijakan kedaluwarsa. Ini semua dilakukan dengan mengesampingkan berbagai sumber perpustakaan mobil-ui.

Fokus cache riwayat

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

  • car_ui_focus_history_cache_type :
    1. Tembolok dinonaktifkan.
    2. Cache akan kedaluwarsa setelah beberapa waktu (lihat di bawah).
    3. Cache tidak akan pernah kedaluwarsa.
  • car_ui_focus_history_expiration_period_ms : Berapa milidetik sebelum cache kedaluwarsa jika tipe cache disetel ke dua (2) (lihat di atas).

Cache riwayat FocusArea

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

  • car_ui_focus_area_history_cache_type :
    1. Tembolok dinonaktifkan.
    2. Cache kedaluwarsa setelah beberapa waktu (lihat di bawah).
    3. Cache tidak pernah kedaluwarsa.
  • car_ui_focus_area_history_expiration_period_ms : Berapa milidetik sebelum cache kedaluwarsa jika tipe cache disetel 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 Mobil, Android 12 )
OEM dapat menimpa dua sumber daya integer 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 menahan rotasi. Jika interval antara penahan ini dan penahan rotasi sebelumnya lebih kecil dari nilai ini, maka akan diperlakukan sebagai tiga penahan rotasi. Setel ini ke 2147483647 untuk menonaktifkan akselerasi 3×.
  • rotation_acceleration_2x_ms : Mirip dengan rotation_acceleration_3x_ms . Digunakan untuk akselerasi 2x. Setel ini ke 2147483647 untuk menonaktifkan akselerasi 2×.

Akselerasi bekerja paling baik ketika ada cap waktu individu untuk setiap detent rotasi, seperti yang dipersyaratkan oleh VHAL. Jika ini tidak tersedia, RotaryService mengasumsikan bahwa detent 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),

Sorotan fokus

OEM dapat mengganti sorotan fokus default dalam kerangka kerja Android dan beberapa sumber daya sorotan fokus di perpustakaan mobil-ui.

Sorotan fokus default

Kerangka kerja Android menyediakan sorotan fokus default melalui atribut selectableItemBackground . Di Theme.DeviceDefault , atribut ini merujuk ke item_background.xml di Core . OEM dapat melapisi item_background.xml untuk mengubah drawable sorotan fokus default.

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

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

Fokus sorot sumber daya di perpustakaan mobil-ui

OEM dapat mengganti beberapa sumber daya perpustakaan mobil 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 . Sumber daya ini harus dihamparkan sehingga sorotan fokus konsisten dengan sorotan fokus default yang dapat digambar.

( Android 11 QPR3, Android 11 Mobil, Android 12 )
Sumber daya berikut digunakan untuk menunjukkan saat tampilan difokuskan tetapi tidak ditekan:

  • car_ui_rotary_focus_fill_color : Isi warna.
  • car_ui_rotary_focus_stroke_color : Warna garis.
  • car_ui_rotary_focus_stroke_width : Ketebalan garis luar.

( Android 11 QPR3, Android 11 Mobil, Android 12 )
Sumber daya berikut digunakan untuk menunjukkan saat tampilan difokuskan dan ditekan:

  • car_ui_rotary_focus_pressed_fill_color : Isi warna.
  • car_ui_rotary_focus_pressed_stroke_color : Warna garis.
  • car_ui_rotary_focus_pressed_stroke_width : Ketebalan garis luar.

Terkadang tombol diberi warna latar belakang yang solid untuk menarik perhatian pengguna, seperti pada contoh yang ditampilkan. Ini mungkin membuat sorotan fokus sulit dilihat.

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

Dalam situasi ini, pengembang dapat menentukan sorotan fokus khusus menggunakan warna 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

Warna apa pun bisa transparan dan salah satu dimensi bisa nol jika, misalnya, Anda hanya menginginkan isian atau hanya garis luar.

Sorotan Area Fokus

( Android 11 QPR3, Android 11 Mobil, Android 12 )
FocusArea dapat menggambar dua jenis sorotan saat salah satu turunannya difokuskan. 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 : Gambarkan sorotan di atas FocusArea dan turunannya. Di AOSP, drawable ini adalah garis besar di sekitar FocusArea . OEM dapat mengganti car_ui_focus_area_foreground_highlight .
  • car_ui_enable_focus_area_background_highlight : Gambarkan sorotan di atas FocusArea tetapi di belakang turunannya. Di AOSP, drawable ini adalah isian yang solid. OEM dapat mengganti car_ui_focus_area_background_highlight .

Editor Metode Masukan

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

( Android 11 QPR3, Android 11 Mobil, Android 12 )
OEM harus melapisi sumber daya string default_touch_input_method di RotaryService untuk menentukan ComponentName dari 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 rotary, mereka harus menentukan ComponentName -nya di sumber daya rotary_input_method . Jika sumber daya ini dihamparkan, IME yang ditentukan akan digunakan setiap kali pengguna berinteraksi dengan head unit melalui dorong, rotasi, dan tombol Tengah pengontrol putar. Saat pengguna menyentuh layar, IME sebelumnya akan digunakan. Tombol Kembali (dan tombol lain pada pengontrol putar) tidak berpengaruh pada pemilihan IME. Jika sumber daya ini tidak dilapis, tidak ada peralihan IME yang terjadi. Carboard tidak mendukung putar sehingga pengguna tidak dapat memasukkan teks melalui pengontrol putar jika OEM belum menyediakan IME putar.

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

Dorongan di luar layar

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

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

( Android 11 QPR3, Android 11 Mobil, Android 12 )
Ini ditentukan dengan melapisi sumber daya array berikut di RotaryService :

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

Konfigurasi lainnya

Anda harus melapisi sumber daya RotaryService berikut:

  • ( Android 11 QPR3, Android 11 Mobil, Android 12 )
    config_showHeadsUpNotificationOnBottom : Nilai Boolean untuk menunjukkan apakah pemberitahuan pendahuluan harus ditampilkan di bagian bawah sebagai lawan dari bagian atas. Ini harus memiliki nilai yang sama dengan sumber daya Boolean config_showHeadsUpNotificationOnBottom 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 pendahuluan. Ini harus memiliki nilai yang 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. Ini harus menyertakan judul jendela aplikasi yang mewakili TaskViews atau TaskDisplayAreas . Secara default, daftar ini hanya berisi "Peta".

Anda dapat melapisi sumber daya RotaryService berikut:

  • ( Android 11 QPR3, Android 11 Mobil, Android 12 )
    long_press_ms : Nilai integer untuk menunjukkan berapa milidetik tombol Tengah harus ditekan untuk memicu penekanan lama. Nol menunjukkan batas waktu tekan lama default sistem harus digunakan. Ini adalah nilai default.