【Andorid】input系统的事件处理

【Andorid】input系统的事件处理

http://blog.csdn.net/skywalkzf/article/details/6274726

在上篇中有一个基本的input的设备的简介,这里我们在说一下input core相关的东东。

先来个开胃菜,先看看struct input_dev

[cpp] view plain copy print ?
  1. struct input_dev {  
  2.  const char *name;                               //device的name     
  3.  const char *phys;                               //设备的物理路径   
  4.  const char *uniq;                               //设备唯一的id编码   
  5.  struct input_id id;                             //设备id   
  6.   
  7.  unsigned long evbit[BITS_TO_LONGS(EV_CNT)];     //设备支持的events类型的bitmap(EV_KEY, EV_REL, etc)   
  8.  unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];   //设备使用的keys/buttons的bitmap   
  9.  unsigned long relbit[BITS_TO_LONGS(REL_CNT)];   //设备相关轴心的bitmap???   
  10.  unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];   //设备绝对轴心的bitmap??   
  11.  unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];   //设备支持的混合evetns的bitmap   
  12.  unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];   //设备上存在的leds的bitmap   
  13.  unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];   //设备支持的音效的bitmap   
  14.  unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];     //设备支持的回馈效果的bitmap   
  15.  unsigned long swbit[BITS_TO_LONGS(SW_CNT)];     //设备上是否有开关的bitmap   
  16.   
  17.  unsigned int keycodemax;                        //keycode table的大小   
  18.  unsigned int keycodesize;                       //size of elements in keycode table   
  19.  void *keycode;                                  //设备扫描到的keycodes的映射   
  20.  int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);    //可选的方法来改变当前的keymap,用来修改少量的keymaps。如果不使用,则会有默认的途径来使用   
  21.  int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);   //可选的方法来恢复(retrieve)当前的keymap。   
  22.   
  23.  struct ff_device *ff;                           //如果设备支持力反馈,则这个结构体要关联   
  24.   
  25.  unsigned int repeat_key;                        //存储上次按下的按键值,用来实现软件的自动重复   
  26.  struct timer_list timer;                        //软件自动重复的定时时间   
  27.   
  28.  int sync;                                       //从上次的EV_SYNC后没有新的events就设置为1   
  29.   
  30.  int abs[ABS_MAX + 1];                           //来自绝对轴的当前值   
  31.  int rep[REP_MAX + 1];                           //当前值的自动重复参数例如(delay,rate)   
  32.   
  33.  unsigned long key[BITS_TO_LONGS(KEY_CNT)];      //设备的按键的当前状态   
  34.  unsigned long led[BITS_TO_LONGS(LED_CNT)];      //设备的leds的当前状态   
  35.  unsigned long snd[BITS_TO_LONGS(SND_CNT)];      //音效的当前状态   
  36.  unsigned long sw[BITS_TO_LONGS(SW_CNT)];        //设备开关的当前状态   
  37.   
  38.  int absmax[ABS_MAX + 1];                        //来自绝对坐标的最大events值   
  39.  int absmin[ABS_MAX + 1];                        //来自绝对坐标的最小events值   
  40.  int absfuzz[ABS_MAX + 1];                       //描述轴的噪声   
  41.  int absflat[ABS_MAX + 1];                       //中心位置的大小(used by joydev)   
  42.  int absres[ABS_MAX + 1];  
  43.   
  44.  int (*open)(struct input_dev *dev);             //input_open_device。驱动必须已经可以产生events(通过polling,IRQ,etc)   
  45.  void (*close)(struct input_dev *dev);           //input_close_device   
  46.  int (*flush)(struct input_dev *dev, struct file *file);//清除设备   
  47.  int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);//这个在这个结构体中比较的重要,是上报events的入口。   
  48.   
  49.  struct input_handle *grab;  
  50.   
  51.  spinlock_t event_lock;   //当input core接收或者产生一个events的时候,spinlock起作用   
  52.  struct mutex mutex;      //会串行执行open(),close()和flush()方法   
  53.   
  54.  unsigned int users;      //存储打开此设备的用户数量,这个来有助于知道谁是第一个打开设备的用户,谁是最后一个关闭设备的用户   
  55.  bool going_away;         //   
  56.   
  57.  struct device dev;  
  58.   
  59.  struct list_head h_list;     //设备的input handles的列表   
  60.  struct list_head node;       //用来在input_dev_list中放置设备   
  61. }  
struct input_dev { const char *name; //device的name const char *phys; //设备的物理路径 const char *uniq; //设备唯一的id编码 struct input_id id; //设备id unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //设备支持的events类型的bitmap(EV_KEY, EV_REL, etc) unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; //设备使用的keys/buttons的bitmap unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; //设备相关轴心的bitmap??? unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; //设备绝对轴心的bitmap?? unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; //设备支持的混合evetns的bitmap unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; //设备上存在的leds的bitmap unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; //设备支持的音效的bitmap unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; //设备支持的回馈效果的bitmap unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; //设备上是否有开关的bitmap unsigned int keycodemax; //keycode table的大小 unsigned int keycodesize; //size of elements in keycode table void *keycode; //设备扫描到的keycodes的映射 int (*setkeycode)(struct input_dev *dev, int scancode, int keycode); //可选的方法来改变当前的keymap,用来修改少量的keymaps。如果不使用,则会有默认的途径来使用 int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode); //可选的方法来恢复(retrieve)当前的keymap。 struct ff_device *ff; //如果设备支持力反馈,则这个结构体要关联 unsigned int repeat_key; //存储上次按下的按键值,用来实现软件的自动重复 struct timer_list timer; //软件自动重复的定时时间 int sync; //从上次的EV_SYNC后没有新的events就设置为1 int abs[ABS_MAX + 1]; //来自绝对轴的当前值 int rep[REP_MAX + 1]; //当前值的自动重复参数例如(delay,rate) unsigned long key[BITS_TO_LONGS(KEY_CNT)]; //设备的按键的当前状态 unsigned long led[BITS_TO_LONGS(LED_CNT)]; //设备的leds的当前状态 unsigned long snd[BITS_TO_LONGS(SND_CNT)]; //音效的当前状态 unsigned long sw[BITS_TO_LONGS(SW_CNT)]; //设备开关的当前状态 int absmax[ABS_MAX + 1]; //来自绝对坐标的最大events值 int absmin[ABS_MAX + 1]; //来自绝对坐标的最小events值 int absfuzz[ABS_MAX + 1]; //描述轴的噪声 int absflat[ABS_MAX + 1]; //中心位置的大小(used by joydev) int absres[ABS_MAX + 1]; int (*open)(struct input_dev *dev); //input_open_device。驱动必须已经可以产生events(通过polling,IRQ,etc) void (*close)(struct input_dev *dev); //input_close_device int (*flush)(struct input_dev *dev, struct file *file);//清除设备 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);//这个在这个结构体中比较的重要,是上报events的入口。 struct input_handle *grab; spinlock_t event_lock; //当input core接收或者产生一个events的时候,spinlock起作用 struct mutex mutex; //会串行执行open(),close()和flush()方法 unsigned int users; //存储打开此设备的用户数量,这个来有助于知道谁是第一个打开设备的用户,谁是最后一个关闭设备的用户 bool going_away; // struct device dev; struct list_head h_list; //设备的input handles的列表 struct list_head node; //用来在input_dev_list中放置设备 }

 

下面开始进入正文
1、input device初始化中几个主要的地方

[cpp] view plain copy print ?
  1. input_register_handler//这里来注册input的handler,在handler中声明了event,这个event就是在input事件上报时的入口函数,下面的代码流程中我们可以看到   
  2. keypad_input_dev = input_allocate_device();   
  3.          //通过调用kzalloc()来申请一块内存区域。   
  4.          //当然在以后的注册过程中出错,要注意通过input_free_device释放申请到的此块区域   
  5.   
  6. __set_bit(xxx, keypad_input_dev);   
  7.         //通过set bit来设置input_dev的相关的bit,这里就要看自己的设备中到底是使用哪些,   
  8.         //这个可以看看linux/input.h文件中的input_dev   
  9.   
  10. input_register_device();  
  11.        //注册input设备   
  12.        //与之相对应的是input_unregister_device()  
input_register_handler//这里来注册input的handler,在handler中声明了event,这个event就是在input事件上报时的入口函数,下面的代码流程中我们可以看到 keypad_input_dev = input_allocate_device(); //通过调用kzalloc()来申请一块内存区域。 //当然在以后的注册过程中出错,要注意通过input_free_device释放申请到的此块区域 __set_bit(xxx, keypad_input_dev); //通过set bit来设置input_dev的相关的bit,这里就要看自己的设备中到底是使用哪些, //这个可以看看linux/input.h文件中的input_dev input_register_device(); //注册input设备 //与之相对应的是input_unregister_device()        
2、上报过程
这里我们跳过keypad的函数,从input开始
[cpp] view plain copy print ?
  1. input_report_key(struct input_dev *dev, unsigned int code, int value);  
  2.        //上报所读取到的按键值,这里其实是封装了input_event(struct input_dev *dev, unsigend int type, unsigend int code, int value);   
  3.        -----if(is_event_supported(type,dev->evbit, EV_MAX); //根据dev->evbit来判断是否支持当前的type   
  4.        -----add_input_randomness(type,code,value);          //这个主要是给系统加入随机数产生来使用的,这个与input core无关,但是对系统产生随机数很重要   
  5.        -----input_handle_event(dev,type,code,value);  
  6.                  ----input_pass_event(struct input_dev *dev, unsigned int type, unsigend int code, int value)  
  7.                      在这个函数中则调用了handle->handler->event,这个event就是我们在上述结构体中要注意的  
  8.     在这里我们的keypad的event就是kbd_event。     
  9.       kbd_event(struct input_handle *handle, unsigned int event_type, unsigned int event_code, int value)  
  10.           ----kbd_keycode(unsigned int keycode, int down, int hw_raw)  
  11.                ---put_queue(struct vc_data *vc, int ch)//看到这里,我们可以发现将我们所扫描到的keycode传递给了tty设备,关于tty设备和input设备的关系后面在讲  
input_report_key(struct input_dev *dev, unsigned int code, int value); //上报所读取到的按键值,这里其实是封装了input_event(struct input_dev *dev, unsigend int type, unsigend int code, int value); -----if(is_event_supported(type,dev->evbit, EV_MAX); //根据dev->evbit来判断是否支持当前的type -----add_input_randomness(type,code,value); //这个主要是给系统加入随机数产生来使用的,这个与input core无关,但是对系统产生随机数很重要 -----input_handle_event(dev,type,code,value); ----input_pass_event(struct input_dev *dev, unsigned int type, unsigend int code, int value) 在这个函数中则调用了handle->handler->event,这个event就是我们在上述结构体中要注意的 在这里我们的keypad的event就是kbd_event。 kbd_event(struct input_handle *handle, unsigned int event_type, unsigned int event_code, int value) ----kbd_keycode(unsigned int keycode, int down, int hw_raw) ---put_queue(struct vc_data *vc, int ch)//看到这里,我们可以发现将我们所扫描到的keycode传递给了tty设备,关于tty设备和input设备的关系后面在讲

              
3、应用层如何获得              
下面我们看看上面应用层是如何取得的。
首先是framework_base/base/libs/ui/EventHub.cpp
     

[java] view plain copy print ?
  1. bool EventhHub::getEvent(int32_t* outDevciceId,int32_t* outType, int32_t* outScancode, int32_t* outKeycode,  
  2.                               uint32_t* outFlags, int32_t* outValue, nsecs_t* outWhen)  
  3.            -----bool EventHub::openPlatformInput()  //打开platform中的input设备   
  4.                      ----scan_dir()   //扫描input下的设备,当然这里会涉及到系统的一个通知进程inotify,这个后续查看  
bool EventhHub::getEvent(int32_t* outDevciceId,int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t* outFlags, int32_t* outValue, nsecs_t* outWhen) -----bool EventHub::openPlatformInput() //打开platform中的input设备 ----scan_dir() //扫描input下的设备,当然这里会涉及到系统的一个通知进程inotify,这个后续查看

     在这里的getEvent是来获得evnet事件,相当于加了一层过滤,当有新的数据时候,则返回了,应用的thread也开始读取。
其上是jni传递给上层的,最后通过WindowManagerService中开始分发给相关的应用去做处理。

一个简单的图:

 

看了之后才发现内核中的哪个部分也不能小看,小设备,大文章。看来对内核的理解还是不够呀,慢慢的过程呀。。。

你可能感兴趣的:(struct,list,report,input,events,delay)