Android系统源码阅读(11):Android的InputManagerService的工作过程
请对照AOSP版本:6.0.1_r50。
1. 创建InputManager
这里和老罗当年的版本有很大不同了,有了InputManagerService管理InputManager。
1.1
想要探索如何启动的相关server,需要从SystemServer开始探寻。从SystemServer的进程开始运行开始,它就会创建一些系统server,这里就会启动other services。
其中,会创建Input Manager和Window Manager两个服务。
frameworks/base/services/java/com/android/server/SystemServer.java :
Slog.i(TAG, "Input Manager");
inputManager = new InputManagerService(context);
Slog.i(TAG, "Window Manager");
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
//..
inputManager.start();
1.2
先来仔细端详一下InputManagerService的构造函数。这里会调用c++层的初始化函数。
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java :
this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper);
//..
mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
注意这里将DisplayThread的Looper传递过去,DisplayThread是一个单例模式的类,它会启动唯一的线程。同时DisplayThread是一个HandlerThread的子类,实现了Looper循环机制。DisplayThread是用来执行和显示有关的操作,显示操作一般需要比较小的延迟。DisplayThread只能被WindowManager、DisplayManager,InputManager用来执行一些快速地实时操作。
1.3
这一步首先将java层的MessageQueue变为了c++的MessageQueue。然后构造了一个NativeInputManager对象,最后将指向该对象的指针im
返回给java层。
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp :
NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, messageQueue->getLooper());
1.4
在构造NativeInputManager时,会创建一个InputManager对象mInputManager。
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp :
sp<EventHub> eventHub = new EventHub();
mInputManager = new InputManager(eventHub, this, this);
1.5
这一步会创建一个dispatcher负责分发输入事件,一个reader负责获取事件。
frameworks/native/services/inputflinger/InputManager.cpp :
mDispatcher = new InputDispatcher(dispatcherPolicy);
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
initialize();
1.6
这里会创建两个线程,在以后的步骤中会用来运行前面创建的dispathcer和reader。
frameworks/native/services/inputflinger/InputManager.cpp :
mReaderThread = new InputReaderThread(mReader);
mDispatcherThread = new InputDispatcherThread(mDispatcher);
2. 启动InputManager
将视线再次回到SystemServer中,在创建完InputManagerService后,需要将这个Service启动,同样是在1.1的startOtherServices函数里,调用了InputManagerService的成员函数start。
2.1
这里首先调用了c++层的nativeStart,然后InputManagerService将自己交给Watchdog监视。然后注册了PointerSpeedSetting和ShowTouchesSetting两个Observer。
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java :
nativeStart(mPtr);
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
registerPointerSpeedSettingObserver();
registerShowTouchesSettingObserver();
这两个Observer暂时还没搞清楚是干什么的。
2.2
这一步将传来的ptr参数转化为一个NativeInputManager指针,同时开始启动NativeInputManager中的InputManager。
frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp :
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
status_t result = im->getInputManager()->start();
2.3
这里会启动在1.6中创建的两个线程,分别用来分发和监听Input事件。
frameworks/native/services/inputflinger/InputManager.cpp :
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);)
3. 启动InputDispatcher
在2.3中运行的线程以threadLoop为入口,开始进入循环。
3.1
这一步直接将任务交给InputDispatcher的dispatchOnce函数。
frameworks/native/services/inputflinger/InputDispatcher.cpp :<