概述
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);)
28 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] 的定义用的比较灵活。
11 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.
39 $(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 /* 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 处理的只是 对应的- 后面的参数, 后面会对文件路径参数进行处理。
599 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所以目录 进行。依次打开。
473 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] == '