На этой странице описывается, как обрабатывать поворотные входы в VHAL, настраивать сборку для включения службы поворотного управления и как настроить работу поворотного устройства во всех приложениях. Информацию о предустановленных OEM-приложениях, таких как средства запуска OEM, см. в разделе Библиотека автомобильного пользовательского интерфейса (car-ui-library) .
ВХАЛ
Поворотный контроллер поддерживает следующие действия:
- Подталкивайте вверх, вниз, влево и вправо.
- Вращайте по часовой стрелке и против часовой стрелки.
- Нажмите центральную кнопку.
- Нажмите кнопку «Назад».
- Нажмите кнопку «Домой».
- Нажмите другие кнопки, такие как «Телефон» и «Медиа».
См. hardware/interfaces/automotive/vehicle/2.0/types.hal
для получения документации по свойствам системы и соответствующим int32Values
.
VHAL должен обрабатывать следующие действия:
Подтолкнуть
Когда пользователь нажимает поворотный контроллер вправо, VHAL должен использовать свойство HW_KEY_INPUT
со следующими int32Values
для отправки события в Android:
-
ACTION_DOWN
-
KEYCODE_SYSTEM_NAVIGATION_RIGHT
- Целевой дисплей.
Когда пользователь отпускает поворотный контроллер, VHAL должен использовать то же свойство и код клавиши, что и ACTION_UP
. Для подталкивания в других направлениях следует использовать соответствующие коды клавиш.
Кодов клавиш для диагоналей нет, но VHAL может комбинировать горизонтальное и вертикальное событие для создания диагонали, если оборудование поддерживает диагонали. Например, подталкивание вверх и влево должно привести к следующему:
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
В любом порядке (и впоследствии) отпускание поворотного контроллера должно привести к:
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
Пользователь может нажать поворотный контроллер в перпендикулярном направлении, прежде чем отпустить его. Например, следующий сценарий:
Это должно сгенерировать следующую последовательность событий:
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
-
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
Никакие повторяющиеся события не должны генерироваться, пока поворотный контроллер удерживается в одном направлении.
Поворот
Когда пользователь поворачивает поворотный контроллер по часовой стрелке на один фиксатор (щелчок), VHAL должен использовать свойство HW_ROTARY_INPUT
со следующими int32Values
для отправки события в Android:
-
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- Один (1) фиксатор.
- Целевой дисплей.
Временная метка события должна быть установлена на прошедшее время в наносекундах.
Поворот на один (1) фиксатор против часовой стрелки должен вызвать то же событие, но с -1 для количества фиксаторов.
Если несколько фиксаций вращения в одном направлении происходят в быстрой последовательности, VHAL должен объединить фиксации в одно событие, чтобы не перегружать систему событиями. В этом случае временная метка события должна указывать на момент первой фиксации вращения. int32Values
должно включать количество наносекунд между последовательными остановками вращения.
Например, следующая последовательность вращений:
- В момент времени t0 пользователь повернул один фиксатор против часовой стрелки.
- В момент времени t0 + 5 нс пользователь повернул один фиксатор против часовой стрелки.
- В момент времени t0 + 8 нс пользователь повернул один фиксатор против часовой стрелки.
должен сгенерировать это событие:
- Свойство:
HW_ROTARY_INPUT
- Временная метка:
t0
-
int32Values
:-
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- -3 (три фиксации против часовой стрелки).
- Целевой дисплей.
- 5 нс между первой и второй фиксацией.
- 3 нс между второй и третьей фиксацией.
-
Центральная кнопка
Когда пользователь нажимает центральную кнопку, VHAL должен использовать свойство HW_KEY_INPUT
со следующими int32Values
для отправки события в Android:
-
ACTION_DOWN
-
KEYCODE_DPAD_CENTER
- Целевой дисплей.
Когда пользователь отпускает поворотный контроллер, VHAL должен использовать то же свойство и код клавиши, что и ACTION_UP
.
Не создавайте повторяющиеся события, когда центральная кнопка удерживается нажатой.
Кнопка «Назад»
Когда пользователь нажимает кнопку «Назад», VHAL должен использовать свойство HW_KEY_INPUT
со следующими int32Values
для отправки события в Android:
-
ACTION_DOWN
-
KEYCODE_BACK
- Целевой дисплей.
Когда пользователь отпускает поворотный контроллер, VHAL должен использовать то же свойство и код клавиши, что и ACTION_UP
.
Пока центральная кнопка удерживается нажатой, повторяющиеся события не должны генерироваться.
Кнопка «Домой»
Обращайтесь с кнопкой «Домой» так же, как с кнопкой «Назад», но с помощью KEYCODE_HOME
вместо KEYCODE_BACK
.
Другие кнопки
Если поворотный контроллер включает в себя какие-либо дополнительные кнопки, VHAL может управлять ими так, как нравится OEM-производителю, поскольку они не считаются частью поворотного контроллера с точки зрения Android. Обычно они обрабатываются так же, как кнопки «Назад» и «Домой», но с разными кодами клавиш. Например, KEYCODE_CALL
или KEYCODE_MUSIC
.
Конфигурация сборки
Вращающаяся навигация обеспечивается службой доступности под названием RotaryService
. Чтобы включить эту службу в образ системы вашего устройства, добавьте в свой make-файл следующую строку:
PRODUCT_PACKAGES += CarRotaryController
Вы также можете включить в отладочные сборки следующие пакеты:
-
RotaryPlayground
Справочное приложение для роторных игр (см. RotaryPlayground ). -
RotaryIME
Демонстрационный ротационный IME (см. Редакторы методов ввода ). -
CarRotaryImeRRO
Наложение дляRotaryIME
.
Служба ротации включается автоматически при загрузке устройства и при переключении пользователя. Это гарантирует, что пользователь сможет использовать поворотный контроллер во время настройки.
Если вы используете одну и ту же сборку для автомобилей с поворотным контроллером и без него, добавьте CarRotaryController
как показано выше, чтобы в сборку был включен необходимый код. Чтобы предотвратить включение ротационной службы на невращающихся автомобилях, создайте статический RRO, чтобы наложить строковый ресурс rotaryService
в packages/services/Car/service
на пустую строку. Вы будете использовать одну и ту же сборку, но иметь разные конфигурации продукта для вращающихся и неповоротных устройств. Только последний включает наложение.
Кастомизация
OEM-производители могут настраивать логику поиска фокуса, выделение фокуса и некоторые дополнительные элементы с помощью наложений ресурсов в следующих местах:
- car-ui-library находится в
packages/apps/Car/libs/car-ui-lib
-
RotaryService
находится вpackages/apps/Car/RotaryController
-
Core
находится вframeworks/base/core
История подталкивания
OEM-производитель может настроить, включен ли каждый из двух типов истории подталкивания, и, если да, размер кэша и политику срока действия. Все это делается путем переопределения различных ресурсов car-ui-library.
Кэш истории фокуса
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
В этом кэше для каждой области FocusArea
сохраняется последнее сфокусированное представление в пределах FocusArea
, чтобы его можно было сфокусировать при возврате к FocusArea
. Этот кеш можно настроить путем наложения следующих ресурсов car-ui-library:
-
car_ui_focus_history_cache_type
:- Кэш отключен.
- Срок действия кэша истечет через некоторое время (см. ниже).
- Кэш никогда не истечет.
-
car_ui_focus_history_expiration_period_ms
: сколько миллисекунд до истечения срока действия кеша, если для типа кеша установлено значение два (2) (см. выше).
Кэш истории FocusArea
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
Этот кеш хранит историю перемещений, так что перемещение в противоположном направлении может вернуть фокус в ту же самую FocusArea
. Этот кеш можно настроить путем наложения следующих ресурсов car-ui-library:
-
car_ui_focus_area_history_cache_type
:- Кэш отключен.
- Срок действия кэша истекает через некоторое время (см. ниже).
- Срок действия кэша никогда не истекает.
-
car_ui_focus_area_history_expiration_period_ms
period_ms : сколько миллисекунд до истечения срока действия кеша, если для типа кеша установлено значение 2 (см. выше). -
car_ui_clear_focus_area_history_when_rotating
: очищать ли кэш, когда пользователь поворачивает контроллер.
Вращение
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
OEM-производитель может переопределить два целочисленных ресурса в RotaryService
, чтобы указать, существует ли ускорение, например ускорение мыши, для вращения:
-
rotation_acceleration_3x_ms
: интервал времени (в миллисекундах), используемый для принятия решения, должен ли Google ускорить вращение контроллера для фиксации вращения. Если интервал между этой фиксацией и предыдущей фиксацией вращения меньше этого значения, он будет рассматриваться как три фиксации вращения. Установите значение 2147483647, чтобы отключить 3-кратное ускорение. -
rotation_acceleration_2x_ms
: аналогичноrotation_acceleration_3x_ms
. Используется для 2-кратного ускорения. Установите значение2147483647
чтобы отключить ускорение в 2 раза.
Ускорение работает лучше всего, когда для каждого фиксатора вращения имеются отдельные временные метки, как того требует VHAL. Если они недоступны, RotaryService
предполагает, что фиксаторы вращения расположены равномерно.
/** * 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),
Выделение фокуса
OEM-производитель может переопределить выделение фокуса по умолчанию в платформе Android и несколько ресурсов выделения фокуса в car-ui-library.
Выделение фокуса по умолчанию
Платформа Android обеспечивает выделение фокуса по умолчанию с помощью атрибута selectableItemBackground
. В Theme.DeviceDefault
этот атрибут ссылается на item_background.xml
в Core
. OEM-производитель может наложить item_background.xml
, чтобы изменить возможность выделения фокуса по умолчанию.
Этот объект рисования обычно должен быть StateListDrawable
, который настраивает фон на основе различных комбинаций состояний, включая android:state_focused
и android:state_pressed
. Когда пользователь использует поворотный контроллер для фокусировки представления, android:state_focused
будет иметь true
, а android:state_pressed
— false
. Если затем пользователь нажмет центральную кнопку на поворотном контроллере, значения android:state_focused
и android:state_pressed
будут true
, пока пользователь удерживает кнопку нажатой. Когда пользователь отпускает кнопку, только android:state_focused
останется true
.
car-ui-library использует тему, полученную из Theme.DeviceDefault
. В результате это наложение влияет на приложения, использующие эту библиотеку, и приложения, использующие любую тему, производную от Theme.DeviceDefault
. Это не повлияет на приложения, использующие несвязанную тему, например Theme.Material
.
Сосредоточьтесь на выделенных ресурсах в библиотеке car-ui-library
OEM-производитель может переопределить несколько ресурсов car-ui-library, чтобы контролировать, как выглядит выделение фокуса на представлениях с непрямоугольным (например, круглым или в форме таблетки) выделением фокуса, а также в приложениях, использующих тему, не являющуюся производной от Theme.DeviceDefault
. Theme.DeviceDefault
. Эти ресурсы должны быть перекрыты, чтобы выделение фокуса соответствовало рисуемому выделению фокуса по умолчанию .
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
Следующие ресурсы используются для указания того, когда представление находится в фокусе, но не нажимается:
-
car_ui_rotary_focus_fill_color
: цвет заливки. -
car_ui_rotary_focus_stroke_color
: Цвет контура. -
car_ui_rotary_focus_stroke_width
: Толщина контура.
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
Следующие ресурсы используются для указания того, когда представление сфокусировано и нажато:
-
car_ui_rotary_focus_pressed_fill_color
: Цвет заливки. -
car_ui_rotary_focus_pressed_stroke_color
: Цвет контура. -
car_ui_rotary_focus_pressed_stroke_width
: Толщина контура.
Иногда кнопке присваивается сплошной цвет фона, чтобы привлечь к ней внимание пользователя, как в показанном примере. Из-за этого область фокусировки может быть трудно различима.
В этой ситуации разработчик может указать собственное выделение фокуса, используя дополнительные цвета:- ( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
car_ui_rotary_focus_fill_secondary_color
car_ui_rotary_focus_stroke_secondary_color
- ( Андроид 12 )
car_ui_rotary_focus_pressed_fill_secondary_color
car_ui_rotary_focus_pressed_stroke_secondary_color
Любой из цветов может быть прозрачным, а любой размер может быть нулевым, если, например, вам нужна только заливка или только контур.
Выделение FocusArea
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
FocusArea
может рисовать два типа подсветки, когда один из ее потомков находится в фокусе. При желании оба можно использовать вместе. Эта функция по умолчанию отключена в AOSP, но ее можно включить, переопределив ресурсы car-ui-library:
-
car_ui_enable_focus_area_foreground_highlight
: нарисуйте подсветку поверхFocusArea
и ее потомков. В AOSP этот объект рисования представляет собой контур вокругFocusArea
. OEM-производители могут переопределить элементcar_ui_focus_area_foreground_highlight
. -
car_ui_enable_focus_area_background_highlight
: нарисуйте подсветку поверхFocusArea
, но позади ее потомков. В AOSP этот объект представляет собой сплошную заливку. OEM-производители могут переопределить элементcar_ui_focus_area_background_highlight
.
Редакторы методов ввода
Редакторы методов ввода (IME) — это методы ввода. Например, экранная клавиатура.
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
OEM-производитель должен наложить строковый ресурс default_touch_input_method
в RotaryService
, чтобы указать ComponentName
сенсорного IME. Например, если OEM-производитель использует IME, предоставляемый Android Automotive, ему следует указать com.google.android.apps.automotive.inputmethod/.InputMethodService
.
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
Если OEM-производитель создал IME специально для роторного метода, ему следует указать его ComponentName
в ресурсе rotary_input_method
. Если этот ресурс перекрыт, указанный IME используется всякий раз, когда пользователь взаимодействует с головным устройством посредством перемещения, поворота и центральной кнопки поворотного контроллера. Когда пользователь касается экрана, будет использоваться предыдущий IME. Кнопка «Назад» (и другие кнопки на поворотном контроллере) не влияют на выбор IME. Если этот ресурс не перекрыт, переключение IME не происходит. Carboard не поддерживает поворотный контроллер, поэтому пользователь не может вводить текст с помощью поворотного контроллера, если OEM не предоставил поворотный IME.
RotaryIME
— это демонстрационный ротационный IME. Хотя это и просто, достаточно попробовать автоматическое переключение IME, описанное выше. Исходный код RotaryIME
можно найти в packages/apps/Car/tests/RotaryIME/
.
Подталкивания за кадром
По умолчанию, когда пользователь пытается отодвинуть край экрана, ничего не происходит. OEM-производитель может настроить то, что должно происходить для каждого из четырех направлений, указав любую комбинацию:
- Глобальное действие, определенное
AccessibilityService
. Например,GLOBAL_ACTION_BACK
. - Код ключа, например
KEYCODE_BACK
. - Намерение запустить действие, представленное в виде URL-адреса.
( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
Они определяются путем наложения следующих ресурсов массива в RotaryService
:
-
off_screen_nudge_global_actions
: массив глобальных действий, которые выполняются, когда пользователь сдвигает вверх, вниз, влево или вправо от края экрана. Никакое глобальное действие не выполняется, если соответствующий элемент этого массива равен -1. -
off_screen_nudge_key_codes
: Массив кодов клавиш событий щелчка, которые вводятся, когда пользователь смещает вверх, вниз, влево или вправо от края экрана. Никакие события не вводятся, если соответствующий элемент этого массива равен 0 (KEYCODE_UNKNOWN
). -
off_screen_nudge_intents
: массив намерений для запуска действия, когда пользователь сдвигает вверх, вниз, влево или вправо от края экрана. Никакая активность не запускается, если соответствующий элемент этого массива пуст.
Другие конфигурации
Вам следует наложить следующие ресурсы RotaryService
:
- ( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
config_showHeadsUpNotificationOnBottom
: логическое значение, указывающее, должны ли хедз-ап-уведомления отображаться внизу, а не вверху. Оно должно иметь то же значение, что и логический ресурсconfig_showHeadsUpNotificationOnBottom
вframeworks/base/packages/CarSystemUI/res/values/config.xml
- ( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
notification_headsup_card_margin_horizontal
: левое и правое поле для окна хедз-ап уведомлений. Оно должно иметь то же значение, что и ресурс измеренияnotification_headsup_card_margin_horizontal
вpackages/apps/Car/Notification/res/values/dimens.xml
- ( Андроид 12 )
excluded_application_overlay_window_titles
: Массив заголовков окон, которые не следует считать наложенными окнами. Сюда должны входить заголовки окон приложений, которые представляютTaskViews
илиTaskDisplayAreas
. По умолчанию этот список содержит только «Карты».
Вы можете наложить следующий ресурс RotaryService
:
- ( Android 11 QPR3, Android 11 для автомобилей, Android 12 )
long_press_ms
: целочисленное значение, обозначающее, сколько миллисекунд необходимо удерживать центральную кнопку, чтобы вызвать длительное нажатие. Ноль указывает на то, что следует использовать системный таймаут по умолчанию при длительном нажатии. Это значение по умолчанию.