android Input专题- Q/R/S 10/11/12 InputManager源码分析 1、SystemServer中InputManagerService创建与启动base/services/java/com/android/server/SystemServer.javaprivatevoidstartOtherServices(){//省略部分traceBeginAndSlog(StartInputManagerService);inputManagernewInputManagerService(context);traceEnd();traceBeginAndSlog(StartWindowManagerService);// WMS needs sensor service readyConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart,START_SENSOR_SERVICE);mSensorServiceStartnull;wmWindowManagerService.main(context,inputManager,!mFirstBoot,mOnlyCore,newPhoneWindowManager(),mActivityManagerService.mActivityTaskManager);ServiceManager.addService(Context.WINDOW_SERVICE,wm,/* allowIsolated */false,DUMP_FLAG_PRIORITY_CRITICAL|DUMP_FLAG_PROTO);ServiceManager.addService(Context.INPUT_SERVICE,inputManager,/* allowIsolated */false,DUMP_FLAG_PRIORITY_CRITICAL);traceEnd();//省略部分traceBeginAndSlog(StartInputManager);inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());inputManager.start();//这里再调用starttraceEnd();//省略部分}这里以前讲过在SystemServer中会对系统中很多service进行启动这里我们就发现有对InputManagerService进行对应的构造和添加2、Native层面的InputManager启动publicInputManagerService(Contextcontext){this.mContextcontext;this.mHandlernewInputManagerHandler(DisplayThread.get().getLooper());//省略部分mPtrnativeInit(this,mContext,mHandler.getLooper().getQueue());//省略部分}这里InputManagerService构造方法中就是调用了nativeInit这个方法是native方法来看看对应的native方法base/services/core/jni/com_android_server_input_InputManagerService.cppstaticjlongnativeInit(JNIEnv*env,jclass/* clazz */,jobject serviceObj,jobject contextObj,jobject messageQueueObj){spMessageQueuemessageQueueandroid_os_MessageQueue_getMessageQueue(env,messageQueueObj);if(messageQueuenullptr){jniThrowRuntimeException(env,MessageQueue is not initialized.);return0;}NativeInputManager*imnewNativeInputManager(contextObj,serviceObj,messageQueue-getLooper());im-incStrong(0);returnreinterpret_castjlong(im);}这里主要就是构造了一个NativeInputManagerbase/services/core/jni/com_android_server_input_InputManagerService.cppNativeInputManager::NativeInputManager(jobject contextObj,jobject serviceObj,constspLooperlooper):mLooper(looper),mInteractive(true){//省略部分mInputManagernewInputManager(this,this);defaultServiceManager()-addService(String16(inputflinger),mInputManager,false);}这里主要就是对我们InputManager进行构造然后把它添加到了servicemanager而且传递的两个参数都是NativeInputManager类本身这里它的类结构其实是实现了几个接口方便InputManager里面传递和调用base/services/core/jni/com_android_server_input_InputManagerService.cppclassNativeInputManager:publicvirtualRefBase,publicvirtualInputReaderPolicyInterface,publicvirtualInputDispatcherPolicyInterface,publicvirtualPointerControllerPolicyInterface那么接下来重点就分析我们的InputManager构造native/services/inputflinger/InputManager.cppInputManager::InputManager(constspInputReaderPolicyInterfacereaderPolicy,constspInputDispatcherPolicyInterfacedispatcherPolicy){mDispatchernewInputDispatcher(dispatcherPolicy);mClassifiernewInputClassifier(mDispatcher);mReadercreateInputReader(readerPolicy,mClassifier);initialize();}这里首先是进行了new InputDispatcher再是把构造对象作为InputClassifier的构造参数然后再是createInputReader而且把InputClassifier对象也传递给了InputReader看看createInputReaderspInputReaderInterfacecreateInputReader(constspInputReaderPolicyInterfacepolicy,constspInputListenerInterfacelistener){returnnewInputReader(newEventHub(),policy,listener);}InputReader::InputReader(constspEventHubInterfaceeventHub,constspInputReaderPolicyInterfacepolicy,constspInputListenerInterfacelistener):mContext(this),mEventHub(eventHub),mPolicy(policy),mNextSequenceNum(1),mGlobalMetaState(0),mGeneration(1),mDisableVirtualKeysTimeout(LLONG_MIN),mNextTimeout(LLONG_MAX),mConfigurationChangesToRefresh(0){mQueuedListenernewQueuedInputListener(listener);//listener是作为后面连接InputDispatcher纽带{// acquire lockAutoMutex_l(mLock);//第一次执行时候一般都是一些初始化的还没获取到真正一些devices相关信息refreshConfigurationLocked(0);updateGlobalMetaStateLocked();}// release lock}这里就是构造出了InputReader而且传递了一个EventHub也是立即构造的整个input系统其实就是InputReader和InputDispatcher最为重要。而且二者其实也是间接相连的这样才方便后面InputReader读取加工好了数据就传递到InputDispatcher中让InputDispatcher做下一步的传递工作。再来看到有new一个EventHub来看看它是干啥的native/services/inputflinger/EventHub.cppEventHub::EventHub(void):mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),mNextDeviceId(1),mControllerNumbers(),mOpeningDevices(nullptr),mClosingDevices(nullptr),mNeedToSendFinishedDeviceScan(false),mNeedToReopenDevices(false),mNeedToScanDevices(true),mPendingEventCount(0),mPendingEventIndex(0),mPendingINotify(false){acquire_wake_lock(PARTIAL_WAKE_LOCK,WAKE_LOCK_ID);mEpollFdepoll_create1(EPOLL_CLOEXEC);//省略部分mINotifyFdinotify_init();mInputWdinotify_add_watch(mINotifyFd,DEVICE_PATH,IN_DELETE|IN_CREATE);//省略部分structepoll_eventeventItem;memset(eventItem,0,sizeof(eventItem));eventItem.eventsEPOLLIN;eventItem.data.fdmINotifyFd;intresultepoll_ctl(mEpollFd,EPOLL_CTL_ADD,mINotifyFd,eventItem);//省略部分intwakeFds[2];resultpipe(wakeFds);mWakeReadPipeFdwakeFds[0];mWakeWritePipeFdwakeFds[1];resultfcntl(mWakeReadPipeFd,F_SETFL,O_NONBLOCK);resultfcntl(mWakeWritePipeFd,F_SETFL,O_NONBLOCK);eventItem.data.fdmWakeReadPipeFd;resultepoll_ctl(mEpollFd,EPOLL_CTL_ADD,mWakeReadPipeFd,eventItem);//省略部分}我相信看到这里的EventHub大家应该会有非常非常熟悉的想到getevent源码二者其实本质的功能都是一样的这里使用的epoll来监听各个fd的变化getevent中使用是poll。这里大概可以看出EventHub职责就是来获取/dev/input/路径设备的及对数据进行获取和getevent职责一样后面再使用到的时候再进行具体分析。接下来继续分析InputManager构造的最后一个方法initializevoidInputManager::initialize(){mReaderThreadnewInputReaderThread(mReader);mDispatcherThreadnewInputDispatcherThread(mDispatcher);}这里把mReaderThread和mDispatcherThread构造出来了它们就是native层面的Thread对象这里在入门课时候就已经讲解过了但是这里只是创建了线程并没有启动那么到这里构造部分就分析完成了但是还没看到最关键的两个线程启动。其实这个启动是在文章一开始的SystemServer类中startOtherServices触发的通过调用inputManager.start()方法base/services/core/java/com/android/server/input/InputManagerService.javapublicvoidstart(){Slog.i(TAG,Starting input manager);nativeStart(mPtr);//省略部分}这里调用是nativeStart方法有到了我们的native层base/services/core/jni/com_android_server_input_InputManagerService.cppstaticvoidnativeStart(JNIEnv*env,jclass/* clazz */,jlong ptr){NativeInputManager*imreinterpret_castNativeInputManager*(ptr);status_t resultim-getInputManager()-start();if(result){jniThrowRuntimeException(env,Input manager could not be started.);}}这里其实只干了一件关键事情调用了InputManager的startnative/services/inputflinger/InputManager.cppstatus_tInputManager::start(){status_t resultmDispatcherThread-run(InputDispatcher,PRIORITY_URGENT_DISPLAYPRIORITY_MORE_FAVORABLE);//省略部分resultmReaderThread-run(InputReader,PRIORITY_URGENT_DISPLAYPRIORITY_MORE_FAVORABLE);//省略部分returnOK;}这里其实就是干了把InputDispatcher和InputReader两个线程启动运行起来那本节课就先分析到这里目前就算把InputDispatcher和InputReader开始执行部分引出来了。更多fw实战干货参考课程:https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw