getevent 简单分析

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 tool\n", 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, %s\n", 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 %s\n", 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] == '\0' ||
488             (de->d_name[1] == '.' && de->d_name[2] == '\0')))
489             continue;
490         strcpy(filename, de->d_name);
491         open_device(devname, print_flags);
492     }                                                                                                                                                                                                         
493     closedir(dir);
494     return 0;
495 }

最后不断的等待 我们的event 节点内的信息的出现, 读取出来进行显示。给到命令输入者。

652                        
653     while(1) {         
654         //int pollres =
655         poll(ufds, nfds, -1);
656         //printf("poll %d, returned %d\n", 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 event\n");
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     }

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值