这两天准备写一下input子系统的分析,过程中发现了两个好工具,呵呵,就是本文介绍的主角:getevent用于获取当前系统input设备的一些参数和实时事件的数据;sendevent用于发送input事件,这样在调试的时候遇到有的样机按键坏了或者触摸屏坏了就方便了,工具的源码位于Android SDK的system/core/toolbox下面。
一、getevent
首先看一下命令的用法说明:
# getevent -h
Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-p] [-q] [-c count] [-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)
-p: show possible events (errs, dev, name, pos. events)
-q: quiet (clear verbosity mask)
-c: print given number of events then exit
-r: print rate events are received
其中 [-t] 参数显示事件的时间戳,[-n] 取消事件显示时的换行符,[-s switchmask] 得到指定位的开关状态,[-S] 得到所有开关的状态,[-v [mask]] 根据mask的值显示相关信息,后面详细介绍mask的使用方法,[-p] 显示每个设备支持的事件类型和编码,[-q] 只显示事件数据,[-c count] 只显示count次事件的数据,[-r] 显示事件接收频率。下面看一下命令以及相关参数的使用结果:
1、getevent -p
# getevent -p
add device 1: /dev/input/event4
name: "tempsensor"
events:
SYN (0000): 0000 0003
ABS (0003): 0010 value 0, min 0, max 100, fuzz 0 flat 0
add device 2: /dev/input/event3
name: "accsensor"
events:
SYN (0000): 0000 0003
ABS (0003): 0000 value -23, min 0, max 0, fuzz 0 flat 0
0001 value -8, min 0, max 0, fuzz 0 flat 0
0002 value -966, min 0, max 0, fuzz 0 flat 0
add device 3: /dev/input/event2
name: "xx_keypad"
events:
SYN (0000): 0000 0001
KEY (0001): 0000 0001 0002 0003 0004 0005 0006 0007
0008 0009 000a 000b 000c 000d 000e 000f
0010 0011 0012 0013 0014 0015 0016 0017
0018 0019 001a 001b 001c 001d 001e 001f
0020 0021 0022 0023 0024 0025 0026 0027
0028 0029 002a 002b 002c 002d 002e 002f
0030 0031 0032 0033 0034 0035 0036 0037
0038 0039 003a 003b 003c 003d 003e 003f
0074
add device 4: /dev/input/event1
name: "xx_ts"
events:
SYN (0000): 0000 0001 0003
KEY (0001): 0066 008b 009e 00d9
ABS (0003): 0030 value 0, min 0, max 255, fuzz 0 flat 0
0035 value 0, min 0, max 320, fuzz 0 flat 0
0036 value 0, min 0, max 480, fuzz 0 flat 0
可以看到 [-p] 参数显示出来当前系统存在的所有input设备,并且把每个设备支持的事件类型以及编码都列举了出来,比如xx_ts:
SYN (0000): 0000 0001 0003
表示xx_ts支持的事件类型有:
EV_SYN [0000] (同步事件),
EV_KEY [0001] (按键事件),
EV_ABS [0003] (绝对值事件);
KEY (0001): 0066 008b 009e 00d9
表示xx_ts支持的按键编码有:KEY_HOME [0066] (HOME键),KEY_MENU [008b] (MENU键)
KEY_BACK [009e] (BACK键),KEY_SEARCH [00d9] (SEARCH键)
ABS (0003): 0030 value 0, min 0, max 255, fuzz 0 flat 0
0035 value 0, min 0, max 320, fuzz 0 flat 0
0036 value 0, min 0, max 480, fuzz 0 flat 0
表示xx_ts支持的绝对值编码有:ABS_MT_TOUCH_MAJOR [0030] (接触面长轴值) {有效值范围[0, 255]}
ABS_MT_POSITION_X [0035] (x轴坐标) {有效值范围[0, 320]}
ABS_MT_POSITION_Y [0036] (y轴坐标) {有效值范围[0, 480]}
2、getevent -v [mask][-v] 参数会根据mask的值决定显示内容,在源码中可以找到相应位的定义:
enum {
PRINT_DEVICE_ERRORS = 1U << 0,
PRINT_DEVICE = 1U << 1,
PRINT_DEVICE_NAME = 1U << 2,
PRINT_DEVICE_INFO = 1U << 3,
PRINT_VERSION = 1U << 4,
PRINT_POSSIBLE_EVENTS = 1U << 5,
};
其中 PRINT_DEVICE_ERRORS 显示错误信息,PRINT_DEVICE 显示设备个数,PRINT_DEVICE_NAME 显示设备名称,PRINT_DEVICE_INFO 显示设备信息,PRINT_VERSION 显示设备版本号,PRINT_POSSIBLE_EVENTS 显示设备支持的事件类型及编码。唯一觉得有缺憾的是 [-v] 参数执行后会一直显示事件的数据,而没有mask决定是否显示这些数据,不过可以通过grep过滤掉。在输入命令时根据相应的位决定mask值:
# getevent -v 63
add device 1: /dev/input/event4
bus: 0000
vendor 0000
product 0000
version 0000
name: "tempsensor"
location: ""
id: ""
version: 1.0.0
events:
SYN (0000): 0000 0003
ABS (0003): 0010 value 0, min 0, max 100, fuzz 0 flat 0
...
这样就显示出了所有的信息。
# sendevent
use: sendevent device type code value
可以看到sendevent需要4个参数即:device,type,code,value。这些值可以由input子系统定义,也可以从getevent里面获取,比如我们要模拟一次
BACK 事件,根据前面的信息可知BACK的编码为0x9e即158,那我们输入如下命令即可模拟一次BACK键的按下和弹起:
# sendevent /dev/input/event1 1 158 1
# sendevent /dev/input/event1 1 158 0
device需要是支持该按键的设备这里是xx_ts;type为1表示是按键事件;value为1表示按下,为0表示弹起,一次按键事件由按下和弹起两个操作组成。另外Android还在framework层提供了输入键值的工具input,这些我们后面再详细分析。