Android Input系统原理一

  1. getevent 命令使用

    getevent -h
    getevent -lrt

    -t 表示事件发生时间
    -l label event types and names in plain text 表示把event事件类型名字打出来
    -r 显示一下接受事件速率

    130|console:/ # getevent -lrt
    could not get driver version for /dev/input/mice, Not a typewriter
    add device 1: /dev/input/event2
    name: "cec_input"
    add device 2: /dev/input/event1
    name: "aml_vkeypad"
    could not get driver version for /dev/input/mouse0, Not a typewriter
    add device 3: /dev/input/event0
    name: "aml_keypad"
    add device 4: /dev/input/event3
    name: "input_btrcu"

    [ 3298.022144] /dev/input/event0: EV_SYN SYN_REPORT 00000000
    [ 3298.176073] /dev/input/event0: EV_KEY KEY_VOLUMEUP UP
    [ 3298.176073] /dev/input/event0: EV_SYN SYN_REPORT 00000000 rate 6

    拆分一下这条命令
    [ 3298.022144] /dev/input/event0: EV_KEY KEY_VOLUMEUP DOWN
    分别对应
    时间 节点 事件类型 事件code 事件value

getevent事件是驱动上报的,可以用这条命令定位input问题是驱动问题还是驱动之上的问题

2.getevent源码

system/core/toolbox/getevent.c

cpp 复制代码
nfds = 1;  //pollfd数组大小
ufds = calloc(1, sizeof(ufds[0]));//pollfd数组

ufds[0].fd = inotify_init();//使用inotify fd监听节点变化  也可以监听文件夹内容的变化
ufds[0].events = POLLIN;  //想要监听的事件
cpp 复制代码
//如果使用  getevent /dev/input/event0  指定一个具体的节点  将会进入这个流程
if(device) {
    if(!print_flags_set)
        print_flags |= PRINT_DEVICE_ERRORS;
    res = open_device(device, print_flags);
    if(res < 0) {
        return 1;
    }
}
cpp 复制代码
//监听指定路径  有新的删除节点或新增节点,都会触发 pollin事件
res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
cpp 复制代码
//扫描路径,将/dev/input/路径下的文件都添加到poll中监听
res = scan_dir(device_path, print_flags);  

static int scan_dir(const char *dirname, int print_flags) {
......
......
    while((de = readdir(dir))) {
        if(de->d_name[0] == '.' &&
           (de->d_name[1] == '\0' ||
            (de->d_name[1] == '.' && de->d_name[2] == '\0')))
            continue;
        strcpy(filename, de->d_name);
        open_device(devname, print_flags);
    }
......
......
}

static int open_device(const char *device, int print_flags)
{
......
......
    ufds[nfds].fd = fd; //将/dev/input/下每个节点对应fd放入ufds中
    ufds[nfds].events = POLLIN;
    device_names[nfds] = strdup(device);
    nfds++;

    return 0;
}
cpp 复制代码
while(1) {
    //int pollres =
    //监听文件描述符变化
    poll(ufds, nfds, -1);
    //printf("poll %d, returned %d\n", nfds, pollres);
    //如果是文件描述符0变化,意味着/dev/input/路径下有新文件被创建或删除,将变化同步到poll数组中
    if(ufds[0].revents & POLLIN) {
        read_notify(device_path, ufds[0].fd, print_flags);
    }
    //从1开始遍历监听的具体的节点信息,将对应的信息打印出来
    for(i = 1; i < nfds; i++) {
        if(ufds[i].revents) {
            if(ufds[i].revents & POLLIN) {
                res = read(ufds[i].fd, &event, sizeof(event));
                if(res < (int)sizeof(event)) {
                    fprintf(stderr, "could not get event\n");
                    return 1;
                }
                if(get_time) {
                    printf("[%8ld.%06ld] ", event.time.tv_sec, event.time.tv_usec);
                }
                if(print_device)
                    printf("%s: ", device_names[i]);
                print_event(event.type, event.code, event.value, print_flags);
                if(sync_rate && event.type == 0 && event.code == 0) {
                    int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec;
                    if(last_sync_time)
                        printf(" rate %lld", 1000000LL / (now - last_sync_time));
                    last_sync_time = now;
                }
                printf("%s", newline);
                if(event_count && --event_count == 0)
                    return 0;
            }
        }
    }
}
  1. 多指触控协议分析 (无环境查看,这部分只做笔记)

1.EV_SYN

同步事件,在事件开始或完成会有

对应code:

0004:代表一个事件开始(不必要)

0005:代表一个事件开始(不必要)

SYN_REPORT:代表一个事件的结束(必要)

可以看到遥控器触发也会有SYN_REPORT 的code

2.EV_ABS

事件的一种绝对坐标类型

对应code:

1 ABS_MT_SLOT

本质代表着不同手指,它的value代表手指id

2 ABS_MT_TRACKING_ID

类型B特有的,实际上,每个slot会和一个ID相对应,一个非负数的表示一次接触,-1表示这是一个无用的slot(或者理解为一次接触的结束)无论在接触的类型相对应的slot发生了改变,驱动都应该通过改变这个值来使这个slot失效。并且下一次触摸的ID值会是这次的值加1。

3 ABS_MT_POSITION_X ABS_MT_POSITION_Y

相对于屏幕中心的 x, y坐标

4 ABS_MT_TOUCH_MAJOR

接触部分的长轴长度。相当于椭圆的长轴。

5 ABS_MT_TOUCH_MINOR

接触部分的短轴长度。相当于椭圆的短轴。

6 ABS_MT_PRESSURE

代表按下压力,有的设备不一定有

3.EV_KEY

事件的一种类型。表示是按键(不仅仅指的物理按键也包括TOUCH)事件

对应code:

1 BIN_TOUCH

触摸按键。其值是DOWN或者UP。

2 BIN_TOOL_FINGER

按键的是finger,并且其值也是DOWN或者UP

具体案例可看

android多指控制协议详细解答_touchmajor-CSDN博客

相关推荐
恋猫de小郭21 分钟前
对于普通程序员来说 AI 是什么?AI 究竟用的是什么?
前端·flutter·ai编程
大怪v39 分钟前
前端:人工智能?我也会啊!来个花活,😎😎😎“自动驾驶”整起!
前端·javascript·算法
我是天龙_绍40 分钟前
vue3 props 如何写ts,进行类型标注
前端
CYRUS_STUDIO44 分钟前
用 Frida 控制 Android 线程:kill 命令、挂起与恢复全解析
android·linux·逆向
CYRUS_STUDIO1 小时前
Frida 实战:Android JNI 数组 (jobjectArray) 操作全流程解析
android·逆向
叫我詹躲躲1 小时前
n8n 自动化工作流平台完整部署
前端·langchain·领域驱动设计
遂心_2 小时前
为什么 '1'.toString() 可以调用?深入理解 JavaScript 包装对象机制
前端·javascript
IT_陈寒2 小时前
JavaScript 性能优化:5 个被低估的 V8 引擎技巧让你的代码快 200%
前端·人工智能·后端
岛风风3 小时前
关于手机的设备信息
前端
ReturnTrue8683 小时前
nginx性能优化之Gzip
前端