上一篇Linux/Android——input系统之 kernel层 与 frameworks层交互 (五) 中有介绍kernel层一下以及与Android这边frameworks层之间的联系,算是打通android 应用层与 kernel驱动层,对整个input系统的学习是至关重要的,其中frameworks层只是简单记录了几个接入点,这里开始分析frameworks层的细节部分。
撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/42392311
input服务的启动:
android启动的时候会启动很多个service,这个可以参考SystemServer.Java ,会启动InputManagerService这个服务:
- Slog.i(TAG, "Input Manager");
- inputManager = new InputManagerService(context, wmHandler);
-
- ...
-
- ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
直接看InputManagerService.java中的start函数:
- public void start() {
- Slog.i(TAG, "Starting input manager");
- nativeStart(mPtr);
-
- ...
-
- }
这个牵扯到android的server的jni,最开始是在SystemServer中加载android_server这个动态库,
至于这个动态库的编译可参考/frameworks/base/services/jni/Android.mk中的内容
所以在调用这个nativeStart方法时,相关的动态库已经加载到SystemServer的进程中。
先看下这个start函数在jni文件中的实现,frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp中:
- static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {
- NativeInputManager* im = reinterpret_cast(ptr);
-
- status_t result = im->getInputManager()->start();
- if (result) {
- jniThrowRuntimeException(env, "Input manager could not be started.");
- }
- }
其实熟悉JNI的话,我分析到这里,就应该差不多了。。对于JNI 不是很了解的话可以参考我之前的博客: Andorid——ubuntu下的 NDK / JNI
看下NativeInputManager构造函数中的:
- sp eventHub = new EventHub();
- mInputManager = new InputManager(eventHub, this, this);
这里的JNI部分就不多说了,现在就看这个InputManager的start方法,上面提到到Android.mk,可以看到include了一个libinput的动态库,
而这个动态库的路径是在/frameworks/base/services/input下,这就明了啦.此目录下有InputManager.cpp . EventHub.cpp等
直接看start:
- status_t InputManager::start() {
- status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
- if (result) {
- ALOGE("Could not start InputDispatcher thread due to error %d.", result);
- return result;
- }
-
- result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
- if (result) {
- ALOGE("Could not start InputReader thread due to error %d.", result);
-
- mDispatcherThread->requestExit();
- return result;
- }
-
- return OK;
- }
到这里算是看到真面目的感觉,看这两个线程,字面意思,一个是分发给input事件给当前的activity的,一个是读取从下层发上来的input事件的
InputDispatcher分发:
从上面的线程启动分析:
- bool InputDispatcherThread::threadLoop() {
- mDispatcher->dispatchOnce();
- return true;
- }
调用分发一次的函数:
- void InputDispatcher::dispatchOnce() {
- nsecs_t nextWakeupTime = LONG_LONG_MAX;
- {
- AutoMutex _l(mLock);
- mDispatcherIsAliveCondition.broadcast();
-
-
-
- if (!haveCommandsLocked()) {
- dispatchOnceInnerLocked(&nextWakeupTime);
- }
-
-
-
- if (runCommandsLockedInterruptible()) {
- nextWakeupTime = LONG_LONG_MIN;
- }
- }
-
-
- nsecs_t currentTime = now();
- int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
- mLooper->pollOnce(timeoutMillis);
- }
这个是处理input事件的,后续分析,先看怎么读取事件.
InputReader读取:
源码位于frameworks/base/libs/ui/InputReader.cpp ,开启线程如下:
- bool InputReaderThread::threadLoop() {
- mReader->loopOnce();
- return true;
- }
这里看这个loopOnce:
- void InputReader::loopOnce() {
-
- ...
-
- size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
-
- ...
-
- if (count) {
- processEventsLocked(mEventBuffer, count);
- }
-
- ...
-
- }
可以看到这里就到了获取event事件了。上一篇中有提到!
getEvent中会一直read,直到get到event之后,通过precessevent处理,最终会唤醒上面介绍到的InputDispatcherThread,通知它有新的事件来了