getevent是 安卓系统下代码的小工具 能很好的确认底层是否有 某些事件的上报。
在Android 释放的源代码里 alps/docs/source.android.com/en/devices/input 有该小工具的一些基本使用方法。
adb shell getevent -p
用来显示 当前系统的各个input设备的上报功能。
adb shell getevent -lp
加上-l会显示对应的事件文本标号。
adb shell getevent -lt
显示活动事件, 经常用来实时抓取。
LOCAL_MODULE := toolbox
可发现统一了 几个 小工具的入口。 用的是三个不同的链接。
LOCAL_POST_INSTALL_CMD := $(hide) $(foreach t,$(ALL_TOOLS),ln -sf toolbox $(TARGET_OUT)/bin/$(t);)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1928 int main(int argc, char** argv) { 29 // Let's assume that none of this code handles broken pipes. At least ls, 30 // ps, and top were broken (though I'd previously added this fix locally 31 // to top). We exit rather than use SIG_IGN because tools like top will 32 // just keep on writing to nowhere forever if we don't stop them. 33 signal(SIGPIPE, SIGPIPE_handler); 34 35 char* cmd = strrchr(argv[0], '/'); 36 char* name = cmd ? (cmd + 1) : argv[0]; 37 38 for (size_t i = 0; tools[i].name; i++) { 39 if (!strcmp(tools[i].name, name)) { 40 return tools[i].func(argc, argv); 41 } 42 } 43 44 printf("%s: no such tooln", argv[0]); 45 return 127; 46 }
而tools[i] 的定义用的比较灵活。
1
2
3
4
5
6
7
8
9
1011 static struct { 12 const char* name; 13 int (*func)(int, char**); 14 } tools[] = { 15 #define TOOL(name) { #name, name##_main }, 16 #include "tools.h" 17 #undef TOOL 18 { 0, 0 }, 19 };
tools[i] 这个数组的生成是结合了Android.mk.
1
2
3
4
539 $(LOCAL_PATH)/toolbox.c: $(intermediates)/tools.h 40 41 TOOLS_H := $(intermediates)/tools.h 42 $(TOOLS_H): PRIVATE_TOOLS := toolbox $(ALL_TOOLS) 43 $(TOOLS_H): PRIVATE_CUSTOM_TOOL = echo "/* file generated automatically */" > $@ ; for t in $(PRIVATE_TOOLS) ; do echo "TOOL($$t)" >> $@ ; done
自动生成在out/target/product/k80_bsp/obj/EXECUTABLES/toolbox_intermediates/tools.h
1
2
3
4
5
61 /* file generated automatically */ 2 TOOL(toolbox) 3 TOOL(dd) 4 TOOL(getevent) 5 TOOL(newfs_msdos)
对应TOOL(getevent)就可以发现实际上是导入到了 getevent 的入口
int getevent_main(int argc, char *argv[])
通过 c = getopt(argc, argv, "tns:Sv::dpilqc:rh");
分析用户输入命令的参数。
分别存放到不同的flag中。 主要flag为 print_flags,使用它的不同位数进行标记。
getopt 处理的只是 对应的- 后面的参数, 后面会对文件路径参数进行处理。
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
37599 if(dont_block == -1) 600 dont_block = 0; 601 602 if (optind + 1 == argc) { 603 device = argv[optind]; 604 optind++; 605 } 606 if (optind != argc) { 607 usage(argv[0]); 608 exit(1); 609 } 610 nfds = 1; 611 ufds = calloc(1, sizeof(ufds[0])); 612 ufds[0].fd = inotify_init(); 613 ufds[0].events = POLLIN; 614 if(device) { 615 if(!print_flags_set) 616 print_flags |= PRINT_DEVICE_ERRORS; 617 res = open_device(device, print_flags); 618 if(res < 0) { 619 return 1; 620 } 621 } else { 622 if(!print_flags_set) 623 print_flags |= PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME; 624 print_device = 1; 625 res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); 626 if(res < 0) { 627 fprintf(stderr, "could not add watch for %s, %sn", device_path, strerror(errno)); 628 return 1; 629 } 630 res = scan_dir(device_path, print_flags); 631 if(res < 0) { 632 fprintf(stderr, "scan dir failed for %sn", device_path); 633 return 1; 634 } 635 }
mian-》open_device
打印传入的dev, 进行一些version product等 的打印。
如果 没有传入 打印的参数。 将对 main--》scan_dir --》open_device所以目录 进行。依次打开。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23473 static int scan_dir(const char *dirname, int print_flags) 474 { 475 char devname[PATH_MAX]; 476 char *filename; 477 DIR *dir; 478 struct dirent *de; 479 dir = opendir(dirname); 480 if(dir == NULL) 481 return -1; 482 strcpy(devname, dirname); 483 filename = devname + strlen(devname); 484 *filename++ = '/'; 485 while((de = readdir(dir))) { 486 if(de->d_name[0] == '.' && 487 (de->d_name[1] == '' || 488 (de->d_name[1] == '.' && de->d_name[2] == ''))) 489 continue; 490 strcpy(filename, de->d_name); 491 open_device(devname, print_flags); 492 } 493 closedir(dir); 494 return 0; 495 }
最后不断的等待 我们的event 节点内的信息的出现, 读取出来进行显示。给到命令输入者。
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
35652 653 while(1) { 654 //int pollres = 655 poll(ufds, nfds, -1); 656 //printf("poll %d, returned %dn", nfds, pollres); 657 if(ufds[0].revents & POLLIN) { 658 read_notify(device_path, ufds[0].fd, print_flags); 659 } 660 for(i = 1; i < nfds; i++) { 661 if(ufds[i].revents) { 662 if(ufds[i].revents & POLLIN) { 663 res = read(ufds[i].fd, &event, sizeof(event)); 664 if(res < (int)sizeof(event)) { 665 fprintf(stderr, "could not get eventn"); 666 return 1; 667 } 668 if(get_time) { 669 printf("[%8ld.%06ld] ", event.time.tv_sec, event.time.tv_usec); 670 } 671 if(print_device) 672 printf("%s: ", device_names[i]); 673 print_event(event.type, event.code, event.value, print_flags); 674 if(sync_rate && event.type == 0 && event.code == 0) { 675 int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec; 676 if(last_sync_time) 677 printf(" rate %lld", 1000000LL / (now - last_sync_time)); 678 last_sync_time = now; 679 } 680 printf("%s", newline); 681 if(event_count && --event_count == 0) 682 return 0; 683 } 684 } 685 } 686 }
最后
以上就是缥缈红酒最近收集整理的关于getevent 简单分析的全部内容,更多相关getevent内容请搜索靠谱客的其他文章。
发表评论 取消回复