geteventの単純な分析

geteventはAndroidシステムのコード用の小さなツールで、下部に特定のイベントが報告されているかどうかを確認できます。

Androidによってリリースされたソースコードでは、alps / docs / source.android.com / en / devices / inputにガジェットの基本的な使用方法がいくつかあります。

adbシェルgetevent -p

現在のシステムの各入力デバイスのレポート機能を表示するために使用されます。

adbシェルgetevent -lp

-lを追加すると、対応するイベントテキストラベルが表示されます。

 adbシェルgetevent -lt

アクティブなイベントを表示します。リアルタイムでキャプチャするためによく使用されます。

 

LOCAL_MODULE:=ツールボックス

いくつかのガジェットの入り口が統一されていることがわかります。3つの異なるリンクが使用されます。

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 }

ツール[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

in / 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");を渡します。

ユーザー入力コマンドのパラメーターを分析します。

別のフラグに格納されます。メインフラグは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     }

ミアン-》 open_device

入ってくるデバイスを印刷し、いくつかのバージョンの製品を印刷します。

印刷パラメーターが渡されない場合。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 }

最後に、イベントノードの情報が表示されるのを常に待ち、それを読み取って表示します。コマンド入力へ。

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     }

 

リリース8元の記事 ウォンの賞賛0 ビュー2874

おすすめ

転載: blog.csdn.net/skyxiaoyan1/article/details/84618895