【android 9】【input】【1.工具篇】

1.Getevent工具使用及参数说明

当用户触摸屏幕或者按下按键时,首先触发的是硬件驱动,硬件驱动会将事件写入设备节点(/dev/input),这便是内核的原始输入事件,getevent指令的作用便是读取内核中的原始输入事件。

1.1 getevent指令的使用

首先adb shell进入机器后,输入 getevent -h

130|1:/ $ getevent -h
Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-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, props=64)//打印硬件的基本信息
    -d: show HID descriptor, if available
    -p: show possible events (errs, dev, name, pos. events) //显示所有的事件,如果是按键,则会显示所有key,如果是触摸屏,则会显示绝对坐标系的值
    -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

1.1.1 getevent

不带任何参数显示如下:

130|:/ $ getevent
add device 11: /dev/input/event1 //设备节点
  name:     "pmic_pwrkey"  //设备名称 手机上的power电源按键
/dev/input/event1: 0001 0074 00000001 //按键按下信息
/dev/input/event1: 0000 0000 00000000 /同步事件信息
/dev/input/event1: 0001 0074 00000000 //按键抬起信息
/dev/input/event1: 0000 0000 00000000 /同步事件信息

1.1.2 getevent -t

携带事件发生的时间戳

add device 11: /dev/input/event1 //设备节点
  name:     "pmic_pwrkey"  //设备名称 手机上的power电源按键

[   63641.462544] /dev/input/event1: 0001 0074 00000001 //按键按下信息
[   63641.462544] /dev/input/event1: 0000 0000 00000000 //同步事件信息
[   63641.547853] /dev/input/event1: 0001 0074 00000000 //按键抬起信息
[   63641.547853] /dev/input/event1: 0000 0000 00000000 //同步事件信息

1.1.3 getevent -n

没有换行符

/dev/input/event1: 0001 0074 00000001/dev/input/event1: 0000 0000 00000000/dev/input/event1: 0001 0074 00000000/dev/input/event1: 0000 0000 00000000

1.1.4 getevent -v

显示硬件的一些供应商等信息

add device 11: /dev/input/event1
  bus:      0000
  vendor    0000
  product   0000
  version   0000
  name:     "pmic_pwrkey"
  location: "pmic_pwrkey/input0"
  id:       ""
  version:  1.0.1

1.1.5 getevent -p

add device 4: /dev/input/event8
  name:     "touchpanel"// 触摸屏
  events:
    KEY (0001): 003e  008e  0145  014a
    ABS (0003): 0000  : value 0, min 0, max 19840, fuzz 0, flat 0, resolution 0
                0001  : value 0, min 0, max 44352, fuzz 0, flat 0, resolution 0
                0018  : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
                0021  : value 924, min 0, max 0, fuzz 0, flat 0, resolution 0
                0022  : value 148, min 0, max 0, fuzz 0, flat 0, resolution 0
                0023  : value 117, min 0, max 0, fuzz 0, flat 0, resolution 0
                002f  : value 0, min 0, max 9, fuzz 0, flat 0, resolution 0
                0030  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
                0031  : value 0, min 0, max 255, fuzz 0, flat 0, resolution 0
                0032  : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
                0035  : value 0, min 0, max 19840, fuzz 0, flat 0, resolution 0
                0036  : value 0, min 0, max 44352, fuzz 0, flat 0, resolution 0
                0037  : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0
                0039  : value 0, min 0, max 65535, fuzz 0, flat 0, resolution 0
                003a  : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0

add device 11: /dev/input/event1 
  name:     "pmic_pwrkey" //手机的电源按键
  events:
    KEY (0001): 0074 //电源按键对应的值

1.1.6 getevent -i

相当于-v和-p的合体

add device 11: /dev/input/event1
  bus:      0000
  vendor    0000
  product   0000
  version   0000
  name:     "pmic_pwrkey"
  location: "pmic_pwrkey/input0"
  id:       ""
  version:  1.0.1
  events:
    KEY (0001): 0074
  input props:

1.1.7 getevent -l

/dev/input/event1: EV_KEY       KEY_POWER            DOWN
/dev/input/event1: EV_SYN       SYN_REPORT           00000000
/dev/input/event1: EV_KEY       KEY_POWER            UP
/dev/input/event1: EV_SYN       SYN_REPORT           00000000

1.1.8 getevent -q

去除了所有设备信息,只有event事件

130|:/ $ getevent -q
/dev/input/event1: 0001 0074 00000001
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0074 00000000
/dev/input/event1: 0000 0000 00000000

1.1.9 getevent -c

输入指定条数的信息

130|:/ $ getevent -c 3
add device 11: /dev/input/event1
  name:     "pmic_pwrkey"
/dev/input/event1: 0001 0074 00000001
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0074 00000000

1.1.10 getevent - r

输出信息产生的速度,例如:按下或抬起的速度很快 rate值就越高

/dev/input/event1: 0001 0074 00000001
/dev/input/event1: 0000 0000 00000000 rate 7
/dev/input/event1: 0001 0074 00000000
/dev/input/event1: 0000 0000 00000000 rate 0

1.2 事件类型格式分析

格式是 :/dev/input/eventX type code value
例如:/dev/input/event1: 0001 0074 00000001

1.2.1 type

其中type的内容如下:

#define EV_SYN 0x00 //代表同步事件
#define EV_KEY 0x01 //按键事件
#define EV_REL 0x02 //相对坐标,用来描述相对坐标轴上数值的变化,例如:鼠标向左方移动了5个单位。
#define EV_ABS 0x03 //绝对坐标,用来描述相对坐标轴上数值的变化,例如:描述触摸屏上坐标的值。
#define EV_MSC 0x04 //杂项事件,当不能匹配现有的类型时,使用该类型进行描述。
#define EV_SW 0x05 //开关事件, 用来描述具备两种状态的输入开关。
#define EV_LED 0x11 //EV_LED事件类型通常与设备上的物理LED指示灯相关,例如键盘背光灯、通知LED等
#define EV_SND 0x12 //描述声音事件
#define EV_REP 0x14 //用于可以自动重复的设备
#define EV_FF 0x15 //强力回馈事件,如打游戏时的震动事件
#define EV_PWR 0x16 //特别用于电源开关的输入

1.2.2 code

code事件会跟随type事件的不同而代表不同的含义
1.当type是EV_KEY,则code KEY_POWER代表电源按键。

详情可以看下列网址指向的地点
http://aospxref.com/android-14.0.0_r2/xref/bionic/libc/kernel/uapi/linux/input-event-codes.h

1.3 key事件类型分析

声明:由于本人之前是在安卓9进行蓝牙手柄的开发,所以此篇分析是当时基于安卓9进行的分析,而上面的指令是笔者用安卓14的手机进行内容获取。其中笔者发现按键的信息发生了变化。为何不用安卓9?因为本人最近整理的时候没有安卓9的环境。

1.3.1 安卓9 按键消息和安卓14 按键消息的差异?

安卓9:
按下和抬起一共6条消息

按下:
/dev/input/event4: 0004 0004 00090001
/dev/input/event4: 0001 0130 00000001
/dev/input/event4: 0000 0000 00000000
抬起:
/dev/input/event4: 0004 0004 00090001
/dev/input/event4: 0001 0130 00000000
/dev/input/event4: 0000 0000 00000000

安卓14:
按下和抬起是4条消息

/dev/input/event1: 0001 0074 00000001
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0074 00000000
/dev/input/event1: 0000 0000 00000000

1.3.2 安卓9 蓝牙手柄按键消息分析

按下:
/dev/input/event4: 0004 0004 00090001  //第一条消息
/dev/input/event4: 0001 0130 00000001 //第二条消息
/dev/input/event4: 0000 0000 00000000 //第三条消息
抬起:
/dev/input/event4: 0004 0004 00090001 //第四条消息
/dev/input/event4: 0001 0130 00000000 //第五条消息
/dev/input/event4: 0000 0000 00000000 //第六条消息

参数说明:
/dev/input/event4:代表产生事件的设备节点
0004:代表事件类型
0004:代表事件代码
00090001:事件的值

使用getevent -l指令如下:
在这里插入图片描述

第一条数据包分析:

/dev/input/event4: 0004 0004 00090001

0004=EV_MSC,004=MSC_SCAN value=00090001

EV_MSC代表是杂项事件,MSC_SCAN代表是杂项事件中的扫描事件,Value代表值是00090001,说明扫描到BTN_GAMEPAD这个按键有变化

第二条数据包分析:

是一个按键事件,并表示按了什么键,是否按下

/dev/input/event4: 0001 0130 00000001

0001=EV_KEY 0130=BTN_GAMEPAD 00000001=DOWN

EV_KEY代表这是按键类型事件,BTN_GAMEPAD代表手柄注册中的按键是BTN_GAMEPAD,DOWN表示按下

第三条数据包分析:
/dev/input/event4: 0000 0000 00000000

0000= EV_SYN 0000= SYN_REPORT value=00000000

同步包,在应用层和驱动层做信息同步,标识一个独立的事件的发生,它与另一个同步包夹中间的一组的打印就是一个事件的发生

EV_SYN代表,是同步类型,
SYN_REPORT:当多个输入数据在同一时间发生变化时,SYN_REPORT用于把这些数据进行打包和包同步。例如,一次鼠标的移动可以上报REL_X和REL_Y两个数值,然后发出一个SYN_REPORT。

Value就是扫描到的值。

第四条数据包分析:

/dev/input/event4: 0004 0004 00090001
也是一个扫描事件,同第一条

第五条数据包分析:
/dev/input/event4: 0001 0130 00000000

0001=EV_KEY 0130=BTN_GAMEPAD 00000000=UP

表示是一个按键事件,是BTN_GAMEPAD键,00000000表示抬起

第六条数据包分析:

也是一个同步事件

1.4 motion事件类型分析

一次触摸产生的motion事件其实是三个动作
1.手指按下
2.手指移动
3.手指抬起

此时需要先了解Linux的多点触摸协议

1.4.1 多点触摸协议A

主要用于匿名的设备,,硬件对于触摸点不能被区分和追踪,(大多已经淘汰,故此处不再赘述)
type A设备的驱动程序,需要一次性将当前触摸屏上的所有触摸点的信息全部上报。

1.4.2 多点触摸协议B

硬件有能力追踪并区分触摸点,type B协议和type A协议相比,最大的区别是能够识别某一个触摸点,因此能够减少发送给用户空间的数据。协议B使用的是slot来区分触摸点,要使用ABS_MT_TRACKING_ID消息,此消息不为-1,代表是一个可用的触摸点,如果是-1则代表此触摸点销毁(即手指离开屏幕)

1.4.2.1 变量含义
ABS_MT_POSITION_X //触摸中心位置的X轴坐标
ABS_MT_POSITION_Y ///触摸中心位置的X轴坐标,ABS_MT_POSITION_X 和ABS_MT_POSITION_Y 是多点触摸协议的最小事件集,是最基本的事件,也是必须的事件。
ABS_MT_TOOL_TYPE //触摸工具类型。如手指,触摸笔等
ABS_MT_TRACKING_ID //用来追踪和识别压下到提起期间的某一个触摸点
ABS_MT_TOUCH_MAJOR //触摸点椭圆形最长的那个方向的直径
ABS_MT_TOUCH_MINOR //触摸点椭圆形短一点的那个方向的直径,如果是圆形,ABS_MT_TOUCH_MINOR可以省略
ABS_MT_WIDTH_MAJOR //触摸工具的椭圆的最长的那个方向的直径
ABS_MT_WIDTH_MINOR //触摸工具的圆形短一点的那个方向的直径
ABS_MT_PRESSURE //触摸点的压力大小

此处,应该会有读者疑问ABS_MT_TOUCH_MAJOR和ABS_MT_WIDTH_MAJOR 的区别是什么呢?

答:假定我们的手指按在玻璃上,那么ABS_MT_TOUCH_MAJOR描述的是我们真正手指接触的面积,而ABS_MT_WIDTH_MAJOR代表我们手指头的面积,随着我们按压玻璃用力的加深,ABS_MT_TOUCH_MAJOR会接近于ABS_MT_WIDTH_MAJOR。

问:那么为什么要设置这两个参数呢?

答:这两个参数的可以反应触摸点压力的大小。
ABS_MT_PRESSURE =ABS_MT_TOUCH_MAJOR/ABS_MT_WIDTH_MAJOR。
设备的压力值大小计算方法由设备本身决定。并不相同。只是提供一种可能。

1.4.2.2 协议B举例

手指按下
此时有两个手指触摸屏幕,表示按下,即产生两个触摸点

        ABS_MT_SLOT 0 //用slot 0表示第一个触摸点
        ABS_MT_TRACKING_ID 45 //记录触摸点ID,用于区分触摸点
        ABS_MT_POSITION_X x[0] //第一个触摸点按下的x位置。ABS_MT_POSITION_X和ABS_MT_POSITION_Y是多点触摸协议的最小事件集,
        ABS_MT_POSITION_Y y[0] //第一个触摸点按下的y的位置。
        ABS_MT_SLOT 1 //用slot 0表示第二个触摸点
        ABS_MT_TRACKING_ID 46 //记录触摸点ID,用于区分触摸点
        ABS_MT_POSITION_X x[1] //第二个触摸点按下的x位置。
        ABS_MT_POSITION_Y y[1] //第二个触摸点按下的y位置。
        SYN_REPORT //上报消息

手指移动
情况1:只有第一个触点45 移动x方向,如何报告?

        ABS_MT_SLOT 0 //表示第一个触摸点
        ABS_MT_POSITION_X x[0] //表示此时x的位置
        SYN_REPORT //事件上报

情况2:两个触点都移动了x方向,如何报告?

        ABS_MT_SLOT 0 //表示第一个触摸点
        ABS_MT_POSITION_X x[0] //表示此时第一个触点x的位置
        ABS_MT_SLOT 1 //表示第二个触摸点
        ABS_MT_POSITION_X x[0] //表示此时第二个触点x的位置
        SYN_REPORT //事件上报

此时可以看出,协议A是所有触点都上报,而协议B只上报变化的触点,因此减少了许多消息

手指抬起
情况1:第一跟手指抬起,第二根手指仍在滑动,如何报告?

ABS_MT_SLOT 0 //表示第一个触摸点
ABS_MT_TRACKING_ID -1 //表示第一个触点销毁
SYN_REPORT //事件上报
ABS_MT_SLOT 1 
ABS_MT_POSITION_X x[0]
SYN_REPORT

情况二:两根手指都抬起,如何报告?

ABS_MT_SLOT 0 //表示第一个触摸点
ABS_MT_TRACKING_ID -1 //表示第一个触点销毁
SYN_REPORT //事件上报
ABS_MT_SLOT 1 //表示第二个触摸点
ABS_MT_TRACKING_ID -1 //表示第二个触点销毁
SYN_REPORT //事件上报

1.4.3 getevent -l motion事件分析

此处基于笔者手机获取信息如下:

1.4.3.1 当两根手指按下时
/dev/input/event8: EV_ABS       ABS_MT_SLOT          00000000 //第一个触摸点   00000000 
/dev/input/event8: EV_ABS       ABS_MT_TRACKING_ID   00000010 //第一个触摸点 对应的id
/dev/input/event8: EV_KEY       BTN_TOUCH            DOWN // 当设备驱动报告了BTN_TOUCH键值,Android系统将认为BTN_TOUCH总是被用于指示触摸工具是否真正地接触触摸屏或仅仅在上方盘旋。
/dev/input/event8: EV_KEY       BTN_TOOL_FINGER      DOWN //BTN_TOOL_FINGER表示的是按键类型为手指
/dev/input/event8: EV_ABS       ABS_MT_WIDTH_MAJOR   00000005  //触摸工具的主轴
/dev/input/event8: EV_ABS       ABS_MT_TOUCH_MINOR   00000005 //触摸点最小轴
/dev/input/event8: EV_ABS       ABS_MT_PRESSURE      00000005 //触摸压力大小
/dev/input/event8: EV_ABS       ABS_MT_POSITION_X    000010fc //触摸点的x坐标
/dev/input/event8: EV_ABS       ABS_MT_POSITION_Y    000075cc //触摸点的y坐标
/dev/input/event8: EV_ABS       ABS_PROFILE          0000084e //ABS_PROFILE在多指触控协议中主要用于描述输入设备(如触摸屏)的一些物理特性。它可能包括设备的分辨率、尺寸、形状等参数
/dev/input/event8: EV_SYN       SYN_REPORT           00000000 //事件上报

/dev/input/event8: EV_ABS       ABS_MT_SLOT          00000001 //第二个触摸点   00000001
/dev/input/event8: EV_ABS       ABS_MT_TRACKING_ID   00000011 //第二个触摸点 对应的id
/dev/input/event8: EV_ABS       ABS_MT_TOUCH_MINOR   00000009 //触摸点最小轴
/dev/input/event8: EV_ABS       ABS_MT_PRESSURE      00000009 //触摸压力大小
/dev/input/event8: EV_ABS       ABS_MT_POSITION_X    000011f7 //触摸点的x坐标
/dev/input/event8: EV_ABS       ABS_MT_POSITION_Y    000085d8 //触摸点的y坐标
/dev/input/event8: EV_ABS       ABS_PROFILE          0000046a //ABS_PROFILE在多指触控协议中主要用于描述输入设备(如触摸屏)的一些物理特性。它可能包括设备的分辨率、尺寸、形状等参数
/dev/input/event8: EV_SYN       SYN_REPORT  //事件上报
1.4.3.2 当两根手指移动时
/dev/input/event8: EV_ABS       ABS_MT_SLOT          00000000 //第一个触摸点
/dev/input/event8: EV_ABS       ABS_MT_POSITION_X    0000110f //触摸点的x坐标
/dev/input/event8: EV_ABS       ABS_MT_POSITION_Y    000075d4 //触摸点的y坐标
/dev/input/event8: EV_ABS       ABS_MT_SLOT          00000001 //第二个触摸点
/dev/input/event8: EV_ABS       ABS_MT_POSITION_X    00001237 //触摸点的x坐标
/dev/input/event8: EV_ABS       ABS_MT_POSITION_Y    000085f6 //触摸点的y坐标
/dev/input/event8: EV_SYN       SYN_REPORT           00000000 //事件上报
1.4.3.2 当两根手指抬起时
/dev/input/event8: EV_ABS       ABS_MT_SLOT          00000000 //第一个触摸点
/dev/input/event8: EV_ABS       ABS_MT_TRACKING_ID   ffffffff //值为-1,代表第一个触摸点销毁
/dev/input/event8: EV_SYN       SYN_REPORT           00000000
/dev/input/event8: EV_ABS       ABS_MT_SLOT          00000001 //第二个触摸点
/dev/input/event8: EV_ABS       ABS_MT_TRACKING_ID   ffffffff //值为-1,代表第二个触摸点销毁
/dev/input/event8: EV_KEY       BTN_TOUCH            UP //当设备驱动报告了BTN_TOUCH键值,Android系统将认为BTN_TOUCH总是被用于指示触摸工具是否真正地接触触摸屏或仅仅在上方盘旋。
/dev/input/event8: EV_KEY       BTN_TOOL_FINGER      UP //表示按键类型为手指
/dev/input/event8: EV_SYN       SYN_REPORT           00000000 //同步事件

后续

那么这些消息,input是如何处理的呢?后续的篇幅会根据源码进行逐行分析。欢迎关注。

  • 36
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值