[Internship] Android getevent.c weekly source code analysis

[Internship] Android getevent.c weekly source code analysis

I. Overview

getevent sendEvent are two tools and the Android system
input adb shell cmd at the command line shell into the Android device
input getevent, obtain current device event
input sendevent, an analog device generates an event
source in the two command systems Android system / the core / toolbox / directory
name and respectively getevent.c sendevent.c, the underlying code belonging Android

Two .Android input system

1. Input device and input events

Mentioned input device, we can think of with a touch screen and keyboard, Android actually supports not only these two input devices, including the mouse, and handle some of the sensors are all input devices.
When the input device is available, Linux kernel creates a named event0 ~ n or other device node name in the / dev / input / directory for the device. When the input device is not available, the corresponding node will be removed. Function can obtain the corresponding input device in the device node from the user space via ioctl () type, manufacturer, and other information is described.

For example: entering getevent adb shell input
printing information as associated apparatus
the Add Device. 1: / dev / INPUT / EVENT4
name: "proximity_sensor" // distance sensor
the Add Device 2: / dev / INPUT / EVENT3
name: "accelerometer_sensor" // The acceleration sensor
the Add Device. 3: / dev / INPUT / EVENT1
name: "meta_event" //
the Add Device. 4: / dev / INPUT / event0
name: "qpnp_pon" key // Power
could not get driver version for / dev / input / mice , not A Typewriter
the Add Device 5: / dev / the INPUT / event5
name: "the GPIO-keys" // keyboard
the Add Device 6: / dev / the INPUT / event2
name: "sec_touchkey" // virtual keys
could not get driver version for / dev / the INPUT / Mouse0, Not A Typewriter
the Add Device 7: / dev / the INPUT / event6
name: "sec_touchscreen" // touch screen

Android input event is generated : when the user operates the input device, Linux kernel receive the corresponding hardware interrupts, and interrupt processing to the original input event data, the writing apparatus corresponding to the node in the user space can read () function the event read out.
Android input system works : monitoring / all device nodes dev / input / under, when a node has data to read, the data is read out and the corresponding translational processing, to find a suitable window in all events received person, and distributed to it.

Workflow 2.Android input system

Here Insert Picture Description

. (1) Composition & Function:

Linux kernel : receiving an interrupt input device, the raw event data is written to the device node.

Device node : IMS core and connected

InputManagerService (the IMS) : Android system service layer and two parts Java Native layer. Java layer is responsible for communication with the WMS. Native container layer is a running InputReader InputDispatcher two critical components and input system.

EventHub : direct access to all the device nodes will be processed underlying event of all system-related input by the user is returned to the function named getEvents () a. These events include the original input event, add or delete nodes and other equipment.

InputReader : One of the key components of the IMS. It runs in a separate thread, responsible for the management and configuration of input devices list, while the input event processing. Through its thread loop continuously through getEvents () function will be removed from the events and processed EventHub. For additions and deletions event device node, it updates the list of input devices and configuration. For the original input events, InputReader its translation, assembly, packaging to include more information, more readable input events, and then to InputDispatcher be distributed.

InputReaderPolicy : provide policy configuration to InputReader event processing.

InputDispatcher : Another key component in the IMS. It also runs on a separate thread.
InputDispatcher in keeping the information from all the windows of WMS, which after receiving input from InputReader the event, will find a suitable window in their custody window and event distribution to the window.

InputDispatcherPolicy : providing policy control for the distribution of InputDispatcher process. Such as the interception of certain input events are used for special purposes, or to prevent certain events will be distributed to the target window. eg: home keys are taken into PhoneWindowManager InputDispatcherPolicy for processing, and to prevent the window from the HOME key press event is received.

WindowManagerSevice (the WMS) : When the new window, WMS created the event delivery channels used for the new window and IMS. WMS information of all windows, including windows clickable area, the focus window and other real-time updates to the IMS InputDispatcher in the InputDispatcher events will be correctly distributed to the specified window.

ViewRootImpl : application layer event distributing the entrance window of the received input events along the control tree distributed to the appropriate controls.

. (2) workflow:

Kernel raw event writing device node, InputReader by EventHub the original event taken out and translated into Android input event processing, and then to InputDispatcher . InputDispatcher according to WMS window information provided by the event will be distributed to the appropriate window. Window corresponding ViewRootImpl objects along the control tree event will be distributed to the appropriate controls. Ultimately, control of events received a response.

Three .getevent.c source code analysis

1. Basics

(1).INotify

INotify is a file system is a Linux kernel provided by the change notification mechanism . It can change the application to monitor the file system, such as a new file, deleting, reading and writing. INotify mechanism has two basic objects, respectively
inotify objects and watch objects are represented using file descriptors.

inotify object corresponds to a queue, the application can be added to a plurality of listeners inotify object. When something is listening
when occurs, the can () function will read out the event information from the object through the inotify read.

inotify objects created :int inotifyFd = notify_init();

watch object is used to describe an event monitor changes in the file system. It is a tuple, including targets and monitor event
mask two elements. Monitor goal is a path to the file system, the file may also be a folder. The event mask
code indicates a need need to listen to the type of event, each event represents a mask. Can listen to the kind of event
a lot of class, including the file was created (IN_CREATE) and delete (IN_DELETE).

Create watch objects :
int wd = inotify_add_watch(inotifyFd,”/dev/input”,IN_CREATE | IN_DELETE);
After creating the above watch, when the device node / dev / input / under creation and deletion operations occur, set a corresponding
event objects written inotify notifyFd as described.

Reads the event information : size_t len = read(inotifyFd,events_buf,BUF_LEN);
events_buf inotify_event array pointer is, the number of read events depends on the length of the array, BUF_LEN
length of events_buf.
inotify_event {struct
__s32 WD; // event corresponding to watch the object descriptor
__u32 mask; // Event Type EG: the IN_CREATE
__u32 Cookie;
__u32 len; // name length field
char name [0]; // store file generating this event path
}
by iNotify mechanism to avoid the trouble of polling the file system, but there is a problem, not through iNotify mechanism
through callback to notify events, but requires the user to take the initiative to read events from inotify object.

(2).poll

poll is a mechanism to monitor whether the file is readable and mechanisms will determine whether the poll fds files readable, if read
will return immediately, the return value is the number of readable fd, if unreadable, then the process will sleep timeout will be
so long, and then again determines whether the file is readable, and if so, returns the number of fd, and if not,
0 is returned.
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
Parameters:
typedef struct the pollfd {
int fd; / * need to be detected or the selected file descriptor * /
Short Events; / * events of interest on the file descriptor fd /
Short the revents; /
on current actual file descriptor fd events * /
};
event type:
POLLIN data readable
POLLRDNORM ordinary data readable
POLLRDBAND have the priority data readable
POLLPRI there is urgent data to read
POLLOUT write data will not lead to blocking
POLLWRNORM write ordinary data will not cause blocking
POLLWRBAND write priority data will not lead to blocking
POLLMSG SIGPOLL messages are available
POLLER specified file descriptor error occurs
POLLHUP specified file descriptor suspend event
POLLNVAL specified illegal file descriptor

typedef unsigned long nfds_t; / * total number of elements in the body structure of the fds * /

timeout: poll function call blocking event, in milliseconds, it has been blocked is less than 0.

Return Value:

0: fds are ready to read, write, or the number of error descriptors
= 0: fds are not ready to read, write, or error of the number of descriptors, then poll the timeout, the timeout event timeout
= -1: poll function call failed, automatically sets the global variable errno.

(2).Ioctl

ioctl function is a device driver for I / O channel managing device.
int ioctl(int fd, int cmd, …);
Parameters:
FD: using file open function returns the identifier when the user program to open the device,
cmd: the user program to the device control command,
            the Linux kernel defined command code (cmd):
            Device Type: 8bit SEQ ID NO: 8bit direction: 2bit data size: 8 ~ 14bit
...: complementary parameters, up to a general, the availability and cmd parameters of significance related.

2.getevent instruction

Enter getevent In adb shell, it will be returned unprocessed event information for us.
Format: event generation device (device) event type (type) event code (code) event value (value)
             of the type, code, are hexadecimal value.
For example: / dev / input / event3: 0002 0001 ffffff5b

3.getevent.c source code analysis

(1) The program execution entry: getevent_main(int argc, char *argv[]);
. (2) by getopt(argc, argv, "tns:Sv::dpilqc:rh")analyzing the parameters.
(3) Create inotify objects, the operator returns the settings stored in listening ufds ufds event as read data.
     ufds[0].fd = inotify_init();
     ufds[0].events = POLLIN;
(4) Set the watch object inotify objects, create and delete monitor / dev / input directory files
     res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE);
(5) Call poll function block waiting for the event originated in a while loop
     poll(ufds, nfds, -1);
(6). When the actual event as there is when data is read, call read_notify () function
     if(ufds[0].revents & POLLIN) {
        read_notify(device_path, ufds[0].fd, print_flags);
     }
inside read_notify () function call open_device () function of the input apparatus or device for increasing the call close_device () function to delete the input device device, internal open_device () function and close_device () function by ioctl () function to control the input device.
(7). If the actual event data is read, read, stored in the object event input_event.
     res = read(ufds[i].fd, &event, sizeof(event));
(8) Call print_event () function prints event
     print_event(event.type, event.code, event.value, print_flags);

Published 10 original articles · won praise 5 · Views 589

Guess you like

Origin blog.csdn.net/LeeDuoZuiShuai/article/details/97536678