Android supports a variety of touch screens and touch pads, including
stylus-based digitizer tablets.
Touch screens
are touch devices that are associated with a display such that
the user has the impression of directly manipulating items on screen.
Touch pads
are touch devices that aren't associated with a display, such as a
digitizer tablet. Touch pads are typically used for pointing or for
absolute indirect positioning or gesture-based control of a user interface.
Touch devices can have buttons whose functions are similar to mouse buttons.
Touch devices can sometimes be manipulated using a variety of different tools
such as fingers or a stylus depending on the underlying touch sensor technology.
Touch devices are sometimes used to implement virtual keys. For example, on
some Android devices, the touch screen sensor area extends beyond the edge of
the display and serves dual purpose as part of a touch sensitive key pad.
Due to the great variety of touch devices, Android relies on a large number of
configuration properties to describe the characteristics and desired behavior
of each device.
Touch device classification
An input device is classified as a
multi-touch
device if both of
the following conditions hold:
- The input device reports the presence of the
ABS_MT_POSITION_X
and
ABS_MT_POSITION_Y
absolute axes.
- The input device does not have any gamepad buttons. This condition
resolves an ambiguity with certain gamepads that report axes with codes
that overlaps those of the MT axes.
An input device is classified as a
single-touch
device if both of the
following conditions hold:
- The input device is not classified as a multi-touch device. An input device
is either classified as a single-touch device or as a multi-touch device,
never both.
- The input device reports the presence of the
ABS_X
and
ABS_Y
absolute
axes, and the presence of the
BTN_TOUCH
key code.
When an input device is classified as a touch device, the presence
of virtual keys is determined by attempting to load the virtual key map file
for the device. If a virtual key map is available, then the key layout
file for the device is also loaded. Refer to [Virtual key map files](#virtual-key-map-files)
for information about about the location and format of these files.
Next, the system loads the input device configuration file for the touch device.
All built-in touch devices should have input device configuration files.
If no input device configuration file is present, the system
chooses a default configuration that's appropriate for general-purpose
touch peripherals such as external USB or Bluetooth HID touch screens
or touch pads. These defaults aren't designed for built-in touch screens and
can result in incorrect behavior.
After the input device configuration loaded, the system classifies the
input device as a
touch screen
,
touch pad
, or
pointer
device.
- A
touch screen
device is used for direct manipulation of objects on the
screen. The user directly touches the screen, so the system doesn't
require any additional affordances to indicate the objects being
manipulated.
- A
touch pad
device is used to provide absolute positioning information
to an app about touches on a given sensor area. It can be useful
for digitizer tablets.
- A
pointer
device is used for indirect manipulation of objects on the
screen using a cursor. Fingers are interpreted as multi-touch pointer
gestures. Other tools, such as styluses, are interpreted using
absolute positions. See
Indirect multi-touch pointer
gestures
for more information.
The following rules are used to classify the input device as a touch screen,
touch pad, or pointer device.
- If the
touch.deviceType
property is set, then the device type is
set as indicated.
- If the input device reports the presence of the
INPUT_PROP_DIRECT
input property (through the
EVIOCGPROP
ioctl), then the device type is
set to
touch screen
. This condition assumes that direct input touch
devices are attached to a display that is also connected.
- If the input device reports the presence of the
INPUT_PROP_POINTER
input property (through the
EVIOCGPROP
ioctl), then the device type
set to
pointer
.
- If the input device reports the presence of the
REL_X
or
REL_Y
relative axes, then the device type is set to
touch pad
. This condition
resolves an ambiguity for input devices that consist of both a mouse and
a touch pad. In this case, the touch pad isn't used to control
the pointer because the mouse already controls it.
- Otherwise, the device type is set to
pointer
. This default ensures
that touch pads that haven't been designated any other special purpose
control the pointer.
Buttons are
optional
controls that apps can use to perform
additional functions. Buttons on touch devices behave similarly to mouse
buttons and are mainly of use with
pointer
type touch devices or with a
stylus.
The following buttons are supported:
BTN_LEFT
: Mapped to
MotionEvent.BUTTON_PRIMARY
.
BTN_RIGHT
: Mapped to
MotionEvent.BUTTON_SECONDARY
.
BTN_MIDDLE
: Mapped to
MotionEvent.BUTTON_MIDDLE
.
BTN_BACK
and
BTN_SIDE
: Mapped to
MotionEvent.BUTTON_BACK
.
Pressing this button also synthesizes a key press with the key code
KeyEvent.KEYCODE_BACK
.
BTN_FORWARD
and
BTN_EXTRA
: Mapped to
MotionEvent.BUTTON_FORWARD
. Pressing this button also synthesizes a key press
with the key code
KeyEvent.KEYCODE_FORWARD
.
BTN_STYLUS
: Mapped to
MotionEvent.BUTTON_SECONDARY
.
BTN_STYLUS2
: Mapped to
MotionEvent.BUTTON_TERTIARY
.
A
tool
is a finger, stylus, or other apparatus that is used to interact with
the touch device. Some touch devices can distinguish between different
types of tools.
Elsewhere in Android, as in the
MotionEvent
API, a tool is often referred
to as a
pointer
.
The following tool types are supported:
BTN_TOOL_FINGER
and
MT_TOOL_FINGER
: Mapped to
MotionEvent.TOOL_TYPE_FINGER
.
BTN_TOOL_PEN
and
MT_TOOL_PEN
: Mapped to
MotionEvent.TOOL_TYPE_STYLUS
.
BTN_TOOL_RUBBER
: Mapped to
MotionEvent.TOOL_TYPE_ERASER
.
BTN_TOOL_BRUSH
: Mapped to
MotionEvent.TOOL_TYPE_STYLUS
.
BTN_TOOL_PENCIL
: Mapped to
MotionEvent.TOOL_TYPE_STYLUS
.
BTN_TOOL_AIRBRUSH
: Mapped to
MotionEvent.TOOL_TYPE_STYLUS
.
BTN_TOOL_MOUSE
: Mapped to
MotionEvent.TOOL_TYPE_MOUSE
.
BTN_TOOL_LENS
: Mapped to
MotionEvent.TOOL_TYPE_MOUSE
.
BTN_TOOL_DOUBLETAP
,
BTN_TOOL_TRIPLETAP
, and
BTN_TOOL_QUADTAP
: Mapped to
MotionEvent.TOOL_TYPE_FINGER
.
Tools can either be in contact with the touch device or in range and hovering
above it. Not all touch devices can sense the presence of a tool
hovering above the touch device. Those that do, such as RF-based stylus digitizers,
can often detect when the tool is within a limited range of the digitizer.
The
InputReader
component distinguishes touching tools from hovering
tools. Likewise, touching tools and hovering tools are reported to apps
in different ways.
Touching tools are reported to apps as touch events
using
MotionEvent.ACTION_DOWN
,
MotionEvent.ACTION_MOVE
,
MotionEvent.ACTION_DOWN
,
MotionEvent.ACTION_POINTER_DOWN
and
MotionEvent.ACTION_POINTER_UP
.
Hovering tools are reported to apps as generic motion events using
MotionEvent.ACTION_HOVER_ENTER
,
MotionEvent.ACTION_HOVER_MOVE
,
and
MotionEvent.ACTION_HOVER_EXIT
.
Touch device driver requirements
- Touch device drivers should register only the axes and key codes for the axes
and buttons that they support. Registering unsupported axes or key codes
can confuse the device classification algorithm or cause the system to incorrectly
detect the capabilities of the device. For example, if the device reports the
BTN_TOUCH
key code, the system
assumes that
BTN_TOUCH
is always used to indicate whether the tool is
touching the screen. Therefore,
BTN_TOUCH
shouldn't be used to indicate
that the tool is merely in the range and hovering.
- Single-touch devices use the following Linux input events:
ABS_X
:
(REQUIRED)
Reports the X coordinate of the tool.
ABS_Y
:
(REQUIRED)
Reports the Y coordinate of the tool.
ABS_PRESSURE
:
(optional)
Reports the physical pressure applied to the tip
of the tool or the signal strength of the touch contact.
ABS_TOOL_WIDTH
:
(optional)
Reports the cross-sectional area or width of
the touch contact or of the tool itself.
ABS_DISTANCE
:
(optional)
Reports the distance of the tool from the surface
of the touch device.
ABS_TILT_X
:
(optional)
Reports the tilt of the tool from the surface of
the touch device along the X axis.
ABS_TILT_Y
:
(optional)
Reports the tilt of the tool from the surface of
the touch device along the Y axis.
BTN_TOUCH
:
(REQUIRED)
Indicates whether the tool is touching the
device.
BTN_LEFT
,
BTN_RIGHT
,
BTN_MIDDLE
,
BTN_BACK
,
BTN_SIDE
,
BTN_FORWARD
,
BTN_EXTRA
,
BTN_STYLUS
,
BTN_STYLUS2
:
(optional)
Reports
button
states.
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
:
(optional)
Reports the
tool type
.
- Multi-touch devices use the following Linux input events:
ABS_MT_POSITION_X
:
(REQUIRED)
Reports the X coordinate of the tool.
ABS_MT_POSITION_Y
:
(REQUIRED)
Reports the Y coordinate of the tool.
ABS_MT_PRESSURE
:
(optional)
Reports the physical pressure applied to the
tip of the tool or the signal strength of the touch contact.
ABS_MT_TOUCH_MAJOR
:
(optional)
Reports the cross-sectional area of the
touch contact, or the length of the longer dimension of the touch contact.
ABS_MT_TOUCH_MINOR
:
(optional)
Reports the length of the shorter dimension
of the touch contact. This axis should not be used if
ABS_MT_TOUCH_MAJOR
is
reporting an area measurement.
ABS_MT_WIDTH_MAJOR
:
(optional)
Reports the cross-sectional area of the
tool itself, or the length of the longer dimension of the tool itself. Don't use this axis
unless you know the dimensions of the tool itself.
ABS_MT_WIDTH_MINOR
:
(optional)
Reports the length of the shorter dimension
of the tool itself. This axis should not be used if
ABS_MT_WIDTH_MAJOR
is reporting
an area measurement or if the dimensions of the tool itself are unknown.
ABS_MT_ORIENTATION
:
(optional)
Reports the orientation of the tool.
ABS_MT_DISTANCE
:
(optional)
Reports the distance of the tool from the
surface of the touch device.
ABS_MT_TOOL_TYPE
:
(optional)
Reports the
tool type
as
MT_TOOL_FINGER
or
MT_TOOL_PEN
.
ABS_MT_TRACKING_ID
:
(optional)
Reports the tracking ID of the tool.
The tracking ID is an arbitrary non-negative integer that is used to identify
and track each tool independently when multiple tools are active. For example,
when multiple fingers are touching the device, each finger should be assigned a distinct
tracking ID that is used as long as the finger remains in contact. Tracking IDs
can be reused when their associated tools move out of range.
ABS_MT_SLOT
:
(optional)
Reports the slot ID of the tool, when using the
Linux multi-touch protocol 'B'. Refer to the Linux multi-touch protocol documentation
for more details.
BTN_TOUCH
:
(REQUIRED)
Indicates whether the tool is touching the
device.
BTN_LEFT
,
BTN_RIGHT
,
BTN_MIDDLE
,
BTN_BACK
,
BTN_SIDE
,
BTN_FORWARD
,
BTN_EXTRA
,
BTN_STYLUS
,
BTN_STYLUS2
:
(optional)
Reports
button
states.
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
:
(optional)
Reports the
tool type
.
- If axes for both the single-touch and multi-touch protocol are defined, then
only the multi-touch axes are used and the single-touch axes are ignored.
The minimum and maximum values of the
ABS_X
,
ABS_Y
,
ABS_MT_POSITION_X
,
and
ABS_MT_POSITION_Y
axes define the bounds of the active area of the device
in device-specific surface units. In the case of a touch screen, the active area
describes the part of the touch device that actually covers the display.
For a touch screen, the system automatically interpolates the reported touch
positions in surface units to obtain touch positions in display pixels according
to the following calculation:
displayX = (x - minX) * displayWidth / (maxX - minX + 1)
displayY = (y - minY) * displayHeight / (maxY - minY + 1)
A touch screen might report touches outside of the reported active area.
Touches that are initiated outside the active area are not delivered to apps
but can be used for virtual keys.
Touches that are initiated inside the active area, or that enter and exit the display
area are delivered to apps. Consequently, if a touch starts within the
bounds of an app and then moves outside of the active area, the app
might receive touch events with display coordinates that are negative or beyond the
bounds of the display. This is expected behavior.
A touch device should never clamp touch coordinates to the bounds of the active
area. If a touch exits the active area, it should be reported as being outside of
the active area, or it should not be reported at all.
For example, if the user's finger is touching near the top-left corner of the
touch screen, it might report a coordinate of (minX, minY). If the finger continues
to move further outside of the active area, the touch screen should either start
reporting coordinates with components less than minX and minY, such as
(minX - 2, minY - 3), or it should stop reporting the touch altogether.
In other words, the touch screen should
not
be reporting (minX, minY)
when the user's finger is really touching outside of the active area.
Clamping touch coordinates to the display edge creates an artificial
hard boundary around the edge of the screen which prevents the system from
smoothly tracking motions that enter or exit the bounds of the display area.
The values reported by
ABS_PRESSURE
or
ABS_MT_PRESSURE
, if they
are reported at all, must be non-zero when the tool is touching the device
and zero otherwise to indicate that the tool is hovering.
Reporting pressure information is
optional
but strongly recommended.
Apps can use pressure information to implement pressure-sensitive drawing
and other effects.
The values reported by
ABS_TOOL_WIDTH
,
ABS_MT_TOUCH_MAJOR
,
ABS_MT_TOUCH_MINOR
,
ABS_MT_WIDTH_MAJOR
, or
ABS_MT_WIDTH_MINOR
should be non-zero when the tool
is touching the device and zero otherwise, but this isn't required.
For example, the touch device might be able to measure the size of finger touch
contacts but not stylus touch contacts.
Reporting size information is
optional
but strongly recommended.
Apps can use pressure information to implement size-sensitive drawing
and other effects.
The values reported by
ABS_DISTANCE
or
ABS_MT_DISTANCE
should
approach zero when the tool is touching the device. The distance can remain non-zero
even when the tool is in direct contact. The exact values reported depend
on the manner in which the hardware measures distance.
Reporting distance information is
optional
but recommended for
stylus devices.
The values reported by
ABS_TILT_X
and
ABS_TILT_Y
should be zero
when the tool is perpendicular to the device. A non-zero tilt indicates
that the tool is held at an incline.
The tilt angles along the X and Y axes are assumed to be specified in degrees
from perpendicular. The center point (perfectly perpendicular) is given
by
(max + min) / 2
for each axis. Values smaller than the center point
represent a tilt up or to the left, values larger than the center point
represent a tilt down or to the right.
InputReader
converts the X and Y tilt components into a perpendicular
tilt angle ranging from 0 to
PI / 2
radians and a planar orientation angle
ranging from
-PI
to
PI
radians. This representation results in a
description of orientation that is compatible with what is used to describe
finger touches.
Reporting tilt information is
optional
but recommended for stylus devices.
If the tool type is reported by
ABS_MT_TOOL_TYPE
, it supersedes any tool
type information reported by
BTN_TOOL_*
.
If no tool type information is available at all, the tool type defaults to
MotionEvent.TOOL_TYPE_FINGER
.
A tool is determined to be active based on the following conditions:
When using the single-touch protocol, the tool is active if
BTN_TOUCH
,
or
BTN_TOOL_*
is 1.
This condition implies that
InputReader
needs to have at least some
information about the nature of the tool, either whether it is touching,
or at least its tool type. If no information is available,
then the tool is assumed to be inactive (out of range).
- When using the multi-touch protocol 'A', the tool is active whenever it
appears in the most recent sync report. When the tool stops appearing in
sync reports, it ceases to exist.
- When using the multi-touch protocol 'B', the tool is active as long as
it has an active slot. When the slot it cleared, the tool ceases to exist.
- A tool is determined to be hovering based on the following conditions:
- If the tool is
BTN_TOOL_MOUSE
or
BTN_TOOL_LENS
, then the tool
is not hovering, even if either of the following conditions are true.
- If the tool is active and the driver reports pressure information,
and the reported pressure is zero, then the tool is hovering.
- If the tool is active and the driver supports the
BTN_TOUCH
key code and
BTN_TOUCH
has a value of zero, then the tool is hovering.
InputReader
supports both multi-touch protocol 'A' and 'B'. New drivers
should use the 'B' protocol but either works.
As of Android 4.0, touch screen drivers might need to be changed
to comply with the Linux input protocol specification.
The following changes might be required:
When a tool becomes inactive (finger goes "up"), it should stop appearing
in subsequent multi-touch sync reports. When all tools become inactive
(all fingers go "up"), the driver should send an empty sync report packet,
such as
SYN_MT_REPORT
followed by
SYN_REPORT
.
Previous versions of Android expected "up" events to be reported by sending
a pressure value of 0. The old behavior was incompatible with the
Linux input protocol specification and is no longer supported.
Physical pressure or signal strength information should be reported using
ABS_MT_PRESSURE
.
Previous versions of Android retrieved pressure information
from
ABS_MT_TOUCH_MAJOR
. The old behavior was incompatible with the
Linux input protocol specification and is no longer supported.
- Touch size information should be reported using
ABS_MT_TOUCH_MAJOR
.
Previous versions of Android retrieved size information from
ABS_MT_TOOL_MAJOR
. The old behavior was incompatible with the
Linux input protocol specification and is no longer supported.
Touch device drivers no longer need Android-specific customizations.
By relying on the standard Linux input protocol, Android can support a
wider variety of touch peripherals, such as external HID multi-touch
touch screens, using unmodified drivers.
Touch device operation
The following is a brief summary of the touch device operation on Android.
EventHub
reads raw events from the
evdev
driver.
InputReader
consumes the raw events and updates internal state about
the position and other characteristics of each tool. It also tracks
button states.
- If
BACK
or
FORWARD
was pressed or released,
InputReader
notifies
InputDispatcher
about the key event.
InputReader
determines whether a virtual key press occurred. If so,
it notifies
InputDispatcher
about the key event.
InputReader
determines whether the touch was initiated within the
bounds of the display. If so, it notifies
InputDispatcher
about
the touch event.
- If there are no touching tools but there is at least one hovering tool,
InputReader
notifies
InputDispatcher
about the hover event.
- If the touch device type is
pointer
,
InputReader
performs pointer
gesture detection, moves the pointer and spots accordingly and notifies
InputDispatcher
about the pointer event.
InputDispatcher
uses
WindowManagerPolicy
to determine whether
the events should be dispatched and whether they should wake the device.
Then,
InputDispatcher
delivers the events to the appropriate apps.
Touch device configuration
Touch device behavior is determined by the device's axes, buttons, input properties,
input device configuration, virtual key map and key layout.
Refer to the following sections for more details about the files that
participate in keyboard configuration:
Properties
The system relies on many input device configuration properties to configure
and calibrate touch device behavior.
One reason for this is that the device drivers for touch devices often report
the characteristics of touches using device-specific units.
For example, many touch devices measure the touch contact area
using an internal device-specific scale, such as the total number of
sensor nodes that were triggered by the touch. This raw size value would
not be meaningful to apps because they would need to know about the
physical size and other characteristics of the touch device sensor nodes.
The system uses calibration parameters encoded in input device configuration
files to decode, transform, and normalize the values reported by the touch
device into a simpler standard representation that apps can understand.
Documentation conventions
For documentation purposes, we use the following conventions to describe
the values used by the system during the calibration process.
Raw axis values
The following expressions denote the raw values reported by the touch
device driver as
EV_ABS
events.
raw.x
- The value of the
ABS_X
or
ABS_MT_POSITION_X
axis.
raw.y
- The value of the
ABS_Y
or
ABS_MT_POSITION_Y
axis.
raw.pressure
- The value of the
ABS_PRESSURE
or
ABS_MT_PRESSURE
axis, or 0 if
not available.
raw.touchMajor
- The value of the
ABS_MT_TOUCH_MAJOR
axis, or 0 if not available.
raw.touchMinor
- The value of the
ABS_MT_TOUCH_MINOR
axis, or
raw.touchMajor
if
not available.
raw.toolMajor
- The value of the
ABS_TOOL_WIDTH
or
ABS_MT_WIDTH_MAJOR
axis, or 0 if
not available.
raw.toolMinor
- The value of the
ABS_MT_WIDTH_MINOR
axis, or
raw.toolMajor
if not
available.
raw.orientation
- The value of the
ABS_MT_ORIENTATION
axis, or 0 if not available.
raw.distance
- The value of the
ABS_DISTANCE
or
ABS_MT_DISTANCE
axis, or 0 if
not available.
raw.tiltX
- The value of the
ABS_TILT_X
axis, or 0 if not available.
raw.tiltY
- The value of the
ABS_TILT_Y
axis, or 0 if not available.
Raw axis ranges
The following expressions denote the bounds of raw values. They are obtained
by calling
EVIOCGABS
ioctl for each axis.
raw.*.min
- The inclusive minimum value of the raw axis.
raw.*.max
- The inclusive maximum value of the raw axis.
raw.*.range
- Equivalent to
raw.*.max - raw.*.min
.
raw.*.fuzz
- The accuracy of the raw axis. eg. fuzz = 1 implies values are accurate to +/- 1 unit.
raw.width
- The inclusive width of the touch area, equivalent to
raw.x.range + 1
.
raw.height
- The inclusive height of the touch area, equivalent to
raw.y.range + 1
.
Output ranges
The following expressions denote the characteristics of the output coordinate system.
The system uses linear interpolation to translate touch position information from
the surface units used by the touch device into the output units that are
reported to apps such as display pixels.
output.width
- The output width. For touch screens (associated with a display), this
is the display width in pixels. For touch pads (not associated with a display),
the output width equals
raw.width
, indicating that no interpolation
is performed.
output.height
- The output height. For touch screens (associated with a display), this
is the display height in pixels. For touch pads (not associated with a display),
the output height equals
raw.height
, indicating that no interpolation is
performed.
output.diag
- The diagonal length of the output coordinate system, equivalent to
sqrt(output.width ^2 + output.height ^2)
.
Basic configuration
The touch input mapper uses many configuration properties in the input device
configuration file to specify calibration values. The following table describes
some general purpose configuration properties. All other properties are described
in the following sections along with the fields they are used to calibrate.
touch.deviceType
Definition:
touch.deviceType
=
touchScreen
|
touchPad
|
pointer
|
default
Specifies the touch device type.
-
If the value is
touchScreen
, the touch device is a touch screen associated
with a display.
-
If the value is
touchPad
, the touch device is a touch pad not associated
with a display.
-
If the value is
pointer
, the touch device is a touch pad not associated
with a display, and its motions are used for
indirect multi-touch pointer gestures
.
-
If the value is
default
, the system automatically detects the device type
according to the classification algorithm.
Refer to the
Classification
section for more details
about how the device type influences the behavior of the touch device.
In Android 3 and lower, all touch devices were assumed to be touch screens.
touch.orientationAware
Definition:
touch.orientationAware
=
0
|
1
Specifies whether the touch device should react to display orientation changes.
-
If the value is
1
, touch positions reported by the touch device are rotated
whenever the display orientation changes.
-
If the value is
0
, touch positions reported by the touch device are immune
to display orientation changes.
The default value is
1
if the device is a touch screen,
0
otherwise.
The system distinguishes between internal and external touch screens and displays.
An orientation aware internal touch screen is rotated based on the orientation
of the internal display. An orientation aware external touch screen is rotated
based on the orientation of the external display.
Orientation awareness is used to support rotation of touch screens on devices
like the Nexus One. For example, when the device is rotated clockwise 90 degrees
from its natural orientation, the absolute positions of touches are remapped such
that a touch in the top-left corner of the touch screen's absolute coordinate system
is reported as a touch in the top-left corner of the display's rotated coordinate system.
This is done so that touches are reported with the same coordinate system that
apps use to draw their visual elements.
Prior to Honeycomb, all touch devices were assumed to be orientation aware.
touch.gestureMode
Definition:
touch.gestureMode
=
pointer
|
spots
|
default
Specifies the presentation mode for pointer gestures. This configuration property
is only relevant when the touch device is of type
pointer
.
-
If the value is
pointer
, the touch pad gestures are presented by way of a cursor
similar to a mouse pointer.
-
If the value is
spots
, the touch pad gestures are presented by an anchor
that represents the centroid of the gesture and a set of circular spots
that represent the position of individual fingers.
The default value is
pointer
when the
INPUT_PROP_SEMI_MT
input property
is set, or
spots
otherwise.
X and Y fields
The X and Y fields provide positional information for the center of the contact area.
Calculation
The calculation is straightforward: positional information from the touch driver is
linearly interpolated to the output coordinate system.
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
The
touchMajor
and
touchMinor
fields describe the approximate dimensions
of the contact area in output units (pixels).
The
toolMajor
and
toolMinor
fields describe the approximate dimensions
of the
tool
itself in output units (pixels).
The
size
field describes the normalized size of the touch relative to
the largest possible touch that the touch device can sense. The smallest
possible normalized size is 0.0 (no contact, or it is unmeasurable), and the largest
possible normalized size is 1.0 (sensor area is saturated).
When both the approximate length and breadth can be measured, then the
touchMajor
field
specifies the longer dimension and the
touchMinor
field specifies the shorter dimension
of the contact area. When only the approximate diameter of the contact area can be measured,
then the
touchMajor
and
touchMinor
fields are equal.
Likewise, the
toolMajor
field specifies the longer dimension and the
toolMinor
field specifies the shorter dimension of the tool's cross-sectional area.
If the touch size is unavailable but the tool size is available, then the tool size
is set equal to the touch size. Conversely, if the tool size is unavailable
but the touch size is available, then the touch size is set equal to the tool size.
Touch devices measure or report the touch size and tool size in various ways.
The current implementation supports three different kinds of measurements:
diameter, area, and geometric bounding box in surface units.
Definition:
touch.size.calibration
=
none
|
geometric
|
diameter
|
area
|
default
Specifies the kind of measurement used by the touch driver to report the
touch size and tool size.
-
If the value is
none
, the size is set to zero.
-
If the value is
geometric
, the size is assumed to be specified in the same
surface units as the position, so it is scaled in the same manner.
-
If the value is
diameter
, the size is assumed to be proportional to
the diameter (width) of the touch or tool.
-
If the value is
area
, the size is assumed to be proportional to the
area of the touch or tool.
-
If the value is
default
, the system uses the
geometric
calibration if the
raw.touchMajor
or
raw.toolMajor
axis is available, otherwise it uses
the
none
calibration.
touch.size.scale
Definition:
touch.size.scale
= <a non-negative floating point number>
Specifies a constant scale factor used in the calibration.
The default value is
1.0
.
touch.size.bias
Definition:
touch.size.bias
= <a non-negative floating point number>
Specifies a constant bias value used in the calibration.
The default value is
0.0
.
touch.size.isSummed
Definition:
touch.size.isSummed
=
0
|
1
Specifies whether the size is reported as the sum of the sizes of all
active contacts, or is reported individually for each contact.
-
If the value is
1
, the reported size is divided by the number
of contacts prior to use.
-
If the value is
0
, the reported size is used as is.
The default value is
0
.
Some touch devices, particularly "Semi-MT" devices cannot distinguish the
individual dimensions of multiple contacts so they report a size measurement
that represents their total area or width. This property should only be set to
1
for such devices. If in doubt, set this value to
0
.
Calculation
The calculation of the
touchMajor
,
touchMinor
,
toolMajor
,
toolMinor
,
and
size
fields depends on the specified calibration parameters.
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 field
The
pressure
field describes the approximate physical pressure applied to the
touch device as a normalized value between 0.0 (no touch) and 1.0 (normal pressure).
A zero pressure indicates that the tool is hovering.
touch.pressure.calibration
Definition:
touch.pressure.calibration
=
none
|
physical
|
amplitude
|
default
Specifies the kind of measurement used by the touch driver to report the pressure.
-
If the value is
none
, the pressure is unknown so it is set to 1.0 when
touching and 0.0 when hovering.
-
If the value is
physical
, the pressure axis is assumed to measure the actual
physical intensity of pressure applied to the touch pad.
-
If the value is
amplitude
, the pressure axis is assumed to measure the signal
amplitude, which is related to the size of the contact and the pressure applied.
-
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
.
Calculation
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
.
Calculation
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
.
Calculation
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
Example
# 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
Compatibility notes
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
).
Syntax
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
.
Example
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
- 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.
- To confirm the fields are set correctly, run:
$ adb shell getevent -li
- To enable the feature during runtime, run:
$ adb shell device_config put input_native_boot palm_rejection_enabled 1
- Restart the
system_server
process.
$ adb shell stop && adb shell start
- 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: {}
- 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
Further reading