Touch screens and keyboards are the most common and standard input devices on Android. When the input device is available, the Linux kernel creates the corresponding device node named event0 to eventN or other names under /dev/inpu/. When the input device is unavailable, the corresponding node is deleted.

When a user operates on an input device, the Linux kernel receives the corresponding hardware interrupt, and then processes the interrupt into raw input event data and writes it to the corresponding device node. The event data can be read out in user space through the read() function.

The Android input system works by monitoring all device nodes under /dev/inpu/. When a node has data to read, it reads the data and performs a series of translation processes. Then it looks for the appropriate event receiver in all Windows and sends it to it.

Take Nexus5 as an example. In /dev/input. Nexus5, the node has six input devices: event0 to event5.



The Android system provides the Getevent tool for developers to read input events directly from device nodes.

Getevent listens for the contents of the input device node. When an input event is written to the node, getevent reads it out and prints it on the screen. Since Getevent does nothing to the event data, its output is the original event provided by the kernel. Its usage is as follows:

Adb shell getevent [- option] [device_path]

Device_path is optional and specifies the path of the device node to be listened. If omitted, events on all device nodes are listened for.

Next I press and release the Power key.



Its output is hexadecimal. Each piece of data contains four items of information: event generated device node (/dev/in/event0), event type (0x0001), event code (0x0074), and event value (0x00000001).

Therefore, the above meanings of event are as follows: type 0x01 indicates that this event is a key event; code 0x74 indicates the scan code of the power key; value 0x00000001 indicates that the power key is pressed down; 0x00000000 indicates that the power key is lifted up. In addition, event0 is the key qpNP_pon (pwrKey), and event2 is the gPIo-keys (keypad).

You can view the device information corresponding to the event in /proc/bus/inpu/devices.

The source of input events is the device node under /dev/inpu/, and the end of most input events is handled by a window managed by WindowManagerService. The initial input event is the original event generated by the kernel, and the final delivery to the window is a KeyEvent or MotionEvent object. So the main job of the Android input system is to read the raw event in the device node, process and encapsulate it, and then send it to a specific window and the controls in the window. This process is done by multiple participants centered on the InputManagerService system service.

InputManagerService, one of the Android system services, wraps C++ InputManager and provides its callback. It is divided into Java layer and Native layer. The Java layer is responsible for communicating with Windows ManagerService. The Native layer is the operation container of two key components of the input system, InputReader and InputDispatcher.

EventHub directly accesses all device nodes. It returns all incoming system-related underlying events to the consumer through a function called getEvents() to be processed. These events include raw input events, device node additions and deletions, etc. By opening all event* device files under /dev/in/, we can get input events for all input devices, whether it’s touch screens, buttons, or infrared remote controls.

InputReader, which runs in a separate thread, manages the list and configuration of input devices, and processes input events. It continuously pulls events out of EventHub and processes them through its thread loop through the getEvents() function. It updates the input device list to the configuration for add or remove events of device nodes. For raw input events, InputReader translates, assembles, and encapsulates them into more informative, more readable input events, which are then sent to InputDispatcher for distribution.

InputReaderPolicy provides policy configuration for InputReader event processing, such as keyboard layout information.

InputDispatcher, which also runs in a separate thread. InputDispatcher holds information from all Windows of WindowManagerService. Upon receiving an input event from InputReader, it looks for an appropriate window in its custody and sends the event to that window.

InputDispatcherPolicy, which provides policy control for the dispatch of InputDispatcher. Such as intercepting certain input events for a specific purpose, or preventing certain events from being sent to the target window. The Power key is intercepted by InputDispatcherPolicy and processed in PhoneWindowManager.

WindowManagerService, although not part of the input system, is essential to the proper functioning of InputDispatcher. When a new window is created, WindowManagerService creates a channel for event delivery for the new window and InputManagerService. In addition, WindowManagerService updates all window information in real time to InputManagerService’s InputDispatcher, including window clickable areas, focus Windows, and so on. Enables InputDispatcher to correctly dispatch events to the specified window.

ViewRootImpl, the top of the View hierarchy, implements the required protocols between the View and WindowManager. For some Windows, such as the wallpaper window or SurfaceView window, the window is the destination of the input event dispatch. For other Windows that use the Android control system, such as activities and dialog boxes, the end point of the input event is the View. The ViewRootImpl sends the input events received by the window down the control tree to interested controls.

In simple terms, the kernel writes the raw event to the device node, and InputReader constantly takes the raw event out via EventHub and translates it into an Android input event, which is then delivered to InputDispatcher. InputDispatcher delivers the event to the appropriate window based on window information provided by WindowManagerService. The window’s ViewRootImpl object then sends events along the control tree to interested controls. Control updates its own screen and performs specific actions in response to events it receives.

References:

1. Understanding Android Volume III by Dawei Zhang