
Подсистема ввода Android номинально состоит из конвейера событий, который проходит через несколько уровней системы.
Входной конвейер
На самом нижнем уровне физическое устройство ввода выдает сигналы, которые описывают изменения состояния, такие как нажатия клавиш и точки касания. Микропрограмма устройства кодирует и передает эти сигналы каким-либо образом, например, отправляя отчеты USB HID в систему или создавая прерывания на шине I2C.
Затем сигналы декодируются драйвером устройства в ядре Linux. Ядро Linux предоставляет драйверы для многих стандартных периферийных устройств, особенно для тех, которые поддерживают протокол HID. Однако OEM-производитель часто должен предоставлять специальные драйверы для встраиваемых устройств, которые тесно интегрированы в систему на низком уровне, например, сенсорные экраны.
Драйверы устройств ввода отвечают за преобразование сигналов конкретных устройств в стандартный формат событий ввода посредством протокола ввода Linux. Протокол ввода Linux определяет стандартный набор типов событий и кодов в linux/input.h
ядра linux/input.h
. Таким образом, компоненты вне ядра не должны заботиться о деталях, таких как физические коды сканирования, использование HID, сообщения I2C, контакты GPIO и т.п.
Затем компонент Android EventHub
считывает события ввода из ядра, открывая драйвер evdev
связанный с каждым устройством ввода. Затем компонент Android InputReader декодирует события ввода в соответствии с классом устройства и создает поток событий ввода Android. В рамках этого процесса коды событий протокола ввода Linux преобразуются в коды событий Android в соответствии с конфигурацией устройства ввода, файлами раскладки клавиатуры и различными таблицами сопоставления.
Наконец, InputReader
отправляет события ввода в InputDispatcher, который перенаправляет их в соответствующее окно.
Контрольные точки
В конвейере ввода есть несколько этапов, которые влияют на управление поведением устройства ввода.
Конфигурация драйвера и прошивки
Драйверы устройств ввода часто настраивают поведение устройства ввода, задавая параметры в регистрах или даже загружая саму прошивку. Это особенно актуально для встроенных устройств, таких как сенсорные экраны, где большая часть процесса калибровки включает настройку этих параметров или исправление прошивки для обеспечения желаемой точности и скорости отклика, а также для подавления шума.
Параметры конфигурации драйвера часто указываются как параметры модуля в пакете поддержки платы ядра (BSP), чтобы один и тот же драйвер мог поддерживать несколько различных аппаратных реализаций.
В этой документации делается попытка описать конфигурацию драйвера или микропрограммы, но она предлагает руководство по калибровке устройства в целом.
Свойства конфигурации платы
Пакет поддержки платы ядра (BSP) может экспортировать свойства конфигурации платы через SysFS, которые используются компонентом Android InputReader, например размещение виртуальных клавиш на сенсорном экране.
Обратитесь к разделам о классах устройств для получения подробной информации о том, как разные устройства используют свойства конфигурации платы.
Наложения ресурсов
Некоторые режимы ввода настраиваются с помощью наложений ресурсов в config.xml
например, работа переключателя крышки.
Вот несколько примеров:
config_lidKeyboardAccessibility
: определяет влияние переключателя крышки на то, доступна или скрыта аппаратная клавиатура.config_lidNavigationAccessibility
: определяет влияние переключателя крышки на то, является ли трекпад доступным или скрытым.config_longPressOnPowerBehavior
: указывает, что должно произойти, когда пользователь удерживает кнопку питания.config_lidOpenRotation
: определяет влияние переключателя крышки на ориентацию экрана.
Обратитесь к документации в frameworks/base/core/res/res/values/config.xml
для получения подробной информации о каждой опции конфигурации.
Ключевые карты
Карты клавиш используются компонентами Android EventHub
и InputReader
для настройки сопоставления кодов событий Linux с кодами событий Android для клавиш, кнопок джойстика и осей джойстика. Отображение может зависеть от устройства или языка.
Обратитесь к разделам классов устройств для получения подробной информации о том, как разные устройства используют раскладки клавиш.
Файлы конфигурации устройства ввода
Файлы конфигурации устройства ввода используются компонентами Android EventHub
и InputReader
для настройки специальных характеристик устройства, например способа InputReader
информации о размере сенсорного экрана.
Обратитесь к разделам классов устройств для получения подробной информации о том, как разные устройства используют карты конфигурации устройства ввода.
Понимание использования HID и кодов событий
Часто существует несколько разных идентификаторов, используемых для обозначения любой данной клавиши на клавиатуре, кнопки на игровом контроллере, оси джойстика или другого элемента управления. Отношения между этими идентификаторами не всегда одинаковы: они зависят от набора таблиц сопоставления, некоторые из которых являются фиксированными, а некоторые изменяются в зависимости от характеристик устройства, драйвера устройства, текущей локали, конфигурации системы, предпочтения пользователя и другие факторы.
- Код физического сканирования
Физический скан-код - это идентификатор устройства, связанный с каждой клавишей, кнопкой или другим элементом управления. Поскольку физические коды сканирования часто различаются от одного устройства к другому, микропрограммное обеспечение или драйвер устройства отвечают за сопоставление их со стандартными идентификаторами, такими как HID Usages или коды клавиш Linux.
Скан-коды в основном интересны для клавиатур. Другие устройства обычно обмениваются данными на низком уровне с помощью контактов GPIO, сообщений I2C или других средств. Следовательно, верхние уровни программного стека полагаются на драйверы устройств, чтобы понять, что происходит.
- Скрытое использование
Использование HID - это стандартный идентификатор, который используется для сообщения о состоянии элемента управления, такого как клавиша клавиатуры, ось джойстика, кнопка мыши или точка касания. Большинство устройств ввода USB и Bluetooth соответствуют спецификации HID, что позволяет системе взаимодействовать с ними единообразно.
Android Framework использует драйверы HID ядра Linux для преобразования кодов использования HID в коды ключей Linux и другие идентификаторы. Поэтому использование HID в основном представляет интерес для производителей периферийных устройств.
- Код ключа Linux
Код клавиши Linux - это стандартный идентификатор клавиши или кнопки. Коды клавиш Linux определены в заголовочном файле
linux/input.h
с использованием констант, начинающихся с префиксаKEY_
илиBTN_
. Драйверы ввода ядра Linux отвечают за преобразование физических кодов сканирования, использования HID и других сигналов, зависящих от устройства, в коды клавиш Linux и за доставку информации о них как части событийEV_KEY
.Android API иногда называет ключевой код Linux, связанный с ключом, своим «скан-кодом». Это технически неверно, но помогает отличить коды клавиш Linux от кодов клавиш Android в API.
- Код относительной или абсолютной оси Linux
Код относительной или абсолютной оси Linux - это стандартный идентификатор для сообщения об относительных перемещениях или абсолютных положениях вдоль оси, таких как относительные перемещения мыши вдоль оси X или абсолютное положение джойстика вдоль оси X. Код оси Linux определяется в заголовочном файле
linux/input.h
с использованием констант, начинающихся с префиксаREL_
илиABS_
. Драйверы ввода ядра Linux отвечают за преобразование использования HID и других сигналов, зависящих от устройства, в коды осей Linux и за доставку информации о них как часть событийEV_REL
иEV_ABS
.- Код коммутатора Linux
Код переключателя Linux - это стандартный идентификатор для сообщения о состоянии переключателя на устройстве, например переключателе крышки. Коды переключателей Linux определены в заголовочном файле
linux/input.h
с использованием констант, начинающихся с префиксаSW_
. Драйверы ввода ядра Linux сообщают об изменении состояния переключателя какEV_SW
событияхEV_SW
.Приложения Android обычно не получают события от переключателей, но система может использовать их внутри для управления различными функциями устройства.
- Код ключа Android
Код ключа Android - это стандартный идентификатор, определенный в Android API для обозначения определенного ключа, такого как «HOME». Коды клавиш Android определяются классом
android.view.KeyEvent
как константы, начинающиеся с префиксаKEYCODE_
.Раскладка клавиш определяет, как коды клавиш Linux сопоставляются с кодами клавиш Android. Могут использоваться разные раскладки клавиш в зависимости от модели клавиатуры, языка, страны, раскладки или специальных функций.
Комбинации кодов клавиш Android преобразуются в коды символов с использованием карты символов клавиш, зависящей от устройства и локали. Например, когда клавиши, обозначенные как
KEYCODE_SHIFT
иKEYCODE_A
, нажимаются вместе, система ищет комбинацию в карте символов клавиш и находит заглавную букву «A», которая затем вставляется в текстовый виджет с фокусом в данный момент.- Код оси Android
Код оси Android - это стандартный идентификатор, определенный в Android API для обозначения конкретной оси устройства. Коды осей Android определяются классом
android.view.MotionEvent
как константы, начинающиеся с префиксаAXIS_
.Раскладка клавиш определяет, как коды оси Linux сопоставляются с кодами оси Android. Могут использоваться разные раскладки клавиш в зависимости от модели устройства, языка, страны, раскладки или специальных функций.
- Мета-состояние Android
Мета-состояние Android - это стандартный идентификатор, определенный в Android API для обозначения нажатых клавиш-модификаторов. Мета-состояния Android определяются классом
android.view.KeyEvent
как константы, начинающиеся с префиксаMETA_
.Текущее мета-состояние определяется компонентом Android InputReader, который отслеживает нажатие /
KEYCODE_SHIFT_LEFT
клавиш-модификаторов, таких какKEYCODE_SHIFT_LEFT
, и устанавливает / сбрасывает соответствующий флаг мета-состояния.Связь между клавишами-модификаторами и метасостояниями жестко запрограммирована, но раскладка клавиш может изменять способ отображения самих клавиш-модификаторов, что, в свою очередь, влияет на мета-состояния.
- Состояние кнопки Android
Состояние кнопки Android - это стандартный идентификатор, определенный в Android API для указания, какие кнопки (на мыши или стилусе) нажаты. Состояния кнопок Android определяются классом
android.view.MotionEvent
как константы, начинающиеся с префиксаBUTTON_
.Текущее состояние кнопки определяется компонентом Android InputReader, который отслеживает, когда кнопки (на мыши или стилусе) нажимаются / отпускаются, и устанавливает / сбрасывает соответствующий флаг состояния кнопки.
Связь между кнопками и состояниями кнопок жестко запрограммирована.
Дальнейшее чтение
- Коды событий ввода Linux
- Протокол мультитач Linux
- Драйверы ввода Linux
- Силовая обратная связь в Linux
- Информация HID, включая таблицы использования HID