InputManagerService是Android framework中核心service之一,Android framework层涉及的代码也是非常多,
1 | frameworks/native/services/inputflinger/ |

从简单的分类可以看做是两层:
- Java层,
InputManagerService负责对外提供服务,给WindowManagerService提供输入信息的回调 - Native层,监控Linux上报的输入事件,把事件处理成Android的KeyCode,给想要处理的Window发送输入事件
前面介绍了Linux的输入子系统,可以看到应用层的输入子系统框架都是基于驱动抽象出来的文件系统设备节点的读写来处理的,虽然说起来比较简单,但是在整个复杂的Android操作系统中,把输入事件发送到UI层处理还是非常复杂的一个过程。
当用户按下按键或者触摸屏幕时,输入系统会取出驱动上报的时间,经过层层封装转换成Android层能识别的KeyEvent或者MotionEvent,最后交付给对应的目标窗口来消费输入事件。
输入模块的组成:
- Native层的
InputReader负责从EventHub取出事件并处理,再交付给InputDispatcher线程 - Native的
InputDispatcher线程接收到来自InputReader的输入事件,并记录WMS的窗口信息,用来派发到合适的窗口 - Java层的
InputManagerService跟WMS交互,WMS记录窗口信息,同步更新到IMS,为InputDispatcher线程正确派发事件到ViewRootImpl提供保障
InputManagerService启动过程
InputManagerService作为system_server中的重要服务,继承与IInputManager.Stub,作为binder的服务端,client位于InputManager的内部通过IInputManagerStub.asInterface()获取binder的代理端,C/S两端通信协议是由IInputManager.aidl来定义。

IMS涉及到的重要的类:
InputManagerService- 位于Java层的InputManagerService.java文件- 其成员变量
mPtr指向Native层的NativeInputManager对象
- 其成员变量
NativeInputManager- 位于Native层的com_android_server_input_InputManagerService.cpp文件- 其成员
mServiceObj指向Java层的IMS对象 - 其成员
mLooper是指”android.display”线程的Looper
- 其成员
InputManager- 位于libinputflinger中的InputManager.cpp文件InputDispatcher和InputReader的成员变量mPolicy都是指向NativeInputManager对象InputReader的成员mQueuedListener,数据类型为QueuedInputListener;通过其内部成员变量mInnerListener指向InputDispatcher对象;这就是InputReader跟InputDispatcher交互的中间枢纽。
InputDispatcherPolicyInterfaceInputDispatcherInputDispatcherInterfaceInputReaderPolicyInterfaceInputReaderInputReaderInterfaceEventHubInterfaceEventHub
IMS的启动
IMS是伴随着system_server进程的启动而启动的
1 | InputManagerService |
SystemServer.java
1 | private void startOtherServices() { |
IMS初始化
InputManagerService.java
1 | public InputManagerService(Context context) { |
nativeInit
调用到InputManagerService对应的JNI代码com_android_server_input_InputManager.cpp
1 | static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj, jobject contextObj, jobject messageQueueObj) { |
同样的套路,在nativeInit函数中创建了一个NativeInputManager对象,然后转化为指针保存在一个long类型的变量中传递给java层,这样子java层就可以利用这个指针来调用NativeInputManager对象中的成员方法和变量。
NativeInputManager
com_android_server_input_InputManagerService.cpp
1 | NativeInputManager::NativeInputManager(jobject contextObj, |
mLooper是从IMS的”android.display”线程的Looper对象传递下来的。
EventHub
EventHub.cpp
1 | EventHub::EventHub(void) : |
- 创建epoll实例来处理文件IO的多路复用
- 初始化INotify,监听/dev/input/目录下的文件,并且添加到epoll中
- 创建非阻塞管道文件描述符,添加到epoll中
InputManager
InputManager.cpp
1 | InputManager::InputManager( |
创建了InputDispatcher和InputReader对象,这里的Reader和Dispatcher的构造参数都是从NativeInputManager传递过来的
InputManager初始化initialize
InputManager.cpp
1 | void InputManager::initialize() { |
创建两个可以访问InputManagerService成员变量的native线程
InputReader线程InputDispatcher线程
IMS.start
InputManagerService.java
1 | public void start() { |
nativeStart
com_android_server_input_InputManagerService.cpp
1 | static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) { |
InputManager.start
InputManager.cpp
1 | status_t InputManager::start() { |
启动两个线程:
- InputReader
- InputDispatcher
1 | /* Reads raw events from the event hub and processes them, endlessly. */ |
InputReaderThread和InputDispatcherThread都是集成了Android::Thread,实现了threadLoop()接口实现线程的实体。
下面来详细分析一下Android的EventHub。