Hướng dẫn tích hợp dành cho OEM

Trang này mô tả cách xử lý đầu vào quay trong VHAL, định cấu hình bản dựng của bạn để bao gồm dịch vụ quay và cách tùy chỉnh trải nghiệm quay trên tất cả các ứng dụng. Đối với các ứng dụng OEM được cài đặt sẵn, chẳng hạn như trình khởi chạy do OEM cung cấp, hãy xem Thư viện giao diện người dùng ô tô (car-ui-library) .

VHAL

Bộ điều khiển quay hỗ trợ các hành động sau:

  • Di chuyển lên, xuống, trái và phải.
  • Xoay theo chiều kim đồng hồ và ngược chiều kim đồng hồ.
  • Nhấn nút Trung tâm.
  • Nhấn vào nút quay về.
  • Nhấn nút Trang chủ.
  • Nhấn các nút khác, chẳng hạn như Điện thoại và Phương tiện.

Xem hardware/interfaces/automotive/vehicle/2.0/types.hal để biết tài liệu về các thuộc tính hệ thống và int32Values ​​tương ứng.

VHAL nên xử lý các hành động sau:

di chuyển

Khi người dùng đẩy bộ điều khiển quay sang phải, VHAL nên sử dụng thuộc tính HW_KEY_INPUT với các int32Values ​​sau để gửi sự kiện tới Android:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Hiển thị mục tiêu.

Khi người dùng nhả bộ điều khiển quay, VHAL phải sử dụng cùng thuộc tính và mã khóa với ACTION_UP . Di chuyển theo các hướng khác nên sử dụng mã khóa tương ứng.

Không có mã khóa cho đường chéo nhưng VHAL có thể kết hợp sự kiện ngang và dọc để tạo đường chéo nếu phần cứng hỗ trợ đường chéo. Ví dụ: di chuyển lên và sang trái sẽ tạo ra:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

Theo một trong hai thứ tự (và sau đó) nhả bộ điều khiển quay sẽ tạo ra:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Người dùng có thể đẩy bộ điều khiển quay theo hướng vuông góc trước khi nhả nó ra. Ví dụ: kịch bản sau:

Hướng vuông góc
Hình 1. Hướng vuông góc

Điều này sẽ tạo ra chuỗi sự kiện sau:

  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

Không được tạo ra sự kiện lặp lại trong khi bộ điều khiển quay được giữ theo một hướng.

Quay

Khi người dùng xoay bộ điều khiển quay theo chiều kim đồng hồ một chốt chặn (nhấp chuột), VHAL nên sử dụng thuộc tính HW_ROTARY_INPUT với các int32Values ​​sau để gửi sự kiện tới Android:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Một (1) lệnh giam giữ.
  3. Hiển thị mục tiêu.

Dấu thời gian của sự kiện phải được đặt thành thời gian đã trôi qua tính bằng nano giây.

Một (1) vòng quay ngược chiều kim đồng hồ sẽ tạo ra cùng một sự kiện nhưng với -1 cho số lượng chốt.

Nếu nhiều chốt chặn quay theo cùng một hướng xảy ra liên tiếp nhanh chóng, VHAL nên kết hợp các chốt chặn thành một sự kiện duy nhất để không làm hệ thống bị quá tải vì các sự kiện. Trong trường hợp này, dấu thời gian của sự kiện phải là thời điểm xảy ra lần quay vòng đầu tiên. int32Values phải bao gồm số lượng nano giây giữa các khoảng quay liên tiếp.

Ví dụ: chuỗi xoay sau đây:

  • Tại thời điểm t0, người dùng xoay một chốt chặn ngược chiều kim đồng hồ.
  • Tại thời điểm t0 + 5 ns, người dùng xoay một chốt hãm ngược chiều kim đồng hồ.
  • Tại thời điểm t0 + 8 ns, người dùng xoay một chốt hãm ngược chiều kim đồng hồ.

sẽ tạo ra sự kiện này:

  • Thuộc tính: HW_ROTARY_INPUT
  • Dấu thời gian: t0
  • int32Values ​​:
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (ba chốt chặn ngược chiều kim đồng hồ).
    3. Hiển thị mục tiêu.
    4. 5 ns giữa lần giam giữ thứ nhất và thứ hai.
    5. 3 ns giữa mức giam giữ thứ hai và thứ ba.

Nút giữa

Khi người dùng nhấn nút Giữa, VHAL nên sử dụng thuộc tính HW_KEY_INPUT với các int32Values ​​sau để gửi sự kiện tới Android:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Hiển thị mục tiêu.

Khi người dùng nhả bộ điều khiển quay, VHAL phải sử dụng cùng thuộc tính và mã khóa với ACTION_UP .

Không tạo ra các sự kiện lặp lại khi nhấn giữ nút Giữa.

Nút quay lại

Khi người dùng nhấn nút Quay lại, VHAL nên sử dụng thuộc tính HW_KEY_INPUT với các int32Values ​​sau để gửi sự kiện tới Android:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Hiển thị mục tiêu.

Khi người dùng nhả bộ điều khiển quay, VHAL phải sử dụng cùng thuộc tính và mã khóa với ACTION_UP .

Không có sự kiện lặp lại nào được tạo ra khi nhấn giữ nút Giữa.

Nút Home

Xử lý nút Home giống như nút Quay lại nhưng bằng KEYCODE_HOME thay vì KEYCODE_BACK .

Các nút khác

Nếu bộ điều khiển quay bao gồm bất kỳ nút bổ sung nào, VHAL có thể xử lý chúng theo cách mà OEM thích vì chúng không được coi là một phần của nút xoay theo quan điểm của Android. Chúng thường được xử lý giống như nút Quay lại và Trang chủ nhưng có các mã khóa khác nhau. Ví dụ: KEYCODE_CALL hoặc KEYCODE_MUSIC .

Xây dựng cấu hình

Điều hướng quay được cung cấp bởi dịch vụ trợ năng có tên RotaryService . Để đưa dịch vụ này vào hình ảnh hệ thống cho thiết bị của bạn, hãy thêm dòng sau vào tệp thực hiện của bạn:

PRODUCT_PACKAGES += CarRotaryController

Bạn cũng có thể muốn đưa các gói sau vào bản dựng gỡ lỗi:

Dịch vụ quay được kích hoạt tự động khi thiết bị khởi động và khi xảy ra chuyển đổi người dùng. Điều này đảm bảo rằng người dùng có thể sử dụng bộ điều khiển quay trong quá trình thiết lập.

Nếu bạn sử dụng cùng một bản dựng cho ô tô có và không có bộ điều khiển quay, hãy thêm CarRotaryController như hiển thị ở trên để đưa mã cần thiết vào bản dựng. Để ngăn kích hoạt dịch vụ quay trên ô tô không quay, hãy tạo RRO tĩnh để phủ tài nguyên chuỗi rotaryService trong packages/services/Car/service bằng một chuỗi trống. Bạn sẽ sử dụng cùng một bản dựng nhưng có cấu hình sản phẩm riêng biệt cho các thiết bị quay và không quay. Chỉ cái sau mới bao gồm lớp phủ.

Tùy chỉnh

OEM có thể tùy chỉnh logic tìm tiêu điểm, đánh dấu tiêu điểm và một số mục bổ sung thông qua lớp phủ tài nguyên ở các vị trí sau:

  • car-ui-library nằm trong packages/apps/Car/libs/car-ui-lib
  • RotaryService nằm trong packages/apps/Car/RotaryController
  • Core nằm trong frameworks/base/core

Di chuyển lịch sử

OEM có thể định cấu hình xem từng loại lịch sử di chuyển có được bật hay không và nếu có thì kích thước bộ đệm và chính sách hết hạn. Tất cả điều này được thực hiện bằng cách ghi đè các tài nguyên thư viện xe hơi khác nhau.

Bộ nhớ đệm lịch sử tiêu điểm

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
Bộ nhớ đệm cho mỗi FocusArea này lưu trữ chế độ xem được lấy nét gần đây nhất trong FocusArea để nó có thể được lấy nét khi quay lại FocusArea . Bạn có thể định cấu hình bộ nhớ đệm này bằng cách xếp chồng các tài nguyên thư viện xe-ui sau:

  • car_ui_focus_history_cache_type :
    1. Bộ nhớ đệm bị vô hiệu hóa.
    2. Bộ nhớ đệm sẽ hết hạn sau một thời gian (xem bên dưới).
    3. Bộ nhớ đệm sẽ không bao giờ hết hạn.
  • car_ui_focus_history_expiration_period_ms Period_ms : Bao nhiêu mili giây trước khi bộ đệm hết hạn nếu loại bộ đệm được đặt thành hai (2) (xem bên trên).

Bộ đệm lịch sử FocusArea

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
Bộ đệm này lưu trữ lịch sử của các lần di chuyển để việc di chuyển theo hướng ngược lại có thể đưa tiêu điểm trở lại cùng một FocusArea . Bạn có thể định cấu hình bộ nhớ đệm này bằng cách xếp chồng các tài nguyên thư viện xe-ui sau:

  • car_ui_focus_area_history_cache_type :
    1. Bộ nhớ đệm bị vô hiệu hóa.
    2. Bộ nhớ đệm sẽ hết hạn sau một thời gian (xem bên dưới).
    3. Bộ nhớ đệm không bao giờ hết hạn.
  • car_ui_focus_area_history_expiration_period_ms Period_ms : Bao nhiêu mili giây trước khi bộ đệm hết hạn nếu loại bộ đệm được đặt thành 2 (xem bên trên).
  • car_ui_clear_focus_area_history_when_rotating : Có xóa bộ đệm khi người dùng xoay bộ điều khiển hay không.

Vòng xoay

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
OEM có thể ghi đè hai tài nguyên số nguyên trong RotaryService để chỉ định xem có khả năng tăng tốc hay không, chẳng hạn như tăng tốc chuột, để xoay:

  • rotation_acceleration_3x_ms : Khoảng thời gian (tính bằng mili giây) dùng để quyết định xem Google có nên tăng tốc độ xoay của bộ điều khiển để tạm dừng xoay hay không. Nếu khoảng cách giữa chốt chặn này và chốt chặn quay trước đó nhỏ hơn giá trị này thì nó sẽ được coi là ba chốt chặn quay. Đặt giá trị này thành 2147483647 để tắt khả năng tăng tốc 3×.
  • rotation_acceleration_2x_ms : Tương tự như rotation_acceleration_3x_ms . Được sử dụng để tăng tốc 2×. Đặt giá trị này thành 2147483647 để tắt khả năng tăng tốc 2×.

Khả năng tăng tốc hoạt động tốt nhất khi có các dấu thời gian riêng cho từng vòng quay, theo yêu cầu của VHAL. Nếu những thứ này không có sẵn, RotaryService giả định rằng các chốt xoay được đặt cách đều nhau.

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

Tiêu điểm nổi bật

OEM có thể ghi đè tiêu điểm nổi bật mặc định trong khung Android và một số tài nguyên nổi bật tiêu điểm trong thư viện xe hơi.

Đánh dấu tiêu điểm mặc định

Khung Android cung cấp tiêu điểm nổi bật mặc định thông qua thuộc tính selectableItemBackground . Trong Theme.DeviceDefault , thuộc tính này đề cập đến item_background.xml trong Core . OEM có thể phủ lên item_background.xml để thay đổi tiêu điểm đánh dấu mặc định có thể vẽ được.

Bản vẽ này thường phải là StateListDrawable , điều chỉnh nền dựa trên các kết hợp trạng thái khác nhau, bao gồm android:state_focusedandroid:state_pressed . Khi người dùng sử dụng bộ điều khiển quay để tập trung vào chế độ xem, android:state_focused sẽ là true , nhưng android:state_pressed sẽ là false . Sau đó, nếu người dùng nhấn nút Giữa trên bộ điều khiển quay, cả android:state_focusedandroid:state_pressed sẽ true khi người dùng giữ nút. Khi người dùng nhả nút, chỉ android:state_focused vẫn còn true .

car-ui-library sử dụng chủ đề bắt nguồn từ Theme.DeviceDefault . Do đó, lớp phủ này ảnh hưởng đến các ứng dụng sử dụng thư viện này và các ứng dụng sử dụng bất kỳ chủ đề nào bắt nguồn từ Theme.DeviceDefault . Nó sẽ không ảnh hưởng đến các ứng dụng sử dụng chủ đề không liên quan, chẳng hạn như Theme.Material .

Tập trung đánh dấu các tài nguyên trong thư viện car-ui

OEM có thể ghi đè một số tài nguyên thư viện xe hơi để kiểm soát cách hiển thị tiêu điểm nổi bật trên các chế độ xem có điểm nổi bật không phải hình chữ nhật (chẳng hạn như hình tròn hoặc hình viên thuốc) và trong các ứng dụng sử dụng chủ đề không bắt nguồn từ Theme.DeviceDefault . Các tài nguyên này phải được phủ lên sao cho điểm đánh dấu tiêu điểm nhất quán với điểm đánh dấu tiêu điểm mặc định có thể vẽ được.

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
Các tài nguyên sau được sử dụng để cho biết khi nào một chế độ xem được tập trung nhưng không được nhấn:

  • car_ui_rotary_focus_fill_color : Tô màu.
  • car_ui_rotary_focus_stroke_color : Màu đường viền.
  • car_ui_rotary_focus_stroke_width : Độ dày của đường viền.

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
Các tài nguyên sau đây được sử dụng để cho biết khi nào một chế độ xem được tập trung nhấn:

  • car_ui_rotary_focus_pressed_fill_color : Tô màu.
  • car_ui_rotary_focus_pressed_stroke_color : Màu đường viền.
  • car_ui_rotary_focus_pressed_stroke_width : Độ dày của đường viền.

Đôi khi một nút được cung cấp một màu nền đồng nhất để thu hút sự chú ý của người dùng, như trong ví dụ được hiển thị. Điều này có thể làm cho điểm nổi bật khó nhìn thấy.

Nút có nền vững chắc
Hình 2. Nút có nền đồng màu

Trong trường hợp này, nhà phát triển có thể chỉ định điểm đánh dấu tiêu điểm tùy chỉnh bằng cách sử dụng màu phụ :
  • ( Android 11 QPR3, Android 11 Ô tô, 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

Bất kỳ màu nào cũng có thể trong suốt và một trong hai kích thước có thể bằng 0 nếu, chẳng hạn, bạn chỉ muốn tô màu hoặc chỉ muốn đường viền.

Điểm nổi bật của FocusArea

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
FocusArea có thể vẽ hai loại vùng sáng khi một trong các vùng con của nó được lấy nét. Cả hai có thể được sử dụng kết hợp, nếu muốn. Tính năng này bị tắt theo mặc định trong AOSP, nhưng có thể được bật bằng cách ghi đè tài nguyên thư viện xe hơi:

  • car_ui_enable_focus_area_foreground_highlight : Vẽ điểm nổi bật lên trên FocusArea và các thành phần con của nó. Trong AOSP, đối tượng có thể vẽ này là một đường viền xung quanh FocusArea . OEM có thể ghi đè car_ui_focus_area_foreground_highlight có thể vẽ được.
  • car_ui_enable_focus_area_background_highlight : Vẽ điểm nổi bật phía trên FocusArea nhưng phía sau các phần tử con của nó. Trong AOSP, đối tượng có thể vẽ này là một khối điền chắc chắn. OEM có thể ghi đè có thể vẽ car_ui_focus_area_background_highlight .

Trình chỉnh sửa phương thức nhập liệu

Trình chỉnh sửa phương thức nhập (IME) là các phương thức nhập. Ví dụ: bàn phím trên màn hình.

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
OEM phải phủ tài nguyên chuỗi default_touch_input_method trong RotaryService để chỉ định ComponentName của IME dựa trên cảm ứng. Ví dụ: nếu OEM sử dụng IME được cung cấp cùng với Android Automotive thì họ phải chỉ định com.google.android.apps.automotive.inputmethod/.InputMethodService .

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
Nếu OEM đã tạo IME dành riêng cho quay, thì họ phải chỉ định ComponentName của nó trong tài nguyên rotary_input_method . Nếu tài nguyên này được phủ lên thì IME đã chỉ định sẽ được sử dụng bất cứ khi nào người dùng tương tác với bộ phận chính thông qua nút di chuyển, xoay và nút Giữa của bộ điều khiển quay. Khi người dùng chạm vào màn hình, IME trước đó sẽ được sử dụng. Nút Quay lại (và các nút khác trên bộ điều khiển quay) không có tác dụng đối với việc chọn IME. Nếu tài nguyên này không được phủ thì sẽ không có chuyển đổi IME nào xảy ra. Carboard không hỗ trợ quay nên người dùng không thể nhập văn bản thông qua bộ điều khiển quay nếu OEM chưa cung cấp IME quay.

RotaryIME là một IME quay demo. Mặc dù cơ bản nhưng việc thử chuyển đổi IME tự động được mô tả ở trên là đủ. Mã nguồn của RotaryIME có thể được tìm thấy trong packages/apps/Car/tests/RotaryIME/ .

Cú huých ngoài màn hình

Theo mặc định, khi người dùng cố gắng di chuyển mép màn hình thì không có gì xảy ra. OEM có thể định cấu hình những gì sẽ xảy ra cho từng hướng trong số bốn hướng bằng cách chỉ định bất kỳ sự kết hợp nào của:

  1. Một hành động chung được xác định bởi AccessibilityService . Ví dụ: GLOBAL_ACTION_BACK .
  2. Mã khóa, chẳng hạn như KEYCODE_BACK .
  3. Ý định khởi chạy một hoạt động được biểu thị dưới dạng URL.

( Android 11 QPR3, Android 11 Ô tô, Android 12 )
Chúng được chỉ định bằng cách xếp chồng các tài nguyên mảng sau trong RotaryService :

  • off_screen_nudge_global_actions : Mảng hành động chung sẽ thực hiện khi người dùng di chuyển lên, xuống, sang trái hoặc sang phải khỏi mép màn hình. Không có hành động chung nào được thực hiện nếu phần tử liên quan của mảng này là -1.
  • off_screen_nudge_key_codes : Mảng mã khóa của các sự kiện nhấp chuột sẽ được đưa vào khi người dùng di chuyển lên, xuống, sang trái hoặc sang phải khỏi mép màn hình. Không có sự kiện nào được đưa vào nếu phần tử liên quan của mảng này là 0 ( KEYCODE_UNKNOWN ).
  • off_screen_nudge_intents : Mảng ý định khởi chạy một hoạt động khi người dùng di chuyển lên, xuống, sang trái hoặc sang phải khỏi mép màn hình. Không có hoạt động nào được khởi chạy nếu phần tử liên quan của mảng này trống.

Các cấu hình khác

Bạn nên chồng các tài nguyên RotaryService sau:

  • ( Android 11 QPR3, Android 11 Ô tô, Android 12 )
    config_showHeadsUpNotificationOnBottom : Giá trị Boolean để biểu thị liệu thông báo quan trọng có được hiển thị ở phía dưới thay vì phía trên hay không. Giá trị này phải có cùng giá trị với tài nguyên Boolean config_showHeadsUpNotificationOnBottom trong frameworks/base/packages/CarSystemUI/res/values/config.xml
  • ( Android 11 QPR3, Android 11 Ô tô, Android 12 )
    notification_headsup_card_margin_horizontal : Lề trái và phải cho cửa sổ thông báo cảnh báo. Giá trị này phải có cùng giá trị với tài nguyên thứ nguyên notification_headsup_card_margin_horizontal trong packages/apps/Car/Notification/res/values/dimens.xml
  • ( Android 12 )
    excluded_application_overlay_window_titles : Một mảng tiêu đề của các cửa sổ không được coi là cửa sổ lớp phủ. Điều này phải bao gồm tiêu đề của cửa sổ ứng dụng đại diện cho TaskViews hoặc TaskDisplayAreas . Theo mặc định, danh sách này chỉ chứa "Bản đồ".

Bạn có thể phủ lên tài nguyên RotaryService sau:

  • ( Android 11 QPR3, Android 11 Ô tô, Android 12 )
    long_press_ms : Giá trị số nguyên biểu thị số mili giây mà nút Giữa phải được giữ để kích hoạt thao tác nhấn và giữ. Số 0 cho biết nên sử dụng thời gian chờ nhấn và giữ mặc định của hệ thống. Đây là giá trị mặc định.