Руководство по интеграции для OEM-производителей

В этой статье описывается, как обрабатывать поворотные входные данные в VHAL, настраивать сборку для включения службы поворота и как настраивать работу с поворотом во всех приложениях. Информацию о предустановленных OEM-приложениях, таких как OEM-программа запуска, см. в разделе Car UI Library (car-ui-library) .

ВХАЛ

Поворотный контроллер поддерживает следующие действия:

  • Подталкивайте вверх, вниз, влево и вправо.
  • Вращайте по часовой стрелке и против часовой стрелки.
  • Нажмите центральную кнопку.
  • Нажмите кнопку «Назад».
  • Нажмите кнопку «Домой».
  • Нажмите другие кнопки, такие как «Телефон» и «Медиа».

См. hardware/interfaces/automotive/vehicle/2.0/types.hal для получения документации по системным свойствам и соответствующим int32Values ​​.

VHAL должен обрабатывать следующие действия:

Подтолкнуть

Когда пользователь нажимает поворотный контроллер вправо, VHAL должен использовать свойство HW_KEY_INPUT со следующими int32Values ​​для отправки события в Android:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Целевое отображение.

Когда пользователь отпускает поворотный контроллер, 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

Пользователь может нажать поворотный контроллер в перпендикулярном направлении, прежде чем отпустить его. Например, следующий сценарий:

Перпендикулярное направление
Рисунок 1. Перпендикулярное направление

Это должно генерировать следующую последовательность событий:

  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

Повторяющиеся события не должны генерироваться, пока поворотный регулятор удерживается в одном направлении.

Повернуть

Когда пользователь поворачивает поворотный контроллер по часовой стрелке на один фиксатор (щелчок), VHAL должен использовать свойство HW_ROTARY_INPUT со следующими int32Values ​​для отправки события в Android:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Один (1) фиксатор.
  3. Целевое отображение.

Отметка времени события должна быть установлена ​​на прошедшее время в наносекундах.

Одно (1) вращение против часовой стрелки должно генерировать то же самое событие, но с -1 для числа остановок.

Если несколько остановок вращения в одном и том же направлении происходят в быстрой последовательности, VHAL должен объединять фиксации в одно событие, чтобы не перегружать систему событиями. В этом случае временная метка события должна быть, когда произошла первая остановка вращения. int32Values ​​должен включать количество наносекунд между последовательными задержками вращения.

Например, следующая последовательность вращений:

  • В момент времени t0 пользователь повернул один фиксатор против часовой стрелки.
  • В момент времени t0 + 5 нс пользователь повернул один фиксатор против часовой стрелки.
  • В момент времени t0 + 8 нс пользователь повернул один фиксатор против часовой стрелки.

должно генерировать это событие:

  • Свойство: HW_ROTARY_INPUT
  • Отметка времени: t0
  • int32Values :
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (три фиксатора против часовой стрелки).
    3. Целевое отображение.
    4. 5 нс между первой и второй фиксацией.
    5. 3 нс между второй и третьей фиксацией.

Центральная кнопка

Когда пользователь нажимает центральную кнопку, VHAL должен использовать свойство HW_KEY_INPUT со следующими int32Values ​​для отправки события на Android:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Целевое отображение.

Когда пользователь отпускает поворотный контроллер, VHAL должен использовать то же свойство и код клавиши, что и ACTION_UP .

Не генерируйте повторяющиеся события, когда центральная кнопка удерживается нажатой.

Кнопка назад

Когда пользователь нажимает кнопку «Назад», VHAL должен использовать свойство HW_KEY_INPUT со следующими int32Values ​​для отправки события на Android:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Целевое отображение.

Когда пользователь отпускает поворотный контроллер, VHAL должен использовать то же свойство и код клавиши, что и ACTION_UP .

Повторные события не должны генерироваться, пока нажата центральная кнопка.

Домашняя кнопка

Обрабатывайте кнопку «Домой» так же, как кнопку «Назад», но с KEYCODE_HOME вместо KEYCODE_BACK .

Другие кнопки

Если на поворотном контроллере есть какие-либо дополнительные кнопки, VHAL может обрабатывать их, как того хочет OEM-производитель, поскольку с точки зрения Android они не считаются частью поворотного устройства. Обычно они обрабатываются так же, как кнопки «Назад» и «Домой», но с разными кодами клавиш. Например, KEYCODE_CALL или KEYCODE_MUSIC .

Конфигурация сборки

Поворотная навигация предоставляется службой специальных возможностей под названием RotaryService . Чтобы включить эту службу в образ системы для вашего устройства, добавьте в make-файл следующую строку:

PRODUCT_PACKAGES += CarRotaryController

Вы также можете включить следующие пакеты в отладочные сборки:

Служба поворота включается автоматически при загрузке устройства и при переключении пользователя. Это гарантирует, что пользователь может использовать поворотный контроллер во время настройки.

Если вы используете одну и ту же сборку для автомобилей с поворотным контроллером и без него, добавьте 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 )
Этот кэш per- FocusArea хранит последнее сфокусированное представление в FocusArea , чтобы его можно было сфокусировать при возврате к FocusArea . Этот кеш можно настроить, наложив следующие ресурсы car-ui-library:

  • car_ui_focus_history_cache_type :
    1. Кэш отключен.
    2. Кэш истечет через некоторое время (см. ниже).
    3. Кэш никогда не истечет.
  • 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 :
    1. Кэш отключен.
    2. Срок действия кэша истекает через некоторое время (см. ниже).
    3. Кэш никогда не истекает.
  • car_ui_focus_area_history_expiration_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 . Используется для двукратного ускорения. Установите это значение на 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 : Толщина контура.

Иногда кнопке присваивается сплошной цвет фона, чтобы привлечь внимание пользователя, как в показанном примере. Это может затруднить просмотр выделения в фокусе.

Кнопка со сплошным фоном
Рисунок 2. Кнопка со сплошным фоном

В этой ситуации разработчик может указать пользовательскую подсветку фокуса, используя вторичные цвета:
  • ( 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

Любой из цветов может быть прозрачным, и любое измерение может быть нулевым, если, например, вам нужна только заливка или только контур.

Выделение области фокусировки

( 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 может настроить, что должно происходить для каждого из четырех направлений, указав любую комбинацию:

  1. Глобальное действие, определенное AccessibilityService . Например, GLOBAL_ACTION_BACK .
  2. Код ключа, например KEYCODE_BACK .
  3. Намерение запустить действие, представленное в виде 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 : целочисленное значение, указывающее, сколько миллисекунд необходимо удерживать центральную кнопку, чтобы вызвать длительное нажатие. Ноль указывает, что следует использовать системный тайм-аут длительного нажатия по умолчанию. Это значение по умолчанию.