0%

[原创] 简介 Android 多点触控协议及 getevent 使用方法

阅读提示

老习惯,考虑到大忙人很多,为了节省您的时间,先说一下哪些人适合阅读本文。

  • 想了解 Android 多点触控协议
  • 想了解 getevent 的使用方法及解析方法

若您满足以下情况之一,您就可以跳过本文章:

  • 不需要 App 自身拥有“系统级”的全局获取用户触控点坐标的能力
  • 不需要通过 getevent 获取触控信息
  • 只需要获取到自身应用范围内的触控点坐标

前言

本文着重介绍了Android 多点触控协议的相关知识及 adb 命令 getevent 的数据解析方法。具体的程序实现并不是本文的重点。

项目需求

  1. 需要 App 本身能“系统级”的全局获取用户的触控点坐标。并且不能影响触控操作本身。也就是说不能影响用户正常使用手机。
  2. 手机不能 ROOT。
  3. 手机可以连接电脑,但是不能一直连接电脑。

关于 需求1 的示例说明:例如,用户点击了桌面上的“日历” App,在我们自己的 App 中需要获取到用户所点击的坐标,并且用户的点击操作不能受到影响,“日历” App 是可以正常启动的。又比如用户正在玩游戏,我们需要获取到用户所有操作的触控信息。

分析与实现方法

分析

如果是仅获取我们应用自身的触控信息自然是很容易的,但是我们的需求是“系统级”的获取用户触控信息,也就是说还要获取用户在其它应用上的触控信息,很显然这种操作是无法通过 App 本身来实现的,因为这属于危险级权限功能。

那么,可行的方案我们很自然会想到 adb 命令 getevent 可以实现获取全局点击坐标的要求,但是该命令是无法直接在 App 里调用的。原因显而易见,这种危险级操作App 级权限当然是不够的,至少需要shell 级的权限。

实现思路

通过上面的分析,再结合需求3:手机可以连接电脑,这样的话就可以在电脑上通过 adb shell 启动一个 Android 可执行程序,从而让该程序拥有 shell 级 权限,这样我们就可以调用 getevent 命令获取触控信息了。之后该程序再与 App 通信,将获取到的触控信息发送给 App 即可。

这里的关键是我们需要有一个Android 可执行程序。实现Android 可执行程序的方法也有很多,可以是 dex 也可以是其它在 Android 上编译的 C 或 C++ 程序。当然还可以使用像 Go 语言这样的编程语言,直接将程序编译成可以在 Android 上执行的程序。

此外,我们可以在该可执行程序中创建一个守护进程,让程序一直执行,这样程序就不会随着 adb 终端的断开而停止,因此就不需要手机一直连接电脑了,从而满足需求3的要求。

PS:本人是使用 Go 来实现这个Android 可执行程序的。

具体的实现代码,不是本文要讲的重点。因为程序实现的思路才是最重要的,有了思路程序自然就好写了。

正文

先说一个结论:

从 Android 内核 4.14 开始,仅支持多点触控协议“类型 B”。内核驱动程序会将多点触控协议“类型 A”转换成“类型 B”。[^12][^13]

PS:部分 Android 9,10 支持内核 4.14。Android 11 及之后版本,均支持内核 4.14。后文会有进一步的说明。

至于什么是多点触控协议,可以查看后文关于多点触控协议的说明。如何查看内核版本,以及内核版本与 Android 版本的对应关系,详见后文的关于内核版本

关于 getevent

参数说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [-R] [device]
-t: show time stamps
-n: don't print newlines
-s: print switch states for given bits
-S: print all switch states
-v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)
-d: show HID descriptor, if available
-p: show possible events (errs, dev, name, pos. events)
-i: show all device info and possible events
-l: label event types and names in plain text
-q: quiet (clear verbosity mask)
-c: print given number of events then exit
-r: print rate events are received
-R: print event records which can replay by replayevents

查看输入设备支持的事件信息

  • 查看指定输入设备的事件信息
1
$ getevent -lp /dev/input/event4
  • 查看所有输入设备支持的事件信息

    通过此命令,我们可以知道哪个输入设备是负责处理屏幕事件的。

    通过下面的示例,我们得知 /dev/input/event4 是负责处理屏幕事件的。

1
2
add device 5: /dev/input/event4
name: "sec_touchscreen"

说明:也可以使用 getevent -li-i -p 显示更多信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ getevent -lp # Sony Xperia 1 III(SO-51B) Android 11
...
add device 5: /dev/input/event4
name: "sec_touchscreen"
events:
KEY (0001): KEY_POWER KEY_HOMEPAGE BTN_TOOL_FINGER BTN_TOUCH
01c7
ABS (0003): ABS_X : value 0, min 0, max 1643, fuzz 0, flat 0, resolution 0
ABS_Y : value 0, min 0, max 3839, fuzz 0, flat 0, resolution 0
ABS_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1643, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 3839, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
003e : value 126, min 0, max -1, fuzz 0, flat 0, resolution 0
SW (0005): SW_PEN_INSERTED
input props:
INPUT_PROP_DIRECT
add device 6: /dev/input/event3
...

其它真机测试结果详见“附录”中的“处理屏幕事件的输入设备”。

持续获取屏幕触控事件

这回终于说到我们要讲的重点了。该示例是我们程序中要重点处理的部分,通过该示例,我们就可以持续获取用户在屏幕上的全局触控事件。

说明:getevent 命令虽然也可以指明具体使用哪个输入设备,例如,getevent -lt /dev/input/event4。不过在程序中不太容易准确的识别出到底哪个输入设备是处理屏幕事件的。所以建议使用该命令时,不要指明具体的输入设备。因为同一时间,我们通常只会使用一种输入设备,比如手指触控是最常见的。因此 getevent -l 产生的数据通常都是手指触控产生的。所以使用该命令时,可以不指明输入设备。

虽然感觉通过输入设备的 name 应该也可以确认哪个是处理屏幕事件的,但是这个 name 也不固定,所以程序不太好判断。比如,我遇到过值的有: sec_touchscreentouchscreentouchpanelelan-touchscreenhuawei,ts_kitinput_mt_wrapperfts_ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$ getevent -lt # Sony Xperia 1 III(SO-51B) Android 11
add device 1: /dev/input/event8
name: "lahaina-mtp-snd-card Button Jack"
add device 2: /dev/input/event7
name: "lahaina-mtp-snd-card Headset Jack"
add device 3: /dev/input/event6
name: "SOMC Charger Removal"
add device 4: /dev/input/event5
name: "sec_touchscreen_side"
add device 5: /dev/input/event4
name: "sec_touchscreen"
add device 6: /dev/input/event3
name: "bu520x1nvx"
add device 7: /dev/input/event2
name: "AMS TCS3490 Sensor"
add device 8: /dev/input/event0
name: "qpnp_pon"
add device 9: /dev/input/event1
name: "gpio-keys"
[ 4121295.575564] EV_ABS ABS_MT_SLOT 00000000
[ 4121295.575564] EV_ABS ABS_MT_TRACKING_ID 0000233a
[ 4121295.575564] EV_KEY BTN_TOUCH DOWN
[ 4121295.575564] EV_KEY BTN_TOOL_FINGER DOWN
[ 4121295.575564] EV_ABS ABS_MT_POSITION_X 000004e7
[ 4121295.575564] EV_ABS ABS_MT_POSITION_Y 0000098e
[ 4121295.575564] EV_ABS ABS_MT_TOUCH_MAJOR 00000007
[ 4121295.575564] EV_ABS ABS_MT_TOUCH_MINOR 00000007
[ 4121295.575564] EV_ABS ABS_MT_PRESSURE 00000013
[ 4121295.575564] EV_SYN SYN_REPORT 00000000
[ 4121295.600051] EV_ABS ABS_MT_PRESSURE 00000000
[ 4121295.600051] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 4121295.600051] EV_KEY BTN_TOUCH UP
[ 4121295.600051] EV_KEY BTN_TOOL_FINGER UP
[ 4121295.600051] EV_SYN SYN_REPORT 00000000
...

注意,触控事件的值是 16 进制的。

多点触控协议(Multi-touch (MT) Protocol)

理论上,我们只要解析出上面那个示例的结果,就可以得到用户所点击的屏幕坐标了。不过在解析执行结果之前,我们要先了解一个概念,那就是“多点触控协议”[^14][^15]。

Android 设备的“多点触控协议”一共有两种类型,分别是“类型 A”和“类型 B”。强烈建议大家完整的看一下 Linux kernel 官方文档关于多点触控协议的讲解,以及 Android 官方文档关于触控设备的说明。

需要注意前面“正文”中讲到的:

从 Android 内核 4.14 开始,仅支持多点触控协议“类型 B”。内核驱动程序会将多点触控协议“类型 A”转换成“类型 B”。[^12][^13]

多点触控协议 - 类型 A

多点触控协议类型 A (stateless type A protocol),是无状态的。

大多数手机中,使用“类型 A”的设备并不多。目前我测试过的手机中,在部分“华为”手机上遇到过此种协议。大多数手机还是使用“类型 B”的。

关于“类型 A”官网介绍[^14]如下:

For devices handling anonymous contacts (type A), the protocol
describes how to send the raw data for all contacts to the receiver.

简单理解就是发生多点触控时,“类型 A”无法区分及跟踪是哪个手指产生的触控信息,它只知道触控产生的坐标,并将这些原始触控信息发送给所有接收者。

例如:手指1按在了屏幕(x1, y1)的位置,手指2按在了屏幕(x1, y2)的位置,“类型 A”会将(x1, y1)(x1, y2)发送给所有接收者。

关于“类型 A”,这里有几点需要注意的地方:

  1. 发送的数据中,是不包含“手指信息”的。因为该协议只知道触控点信息,无法识别是哪个手指产生的数据。
  2. 虽然手指2的触控坐标 x1,与 手指1的触控坐标 x1 相同,未发生变化,但是“类型 A”在发送数据时,会将手指2的完整触控点信息,也就是(x1, y2)发送给所有接收者,并不会忽略未变化的数据。
  3. 发送的数据中,数据的顺序并不重要,因为每组数据都包含完整的触控点信息,未变化的数据是不会被忽略的。并且数据的过滤和触控点的跟踪应该由用户自己处理[^18]。

接下来让我们看一下“类型 A”的实例:

1
$ getevent -lt

多点触控协议 - 类型 B

多点触控协议类型 B (stateful type B slot protocol),是有状态的。

目前我测试过的手机中,大多数还是使用“类型 B”的。

关于“类型 B”官网介绍[^14]如下:

For devices capable of tracking identifiable contacts (type B), the protocol describes how to send updates for individual contacts via event slots.

简单理解就是,与“类型 A”相比,发生多点触控时,“类型 B”除了发送坐标外,还会额外发送“手指信息”,用于跟踪是哪个手指产生的数据。而且“类型 B”只发送变化的数据

例如,如果手指1点击了(x1,y1)手指2点击了(x1, y2),那么手指2的触控坐标(x1, y2)中,只有 y2 的信息会被发送,因为 x1 并没有发生变化。这么做的好处是显而易见的,那就是减少了发送的数据量。

对于“类型 B”,内核驱动程序会为每个被识别的触控点分配一个 slot,并且使用这个 slot 上报发生变化的数据。通过修改 slotABS_MT_TRACKING_ID,就可以实现触控点信息的新增,替换,删除。

ABS_MT_TRACKING_ID 的值含义,详见后文“常用的触控事件”中关于“ABS_MT_TRACKING_ID”的部分。

对于“类型 B”,由于只有变化的数据会被上报,因此每一个触摸点的完整信息必须由接收端来维护。接收端收到一条 MT(Multi-touch) 消息,我们就应该更新当前 slot 的相关触控信息。

“类型 A”与“类型 B”的主要区别

  1. “类型 B”多了“手指”识别信息。
  2. “类型 B”仅发送变化的数据。

程序中如何区分“类型 A”与“类型 B”

根据我的个人经验(目前还没有阅读相关源代码),在程序中有以下几种方法可以较为方便的区分“类型 A”与“类型 B”:

  • 执行 getevent -lp 命令时:

    • ABS 中若出现 ABS_MT_SLOT,则为 “类型 B”,否则为“类型 A”。
    • ABS 中若出现 ABS_MT_BLOB_ID,则为 “类型 A”,否则无法断定协议类型。
  • 执行 getevent -l 持续获取触控信息时:

    • 只有“类型 A”中会有 SYN_MT_REPORT 事件。
    • 出现 ABS_MT_BLOB_ID 事件,则为 “类型 A”,否则无法断定协议类型。

注意:“类型 A”中不一定包含 ABS_MT_BLOB_ID,但若包含,则一定是 “类型 A”。

具体测试结果详见“附录”中的“处理屏幕事件的输入设备”。

“类型 A”的触控实例

单点触控 - “类型 A”

接下来让我们看一下“类型 A”的单点触控完整实例:

1
2
3
4
5
6
7
8
9
10
11
$ getevent -ltr /dev/input/event5
[ 589.156475] EV_ABS ABS_MT_PRESSURE 00000010
[ 589.156475] EV_ABS ABS_MT_POSITION_X 00000494
[ 589.156475] EV_ABS ABS_MT_POSITION_Y 00000245
[ 589.156475] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 589.156475] EV_SYN SYN_MT_REPORT 00000000
[ 589.156475] EV_KEY BTN_TOUCH DOWN
[ 589.156475] EV_SYN SYN_REPORT 00000000
[ 589.165118] EV_SYN SYN_MT_REPORT 00000000
[ 589.165118] EV_KEY BTN_TOUCH UP
[ 589.165118] EV_SYN SYN_REPORT 00000000 rate 115

组合官方文档[^14],我们将上述示例做最小化处理:

1
2
3
4
EV_ABS       ABS_MT_POSITION_X    00000494 # 16进制(1172) 触控区域(touching region)中心位置的 X 轴坐标
EV_ABS ABS_MT_POSITION_Y 00000245 # 16进制(581) 触控区域(touching region)中心位置的 X 轴坐标
EV_SYN SYN_MT_REPORT 00000000 # 数据包结尾标识。当前触控事件处理结束标识。准备处理下一组事件
EV_SYN SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束

每一组事件数据包的结尾都会有一个 SYN_MT_REPORT 事件,该事件仅出现在“类型 A”中。代表接收者可以接收当前的触控信息并准备开始接收下一组信息。

如果驱动程序除了上报 ABS_MT 事件外,还上报了 BTN_TOUCHABS_PRESSURE 事件,那么最后一个 SYN_MT_REPORT 可能会被忽略掉。否则,最后的 SYN_REPORT 事件会被 input 核心系统 丢掉,从而导致 0 触控点事件(zero-contact event)发送给用户。

编者注:后半句中的“zero-contact event”不是很理解,不知道“zero-contact”是一个术语啊,还是代表“没有触控”的意思。所以附上原文,请高手解答吧。

If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
last SYN_REPORT will be dropped by the input core, resulting in no
zero-contact event reaching userland.

其它事件含义,后文会有详细讲解。

多点触控 - “类型 A”

我们再来看一下“类型 A”的多点触控完整实例(两点触控):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ getevent -ltr /dev/input/event5 # 两点触控
[ 901.662272] EV_ABS ABS_MT_PRESSURE 00000038
[ 901.662272] EV_ABS ABS_MT_POSITION_X 00000385
[ 901.662272] EV_ABS ABS_MT_POSITION_Y 0000085b
[ 901.662272] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 901.662272] EV_SYN SYN_MT_REPORT 00000000
[ 901.662272] EV_KEY BTN_TOUCH DOWN
[ 901.662272] EV_SYN SYN_REPORT 00000000 rate 0
[ 901.668908] EV_ABS ABS_MT_PRESSURE 00000035
[ 901.668908] EV_ABS ABS_MT_POSITION_X 00000385
[ 901.668908] EV_ABS ABS_MT_POSITION_Y 0000085b
[ 901.668908] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 901.668908] EV_SYN SYN_MT_REPORT 00000000
[ 901.668908] EV_SYN SYN_REPORT 00000000 rate 150
[ 901.678505] EV_ABS ABS_MT_PRESSURE 0000003b
[ 901.678505] EV_ABS ABS_MT_POSITION_X 000001ce
[ 901.678505] EV_ABS ABS_MT_POSITION_Y 00000809
[ 901.678505] EV_ABS ABS_MT_TRACKING_ID 00000001
[ 901.678505] EV_SYN SYN_MT_REPORT 00000000
[ 901.678505] EV_SYN SYN_REPORT 00000000 rate 104
[ 901.685855] EV_ABS ABS_MT_PRESSURE 0000002c
[ 901.685855] EV_ABS ABS_MT_POSITION_X 000001ce
[ 901.685855] EV_ABS ABS_MT_POSITION_Y 00000809
[ 901.685855] EV_ABS ABS_MT_TRACKING_ID 00000001
[ 901.685855] EV_SYN SYN_MT_REPORT 00000000
[ 901.685855] EV_SYN SYN_REPORT 00000000 rate 136
[ 901.693931] EV_SYN SYN_MT_REPORT 00000000
[ 901.693931] EV_KEY BTN_TOUCH UP
[ 901.693931] EV_SYN SYN_REPORT 00000000 rate 123

对其做最小化处理:

1
2
3
4
5
6
7
8
EV_ABS       ABS_MT_POSITION_X    00000385 # 16进制(901)  触控区域(touching region)中心位置的 X 轴坐标            
EV_ABS ABS_MT_POSITION_Y 0000085b # 16进制(2139) 触控区域(touching region)中心位置的 X 轴坐标
EV_SYN SYN_MT_REPORT 00000000 # 数据包结尾标识。当前触控事件处理结束标识。准备处理下一组事件
EV_SYN SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束
EV_ABS ABS_MT_POSITION_X 000001ce # 16进制(462) 触控区域(touching region)中心位置的 X 轴坐标
EV_ABS ABS_MT_POSITION_Y 00000809 # 16进制(2057) 触控区域(touching region)中心位置的 X 轴坐标
EV_SYN SYN_MT_REPORT 00000000 # 数据包结尾标识。当前触控事件处理结束标识。准备处理下一组事件
EV_SYN SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束

“类型 B”的触控实例

单点触控 - “类型 B”

接下来让我们看一下“类型 B”的单点触控完整实例[^19]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ getevent -l /dev/input/event4 # Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61
EV_ABS ABS_MT_SLOT 00000000
EV_ABS ABS_MT_TRACKING_ID 00002375
EV_KEY BTN_TOUCH DOWN
EV_KEY BTN_TOOL_FINGER DOWN
EV_ABS ABS_MT_POSITION_X 0000055e
EV_ABS ABS_MT_POSITION_Y 00000842
EV_ABS ABS_MT_TOUCH_MAJOR 00000007
EV_ABS ABS_MT_TOUCH_MINOR 00000006
EV_ABS ABS_MT_PRESSURE 00000010
EV_SYN SYN_REPORT 00000000
EV_ABS ABS_MT_PRESSURE 00000000
EV_ABS ABS_MT_TRACKING_ID ffffffff
EV_KEY BTN_TOUCH UP
EV_KEY BTN_TOOL_FINGER UP
EV_SYN SYN_REPORT 00000000

我们结合官方文档[^14],将上面“类型 B”的实例做最小化处理并加以说明:

1
2
3
4
5
6
7
ABS_MT_SLOT          00000000 # 为新触控点分配 slot 其值为 0
ABS_MT_TRACKING_ID 00002375 # 为新触控点设置 Tracking ID
ABS_MT_POSITION_X 0000055e # 触控区域(touching region)中心位置的 X 轴坐标
ABS_MT_POSITION_Y 00000842 # 触控区域(touching region)中心位置的 Y 轴坐标
SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束
ABS_MT_TRACKING_ID ffffffff # (-1) 触控点已抬起,slot 值 0 可以被复用
SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束

注意:ABS_MT_POSITION_XABS_MT_POSITION_Y 的值是16进制的,它们分别代表的是“**触控区域(touching region)”中心位置的坐标值。注意,该值不一定**是真实的屏幕坐标值,有可能需要进行一次转换,具体转换方法详见事件计算

整个触控过程当中,SYN_REPORT 通常会出现多次,每出现一次 SYN_REPORT 就代表一组触控事件已经处理结束。

另外,什么是“**触控区域(touching region)**”,后文会详细讲解。

多点触控 - “类型 B”

我们再来看一个“类型 B”的多点触控实例[^19](两点触控):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ getevent -l /dev/input/event4 # Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61
EV_ABS ABS_MT_SLOT 00000001
EV_ABS ABS_MT_TRACKING_ID 000016b8
EV_KEY BTN_TOUCH DOWN
EV_KEY BTN_TOOL_FINGER DOWN
EV_ABS ABS_MT_POSITION_X 000001fa
EV_ABS ABS_MT_POSITION_Y 00000479
EV_ABS ABS_MT_TOUCH_MINOR 0000000b
EV_ABS ABS_MT_PRESSURE 0000002c
EV_SYN SYN_REPORT 00000000
EV_ABS ABS_MT_SLOT 00000000
EV_ABS ABS_MT_TRACKING_ID 000016b9
EV_ABS ABS_MT_POSITION_X 00000409
EV_ABS ABS_MT_POSITION_Y 0000047a
EV_ABS ABS_MT_TOUCH_MINOR 0000000a
EV_ABS ABS_MT_PRESSURE 00000026
EV_SYN SYN_REPORT 00000000
EV_ABS ABS_MT_POSITION_X 0000040a
EV_ABS ABS_MT_PRESSURE 00000024
EV_ABS ABS_MT_SLOT 00000001
EV_ABS ABS_MT_POSITION_X 000001f6
EV_ABS ABS_MT_POSITION_Y 00000477
EV_ABS ABS_MT_PRESSURE 0000002a
EV_SYN SYN_REPORT 00000000
EV_ABS ABS_MT_SLOT 00000000
EV_ABS ABS_MT_PRESSURE 00000000
EV_ABS ABS_MT_TRACKING_ID ffffffff
EV_ABS ABS_MT_SLOT 00000001
EV_ABS ABS_MT_PRESSURE 00000000
EV_ABS ABS_MT_TRACKING_ID ffffffff
EV_KEY BTN_TOUCH UP
EV_KEY BTN_TOOL_FINGER UP
EV_SYN SYN_REPORT 00000000

我们再将其做最小化处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ABS_MT_SLOT          00000001 # 为新触控点分配 slot 值为 1          
ABS_MT_TRACKING_ID 000016b8 # 出现新的触控点
ABS_MT_POSITION_X 000001fa # 触控区域(touching region)中心位置的 X 轴坐标
ABS_MT_POSITION_Y 00000479 # 触控区域(touching region)中心位置的 Y 轴坐标
SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束
ABS_MT_SLOT 00000000 # 为新触控点分配 slot 值为 0
ABS_MT_TRACKING_ID 000016b9 # 出现新的触控点
ABS_MT_POSITION_X 00000409 # 触控区域(touching region)中心位置的 X 轴坐标
ABS_MT_POSITION_Y 0000047a # 触控区域(touching region)中心位置的 Y 轴坐标
SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束。
ABS_MT_SLOT 00000001 # 处理 slot 1 的事件(仅处理变化的事件)
ABS_MT_TRACKING_ID ffffffff # (-1) slot 1 触控点已抬起,该 slot 值可以被复用
ABS_MT_SLOT 00000000 # 处理 slot 0 的事件(仅处理变化的事件)
ABS_MT_TRACKING_ID ffffffff # (-1) slot 0 触控点已抬起,该 slot 值可以被复用
SYN_REPORT 00000000 # 数据包结尾标识。表示该组触控事件处理结束

特别说明

在测试的过程中你可能会发现,触控屏幕时 ABS_MT_SLOT 并不会每次都出现,尤其是在单点触控的时候。这是为什么呢?仔细阅读过前文的话,你可能就会想明白了,一切都是因为“‘类型 B’仅发送变化的数据。

假设单点屏幕时,首次出现的 ABS_MT_SLOT 值为 0。那么之后再次单点的话,由于触控点并没有出现两个或更多的情况,因此 ABS_MT_SLOT 的值并不会发生变化,其值始终为0。由于“‘类型 B’仅发送变化的数据”,因此在这种情况下,自然就不会再发送 ABS_MT_SLOT

那单点触控时又怎样才会再出现 ABS_MT_SLOT 呢?如果你明白了上面的道理,那么你可能已经猜到方法了。方法其实很简单,利用“‘类型 B’仅发送变化的数据这一特点。

举例说明:假设手指0点击屏幕时出现的 ABS_MT_SLOT 值为 0,保持手指0处于按下的状态,再按下手指1。由于出现了新的触控点,因此会产生一个新的 ABS_MT_SLOT,假设其值为 1。保持手指0手指1同时处于按下的状态,先抬起手指0(注意,先抬起的是手指0),之后再抬起手指1。完成这些操作后,此后再次进行单点操作时,ABS_MT_SLOT 就会出现了。

让我们用下面的模拟事件来看一下整个过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 按下 “手指0”
ABS_MT_SLOT 00000000 # 为新触控点分配 slot 其值为 0
ABS_MT_TRACKING_ID 000016b8 # 为新触控点设置 Tracking ID
ABS_MT_POSITION_X 000001fa
ABS_MT_POSITION_Y 00000479
SYN_REPORT 00000000 # slot 0 处理结束标识
# 按下 “手指1”
ABS_MT_SLOT 00000001 # 为新触控点分配 slot 其值为 1
ABS_MT_TRACKING_ID 000016b9 # 为新触控点设置 Tracking ID
ABS_MT_POSITION_X 00000409
ABS_MT_POSITION_Y 0000047a
SYN_REPORT 00000000 # slot 1 处理结束标识

# 抬起 “手指0”
ABS_MT_SLOT 00000000 # 开始处理 slot 0 的事件(仅处理变化的事件)
ABS_MT_TRACKING_ID ffffffff # (-1) slot 0 触控点已抬起,其值 0 可以被复用
SYN_REPORT 00000000 # slot 0 处理结束标识
# 抬起 “手指1”
ABS_MT_SLOT 00000001 # 开始处理 slot 1 的事件(仅处理变化的事件)
ABS_MT_TRACKING_ID ffffffff # (-1) slot 1 触控点已抬起,其值 1 可以被复用
SYN_REPORT 00000000 # slot 1 处理结束标识

##### 完成以上两点触控操作后,再进行单点触控操作
ABS_MT_SLOT 00000000 # 为新触控点分配已复用的 slot 值 0
ABS_MT_TRACKING_ID 000016ba # 为新触控点设置 Tracking ID
ABS_MT_POSITION_X 000001e8
ABS_MT_POSITION_Y 00000a10
SYN_REPORT 00000000 # 触控事件数据包结尾标识。表示该组触控事件处理结束
ABS_MT_TRACKING_ID ffffffff # (-1) slot 0 触控点已抬起,slot 值 0 又可以被复用了
SYN_REPORT 00000000 # 触控抬起事件数据包结尾标识。表示该组触控事件处理结束

切记:“‘类型 B’仅发送变化的数据。

关于“触控区域”和“触控面”

关于这两个概念,官网[^14]用了一个形象的例子来讲解,用来说明什么是 ABS_MT_POSITION_X/YABS_MT_TOOL_X/YABS_MT_TOUCH_MAJORABS_MT_WIDTH_MAJOR。进而解释了什么是“触控区域”和“触控面”。

官网举了这样一个例子:想象一下,当你透过玻璃观察一个人将一根手指按在玻璃上某个特定点的过程。当手指与玻璃完全接触时,在整个接触过程,我们会看到两个区域:

一个是内部区域,也就是手指真正想按压的那个点的区域(下图中 a 区域)。这部分区域我们叫做“**触控区域(touch region)**”。

别一个是外部区域,也就整个手指接触玻璃的区域(下图中 b 区域),也可以理解成整个“触控工具”的接触区域。这部分区域我们叫做“**触控面(approaching finger/finger region)**”。

“触控区域(touch region)”的中心点坐标就是 ABS_MT_POSITION_X/Y,也就是下图中 a 的坐标。

“触控面(approaching finger/finger region)”的中心点坐标就是 ABS_MT_TOOL_X/Y,也就是下图中 b 的坐标。

“触控区域”的直径就是 ABS_MT_TOUCH_MAJOR

“触控面”(或称作“触控工具”)的直径就是 ABS_MT_WIDTH_MAJOR

再接着试想下:那个人现在开始在那个点上用力按压了。这个过程中,“触控区域a 变大了,而且变大的幅度相比“触控面b 也更大。因此,通常情况下,ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR 的值也会变大,并且该值通常小于 1。我们可以将该比值理解成触控压力(contact pressure)。当然,对于支持压力检测的设备来说,可以使用 ABS_MT_PRESSURE 作为“触控压力”。

对于支持“**触控悬停(contact hovering)**”的设备来说,可以使用 ABS_MT_DISTANCE 来表明触摸工具与触摸屏表面之间的距离。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 Linux MT                               Win8
__________ _______________________
/ \ | |
/ \ | |
/ ____ \ | |
/ / \ \ | |
\ \ a \ \ | a |
\ \____/ \ | |
\ \ | |
\ b \ | b |
\ \ | |
\ \ | |
\ \ | |
\ / | |
\ / | |
\ / | |
\__________/ |_______________________|

除了上述提到的那些与 MAJOR 有关的事件外,在描述“**触控区域(touch region)a 与“触控面(approaching finger/finger region)**” b 时,还可以使用一些与 MINOR 有关的事件。并且使用 ORIENTATION 事件表示“触控区域”的方向,“触控面”方向用向量 (a-b) 来表示。

常用的触控事件介绍

要想了解完整的触控事件,大家可以参考官网的 “Event Semantics” 这一部分。下面仅列出一些手机设备上经常遇到的触控事件。

  • ABS_MT_SLOT
  • ABS_MT_TRACKING_ID
  • ABS_MT_POSITION_X
  • ABS_MT_POSITION_Y
  • SYN_MT_REPORT
  • SYN_REPORT
  • ABS_MT_TOUCH_MAJOR
  • ABS_MT_TOUCH_MINOR
  • ABS_MT_PRESSURE
  • BTN_TOUCH
  • BTN_TOOL_FINGER

ABS_MT_POSITION_X

触控区域(touching region)”中心位置的 X 轴坐标。

该值是16进制的,其值不一定是真实的屏幕坐标值,有可能需要进行一次转换,具体转换方法详见事件计算

ABS_MT_POSITION_Y

触控区域(touching region)”中心位置的 Y 轴坐标。

该值是16进制的,其值不一定是真实的屏幕坐标值。有可能需要进行一次转换,具体转换方法详见事件计算

ABS_MT_TRACKING_ID

TRACKING_ID 用来标识一个触摸点,追踪其从被按下开始直到抬起的整个过程。该值的取值范围应该足够大,以确保在足够长的时间内,能唯一标识一个触摸点。(通过 getevent -lp 可以知道 TRACKING_ID 的最大值。)

其值含义如下:

  • 非负数的 Tracking ID 代表一个触控点。
  • -1(0xFFFF FFFF) 代表未使用的 slot
  • 一个之前从未出现过Tracking ID 表示这是一个新的触控点。
  • 一个 Tracking ID 不存在了,表示一个被删除的触控点。

ABS_MT_TOUCH_MAJOR

表示“触控区域(touch region)” a 长轴的长度(也就是椭圆形最长的那个方向的长度),用“表面单位(surface unit)”作为单位。假如,“触控面” b 是一个长宽为 x × y 的矩形,那么“触控区域(touch region)” a 长轴最大值就是 sqrt(x^2+y^2),也就是对角线长度。

ABS_MT_TOUCH_MINOR

表示“触控区域” a 短轴的长度(也就是椭圆形最短的那个方向的长度),同样用“**表面单位(surface unit)**”作为单位。如果触控形状是圆形,则可以忽略该事件。

ABS_MT_WIDTH_MAJOR

表示“触控面(approaching finger/finger region)” b 长轴的长度,用“**表面单位(surface unit)**”作为单位。该长度也就是“触控工具”本身最长那个方向的长度,假设“触控区域”和“触控面”(也就是“触控工具”)的方向是一致的。

ABS_MT_TOUCH_MINOR

表示“触控面” b 短轴的长度,同样用“**表面单位(surface unit)**”作为单位。如果触控形状是圆形,同样忽略该事件。

ABS_MT_ORIENTATION

用来表示“触控区域(touch region)”的方向。该值表示以触摸中心为轴,顺时针为正方向并以 90˚ 为单位的方向值。

该值是有符号的,其范围可以任意定。但 0 应该表示“触控区域(touch region)”的方向是 Y 轴方向。负值代表方向向左旋转了(逆时针旋转),正值代表方向向右旋转了(顺时针旋转)。如果方向刚好是 X 轴方向,那么该值应该返回范围内的最大值。

默认情况下,“触控区域(touch region)”是对称的。对于能够真正进行 360˚ 定位的设备,上报的方向值必须超过最大范围,用来表示超过了 1/4 圈( 也就是 90˚)。 对于倒置的手指(即手指向下),应返回最大范围值 * 2

编者注:总感觉这段翻译的不太好,虽然能理解它的意思,但是奈何语文功底不行,感觉表达的不太好。毕竟能理解和能说明白是两回事儿。所以赋上原文:

Touch ellipsis are symmetrical by default. For devices capable of true 360 degree orientation, the reported orientation must exceed the range max to indicate more than a quarter of a revolution. For an upside-down finger, range max * 2 should be returned.

如果触控形状是圆形,或者内核驱动程序无法获取触控形状,那么可以忽略该事件。部分设备只能识别两个方向(即水平或者垂直),那么 ABS_MT_ORIENTATION 的值应该是 01

ABS_MT_PRESSURE

触摸区域压力值。单位:任意单位(arbitrary unit)。用于支持压力检测的设备或任何带有空间压力分布感应信号的设备,用来取代前文提到的使用 TOUCHWIDTH 模拟压力值的情况。

ABS_MT_DISTANCE

表示触摸工具与触摸屏表面之间的距离,用“**表面单位(surface unit)**”作为单位。

数值 0 代表触摸工具已经接触屏幕。正数代表触摸工具正悬浮于触摸屏表面之上。

SYN_REPORT

出现在“类型 B”中,“类型 A”中也有可能会出现。每一组事件数据包的结尾都会有一个 SYN_REPORT 事件,代表一组触控事件已经处理结束。前文已经讲解过。

SYN_MT_REPORT

仅出现在 “类型 A”中。每一组事件数据包的结尾都会有一个 SYN_MT_REPORT 事件,代表接收者可以接收当前的触控信息并准备开始接收下一组信息。

前文已经详细讲解过。

事件计算

如果设备上报了一个矩形形状的触控点,那么我们是无法获得它的水平方向信息的。假设 XY 代表这个触控矩形的两条边的长度,那么我们可以通过下面的公式,得到最主要的信息:

1
2
3
ABS_MT_TOUCH_MAJOR := max(X, Y) 
ABS_MT_TOUCH_MINOR := min(X, Y)
ABS_MT_ORIENTATION := bool(X > Y)

其中 ABS_MT_ORIENTATION 的值应该是 0(垂直) 或者 1(水平),用来表明手指是指向 Y轴(0:垂直)还是 X轴(1:水平)

ABS_MT_POSITION_X/Y 计算方法

前文已经提到了,ABS_MT_POSITION_XABS_MT_POSITION_Y 的值有可能不是真实的屏幕坐标值(这种情况还不少,详见“附录”中“处理屏幕事件的输入设备”的实测结果)。这是为什么呢?

总体来说有以下三种情况:

  • 为了节电,部分支持高分辨率的手机有自动调整分辨率的功能。(例如,三星,Sony 有不少是支持 3K 甚至 4K 的)
  • 部分手机在“显示设置”中,支持手动设置分辨率。(类似上一种情况)
  • 使用 adb shell wm size 手动设置过手机分辨率。

以我手中的 Sony Xperia 1 III(SO-51B)[^19] 为例,该手机是 4K 屏幕,分辨率 1644 × 3840。据说分辨率是动态调整的,且系统应用都支持 4K 分辨率。但实际使用时,我发现手机都工作在 1096 × 2560 模式下,而且也没有找到设置分辨率的地方(除非使用 adb 命令强制设置成 4K)。使用 adb 命令查看该屏幕分辨率:

1
2
$ wm size
Physical size: 1096x2560

在该手机上使用 getevent 查看输入设备信息的部分结果如下(完整结果请查看这里):

1
2
3
4
5
6
7
8
$ getevent -lp # Sony Xperia 1 III(SO-51B) Android 11
...
add device 5: /dev/input/event4
name: "sec_touchscreen"
...
ABS_MT_POSITION_X : value 0, min 0, max 1643, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 3839, fuzz 0, flat 0, resolution 0
...

大家注意看结果里的 ABS_MT_POSITION_XABS_MT_POSITION_Y,它们的 max 值分别是 16433839min 值都是 0,也就是 X 最大范围是 [0,1643], Y 的最大范围是 [0,3839],刚好等于屏幕的真实分辨率 1644 × 3840,而不是实际显示用的分辨率 1096 × 2560。

当我们点击屏幕右下角时, getevent 的运行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ getevent -l /dev/input/event4 # Sony Xperia 1 III(SO-51B) Android 11
/dev/input/event4: EV_ABS ABS_MT_TRACKING_ID 00001adc
/dev/input/event4: EV_KEY BTN_TOUCH DOWN
/dev/input/event4: EV_KEY BTN_TOOL_FINGER DOWN
/dev/input/event4: EV_ABS ABS_MT_POSITION_X 0000057f # 1407
/dev/input/event4: EV_ABS ABS_MT_POSITION_Y 00000d43 # 3395
/dev/input/event4: EV_ABS ABS_MT_TOUCH_MINOR 0000000a
/dev/input/event4: EV_ABS ABS_MT_PRESSURE 00000021
/dev/input/event4: EV_SYN SYN_REPORT 00000000
/dev/input/event4: EV_ABS ABS_MT_POSITION_Y 00000d44 # 3396
/dev/input/event4: EV_SYN SYN_REPORT 00000000
/dev/input/event4: EV_ABS ABS_MT_PRESSURE 00000000
/dev/input/event4: EV_ABS ABS_MT_TRACKING_ID ffffffff
/dev/input/event4: EV_KEY BTN_TOUCH UP
/dev/input/event4: EV_KEY BTN_TOOL_FINGER UP
/dev/input/event4: EV_SYN SYN_REPORT 00000000

同样的,getevent -l 结果里的 ABS_MT_POSITION_XABS_MT_POSITION_Y 的值也是基于屏幕真实分辨率 1644 × 3840 的。例如该例中,点击屏幕右下角后,得到的 ABS_MT_POSITION_XABS_MT_POSITION_Y 坐标对应的十进制值坐标值是 (1407,3395)。

然而我们在开发 APP 时,使用的坐标值恰恰是基于实际显示时的分辨率即 1096 × 2560 的。因此这种情况下,通过 getevent 获取到的 ABS_MT_POSITION_XABS_MT_POSITION_Y 坐标值我们是不能直接使用的,需要进行一次转换。有了上述知识的了解,那么转换公式自然就好写了:

1
2
X=ABS_MT_POSITION_X*(screen width /(ABS_MT_POSITION_X(max-min+1))
Y=ABS_MT_POSITION_Y*(screen height/(ABS_MT_POSITION_Y(max-min+1))

PS:screen widthscreen height 代表使用 Android API 或 adb shell wm size 获取到的屏幕分辨率。例如上例中的 1096 × 2560。

将上例中 getevent 返回的 (1407,3395) 转换成程序用到的有效坐标是 (938,2263):

1
2
x=1407*(1096/1644)=938
y=3395*(2560/3840)=2263

关于内核版本

Android 版本与内核版本的关系

下表列出了 Android 各版本所要求的最低内核版本。

Android版本 发行年[^6] 内核版本 支持终止时间
Android Lollipop
(5.0 API Level 21)
(5.1 API Level 22)
2014/11
2015/03
3.4.0
3.16.1[^7][^9]
Android Marshmallow
(6 API Level 23)
2015/10 3.4.67
3.10.9[^17]
3.10.49[^16]
3.18.10[^8][^9]
Android Nougat
(7.0 API Level 24)
(7.1 API Level 25)
2016/08
2016/10
3.18.48
4.1
4.4.0[^9][^10]
Android Oreo
(8.0 API Level 26)
(8.1 API Level 27)
2017/08
2017/12
3.18.0
4.4.0
4.9.0[^2][^3]
Android Pie
(9 API Level 28)
2018/08 4.4.107
4.9.84
4.14.42[^1][^2]
Android Q
(10 API Level 29)
2019/09 android-4.9-q
android-4.14-q
android-4.19-q[^4]
2023 年 1 月
Android R
(11 API Level 30)
2020/09 android-4.14-stable
android-4.19-stable
android11-5.4[^4]
2024 年 1 月
Android S/Sv2
(12.0 API Level 31)
(12L API Level 32)
2021/10
2022/03
android-4.19-stable
android11-5.4
android12-5.4
android12-5.10[^5]
Android Tiramisu
(13 API Level 33)
2022/08 android12-5.4
android12-5.10
android13-5.10
android13-5.15[^5]

Linux 内核版本

查看 Linux 内核版本的方法如下:

1
2
$ uname -r # Ubuntu 18.04.6 LTS
4.15.0-191-generic
1
2
$ uname -r # Android 11
5.4.61-qgki-00389-g6baf50bb100b

下表是 Linux 内核长期支持(LTS)版的版本与发布日期。数据来自官网 The Linux Kernel Archives。[^11]

Version Maintainer Released Projected EOL
5.15 Greg Kroah-Hartman & Sasha Levin 2021-10-31 Oct, 2023
5.10 Greg Kroah-Hartman & Sasha Levin 2020-12-13 Dec, 2026
5.4 Greg Kroah-Hartman & Sasha Levin 2019-11-24 Dec, 2025
4.19 Greg Kroah-Hartman & Sasha Levin 2018-10-22 Dec, 2024
4.14 Greg Kroah-Hartman & Sasha Levin 2017-11-12 Jan, 2024

附录

处理屏幕事件的输入设备

Google Pixel 7

1
2
$ wm size
Physical size: 1080x2400

下面这个示例中,/dev/input/event4 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ getevent -lp # Google Pixel 7 (Pixel 7) Android 13 - kernel 5.10.107-android13-4-00003                                                                                                         
...
add device 2: /dev/input/event4
name: "fts_ts"
events:
KEY (0001): KEY_W KEY_E KEY_U KEY_O
KEY_S KEY_L KEY_Z KEY_C
KEY_V KEY_M KEY_UP KEY_LEFT
KEY_RIGHT KEY_DOWN KEY_POWER BTN_TOUCH
ABS (0003): ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 63, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR : value 0, min 0, max 63, fuzz 0, flat 0, resolution 0
ABS_MT_ORIENTATION : value 0, min -4096, max 4096, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1079, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 2399, fuzz 0, flat 0, resolution 0
ABS_MT_TOOL_TYPE : value 0, min 0, max 2, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ getevent -ltr /dev/input/event4 # 单点触控
[ 34408.058368] EV_KEY BTN_TOUCH DOWN
[ 34408.058368] EV_ABS ABS_MT_SLOT 00000000
[ 34408.058368] EV_ABS ABS_MT_TRACKING_ID 00000507
[ 34408.058368] EV_ABS ABS_MT_POSITION_X 00000321
[ 34408.058368] EV_ABS ABS_MT_POSITION_Y 000002be
[ 34408.058368] EV_ABS ABS_MT_TOUCH_MAJOR 00000066
[ 34408.058368] EV_ABS ABS_MT_TOUCH_MINOR 0000005d
[ 34408.058368] EV_ABS ABS_MT_PRESSURE 00000025
[ 34408.058368] EV_ABS ABS_MT_ORIENTATION 000007a3
[ 34408.058368] EV_SYN SYN_REPORT 00000000 rate 0
[ 34408.069249] EV_ABS ABS_MT_ORIENTATION 000007a0
[ 34408.069249] EV_SYN SYN_REPORT 00000000 rate 91
[ 34408.073195] EV_ABS ABS_MT_PRESSURE 00000000
[ 34408.073195] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 34408.073195] EV_ABS ABS_MT_ORIENTATION 00000000
[ 34408.073195] EV_KEY BTN_TOUCH UP
[ 34408.073195] EV_SYN SYN_REPORT 00000000 rate 253
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ getevent -ltr /dev/input/event4 # 两点触控
[ 34466.932142] EV_KEY BTN_TOUCH DOWN
[ 34466.932142] EV_ABS ABS_MT_SLOT 00000000
[ 34466.932142] EV_ABS ABS_MT_TRACKING_ID 0000051c
[ 34466.932142] EV_ABS ABS_MT_POSITION_X 00000272
[ 34466.932142] EV_ABS ABS_MT_POSITION_Y 000004a6
[ 34466.932142] EV_ABS ABS_MT_TOUCH_MAJOR 00000079
[ 34466.932142] EV_ABS ABS_MT_TOUCH_MINOR 00000060
[ 34466.932142] EV_ABS ABS_MT_PRESSURE 0000002e
[ 34466.932142] EV_ABS ABS_MT_ORIENTATION 00000e9d
[ 34466.932142] EV_SYN SYN_REPORT 00000000 rate 0
[ 34466.943341] EV_ABS ABS_MT_ORIENTATION 00000e9e
[ 34466.943341] EV_SYN SYN_REPORT 00000000 rate 89
[ 34466.949731] EV_ABS ABS_MT_ORIENTATION 00000e9b
[ 34466.949731] EV_SYN SYN_REPORT 00000000 rate 156
[ 34466.955331] EV_ABS ABS_MT_ORIENTATION 00000e8f
[ 34466.955331] EV_ABS ABS_MT_SLOT 00000001
[ 34466.955331] EV_ABS ABS_MT_TRACKING_ID 0000051d
[ 34466.955331] EV_ABS ABS_MT_POSITION_X 0000017d
[ 34466.955331] EV_ABS ABS_MT_POSITION_Y 000004a4
[ 34466.955331] EV_ABS ABS_MT_TOUCH_MAJOR 00000081
[ 34466.955331] EV_ABS ABS_MT_TOUCH_MINOR 00000060
[ 34466.955331] EV_ABS ABS_MT_PRESSURE 00000031
[ 34466.955331] EV_ABS ABS_MT_ORIENTATION 00000ff2
[ 34466.955331] EV_SYN SYN_REPORT 00000000 rate 178
[ 34466.959294] EV_ABS ABS_MT_SLOT 00000000
[ 34466.959294] EV_ABS ABS_MT_PRESSURE 00000000
[ 34466.959294] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 34466.959294] EV_ABS ABS_MT_ORIENTATION 00000000
[ 34466.959294] EV_ABS ABS_MT_SLOT 00000001
[ 34466.959294] EV_ABS ABS_MT_TOUCH_MAJOR 00000082
[ 34466.959294] EV_SYN SYN_REPORT 00000000 rate 252
[ 34466.963557] EV_ABS ABS_MT_PRESSURE 00000000
[ 34466.963557] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 34466.963557] EV_ABS ABS_MT_ORIENTATION 00000000
[ 34466.963557] EV_KEY BTN_TOUCH UP
[ 34466.963557] EV_SYN SYN_REPORT 00000000 rate 234

Realme GT Neo2

1
2
$ wm size
Physical size: 1080x2400

下面这个示例中,/dev/input/event1 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ getevent -lp # Realme GT Neo2 (RMX3370) Android 13 - kernel 4.19.157-perf+
...
add device 3: /dev/input/event1
name: "touchpanel"
events:
KEY (0001): KEY_F4 KEY_POWER BTN_TOUCH
ABS (0003): ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_WIDTH_MAJOR : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 8639, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 19199, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...
1
2
3
4
5
6
7
8
9
10
$ getevent -ltr /dev/input/event1 # 单点触控
[ 213489.651928] EV_ABS ABS_MT_SLOT 00000000
[ 213489.651928] EV_ABS ABS_MT_TRACKING_ID 00009edc
[ 213489.651928] EV_KEY BTN_TOUCH DOWN
[ 213489.651928] EV_ABS ABS_MT_POSITION_X 00000c79
[ 213489.651928] EV_ABS ABS_MT_POSITION_Y 000015fa
[ 213489.651928] EV_SYN SYN_REPORT 00000000 rate 0
[ 213489.684615] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 213489.684615] EV_KEY BTN_TOUCH UP
[ 213489.684615] EV_SYN SYN_REPORT 00000000 rate 30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ getevent -ltr /dev/input/event1 # 两点触控
[ 213868.593418] EV_ABS ABS_MT_SLOT 00000000
[ 213868.593418] EV_ABS ABS_MT_TRACKING_ID 00009f00
[ 213868.593418] EV_KEY BTN_TOUCH DOWN
[ 213868.593418] EV_ABS ABS_MT_WIDTH_MAJOR 00000007
[ 213868.593418] EV_ABS ABS_MT_PRESSURE 00000008
[ 213868.593418] EV_ABS ABS_MT_POSITION_X 000015b1
[ 213868.593418] EV_ABS ABS_MT_POSITION_Y 00001859
[ 213868.593418] EV_SYN SYN_REPORT 00000000 rate 0
[ 213868.599724] EV_ABS ABS_MT_SLOT 00000001
[ 213868.599724] EV_ABS ABS_MT_TRACKING_ID 00009f01
[ 213868.599724] EV_ABS ABS_MT_TOUCH_MAJOR 00000005
[ 213868.599724] EV_ABS ABS_MT_PRESSURE 0000000a
[ 213868.599724] EV_ABS ABS_MT_POSITION_X 00000bda
[ 213868.599724] EV_ABS ABS_MT_POSITION_Y 00001799
[ 213868.599724] EV_SYN SYN_REPORT 00000000 rate 158
[ 213868.642800] EV_ABS ABS_MT_WIDTH_MAJOR 00000009
[ 213868.642800] EV_SYN SYN_REPORT 00000000 rate 23
[ 213868.649425] EV_ABS ABS_MT_SLOT 00000000
[ 213868.649425] EV_ABS ABS_MT_PRESSURE 00000007
[ 213868.649425] EV_SYN SYN_REPORT 00000000 rate 150
[ 213868.652687] EV_ABS ABS_MT_PRESSURE 00000008
[ 213868.652687] EV_SYN SYN_REPORT 00000000 rate 306
[ 213868.662350] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 213868.662350] EV_ABS ABS_MT_SLOT 00000001
[ 213868.662350] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 213868.662350] EV_KEY BTN_TOUCH UP
[ 213868.662350] EV_SYN SYN_REPORT 00000000 rate 103

Google Pixel 2 XL

1
2
$ wm size
Physical size: 1440x2880

下面这个示例中,/dev/input/event3 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ getevent -lp # Google Pixel 2 XL (Pixel 2 XL) Android 11 - kernel 4.4.223
...
add device 3: /dev/input/event3
name: "touchscreen"
events:
KEY (0001): BTN_TOOL_FINGER BTN_TOUCH
ABS (0003): ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 1024, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR : value 0, min 0, max 1024, fuzz 0, flat 0, resolution 0
ABS_MT_ORIENTATION : value 0, min -128, max 127, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1439, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 2879, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_DISTANCE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ getevent -ltr /dev/input/event3 # 单点触控 
# slot 之前出现过,所以这里再次单点触控时就没有再出现。详见前文的“特别说明”。
[ 760.388978] EV_ABS ABS_MT_TRACKING_ID 00000023
[ 760.388978] EV_KEY BTN_TOUCH DOWN
[ 760.388978] EV_KEY BTN_TOOL_FINGER DOWN
[ 760.388978] EV_ABS ABS_MT_POSITION_X 00000539
[ 760.388978] EV_ABS ABS_MT_POSITION_Y 00000b1c
[ 760.388978] EV_ABS ABS_MT_TOUCH_MAJOR 0000007b
[ 760.388978] EV_ABS ABS_MT_TOUCH_MINOR 00000059
[ 760.388978] EV_ABS ABS_MT_PRESSURE 00000030
[ 760.388978] EV_ABS ABS_MT_ORIENTATION 00000056
[ 760.388978] EV_SYN SYN_REPORT 00000000
[ 760.396504] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 760.396504] EV_KEY BTN_TOUCH UP
[ 760.396504] EV_KEY BTN_TOOL_FINGER UP
[ 760.396504] EV_SYN SYN_REPORT 00000000 rate 132

Sony Xperia 1 III

1
2
$ wm size
Physical size: 1096x2560

下面这个示例中,/dev/input/event4 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ getevent -lp # Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61
...
add device 5: /dev/input/event4
name: "sec_touchscreen"
events:
KEY (0001): KEY_POWER KEY_HOMEPAGE BTN_TOOL_FINGER BTN_TOUCH
01c7
ABS (0003): ABS_X : value 0, min 0, max 1643, fuzz 0, flat 0, resolution 0
ABS_Y : value 0, min 0, max 3839, fuzz 0, flat 0, resolution 0
ABS_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1643, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 3839, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
003e : value 126, min 0, max -1, fuzz 0, flat 0, resolution 0
SW (0005): SW_PEN_INSERTED
input props:
INPUT_PROP_DIRECT
add device 6: /dev/input/event3
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ getevent -ltr /dev/input/event4 # 单点触控
[ 4121295.575564] EV_ABS ABS_MT_SLOT 00000000
[ 4121295.575564] EV_ABS ABS_MT_TRACKING_ID 0000233a
[ 4121295.575564] EV_KEY BTN_TOUCH DOWN
[ 4121295.575564] EV_KEY BTN_TOOL_FINGER DOWN
[ 4121295.575564] EV_ABS ABS_MT_POSITION_X 000004e7
[ 4121295.575564] EV_ABS ABS_MT_POSITION_Y 0000098e
[ 4121295.575564] EV_ABS ABS_MT_TOUCH_MAJOR 00000007
[ 4121295.575564] EV_ABS ABS_MT_TOUCH_MINOR 00000007
[ 4121295.575564] EV_ABS ABS_MT_PRESSURE 00000013
[ 4121295.575564] EV_SYN SYN_REPORT 00000000 rate 0
[ 4121295.600051] EV_ABS ABS_MT_PRESSURE 00000000
[ 4121295.600051] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 4121295.600051] EV_KEY BTN_TOUCH UP
[ 4121295.600051] EV_KEY BTN_TOOL_FINGER UP
[ 4121295.600051] EV_SYN SYN_REPORT 00000000 rate 40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ getevent -ltr /dev/input/event4 # 两点触控
[ 4121604.807775] EV_ABS ABS_MT_SLOT 00000001
[ 4121604.807775] EV_ABS ABS_MT_TRACKING_ID 0000235f
[ 4121604.807775] EV_KEY BTN_TOUCH DOWN
[ 4121604.807775] EV_KEY BTN_TOOL_FINGER DOWN
[ 4121604.807775] EV_ABS ABS_MT_POSITION_X 000003ff
[ 4121604.807775] EV_ABS ABS_MT_POSITION_Y 00000a1c
[ 4121604.807775] EV_ABS ABS_MT_PRESSURE 00000018
[ 4121604.807775] EV_SYN SYN_REPORT 00000000 rate 0
[ 4121604.824235] EV_ABS ABS_MT_SLOT 00000000
[ 4121604.824235] EV_ABS ABS_MT_TRACKING_ID 00002360
[ 4121604.824235] EV_ABS ABS_MT_POSITION_X 000005cf
[ 4121604.824235] EV_ABS ABS_MT_POSITION_Y 000008b3
[ 4121604.824235] EV_ABS ABS_MT_TOUCH_MAJOR 00000009
[ 4121604.824235] EV_ABS ABS_MT_TOUCH_MINOR 00000009
[ 4121604.824235] EV_ABS ABS_MT_PRESSURE 0000001d
[ 4121604.824235] EV_ABS ABS_MT_SLOT 00000001
[ 4121604.824235] EV_ABS ABS_MT_PRESSURE 00000019
[ 4121604.824235] EV_SYN SYN_REPORT 00000000 rate 60
[ 4121604.832362] EV_ABS ABS_MT_SLOT 00000000
[ 4121604.832362] EV_ABS ABS_MT_POSITION_X 000005d0
[ 4121604.832362] EV_ABS ABS_MT_POSITION_Y 000008b2
[ 4121604.832362] EV_ABS ABS_MT_PRESSURE 0000001c
[ 4121604.832362] EV_ABS ABS_MT_SLOT 00000001
[ 4121604.832362] EV_ABS ABS_MT_POSITION_X 000003fe
[ 4121604.832362] EV_ABS ABS_MT_POSITION_Y 00000a1b
[ 4121604.832362] EV_SYN SYN_REPORT 00000000 rate 123
[ 4121604.840575] EV_ABS ABS_MT_TOUCH_MAJOR 00000009
[ 4121604.840575] EV_ABS ABS_MT_SLOT 00000000
[ 4121604.840575] EV_ABS ABS_MT_PRESSURE 00000000
[ 4121604.840575] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 4121604.840575] EV_SYN SYN_REPORT 00000000 rate 121
[ 4121604.847841] EV_ABS ABS_MT_SLOT 00000001
[ 4121604.847841] EV_ABS ABS_MT_PRESSURE 00000000
[ 4121604.847841] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 4121604.847841] EV_KEY BTN_TOUCH UP
[ 4121604.847841] EV_KEY BTN_TOOL_FINGER UP
[ 4121604.847841] EV_SYN SYN_REPORT 00000000 rate 137

OPPO Reno7 A

1
2
$ wm size
Physical size: 1080x2400

下面这个示例中,/dev/input/event2 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ getevent -lp # OPPO Reno7 A (A201OP) Android 11 - kernel 5.4.147-qgki-g63506622819a
...
add device 3: /dev/input/event2
name: "touchpanel"
events:
KEY (0001): KEY_F4 BTN_TOUCH
ABS (0003): ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_WIDTH_MAJOR : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 4319, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 9599, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...
1
2
3
4
5
6
7
8
9
10
$ getevent -ltr /dev/input/event2 # 单点触控
[ 104582.322410] EV_ABS ABS_MT_SLOT 00000000
[ 104582.322410] EV_ABS ABS_MT_TRACKING_ID 000009fc
[ 104582.322410] EV_KEY BTN_TOUCH DOWN
[ 104582.322410] EV_ABS ABS_MT_POSITION_X 00000ca8
[ 104582.322410] EV_ABS ABS_MT_POSITION_Y 00000449
[ 104582.322410] EV_SYN SYN_REPORT 00000000 rate 0
[ 104582.359532] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 104582.359532] EV_KEY BTN_TOUCH UP
[ 104582.359532] EV_SYN SYN_REPORT 00000000 rate 26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ getevent -ltr /dev/input/event2 # 两点触控
[ 104602.018681] EV_ABS ABS_MT_SLOT 00000000
[ 104602.018681] EV_ABS ABS_MT_TRACKING_ID 000009ff
[ 104602.018681] EV_KEY BTN_TOUCH DOWN
[ 104602.018681] EV_ABS ABS_MT_WIDTH_MAJOR 0000000b
[ 104602.018681] EV_ABS ABS_MT_POSITION_X 00000ded
[ 104602.018681] EV_ABS ABS_MT_POSITION_Y 00000438
[ 104602.018681] EV_ABS ABS_MT_SLOT 00000001
[ 104602.018681] EV_ABS ABS_MT_TRACKING_ID 00000a00
[ 104602.018681] EV_ABS ABS_MT_POSITION_X 00000a18
[ 104602.018681] EV_ABS ABS_MT_POSITION_Y 0000041a
[ 104602.018681] EV_SYN SYN_REPORT 00000000 rate 0
[ 104602.050117] EV_ABS ABS_MT_SLOT 00000000
[ 104602.050117] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 104602.050117] EV_SYN SYN_REPORT 00000000 rate 31
[ 104602.060616] EV_ABS ABS_MT_SLOT 00000001
[ 104602.060616] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 104602.060616] EV_KEY BTN_TOUCH UP
[ 104602.060616] EV_SYN SYN_REPORT 00000000 rate 95

HuaWei Mate 20 Pro - “类型 A”

该手机采用的是“多点触控协议 - 类型 A”。且支持“智能分辨率”:1440x3120, 1080x2340, 720x1560。

1
2
$ wm size                                                                                                                            
Physical size: 1440x3120

下面这个示例中,/dev/input/event5 是负责处理屏幕事件的。注意其执行结果中的 ABS 事件一栏,其中是没有 “ABS_MT_SLOT” 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ getevent -lp # HuaWei Mate 20 Pro (LYA-L29) Android 10 - kernel 4.14.116
...
add device 2: /dev/input/event5
name: "huawei,ts_kit"
events:
KEY (0001): KEY_F1 KEY_F2 KEY_F3 KEY_F4
KEY_F5 KEY_F7 KEY_F8 KEY_F9
KEY_F10 KEY_F11 KEY_F12 KEY_F19
KEY_F20 KEY_F21 KEY_F22 KEY_F23
KEY_SWITCHVIDEOMODE KEY_KBDILLUMTOGGLE BTN_TOOL_FINGER BTN_TOUCH
ABS (0003): ABS_X : value 0, min 0, max 1439, fuzz 0, flat 0, resolution 0
ABS_Y : value 0, min 0, max 3119, fuzz 0, flat 0, resolution 0
ABS_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 15, fuzz 0, flat 0, resolution 0
ABS_MT_WIDTH_MAJOR : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
ABS_MT_WIDTH_MINOR : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1439, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 3119, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 15, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...
1
2
3
4
5
6
7
8
9
10
11
$ getevent -ltr /dev/input/event5 # 单点触控
[ 589.156475] EV_ABS ABS_MT_PRESSURE 00000010
[ 589.156475] EV_ABS ABS_MT_POSITION_X 00000494
[ 589.156475] EV_ABS ABS_MT_POSITION_Y 00000245
[ 589.156475] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 589.156475] EV_SYN SYN_MT_REPORT 00000000
[ 589.156475] EV_KEY BTN_TOUCH DOWN
[ 589.156475] EV_SYN SYN_REPORT 00000000
[ 589.165118] EV_SYN SYN_MT_REPORT 00000000
[ 589.165118] EV_KEY BTN_TOUCH UP
[ 589.165118] EV_SYN SYN_REPORT 00000000 rate 115
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ getevent -ltr /dev/input/event5 # 两点触控
[ 901.662272] EV_ABS ABS_MT_PRESSURE 00000038
[ 901.662272] EV_ABS ABS_MT_POSITION_X 00000385
[ 901.662272] EV_ABS ABS_MT_POSITION_Y 0000085b
[ 901.662272] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 901.662272] EV_SYN SYN_MT_REPORT 00000000
[ 901.662272] EV_KEY BTN_TOUCH DOWN
[ 901.662272] EV_SYN SYN_REPORT 00000000 rate 0
[ 901.668908] EV_ABS ABS_MT_PRESSURE 00000035
[ 901.668908] EV_ABS ABS_MT_POSITION_X 00000385
[ 901.668908] EV_ABS ABS_MT_POSITION_Y 0000085b
[ 901.668908] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 901.668908] EV_SYN SYN_MT_REPORT 00000000
[ 901.668908] EV_SYN SYN_REPORT 00000000 rate 150
[ 901.678505] EV_ABS ABS_MT_PRESSURE 0000003b
[ 901.678505] EV_ABS ABS_MT_POSITION_X 000001ce
[ 901.678505] EV_ABS ABS_MT_POSITION_Y 00000809
[ 901.678505] EV_ABS ABS_MT_TRACKING_ID 00000001
[ 901.678505] EV_SYN SYN_MT_REPORT 00000000
[ 901.678505] EV_SYN SYN_REPORT 00000000 rate 104
[ 901.685855] EV_ABS ABS_MT_PRESSURE 0000002c
[ 901.685855] EV_ABS ABS_MT_POSITION_X 000001ce
[ 901.685855] EV_ABS ABS_MT_POSITION_Y 00000809
[ 901.685855] EV_ABS ABS_MT_TRACKING_ID 00000001
[ 901.685855] EV_SYN SYN_MT_REPORT 00000000
[ 901.685855] EV_SYN SYN_REPORT 00000000 rate 136
[ 901.693931] EV_SYN SYN_MT_REPORT 00000000
[ 901.693931] EV_KEY BTN_TOUCH UP
[ 901.693931] EV_SYN SYN_REPORT 00000000 rate 123

HuaWei Nova Lite 3 - “类型 A”

1
2
$ wm size                                                                                                                          
Physical size: 1080x2340

下面这个示例中,/dev/input/event3 是负责处理屏幕事件的。注意其执行结果中的 ABS 事件一栏,其中是没有 “ABS_MT_SLOT” 的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ getevent -lp # HuaWei Nova Lite 3 (POT-LX2J) Android 9 - 4.9.148
add device 1: /dev/input/event3
name: "input_mt_wrapper"
events:
KEY (0001): KEY_F1 00c4 BTN_TOOL_FINGER BTN_TOUCH
ABS (0003): ABS_X : value 0, min 0, max 1079, fuzz 0, flat 0, resolution 0
ABS_Y : value 0, min 0, max 2339, fuzz 0, flat 0, resolution 0
ABS_PRESSURE : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 1, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR : value 0, min 0, max 1, fuzz 0, flat 0, resolution 0
ABS_MT_ORIENTATION : value 0, min -90, max 90, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1079, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 2339, fuzz 0, flat 0, resolution 0
ABS_MT_BLOB_ID : value 0, min 0, max 10, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_PRESSURE : value 0, min 0, max 100, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ getevent -ltr /dev/input/event3 # 单点触控
[ 455.685182] EV_ABS ABS_MT_POSITION_X 000003d9
[ 455.685182] EV_ABS ABS_MT_POSITION_Y 0000090d
[ 455.685182] EV_ABS ABS_MT_PRESSURE 000000f4
[ 455.685182] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 455.685182] EV_ABS ABS_MT_TOUCH_MAJOR 000000b4
[ 455.685182] EV_ABS ABS_MT_TOUCH_MINOR 00000069
[ 455.685182] EV_ABS ABS_MT_ORIENTATION ffffffa7
[ 455.685182] EV_ABS ABS_MT_BLOB_ID 00000000
[ 455.685182] EV_SYN SYN_MT_REPORT 00000000
[ 455.685182] EV_KEY BTN_TOUCH DOWN
[ 455.685182] EV_SYN SYN_REPORT 00000000 rate 0
[ 455.716517] EV_SYN SYN_MT_REPORT 00000000
[ 455.716517] EV_KEY BTN_TOUCH UP
[ 455.716517] EV_SYN SYN_REPORT 00000000 rate 31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ getevent -ltr /dev/input/event3 # 两点触控
[ 670.881154] EV_ABS ABS_MT_POSITION_X 00000146
[ 670.881154] EV_ABS ABS_MT_POSITION_Y 000003a9
[ 670.881154] EV_ABS ABS_MT_PRESSURE 0000018a
[ 670.881154] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 670.881154] EV_ABS ABS_MT_TOUCH_MAJOR 000000c3
[ 670.881154] EV_ABS ABS_MT_TOUCH_MINOR 00000096
[ 670.881154] EV_ABS ABS_MT_ORIENTATION 00000054
[ 670.881154] EV_ABS ABS_MT_BLOB_ID 00000000
[ 670.881154] EV_SYN SYN_MT_REPORT 00000000
[ 670.881154] EV_ABS ABS_MT_POSITION_X 000002e0
[ 670.881154] EV_ABS ABS_MT_POSITION_Y 000002a1
[ 670.881154] EV_ABS ABS_MT_PRESSURE 000001b7
[ 670.881154] EV_ABS ABS_MT_TRACKING_ID 00000001
[ 670.881154] EV_ABS ABS_MT_TOUCH_MAJOR 000000c3
[ 670.881154] EV_ABS ABS_MT_TOUCH_MINOR 000000a5
[ 670.881154] EV_ABS ABS_MT_ORIENTATION 00000050
[ 670.881154] EV_ABS ABS_MT_BLOB_ID 00000000
[ 670.881154] EV_SYN SYN_MT_REPORT 00000000
[ 670.881154] EV_KEY BTN_TOUCH DOWN
[ 670.881154] EV_SYN SYN_REPORT 00000000 rate 0
[ 670.896778] EV_ABS ABS_MT_POSITION_X 00000146
[ 670.896778] EV_ABS ABS_MT_POSITION_Y 000003a9
[ 670.896778] EV_ABS ABS_MT_PRESSURE 00000188
[ 670.896778] EV_ABS ABS_MT_TRACKING_ID 00000000
[ 670.896778] EV_ABS ABS_MT_TOUCH_MAJOR 000000b4
[ 670.896778] EV_ABS ABS_MT_TOUCH_MINOR 00000096
[ 670.896778] EV_ABS ABS_MT_ORIENTATION 00000053
[ 670.896778] EV_ABS ABS_MT_BLOB_ID 00000000
[ 670.896778] EV_SYN SYN_MT_REPORT 00000000
[ 670.896778] EV_ABS ABS_MT_POSITION_X 000002e0
[ 670.896778] EV_ABS ABS_MT_POSITION_Y 000002a1
[ 670.896778] EV_ABS ABS_MT_PRESSURE 000001b3
[ 670.896778] EV_ABS ABS_MT_TRACKING_ID 00000001
[ 670.896778] EV_ABS ABS_MT_TOUCH_MAJOR 000000c3
[ 670.896778] EV_ABS ABS_MT_TOUCH_MINOR 000000a5
[ 670.896778] EV_ABS ABS_MT_ORIENTATION 00000053
[ 670.896778] EV_ABS ABS_MT_BLOB_ID 00000000
[ 670.896778] EV_SYN SYN_MT_REPORT 00000000
[ 670.896778] EV_SYN SYN_REPORT 00000000 rate 64
[ 670.912897] EV_SYN SYN_MT_REPORT 00000000
[ 670.912897] EV_KEY BTN_TOUCH UP
[ 670.912897] EV_SYN SYN_REPORT 00000000 rate 62

Samsung Galaxy S7 edge

1
2
$ wm size
Physical size: 1440x2560

下面这个示例中,/dev/input/event1 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ getevent -lp # Samsung Galaxy S7 edge (SM-935F) Android 8.0 - kernel 3.18.91
...
add device 7: /dev/input/event1
name: "sec_touchscreen"
events:
KEY (0001): BTN_TOOL_FINGER BTN_TOUCH 01c6 01c7
01ca 01cb
ABS (0003): ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 4095, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 4095, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_DISTANCE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_PALM : value 0, min 0, max 1, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ getevent -ltr /dev/input/event1 # 单点触控
[ 3494421.523951] EV_ABS ABS_MT_SLOT 00000000
[ 3494421.523951] EV_ABS ABS_MT_TRACKING_ID 00000493
[ 3494421.523951] EV_KEY BTN_TOUCH DOWN
[ 3494421.523951] EV_KEY BTN_TOOL_FINGER DOWN
[ 3494421.523951] EV_ABS ABS_MT_POSITION_X 00000615
[ 3494421.523951] EV_ABS ABS_MT_POSITION_Y 0000040d
[ 3494421.523951] EV_ABS ABS_MT_TOUCH_MAJOR 00000006
[ 3494421.523951] EV_ABS ABS_MT_TOUCH_MINOR 00000006
[ 3494421.523951] EV_SYN SYN_REPORT 00000000 rate 0
[ 3494421.539278] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 3494421.539278] EV_KEY BTN_TOUCH UP
[ 3494421.539278] EV_KEY BTN_TOOL_FINGER UP
[ 3494421.539278] EV_SYN SYN_REPORT 00000000 rate 65
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ getevent -ltr /dev/input/event1 # 两点触控
[ 3494717.370551] EV_ABS ABS_MT_SLOT 00000000
[ 3494717.370551] EV_ABS ABS_MT_TRACKING_ID 000004eb
[ 3494717.370551] EV_KEY BTN_TOUCH DOWN
[ 3494717.370551] EV_KEY BTN_TOOL_FINGER DOWN
[ 3494717.370551] EV_ABS ABS_MT_POSITION_X 000005dd
[ 3494717.370551] EV_ABS ABS_MT_POSITION_Y 0000029a
[ 3494717.370551] EV_ABS ABS_MT_TOUCH_MAJOR 00000006
[ 3494717.370551] EV_ABS ABS_MT_TOUCH_MINOR 00000006
[ 3494717.370551] EV_ABS ABS_MT_SLOT 00000001
[ 3494717.370551] EV_ABS ABS_MT_TRACKING_ID 000004ec
[ 3494717.370551] EV_ABS ABS_MT_POSITION_X 000008a7
[ 3494717.370551] EV_ABS ABS_MT_POSITION_Y 000004e1
[ 3494717.370551] EV_ABS ABS_MT_TOUCH_MAJOR 00000007
[ 3494717.370551] EV_ABS ABS_MT_TOUCH_MINOR 00000007
[ 3494717.370551] EV_SYN SYN_REPORT 00000000 rate 0
[ 3494717.378048] EV_ABS ABS_MT_SLOT 00000000
[ 3494717.378048] EV_ABS ABS_MT_POSITION_Y 00000298
[ 3494717.378048] EV_SYN SYN_REPORT 00000000 rate 133
[ 3494717.386307] EV_ABS ABS_MT_POSITION_Y 00000296
[ 3494717.386307] EV_SYN SYN_REPORT 00000000 rate 121
[ 3494717.417342] EV_ABS ABS_MT_SLOT 00000001
[ 3494717.417342] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 3494717.417342] EV_ABS ABS_MT_SLOT 00000000
[ 3494717.417342] EV_ABS ABS_MT_TRACKING_ID ffffffff
[ 3494717.417342] EV_KEY BTN_TOUCH UP
[ 3494717.417342] EV_KEY BTN_TOOL_FINGER UP
[ 3494717.417342] EV_SYN SYN_REPORT 00000000 rate 32

Samsung Galaxy Note 4 S-LTE

1
2
$ wm size
Physical size: 1440x2560

下面这个示例中,/dev/input/event2 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ getevent -lp # Samsung Galaxy Note 4 S-LTE (SM-N916K) Android 6.0.1 - 3.10.9
add device 1: /dev/input/event2
name: "sec_touchscreen"
events:
KEY (0001): BTN_TOOL_FINGER BTN_TOUCH
ABS (0003): ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MINOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1439, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 2559, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
ABS_MT_DISTANCE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_PALM : value 0, min 0, max 1, fuzz 0, flat 0, resolution 0
SW (0005): SW_GLOVE
input props:
INPUT_PROP_DIRECT
add device 2: /dev/input/event14
name: "ssp_context"
events:
REL (0002): REL_RX REL_RY REL_RZ
input props:
<none>
...

OPPO A71

1
2
$ wm size
Physical size: 720x1280

下面这个示例中,/dev/input/event1 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ getevent -lp # OPPO A71 (2018) (CPH1801) Android 7.1.1 - 3.18.31
...
add device 4: /dev/input/event1
name: "touchpanel"
events:
KEY (0001): KEY_F4 BTN_TOUCH
ABS (0003): ABS_MT_SLOT : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_WIDTH_MAJOR : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 720, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 1280, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
input props:
INPUT_PROP_DIRECT
...

Asus ZenPad 8

1
2
$ wm size
Physical size: 800x1280

下面这个示例中,/dev/input/event1 是负责处理屏幕事件的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ getevent -lp # Asus ZenPad 8 (P024) Android 6.0.1 - kernel 3.10.49
...
add device 14: /dev/input/event1
name: "elan-touchscreen"
events:
KEY (0001): KEY_POWER KEY_F17 KEY_F18 KEY_F19
KEY_F20 KEY_F21 KEY_F22 KEY_F23
KEY_F24 KEY_POWER2
ABS (0003): ABS_PRESSURE : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_SLOT : value 1, min 0, max 9, fuzz 0, flat 0, resolution 0
ABS_MT_TOUCH_MAJOR : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_X : value 0, min 0, max 1472, fuzz 0, flat 0, resolution 0
ABS_MT_POSITION_Y : value 0, min 0, max 2368, fuzz 0, flat 0, resolution 0
ABS_MT_TRACKING_ID : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
input props:
<none>
...

[^1]: Core Kernel Requirements
[^2]: https://android.googlesource.com/platform/test/vts-testcase/kernel/+/refs/heads/pie-vts-release/lib/version.py
[^3]: https://android.googlesource.com/platform/test/vts-testcase/kernel/+/refs/heads/oreo-vts-release/config/data/
[^4]: Android Common Kernels
[^5]: Feature and launch kernels
[^6]: Android version history
[^7]: https://forum.xda-developers.com/t/kernel-matr1x-v14-5-lollipop-5-0-5-0-1.2007231/
[^8]: https://forum.xda-developers.com/t/rom-kernel-may-16-2020-aosp-direct-marshmallow-6-0-new-kernel-version-3-4-99.4044253/
[^9]: https://android.stackexchange.com/a/51656
[^10]: https://en.wikipedia.org/wiki/Android_Nougat
[^11]: The Linux Kernel Archives
[^12]: Android kernel 4.9 Multi-touch (MT) Protocol
[^13]: Android kernel 4.14 Multi-touch (MT) Protocol
[^14]: Multi-touch (MT) Protocol 英文版中文版中文版
[^15]: Android 官方文档 触控设备

[^16]: Asus ZenPad 8 (P024) Android 6.0.1 - kernel 3.10.49
[^17]: Samsung Galaxy Note 4 S-LTE (SM-N916K) Android 6.0.1 - kernel 3.10.9
[^18]: The mtdev project: http://bitmath.org/code/mtdev/
[^19]: Sony Xperia 1 III(SO-51B) Android 11 - kernel 5.4.61

坚持原创及高品质技术分享,您的支持将鼓励我继续创作!