Сенсорные устройства

Android поддерживает различные сенсорные экраны и сенсорные панели, включая планшеты со стилусом.

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

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

Сенсорные устройства могут иметь кнопки, функции которых аналогичны кнопкам мыши.

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

Сенсорные устройства иногда используются для реализации виртуальных клавиш. Например, на некоторых устройствах Android область сенсорного экрана выходит за пределы края дисплея и выполняет двойную функцию, являясь частью сенсорной клавиатуры.

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

Классификация сенсорных устройств

Устройство ввода классифицируется как устройство с поддержкой мультитач, если выполняются оба следующих условия:

  • Устройство ввода сообщает о наличии абсолютных осей ABS_MT_POSITION_X и ABS_MT_POSITION_Y .
  • Устройство ввода не имеет кнопок геймпада. Это условие устраняет неоднозначность, связанную с некоторыми геймпадами, которые сообщают об осях с кодами, перекрывающими коды осей MT.

Устройство ввода классифицируется как устройство с одним касанием, если выполняются оба следующих условия:

  • Устройство ввода не классифицируется как устройство с поддержкой нескольких касаний. Устройство ввода классифицируется либо как устройство с однокасание, либо как устройство с поддержкой нескольких касаний, но не как устройство с обоими типами касаний.
  • Устройство ввода сообщает о наличии абсолютных осей ABS_X и ABS_Y , а также о наличии кода клавиши BTN_TOUCH .

Если устройство ввода классифицируется как сенсорное, наличие виртуальных клавиш определяется путём попытки загрузки файла карты виртуальных клавиш для устройства. Если карта виртуальных клавиш доступна, также загружается файл раскладки клавиш для устройства. Информация о расположении и формате этих файлов представлена ​​в разделе [Файлы карт виртуальных клавиш](#virtual-key-map-files).

Далее система загружает файл конфигурации устройства ввода для сенсорного устройства.

Все встроенные сенсорные устройства должны иметь файлы конфигурации устройств ввода. Если файл конфигурации отсутствует, система выбирает конфигурацию по умолчанию, подходящую для универсальных сенсорных периферийных устройств, таких как внешние сенсорные экраны HID с USB-портом или Bluetooth, а также сенсорные панели. Эти настройки по умолчанию не предназначены для встроенных сенсорных экранов и могут привести к некорректной работе.

После загрузки конфигурации устройства ввода система классифицирует устройство ввода как сенсорный экран , сенсорную панель или указательное устройство.

  • Сенсорный экран используется для непосредственного управления объектами на экране. Пользователь непосредственно прикасается к экрану, поэтому системе не требуются дополнительные возможности для обозначения объектов, которыми он управляет.
  • Сенсорная панель используется для предоставления приложению информации об абсолютном местоположении касаний к заданной области сенсора. Она может быть полезна для планшетов-дигитайзеров.
  • Указательное устройство используется для косвенного управления объектами на экране с помощью курсора. Пальцы интерпретируются как многосенсорные жесты. Другие инструменты, такие как стилусы, интерпретируются с использованием абсолютных положений. Подробнее см. в разделе Косвенные многосенсорные жесты .

Для классификации устройств ввода на сенсорный экран, сенсорную панель или указательное устройство используются следующие правила.

  • Если свойство touch.deviceType задано, то тип устройства устанавливается указанным образом.
  • Если устройство ввода сообщает о наличии свойства ввода INPUT_PROP_DIRECT (через ioctl-вызов EVIOCGPROP ), то тип устройства устанавливается как сенсорный экран . Это условие предполагает, что устройства прямого сенсорного ввода подключены к дисплею, который также подключен.
  • Если устройство ввода сообщает о наличии свойства ввода INPUT_PROP_POINTER (через ioctl EVIOCGPROP ), то тип устройства устанавливается на указатель .
  • Если устройство ввода сообщает о наличии относительных осей REL_X или REL_Y , то тип устройства устанавливается как сенсорная панель . Это условие устраняет неоднозначность для устройств ввода, которые представляют собой как мышь, так и сенсорную панель. В этом случае сенсорная панель не используется для управления указателем, поскольку ею уже управляет мышь.
  • В противном случае тип устройства устанавливается как «указатель» . Это значение по умолчанию гарантирует, что сенсорные панели, не предназначенные для какого-либо другого специального назначения, будут управлять указателем.

Кнопки

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

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

  • BTN_LEFT : Сопоставлено с MotionEvent.BUTTON_PRIMARY .
  • BTN_RIGHT : сопоставлено с MotionEvent.BUTTON_SECONDARY .
  • BTN_MIDDLE : Сопоставлено с MotionEvent.BUTTON_MIDDLE .
  • BTN_BACK и BTN_SIDE : сопоставлены с MotionEvent.BUTTON_BACK . Нажатие этой кнопки также синтезирует нажатие клавиши с кодом KeyEvent.KEYCODE_BACK .
  • BTN_FORWARD и BTN_EXTRA : сопоставлены с MotionEvent.BUTTON_FORWARD . Нажатие этой кнопки также синтезирует нажатие клавиши с кодом KeyEvent.KEYCODE_FORWARD .
  • BTN_STYLUS : Сопоставлено с MotionEvent.BUTTON_SECONDARY .
  • BTN_STYLUS2 : Сопоставлено с MotionEvent.BUTTON_TERTIARY .

Инструменты и типы инструментов

Инструмент — это палец, стилус или другой предмет, используемый для взаимодействия с сенсорным устройством. Некоторые сенсорные устройства различают разные типы инструментов.

В других частях Android, например в API MotionEvent , инструмент часто называют указателем .

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

  • BTN_TOOL_FINGER и MT_TOOL_FINGER : сопоставлены с MotionEvent.TOOL_TYPE_FINGER .
  • BTN_TOOL_PEN и MT_TOOL_PEN : сопоставлены с MotionEvent.TOOL_TYPE_STYLUS .
  • BTN_TOOL_RUBBER : Сопоставлено с MotionEvent.TOOL_TYPE_ERASER .
  • BTN_TOOL_BRUSH : Сопоставлено с MotionEvent.TOOL_TYPE_STYLUS .
  • BTN_TOOL_PENCIL : Сопоставлено с MotionEvent.TOOL_TYPE_STYLUS .
  • BTN_TOOL_AIRBRUSH : Сопоставлено с MotionEvent.TOOL_TYPE_STYLUS .
  • BTN_TOOL_MOUSE : Сопоставлено с MotionEvent.TOOL_TYPE_MOUSE .
  • BTN_TOOL_LENS : Сопоставлено с MotionEvent.TOOL_TYPE_MOUSE .
  • BTN_TOOL_DOUBLETAP , BTN_TOOL_TRIPLETAP и BTN_TOOL_QUADTAP : сопоставлены с MotionEvent.TOOL_TYPE_FINGER .

Инструменты наведения и прикосновения

Инструменты могут либо контактировать с сенсорным устройством, либо находиться в зоне его действия и парить над ним. Не все сенсорные устройства способны распознавать наличие инструмента, парящего над сенсорным устройством. Те, которые это делают, например, дигитайзеры с радиочастотным стилусом, часто способны определять, когда инструмент находится в ограниченном диапазоне от дигитайзера.

Компонент InputReader различает инструменты, находящиеся под действием нажатия, и инструменты, находящиеся под действием наведения. Аналогично, инструменты, находящиеся под действием нажатия, и инструменты, находящиеся под действием наведения, сообщаются приложениям по-разному.

Инструменты прикосновения передаются приложениям как события прикосновения с помощью MotionEvent.ACTION_DOWN , MotionEvent.ACTION_MOVE , MotionEvent.ACTION_DOWN , MotionEvent.ACTION_POINTER_DOWN и MotionEvent.ACTION_POINTER_UP .

Инструменты наведения передаются приложениям как общие события движения с использованием MotionEvent.ACTION_HOVER_ENTER , MotionEvent.ACTION_HOVER_MOVE и MotionEvent.ACTION_HOVER_EXIT .

Требования к драйверам сенсорных устройств

  • Драйверы сенсорных устройств должны регистрировать только оси и коды клавиш для поддерживаемых ими осей и кнопок. Регистрация неподдерживаемых осей или кодов клавиш может сбить с толку алгоритм классификации устройств или привести к неправильному определению системой его возможностей. Например, если устройство сообщает код клавиши BTN_TOUCH , система предполагает, что BTN_TOUCH всегда используется для указания того, касается ли инструмент экрана. Поэтому BTN_TOUCH не следует использовать для указания того, что инструмент просто находится в зоне действия и завис.
  • Устройства с одним касанием используют следующие события ввода Linux:
    • ABS_X : (ОБЯЗАТЕЛЬНО) Сообщает координату X инструмента.
    • ABS_Y : (ОБЯЗАТЕЛЬНО) Сообщает координату Y инструмента.
    • ABS_PRESSURE : (необязательно) Сообщает физическое давление, приложенное к кончику инструмента, или силу сигнала сенсорного контакта.
    • ABS_TOOL_WIDTH : (необязательно) Сообщает площадь поперечного сечения или ширину сенсорного контакта или самого инструмента.
    • ABS_DISTANCE : (необязательно) Сообщает расстояние инструмента от поверхности сенсорного устройства.
    • ABS_TILT_X : (необязательно) Сообщает наклон инструмента относительно поверхности сенсорного устройства вдоль оси X.
    • ABS_TILT_Y : (необязательно) Сообщает наклон инструмента относительно поверхности сенсорного устройства вдоль оси Y.
    • BTN_TOUCH : (ОБЯЗАТЕЛЬНО) Указывает, касается ли инструмент устройства.
    • BTN_LEFT , BTN_RIGHT , BTN_MIDDLE , BTN_BACK , BTN_SIDE , BTN_FORWARD , BTN_EXTRA , BTN_STYLUS , BTN_STYLUS2 : (необязательно) Сообщает о состояниях кнопок .
    • BTN_TOOL_FINGER , BTN_TOOL_PEN , BTN_TOOL_RUBBER , BTN_TOOL_BRUSH , BTN_TOOL_PENCIL , BTN_TOOL_AIRBRUSH , BTN_TOOL_MOUSE , BTN_TOOL_LENS , BTN_TOOL_DOUBLETAP , BTN_TOOL_TRIPLETAP , BTN_TOOL_QUADTAP : (необязательно) Сообщает тип инструмента .
  • Мультисенсорные устройства используют следующие события ввода Linux:
    • ABS_MT_POSITION_X : (ОБЯЗАТЕЛЬНО) Сообщает координату X инструмента.
    • ABS_MT_POSITION_Y : (ОБЯЗАТЕЛЬНО) Сообщает координату Y инструмента.
    • ABS_MT_PRESSURE : (необязательно) Сообщает физическое давление, приложенное к кончику инструмента, или силу сигнала сенсорного контакта.
    • ABS_MT_TOUCH_MAJOR : (необязательно) Сообщает площадь поперечного сечения сенсорного контакта или длину более длинного измерения сенсорного контакта.
    • ABS_MT_TOUCH_MINOR : (необязательно) Сообщает длину наименьшего измерения сенсорного контакта. Эту ось не следует использовать, если ABS_MT_TOUCH_MAJOR сообщает измерение площади.
    • ABS_MT_WIDTH_MAJOR : (необязательно) Сообщает площадь поперечного сечения самого инструмента или длину его наибольшей стороны. Не используйте эту ось, если вам неизвестны размеры самого инструмента.
    • ABS_MT_WIDTH_MINOR : (необязательно) Сообщает длину наименьшего размера самого инструмента. Эту ось не следует использовать, если ABS_MT_WIDTH_MAJOR сообщает об измерении площади или если размеры самого инструмента неизвестны.
    • ABS_MT_ORIENTATION : (необязательно) Сообщает ориентацию инструмента.
    • ABS_MT_DISTANCE : (необязательно) Сообщает расстояние инструмента от поверхности сенсорного устройства.
    • ABS_MT_TOOL_TYPE : (необязательно) Сообщает тип инструмента как MT_TOOL_FINGER или MT_TOOL_PEN .
    • ABS_MT_TRACKING_ID : (необязательно) Сообщает идентификатор отслеживания инструмента. Идентификатор отслеживания — это произвольное неотрицательное целое число, используемое для независимой идентификации и отслеживания каждого инструмента при использовании нескольких инструментов. Например, при касании устройства несколькими пальцами каждому пальцу должен быть назначен отдельный идентификатор отслеживания, который будет использоваться до тех пор, пока палец остается в контакте. Идентификаторы отслеживания можно использовать повторно, когда соответствующие инструменты выходят за пределы диапазона.
    • ABS_MT_SLOT : (необязательно) Сообщает идентификатор слота инструмента при использовании протокола мультитач Linux «B». Подробнее см. в документации по протоколу мультитач Linux.
    • BTN_TOUCH : (ОБЯЗАТЕЛЬНО) Указывает, касается ли инструмент устройства.
    • BTN_LEFT , BTN_RIGHT , BTN_MIDDLE , BTN_BACK , BTN_SIDE , BTN_FORWARD , BTN_EXTRA , BTN_STYLUS , BTN_STYLUS2 : (необязательно) Сообщает о состояниях кнопок .
    • BTN_TOOL_FINGER , BTN_TOOL_PEN , BTN_TOOL_RUBBER , BTN_TOOL_BRUSH , BTN_TOOL_PENCIL , BTN_TOOL_AIRBRUSH , BTN_TOOL_MOUSE , BTN_TOOL_LENS , BTN_TOOL_DOUBLETAP , BTN_TOOL_TRIPLETAP , BTN_TOOL_QUADTAP : (необязательно) Сообщает тип инструмента .
  • Если определены оси как для протокола одиночного касания, так и для протокола множественного касания, то используются только оси множественного касания, а оси единичного касания игнорируются.
  • Минимальные и максимальные значения осей ABS_X , ABS_Y , ABS_MT_POSITION_X и ABS_MT_POSITION_Y определяют границы активной области устройства в единицах измерения поверхности, характерных для данного устройства. В случае сенсорного экрана активная область описывает ту часть сенсорного устройства, которая фактически покрывает дисплей.

    Для сенсорного экрана система автоматически интерполирует сообщаемые позиции касания в единицах поверхности для получения позиций касания в пикселях дисплея в соответствии со следующим расчетом:

        displayX = (x - minX) * displayWidth / (maxX - minX + 1)
        displayY = (y - minY) * displayHeight / (maxY - minY + 1)
        

    Сенсорный экран может сообщать о касаниях за пределами активной области.

    Касания, инициированные за пределами активной области, не передаются приложениям, но могут использоваться для виртуальных клавиш.

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

    Сенсорное устройство никогда не должно ограничивать координаты касания границами активной области. Если касание выходит за пределы активной области, оно должно быть зафиксировано как находящееся за её пределами, или не должно быть зафиксировано вообще.

    Например, если палец пользователя касается экрана в районе верхнего левого угла, он может сообщить координаты (minX, minY). Если палец продолжает двигаться дальше за пределы активной области, сенсорный экран должен либо начать сообщать координаты с компонентами, меньшими minX и minY, например (minX - 2, minY - 3), либо полностью прекратить сообщать о касании. Другими словами, сенсорный экран не должен сообщать координаты (minX, minY), когда палец пользователя действительно касается экрана за пределами активной области.

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

  • Значения, сообщаемые ABS_PRESSURE или ABS_MT_PRESSURE , если они вообще сообщаются, должны быть ненулевыми, когда инструмент касается устройства, и нулевыми в противном случае, чтобы указать, что инструмент завис.

    Сообщать информацию о давлении необязательно , но настоятельно рекомендуется. Приложения могут использовать эту информацию для реализации рисования с учётом давления и других эффектов.

  • Значения, возвращаемые ABS_TOOL_WIDTH , ABS_MT_TOUCH_MAJOR , ABS_MT_TOUCH_MINOR , ABS_MT_WIDTH_MAJOR или ABS_MT_WIDTH_MINOR , должны быть ненулевыми, когда инструмент касается устройства, и нулевыми в противном случае, но это не обязательно. Например, сенсорное устройство может измерять размер касаний пальцем, но не стилусом.

    Сообщать информацию о размере необязательно , но настоятельно рекомендуется. Приложения могут использовать информацию о нажиме для реализации рисования с учётом размера и других эффектов.

  • Значения, возвращаемые ABS_DISTANCE или ABS_MT_DISTANCE должны стремиться к нулю при касании инструмента устройства. Расстояние может оставаться отличным от нуля даже при прямом контакте инструмента. Точные значения зависят от способа измерения расстояния оборудованием.

    Предоставление информации о расстоянии необязательно , но рекомендуется для устройств со стилусом.

  • Значения ABS_TILT_X и ABS_TILT_Y должны быть равны нулю, когда инструмент расположен перпендикулярно устройству. Наклон, отличный от нуля, указывает на то, что инструмент находится под наклоном.

    Углы наклона по осям X и Y задаются в градусах от перпендикуляра. Центральная точка (абсолютно перпендикулярная) определяется как (max + min) / 2 для каждой оси. Значения, меньшие, чем центральная точка, соответствуют наклону вверх или влево, значения, большие, чем центральная точка, соответствуют наклону вниз или вправо.

    InputReader преобразует компоненты наклона по осям X и Y в перпендикулярный угол наклона в диапазоне от 0 до PI / 2 радиан и угол ориентации в плоскости в диапазоне от -PI до PI радиан. Это представление приводит к описанию ориентации, совместимому с описанием прикосновений пальцев.

    Предоставление информации о наклоне не является обязательным , но рекомендуется для устройств со стилусом.

  • Если тип инструмента указан в ABS_MT_TOOL_TYPE , он заменяет любую информацию о типе инструмента, указанную в BTN_TOOL_* . Если информация о типе инструмента отсутствует, по умолчанию используется тип MotionEvent.TOOL_TYPE_FINGER .

  • Инструмент определяется как активный на основании следующих условий:

    • При использовании протокола одного касания инструмент активен, если BTN_TOUCH или BTN_TOOL_* равен 1.

      Это условие подразумевает, что InputReader должен иметь хотя бы некоторую информацию о природе инструмента: касается ли он объекта или, по крайней мере, его тип. Если информация отсутствует, инструмент считается неактивным (вне диапазона).

    • При использовании протокола мультитач «A» инструмент активен всегда, когда он появляется в последнем отчёте синхронизации. Когда инструмент перестаёт появляться в отчётах синхронизации, он перестаёт существовать.
    • При использовании протокола мультитач «B» инструмент активен, пока у него есть активный слот. После освобождения слота инструмент перестаёт существовать.
  • Инструмент определяется как зависший на основании следующих условий:
    • Если инструмент — BTN_TOOL_MOUSE или BTN_TOOL_LENS , то инструмент не зависает, даже если выполняется любое из следующих условий.
    • Если инструмент активен и водитель сообщает информацию о давлении, а сообщаемое давление равно нулю, то инструмент завис.
    • Если инструмент активен и драйвер поддерживает код клавиши BTN_TOUCH , а BTN_TOUCH имеет значение ноль, то инструмент зависает.
  • InputReader поддерживает оба протокола мультитач: A и B. Новые драйверы должны использовать протокол B, но работает любой из них.
  • Начиная с Android 4.0, может потребоваться изменение драйверов сенсорного экрана для соответствия спецификации протокола ввода Linux.

    Могут потребоваться следующие изменения:

    • Когда инструмент становится неактивным (палец поднят вверх), он должен перестать отображаться в последующих отчётах синхронизации мультисенсорных устройств. Когда все инструменты становятся неактивными (все пальцы подняты вверх), драйвер должен отправить пустой пакет отчёта синхронизации, например, SYN_MT_REPORT , а затем SYN_REPORT .

      В предыдущих версиях Android события «вверх» ожидались путем отправки значения давления, равного 0. Старое поведение было несовместимо со спецификацией протокола ввода Linux и больше не поддерживается.

    • Информацию о физическом давлении или силе сигнала следует сообщать с помощью ABS_MT_PRESSURE .

      Предыдущие версии Android получали информацию о давлении из ABS_MT_TOUCH_MAJOR . Старое поведение было несовместимо со спецификацией протокола ввода Linux и больше не поддерживается.

    • Информацию о размере сенсорного экрана следует сообщать с помощью ABS_MT_TOUCH_MAJOR .

      Предыдущие версии Android получали информацию о размере из ABS_MT_TOOL_MAJOR . Старое поведение было несовместимо со спецификацией протокола ввода Linux и больше не поддерживается.

    Драйверы сенсорных устройств больше не требуют специальных настроек для Android. Используя стандартный протокол ввода Linux, Android может поддерживать более широкий спектр сенсорных периферийных устройств, таких как внешние HID-дисплеи с поддержкой мультитач, используя немодифицированные драйверы.

Управление сенсорным устройством

Ниже приведен краткий обзор работы сенсорного устройства на базе Android.

  1. EventHub считывает необработанные события из драйвера evdev .
  2. InputReader получает необработанные события и обновляет внутреннее состояние положения и других характеристик каждого инструмента. Он также отслеживает состояния кнопок.
  3. Если была нажата или отпущена клавиша BACK или FORWARD , InputReader уведомляет InputDispatcher о событии клавиши.
  4. InputReader определяет, произошло ли нажатие виртуальной клавиши. Если да, он уведомляет InputDispatcher о событии нажатия клавиши.
  5. InputReader определяет, было ли касание инициировано в пределах экрана. Если да, он уведомляет InputDispatcher о событии касания.
  6. Если нет соприкасающихся инструментов, но есть хотя бы один наведенный инструмент, InputReader уведомляет InputDispatcher о событии наведения.
  7. Если тип сенсорного устройства — указатель , InputReader выполняет обнаружение жеста указателя, перемещает указатель и точки соответствующим образом и уведомляет InputDispatcher о событии указателя.
  8. InputDispatcher использует WindowManagerPolicy для определения необходимости отправки событий и необходимости пробуждения устройства. Затем InputDispatcher доставляет события соответствующим приложениям.

Конфигурация сенсорного устройства

Поведение сенсорного устройства определяется осями устройства, кнопками, свойствами ввода, конфигурацией устройства ввода, картой виртуальных клавиш и расположением клавиш.

Более подробную информацию о файлах, участвующих в настройке клавиатуры, можно найти в следующих разделах:

Характеристики

Система использует множество свойств конфигурации устройства ввода для настройки и калибровки поведения сенсорного устройства.

Одной из причин этого является то, что драйверы сенсорных устройств часто сообщают характеристики касаний, используя единицы измерения, специфичные для данного устройства.

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

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

Соглашения о документации

В целях документирования мы используем следующие условные обозначения для описания значений, используемых системой в процессе калибровки.

Исходные значения осей

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

raw.x
Значение оси ABS_X или ABS_MT_POSITION_X .
raw.y
Значение оси ABS_Y или ABS_MT_POSITION_Y .
raw.pressure
Значение оси ABS_PRESSURE или ABS_MT_PRESSURE , или 0, если недоступно.
raw.touchMajor
Значение оси ABS_MT_TOUCH_MAJOR или 0, если недоступно.
raw.touchMinor
Значение оси ABS_MT_TOUCH_MINOR или raw.touchMajor , если оно недоступно.
raw.toolMajor
Значение оси ABS_TOOL_WIDTH или ABS_MT_WIDTH_MAJOR , или 0, если недоступно.
raw.toolMinor
Значение оси ABS_MT_WIDTH_MINOR или raw.toolMajor , если оно недоступно.
raw.orientation
Значение оси ABS_MT_ORIENTATION или 0, если недоступно.
raw.distance
Значение оси ABS_DISTANCE или ABS_MT_DISTANCE , или 0, если недоступно.
raw.tiltX
Значение оси ABS_TILT_X или 0, если недоступно.
raw.tiltY
Значение оси ABS_TILT_Y или 0, если недоступно.

Диапазоны необработанных осей

Следующие выражения определяют границы исходных значений. Они получаются путем вызова ioctl-функции EVIOCGABS для каждой оси.

raw.*.min
Минимальное включенное значение исходной оси.
raw.*.max
Максимальное значение необработанной оси.
raw.*.range
Эквивалентно raw.*.max - raw.*.min .
raw.*.fuzz
Точность необработанной оси. Например, fuzz = 1 подразумевает, что значения имеют точность +/- 1 единица.
raw.width
Общая ширина сенсорной области, эквивалентная raw.x.range + 1 .
raw.height
Высота сенсорной области (включая ее), эквивалентная raw.y.range + 1 .

Выходные диапазоны

Следующие выражения определяют характеристики выходной системы координат. Система использует линейную интерполяцию для перевода информации о положении касания из единиц измерения поверхности, используемых сенсорным устройством, в выходные единицы, которые передаются приложениям, например, в пиксели дисплея.

output.width
Ширина выходного изображения. Для сенсорных экранов (связанных с дисплеем) это ширина изображения в пикселях. Для сенсорных панелей (не связанных с дисплеем) ширина выходного изображения равна raw.width , что означает, что интерполяция не выполняется.
output.height
Высота вывода. Для сенсорных экранов (связанных с дисплеем) это высота отображения в пикселях. Для сенсорных панелей (не связанных с дисплеем) высота вывода равна raw.height , что означает, что интерполяция не выполняется.
output.diag
Длина диагонали выходной системы координат, эквивалентная sqrt(output.width ^2 + output.height ^2) .

Базовая конфигурация

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

тип сенсорного устройства

Определение: touch.deviceType = touchScreen | touchPad | pointer | default

Указывает тип сенсорного устройства.

  • Если значение равно touchScreen , то сенсорное устройство представляет собой сенсорный экран, связанный с дисплеем.

  • Если значение равно touchPad , сенсорное устройство представляет собой сенсорную панель, не связанную с дисплеем.

  • Если значение равно pointer , сенсорное устройство представляет собой сенсорную панель, не связанную с дисплеем, а ее движения используются для косвенных многосенсорных жестов указателя .

  • Если установлено значение default , система автоматически определяет тип устройства в соответствии с алгоритмом классификации.

Более подробную информацию о том, как тип устройства влияет на поведение сенсорного устройства, см. в разделе «Классификация» .

В Android 3 и ниже все сенсорные устройства предполагались как сенсорные экраны.

touch.orientationAware

Определение: touch.orientationAware = 0 | 1

Указывает, должно ли сенсорное устройство реагировать на изменение ориентации дисплея.

  • Если значение равно 1 , позиции касания, сообщаемые сенсорным устройством, поворачиваются при каждом изменении ориентации дисплея.

  • Если значение равно 0 , позиции касания, сообщаемые сенсорным устройством, не подвержены изменениям ориентации дисплея.

Значение по умолчанию — 1 если устройство имеет сенсорный экран, в противном случае 0 .

Система различает внутренние и внешние сенсорные экраны и дисплеи. Внутренний сенсорный экран с распознаванием ориентации поворачивается в зависимости от ориентации внутреннего дисплея. Внешний сенсорный экран с распознаванием ориентации поворачивается в зависимости от ориентации внешнего дисплея.

Распознавание ориентации используется для поддержки поворота сенсорных экранов на таких устройствах, как Nexus One. Например, при повороте устройства по часовой стрелке на 90 градусов от его естественной ориентации абсолютные координаты касаний переопределяются таким образом, что касание в верхнем левом углу абсолютной системы координат сенсорного экрана регистрируется как касание в верхнем левом углу повёрнутой системы координат дисплея. Это сделано для того, чтобы касания регистрировались в той же системе координат, которую приложения используют для отрисовки своих визуальных элементов.

До появления Honeycomb предполагалось, что все сенсорные устройства распознают ориентацию.

touch.gestureMode

Определение: touch.gestureMode = pointer | spots | default

Задаёт режим представления для жестов указателя. Это свойство конфигурации актуально только для сенсорных устройств типа «указатель» .

  • Если значение равно pointer , жесты сенсорной панели представлены в виде курсора, похожего на указатель мыши.

  • Если значение равно spots , жесты сенсорной панели представлены якорем, который представляет собой центроид жеста, и набором круглых точек, которые представляют положение отдельных пальцев.

Значение по умолчанию — pointer , если задано свойство ввода INPUT_PROP_SEMI_MT , в противном случае — spots .

Поля X и Y

Поля X и Y предоставляют позиционную информацию для центра контактной области.

Расчет

Расчет прост: позиционная информация от сенсорного драйвера линейно интерполируется в выходную систему координат.

xScale = output.width / raw.width
yScale = output.height / raw.height

If not orientation aware or screen rotation is 0 degrees:
output.x = (raw.x - raw.x.min) * xScale
output.y = (raw.y - raw.y.min) * yScale
Else If rotation is 90 degrees:
    output.x = (raw.y - raw.y.min) * yScale
    output.y = (raw.x.max - raw.x) * xScale
Else If rotation is 180 degrees:
    output.x = (raw.x.max - raw.x) * xScale
    output.y = (raw.y.max - raw.y) * yScale
Else If rotation is 270 degrees:
    output.x = (raw.y.max - raw.y) * yScale
    output.y = (raw.x - raw.x.min) * xScale
End If

touchMajor, touchMinor, toolMajor, toolMinor, поля размера

Поля touchMajor и touchMinor описывают приблизительные размеры области контакта в выходных единицах (пикселях).

Поля toolMajor и toolMinor описывают приблизительные размеры самого инструмента в выходных единицах (пикселях).

Поле size описывает нормализованный размер касания относительно максимально возможного касания, которое может распознать сенсорное устройство. Наименьший возможный нормализованный размер равен 0,0 (контакт отсутствует или измерение невозможно), а наибольший возможный нормализованный размер равен 1,0 (область сенсора заполнена).

Если можно измерить и приблизительную длину, и приблизительную ширину, поле touchMajor определяет большую сторону, а поле touchMinor — меньшую сторону контактной области. Если можно измерить только приблизительный диаметр контактной области, поля touchMajor и touchMinor равны.

Аналогично, поле toolMajor определяет больший размер, а поле toolMinor определяет меньший размер площади поперечного сечения инструмента.

Если размер касания недоступен, но доступен размер инструмента, то размер инструмента устанавливается равным размеру касания. И наоборот, если размер инструмента недоступен, но доступен размер касания, то размер касания устанавливается равным размеру инструмента.

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

Определение: touch.size.calibration = none | geometric | diameter | area | default

Указывает тип измерения, используемый драйвером сенсора для определения размера касания и размера инструмента.

  • Если значение равно none , размер устанавливается равным нулю.

  • Если значение является geometric , предполагается, что размер указан в тех же единицах измерения поверхности, что и положение, поэтому он масштабируется таким же образом.

  • Если значение равно diameter , размер считается пропорциональным диаметру (ширине) прикосновения или инструмента.

  • Если значение равно area , размер считается пропорциональным площади касания или инструмента.

  • Если задано значение default , система использует geometric калибровку, если доступна ось raw.touchMajor или raw.toolMajor , в противном случае используется none калибровки.

сенсорный.размер.масштаб

Определение: touch.size.scale = <неотрицательное число с плавающей точкой>

Задает постоянный масштабный коэффициент, используемый при калибровке.

Значение по умолчанию — 1.0 .

сенсорный.размер.предвзятость

Определение: touch.size.bias = <неотрицательное число с плавающей точкой>

Задает постоянное значение смещения, используемое при калибровке.

Значение по умолчанию — 0.0 .

touch.size.isSummed

Определение: touch.size.isSummed = 0 | 1

Указывает, указывается ли размер как сумма размеров всех активных контактов или указывается отдельно для каждого контакта.

  • Если значение равно 1 , сообщаемый размер делится на количество контактов до использования.

  • Если значение равно 0 , указанный размер используется как есть.

Значение по умолчанию — 0 .

Некоторые сенсорные устройства, особенно устройства «Semi-MT», не различают отдельные размеры нескольких контактов, поэтому они сообщают размер, представляющий их общую площадь или ширину. Для таких устройств это свойство следует устанавливать только равным 1 В случае сомнений установите значение 0 .

Расчет

Расчет полей touchMajor , touchMinor , toolMajor , toolMinor и size зависит от указанных параметров калибровки.

If raw.touchMajor and raw.toolMajor are available:
    touchMajor = raw.touchMajor
    touchMinor = raw.touchMinor
    toolMajor = raw.toolMajor
    toolMinor = raw.toolMinor
Else If raw.touchMajor is available:
    toolMajor = touchMajor = raw.touchMajor
    toolMinor = touchMinor = raw.touchMinor
Else If raw.toolMajor is available:
    touchMajor = toolMajor = raw.toolMajor
    touchMinor = toolMinor = raw.toolMinor
Else
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
End If

size = avg(touchMajor, touchMinor)

If touch.size.isSummed == 1:
    touchMajor = touchMajor / numberOfActiveContacts
    touchMinor = touchMinor / numberOfActiveContacts
    toolMajor = toolMajor / numberOfActiveContacts
    toolMinor = toolMinor / numberOfActiveContacts
    size = size / numberOfActiveContacts
End If

If touch.size.calibration == "none":
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
Else If touch.size.calibration == "geometric":
    outputScale = average(output.width / raw.width, output.height / raw.height)
    touchMajor = touchMajor * outputScale
    touchMinor = touchMinor * outputScale
    toolMajor = toolMajor * outputScale
    toolMinor = toolMinor * outputScale
Else If touch.size.calibration == "area":
    touchMajor = sqrt(touchMajor)
    touchMinor = touchMajor
    toolMajor = sqrt(toolMajor)
    toolMinor = toolMajor
Else If touch.size.calibration == "diameter":
    touchMinor = touchMajor
    toolMinor = toolMajor
End If

If touchMajor != 0:
    output.touchMajor = touchMajor * touch.size.scale + touch.size.bias
Else
    output.touchMajor = 0
End If

If touchMinor != 0:
    output.touchMinor = touchMinor * touch.size.scale + touch.size.bias
Else
    output.touchMinor = 0
End If

If toolMajor != 0:
    output.toolMajor = toolMajor * touch.size.scale + touch.size.bias
Else
    output.toolMajor = 0
End If

If toolMinor != 0:
    output.toolMinor = toolMinor * touch.size.scale + touch.size.bias
Else
    output.toolMinor = 0
End If

output.size = size

поле давления

Поле pressure описывает приблизительное физическое давление, прилагаемое к сенсорному устройству, как нормализованное значение между 0,0 (нет касания) и 1,0 (нормальное давление).

Нулевое давление указывает на то, что инструмент завис.

калибровка.сенсорного.давления

Определение: touch.pressure.calibration = none | physical | amplitude | default

Указывает тип измерения, используемый драйвером сенсора для определения давления.

  • Если значение равно none , давление неизвестно, поэтому оно устанавливается равным 1,0 при касании и 0,0 при наведении.

  • Если значение physical , предполагается, что ось давления измеряет фактическую физическую интенсивность давления, прилагаемого к сенсорной панели.

  • Если значение равно amplitude , предполагается, что ось давления измеряет амплитуду сигнала, которая связана с размером контакта и приложенным давлением.

  • If the value is default , the system uses the physical calibration if the pressure axis available, otherwise uses none .

touch.pressure.scale

Definition: touch.pressure.scale = <a non-negative floating point number>

Specifies a constant scale factor used in the calibration.

The default value is 1.0 / raw.pressure.max .

Расчет

The calculation of the pressure field depends on the specified calibration parameters.

If touch.pressure.calibration == "physical" or "amplitude":
    output.pressure = raw.pressure * touch.pressure.scale
Else
    If hovering:
        output.pressure = 0
    Else
        output.pressure = 1
    End If
End If

orientation and tilt fields

The orientation field describes the orientation of the touch and tool as an angular measurement. An orientation of 0 indicates that the major axis is oriented vertically, -PI/2 indicates that the major axis is oriented to the left, PI/2 indicates that the major axis is oriented to the right. When a stylus tool is present, the orientation range can be described in a full circle range from -PI or PI .

The tilt field describes the inclination of the tool as an angular measurement. A tilt of 0 indicates that the tool is perpendicular to the surface. A tilt of PI/2 indicates that the tool is flat on the surface.

touch.orientation.calibration

Definition: touch.orientation.calibration = none | interpolated | vector | default

Specifies the kind of measurement used by the touch driver to report the orientation.

  • If the value is none , the orientation is unknown so it is set to 0.
  • If the value is interpolated , the orientation is linearly interpolated such that a raw value of raw.orientation.min maps to -PI/2 and a raw value of raw.orientation.max maps to PI/2 . The center value of (raw.orientation.min + raw.orientation.max) / 2 maps to 0 .
  • If the value is vector , the orientation is interpreted as a packed vector consisiting of two signed 4-bit fields. This representation is used on Atmel Object Based Protocol parts. When decoded, the vector yields an orientation angle and confidence magnitude. The confidence magnitude is used to scale the size information, unless it is geometric.
  • If the value is default , the system uses the interpolated calibration if the orientation axis available, otherwise uses none .

Расчет

The calculation of the orientation and tilt fields depends on the specified calibration parameters and available input.

If touch.tiltX and touch.tiltY are available:
    tiltXCenter = average(raw.tiltX.min, raw.tiltX.max)
    tiltYCenter = average(raw.tiltY.min, raw.tiltY.max)
    tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180
    tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180
    output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle))
    output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle))
Else If touch.orientation.calibration == "interpolated":
    center = average(raw.orientation.min, raw.orientation.max)
    output.orientation = PI / (raw.orientation.max - raw.orientation.min)
    output.tilt = 0
Else If touch.orientation.calibration == "vector":
    c1 = (raw.orientation & 0xF0) >> 4
    c2 = raw.orientation & 0x0F

    If c1 != 0 or c2 != 0:
        If c1 >= 8 Then c1 = c1 - 16
        If c2 >= 8 Then c2 = c2 - 16
        angle = atan2(c1, c2) / 2
        confidence = sqrt(c1*c1 + c2*c2)

        output.orientation = angle

        If touch.size.calibration == "diameter" or "area":
            scale = 1.0 + confidence / 16
            output.touchMajor *= scale
            output.touchMinor /= scale
            output.toolMajor *= scale
            output.toolMinor /= scale
        End If
    Else
        output.orientation = 0
    End If
    output.tilt = 0
Else
    output.orientation = 0
    output.tilt = 0
End If

If orientation aware:
    If screen rotation is 90 degrees:
        output.orientation = output.orientation - PI / 2
    Else If screen rotation is 270 degrees:
        output.orientation = output.orientation + PI / 2
    End If
End If

distance field

The distance field describes the distance between the tool and the touch device surface. A value of 0.0 indicates direct contact and larger values indicate increasing distance from the surface.

touch.distance.calibration

Definition: touch.distance.calibration = none | scaled | default

Specifies the kind of measurement used by the touch driver to report the distance.

  • If the value is none , the distance is unknown so it is set to 0.

  • If the value is scaled , the reported distance is multiplied by a constant scale factor.

  • If the value is default , the system uses the scaled calibration if the distance axis available, otherwise uses none .

touch.distance.scale

Definition: touch.distance.scale = <a non-negative floating point number>

Specifies a constant scale factor used in the calibration.

The default value is 1.0 .

Расчет

The calculation of the distance field depends on the specified calibration parameters.

If touch.distance.calibration == "scaled":
    output.distance = raw.distance * touch.distance.scale
Else
    output.distance = 0
End If

Пример

# Input device configuration file for a touch screen that supports pressure,
# size and orientation. The pressure and size scale factors were obtained
# by measuring the characteristics of the device itself and deriving
# useful approximations based on the resolution of the touch sensor and the
# display.
#
# Note that these parameters are specific to a particular device model.
# Different parameters need to be used for other devices.

# Basic Parameters
touch.deviceType = touchScreen
touch.orientationAware = 1

# Size
# Based on empirical measurements, we estimate the size of the contact
# using size = sqrt(area) * 28 + 0.
touch.size.calibration = area
touch.size.scale = 28
touch.size.bias = 0
touch.size.isSummed = 0

# Pressure
# Driver reports signal strength as pressure.
#
# A normal index finger touch typically registers about 80 signal strength
# units although we don't expect these values to be accurate.
touch.pressure.calibration = amplitude
touch.pressure.scale = 0.0125

# Orientation
touch.orientation.calibration = vector

Примечания о совместимости

The configuration properties for touch devices changed significantly in Android Ice Cream Sandwich 4.0. All input device configuration files for touch devices must be updated to use the new configuration properties.

Older touch device drivers might also need to be updated.

Virtual key map files

Touch devices can be used to implement virtual keys.

There are several ways of doing this, depending on the capabilities of the touch controller. Some touch controllers can be directly configured to implement soft keys by setting firmware registers. Other times it is desirable to perform the mapping from touch coordinates to key codes in software.

When virtual keys are implemented in software, the kernel must export a virtual key map file called virtualkeys.<devicename> as a board property. For example, if the touch screen device drivers reports its name as "touchyfeely" then the virtual key map file must have the path /sys/board_properties/virtualkeys.touchyfeely .

A virtual key map file describes the coordinates and Linux key codes of virtual keys on the touch screen.

In addition to the virtual key map file, there must be a corresponding key layout file and key character map file to map the Linux key codes to Android key codes and to specify the type of the keyboard device (usually SPECIAL_FUNCTION ).

Синтаксис

A virtual key map file is a plain text file consisting of a sequence of virtual key layout descriptions either separated by newlines or by colons.

Comment lines begin with '#' and continue to the end of the line.

Each virtual key is described by 6 colon-delimited components:

  • 0x01 : A version code. Must always be 0x01 .
  • <Linux key code>: The Linux key code of the virtual key.
  • <centerX>: The X pixel coordinate of the center of the virtual key.
  • <centerY>: The Y pixel coordinate of the center of the virtual key.
  • <width>: The width of the virtual key in pixels.
  • <height>: The height of the virtual key in pixels.

All coordinates and sizes are specified in terms of the display coordinate system.

Here is a virtual key map file all written on one line.

# All on one line
0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55

The same virtual key map file can also be written on multiple lines.

# One key per line
0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

In the above example, the touch screen has a resolution of 480x800. Accordingly, all of the virtual keys have a <centerY> coordinate of 835, which is a little bit below the visible area of the touch screen.

The first key has a Linux scan code of 158 ( KEY_BACK ), centerX of 55 , centerY of 835 , width of 90 , and height of 55 .

Пример

Virtual key map file: /sys/board_properties/virtualkeys.touchyfeely .

0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

Key layout file: /system/usr/keylayout/touchyfeely.kl .

key 158 BACK
key 139 MENU
key 172 HOME
key 217 SEARCH

Key character map file: /system/usr/keychars/touchyfeely.kcm .

type SPECIAL_FUNCTION

Indirect multi-touch pointer gestures

In pointer mode, the system interprets the following gestures:

  • Single finger tap: click.
  • Single finger motion: move the pointer.
  • Single finger motion plus button presses: drag the pointer.
  • Two finger motion both fingers moving in the same direction: drag the area under the pointer in that direction. The pointer itself does not move.
  • Two finger motion both fingers moving towards each other or apart in different directions: pan/scale/rotate the area surrounding the pointer. The pointer itself does not move.
  • Multiple finger motion: freeform gesture.

Palm rejection

As of Android 13, the system can automatically reject inputs from palms when the built-in framework is enabled. In-house, custom-built solutions are still supported, though they might need to be modified to return the TOOL_TYPE_PALM flag when a palm is detected. The built-in framework also works in conjunction with custom solutions.

The actual model looks at the first 90 ms of gesture data, at the current pointer, and at the surrounding pointers, then considers how far away from the display edge the touches are. It then determines, on a per-pointer basis, which of the pointers are palms. It also takes into account the size of each contact, as reported by touchMajor and touchMinor . The Android framework then removes the pointers that are marked as palms from the touch stream.

If a pointer was already sent to the apps, then the system either:

  • (If there are other active pointers) Cancels the pointer with ACTION_POINTER_UP and FLAG_CANCELED set.
  • (If this is the only pointer) Cancels the pointer with ACTION_CANCEL .

A public API, MotionEvent.FLAG_CANCELED , indicates that the current event shouldn't trigger user action. This flag is set for both ACTION_CANCEL and ACTION_POINTER_UP .

If the palm pointer wasn't sent to apps, then the system simply drops the pointer.

Enable palm rejection

  1. In your touch driver, use the input_abs_set_res macro to set the resolutions for the following fields (units are pixels per mm ):
    • ABS_MT_POSITION_X
    • ABS_MT_POSITION_Y
    • ABS_MT_TOUCH_MAJOR
    • ABS_MT_TOUCH_MINOR

    Support for ABS_MT_TOUCH_MINOR is optional. However, if your device does support it, make sure the resolution is set correctly.

  2. To confirm the fields are set correctly, run:
        $ adb shell getevent -li
    
  3. To enable the feature during runtime, run:
        $ adb shell device_config put input_native_boot palm_rejection_enabled 1
    
  4. Restart the system_server process.
         $ adb shell stop && adb shell start
        
  5. Confirm that adb shell dumpsys input shows that there are palm rejectors inside UnwantedInteractionBlocker . If it doesn't, check the input-related logs to find clues on what might be misconfigured.

    See the following example for reference:

    UnwantedInteractionBlocker:
      mEnablePalmRejection: true
      isPalmRejectionEnabled (flag value): true
      mPalmRejectors:
        deviceId = 3:
          mDeviceInfo:
            max_x = 
            max_y = 
            x_res = 11.00
            y_res = 11.00
            major_radius_res = 1.00
            minor_radius_res = 1.00
            minor_radius_supported = true
            touch_major_res = 1
            touch_minor_res = 1
          mSlotState:
            mSlotsByPointerId:
    
            mPointerIdsBySlot:
    
          mSuppressedPointerIds: {}
    
  6. To permanently enable the feature, add the corresponding sysprop command in your init**rc file:

    setprop persist.device_config.input_native_boot.palm_rejection_enabled 1
    

Дальнейшее чтение