Android input device/handler processing

The handler is used to process input_event, and the device is the device that sends the input_event event. First, let's take a look at which devices and handlers (parts) are there.

input_register_handler 对应 input_dev_list
cpu-boost     cpu-boost.c
sysrq         sysrq.c
leds          input-leds.c
evdev         evdev.c
kgsl          adreno.c
...               

input_register_device 对应 input_handler_list
gpio-keys     gpio_keys.c
atmle_mxt_ts  atmel_maxtouch_ts.c
qpnp_pon      qpnp-power-on.c 
...

The input-related initialization interface mainly has two input_register_handler/input_register_device to bind dev and handler through two linked lists of input_dev_list and input_handler_list . One dev corresponds to multiple handlers, and one handler corresponds to multiple devs.

list_for_each_entry(handler, &input_handler_list, node)
  		input_attach_handler(dev, handler);

list_for_each_entry(handler, &input_handler_list, node)
        input_attach_handler(dev, handler);

input_register_handler registers an interface with the system ( kernel/msm-4.19/include/linux/input.h )

struct input_handler {
    
    
 
  	void *private;
  
  	void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
  	void (*events)(struct input_handle *handle,
  		       const struct input_value *vals, unsigned int count);
  	bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
  	bool (*match)(struct input_handler *handler, struct input_dev *dev);
  	int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
  	void (*disconnect)(struct input_handle *handle);
  	void (*start)(struct input_handle *handle);
  
  	bool legacy_minors;
  	int minor;
  	const char *name;
  
  	const struct input_device_id *id_table;
  
  	struct list_head	h_list;
  	struct list_head	node;
  };

Let's take a look at where these functions in the handler are used. When registering, call the handler's id_table/connect/match

input_attach_handler -> input_match_device -> input_match_device_id(通过handler->id_table与dev的id进行匹配)
                     			    	   -> handler->match(match为空或者调用handler的match进行匹配)
                     ->  handler->connect (匹配成功后会再connect中做handler和device的绑定)
			                -> input_open_device(其中会有标志handle->open++ input_event中会用到)

The following is the id_table that supports all devices, and evdev_ids corresponds to evdev, because all basically all events of match all devices will be processed here

static const struct input_device_id evdev_ids[] = {
    
    
  	{
    
     .driver_info = 1 },	/* Matches all devices */
  	{
    
     },			/* Terminating zero entry */
  };

Call the filter/events/event of the handler in the process of reporting the event

input_event -> input_handle_event -> input_pass_values -> (其中会遍历handler list(h_list))
					-> input_to_handler (主要是对应handler的三个api)
(1)handler->filter  过滤event,如果filter成功则会直接return(因此也可以在kernel中去做键值隐射)
(2)handler->events  处理events的函数,同下
(3)handler->event   当events不存在时调用event	

The handler will eventually be processed by evdev, and written into the buffer through __pass_event for the upper layer evdev_read to read the event.

Guess you like

Origin blog.csdn.net/qq_40405527/article/details/130830500