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博客

相关推荐
工程师老罗1 小时前
如何在Android工程中配置NDK版本
android
崔庆才丨静觅1 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60612 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了2 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅2 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅2 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
七夜zippoe3 小时前
CANN Runtime任务描述序列化与持久化源码深度解码
大数据·运维·服务器·cann
盟接之桥3 小时前
盟接之桥说制造:引流品 × 利润品,全球电商平台高效产品组合策略(供讨论)
大数据·linux·服务器·网络·人工智能·制造
崔庆才丨静觅3 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment3 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端