На этой странице описано, как обрабатывать ввод с поворотного регулятора в VHAL, как настроить сборку для включения службы поворотного регулятора и как настроить работу поворотного регулятора во всех приложениях. Информацию о предустановленных OEM-приложениях, таких как предоставленный OEM-лаунчер, см. в разделе «Библиотека пользовательского интерфейса автомобилей» (car-ui-library) .
ВХАЛ
Поворотный регулятор поддерживает следующие действия:
- Подталкивайте вверх, вниз, влево и вправо.
- Вращайте по часовой стрелке и против часовой стрелки.
- Нажмите кнопку «Центр».
- Нажмите кнопку «Назад».
- Нажмите кнопку «Домой».
- Нажмите и другие кнопки, например, «Телефон» и «Медиа».
Документацию по системным свойствам и соответствующим int32Values см. в файле hardware/interfaces/automotive/vehicle/2.0/types.hal .
Система 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 может обрабатывать их так, как пожелает производитель, поскольку с точки зрения Android они не считаются частью поворотного контроллера. Обычно они обрабатываются так же, как кнопки «Назад» и «Домой», но с другими кодами клавиш. Например, KEYCODE_CALL или KEYCODE_MUSIC .
Конфигурация сборки
Роторная навигация обеспечивается службой специальных возможностей под названием RotaryService . Чтобы включить эту службу в образ системы вашего устройства, добавьте следующую строку в ваш makefile:
PRODUCT_PACKAGES += CarRotaryController
В отладочные сборки также могут быть включены следующие пакеты:
-
RotaryPlaygroundсправочное приложение для роторной электроники (см. RotaryPlayground ). -
RotaryIMEдемонстрационная версия RotaryIME (см. Редакторы методов ввода ). -
CarRotaryImeRROнакладка дляRotaryIME.
Функция поворотного регулятора включается автоматически при загрузке устройства и при переключении пользователем. Это гарантирует, что пользователь сможет использовать поворотный регулятор во время настройки.
Если вы используете одну и ту же сборку для автомобилей с поворотным контроллером и без него, добавьте CarRotaryController как показано выше, чтобы необходимый код был включен в сборку. Чтобы предотвратить включение службы поворотного контроллера на автомобилях без поворотного контроллера, создайте статический RRO, который заменит строковый ресурс rotaryService в packages/services/Car/service пустой строкой. Вы будете использовать одну и ту же сборку, но с отдельными конфигурациями продукта для устройств с поворотным и без поворотного контроллера. Только для последних будет включена замена.
Настройка
Производители оборудования могут настраивать логику поиска фокуса, подсветку фокуса и некоторые дополнительные элементы с помощью наложений ресурсов в следующих местах:
- Библиотека car-ui-library находится в
packages/apps/Car/libs/car-ui-lib -
RotaryServiceнаходится вpackages/apps/Car/RotaryController -
Coreнаходится вframeworks/base/core
История подталкивания
Производитель оборудования может настроить, включен ли каждый из двух типов истории подсказок, и если да, то размер кэша и политику истечения срока его действия. Все это делается путем переопределения различных ресурсов car-ui-library.
кэш истории фокусировки
( Android 11 QPR3, Android 11 Car, 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 Car, Android 12 )
Этот кэш хранит историю перемещений, чтобы перемещение в противоположном направлении могло вернуть фокус в ту же FocusArea . Этот кэш можно настроить, наложив следующие ресурсы car-ui-library:
-
car_ui_focus_area_history_cache_type:- Кэширование отключено.
- Кэш сгорает через некоторое время (см. ниже).
- Срок действия кэша никогда не истекает.
-
car_ui_focus_area_history_expiration_period_ms: За сколько миллисекунд истекает срок действия кэша, если для типа кэша установлено значение 2 (см. выше). -
car_ui_clear_focus_area_history_when_rotating: Следует ли очищать кэш при повороте контроллера пользователем.
Вращение
( Android 11 QPR3, Android 11 Car, Android 12 )
Производитель оборудования может переопределить два целочисленных ресурса в RotaryService , чтобы указать, требуется ли ускорение вращения, например, ускорение мыши:
-
rotation_acceleration_3x_ms: Временной интервал (в миллисекундах), используемый для определения того, следует ли Google ускорять вращение контроллера на один оборот. Если интервал между этим оборотом и предыдущим оборотом меньше этого значения, он будет рассматриваться как три оборота. Установите значение 2147483647, чтобы отключить 3-кратное ускорение. -
rotation_acceleration_2x_ms: Аналогичноrotation_acceleration_3x_ms. Используется для двукратного ускорения. Установите значение2147483647, чтобы отключить двукратное ускорение.
Наилучшая работа ускорения достигается при наличии отдельных временных меток для каждого положения фиксатора вращения, как того требует 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),
Выделение фокуса
Производитель оборудования может переопределить подсветку фокуса по умолчанию в фреймворке Android, а также несколько ресурсов подсветки фокуса в car-ui-library.
Подсветка по умолчанию
В Android-фреймворке подсветка фокуса по умолчанию обеспечивается атрибутом selectableItemBackground . В Theme.DeviceDefault этот атрибут ссылается на item_background.xml в Core . Производитель оборудования может наложить 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
Производитель оборудования может переопределить несколько ресурсов car-ui-library, чтобы управлять внешним видом подсветки фокуса на элементах интерфейса с непрямоугольной (например, круглой или в форме таблетки) формой подсветки, а также в приложениях, использующих тему, не наследующуюся от Theme.DeviceDefault . Эти ресурсы следует перекрывать таким образом, чтобы подсветка фокуса соответствовала стандартному изображению подсветки фокуса .
( Android 11 QPR3, Android 11 Car, 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 Car, 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 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
Любой из цветов может быть прозрачным, а любой из параметров может быть равен нулю, если, например, вам нужна только заливка или только контур.
Выделение фокусной области
( Android 11 QPR3, Android 11 Car, Android 12 )
FocusArea может отображать два типа подсветки, когда один из его потомков находится в фокусе. При желании оба типа можно использовать совместно. Эта функция по умолчанию отключена в AOSP, но её можно включить, переопределив ресурсы car-ui-library:
-
car_ui_enable_focus_area_foreground_highlight: Рисует подсветку поверхFocusAreaи её потомков. В AOSP этот ресурс представляет собой контур вокругFocusArea. Производители оборудования могут переопределить ресурсcar_ui_focus_area_foreground_highlight. -
car_ui_enable_focus_area_background_highlight: Рисует подсветку поверхFocusArea, но позади её потомков. В AOSP этот ресурс представляет собой сплошную заливку. Производители оборудования могут переопределить ресурсcar_ui_focus_area_background_highlight.
Редакторы методов ввода
Редакторы методов ввода (IME) — это методы ввода. Например, экранная клавиатура.
( Android 11 QPR3, Android 11 Car, Android 12 )
Производитель оборудования должен переопределить строковый ресурс default_touch_input_method в RotaryService , чтобы указать ComponentName интерфейса ввода с сенсорного экрана. Например, если производитель использует интерфейс ввода, предоставляемый Android Automotive, он должен указать com.google.android.apps.automotive.inputmethod/.InputMethodService .
( Android 11 QPR3, Android 11 Car, Android 12 )
Если производитель создал IME специально для поворотного регулятора, ему следует указать его ComponentName в ресурсе rotary_input_method . Если этот ресурс перекрывает другой ресурс, указанный IME будет использоваться всякий раз, когда пользователь взаимодействует с головным устройством с помощью кнопок «сдвиг», «вращение» и «Центрирование» на поворотном регуляторе. При касании экрана будет использоваться предыдущий IME. Кнопка «Назад» (и другие кнопки на поворотном регуляторе) не влияют на выбор IME. Если этот ресурс не перекрывает другой ресурс, переключение IME не происходит. Carboard не поддерживает поворотный регулятор, поэтому пользователь не может вводить текст через поворотный регулятор, если производитель не предоставил IME для поворотного регулятора.
RotaryIME — это демонстрационная версия роторного IME. Несмотря на свою простоту, она достаточна для тестирования автоматического переключения IME, описанного выше. Исходный код RotaryIME можно найти в packages/apps/Car/tests/RotaryIME/ .
Подсказки за кадром
По умолчанию, когда пользователь пытается сдвинуть устройство за край экрана, ничего не происходит. Производитель оборудования может настроить действия для каждого из четырех направлений, указав любую комбинацию следующих параметров:
- Глобальное действие, определяемое классом
AccessibilityService. Например,GLOBAL_ACTION_BACK. - Код ключа, например,
KEYCODE_BACK. - Намерение запустить действие, представленное в виде URL-адреса.
( Android 11 QPR3, Android 11 Car, 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 Car, Android 12 )
config_showHeadsUpNotificationOnBottom: Логическое значение, указывающее, следует ли отображать всплывающие уведомления внизу или вверху. Это значение должно совпадать со значением логического ресурсаconfig_showHeadsUpNotificationOnBottomвframeworks/base/packages/CarSystemUI/res/values/config.xml - ( Android 11 QPR3, Android 11 Car, Android 12 )
notification_headsup_card_margin_horizontal: Левый и правый отступы для окна всплывающего уведомления. Это значение должно совпадать со значением ресурса dimensnotification_headsup_card_margin_horizontalвpackages/apps/Car/Notification/res/values/dimens.xml - ( Android 12 )
excluded_application_overlay_window_titles: Массив заголовков окон, которые не следует считать окнами наложения. Сюда должны входить заголовки окон приложений, представляющихTaskViewsилиTaskDisplayAreas. По умолчанию этот список содержит только "Карты".
Вы можете наложить следующий ресурс RotaryService :
- ( Android 11 QPR3, Android 11 Car, Android 12 )
long_press_ms: Целочисленное значение, указывающее, сколько миллисекунд необходимо удерживать кнопку Center для выполнения длительного нажатия. Ноль означает, что следует использовать стандартное системное время ожидания длительного нажатия. Это значение по умолчанию.