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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Если задано свойство 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

Определение: 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, size fields

Поля 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

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

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

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

touch.size.bias

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

  • Если значение установлено default , система использует physical калибровку, если ось давления доступна, в противном случае не использует 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.

Отторжение ладони

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
    

Дополнительная информация