0.前言
Android input事件基本可以分为input事件的获取以及input的事件分发这两个过程,那么我们就从这两个方面进行分析。
首先input事件肯定是从你点击屏幕或者按下了某个按键或者触发了屏幕旋转等事件开始的,但是这些基本都已经和硬件已经强相关了,我们也就不需要去了解这些。就从systemserver开始创建inputmanagerservice(以下简称ims)开始吧。
ps.本文基于9.0代码
1.input事件的获取
首先我们从systemserver创建ims的地方开始吧:
724 private void startOtherServices() {
//去掉了无关的代码
853 traceBeginAndSlog("StartInputManagerService");
//创建ims
854 inputManager = new InputManagerService(context);
855 traceEnd();
856
857 traceBeginAndSlog("StartWindowManagerService");
858 // WMS needs sensor service ready
859 ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
860 mSensorServiceStart = null;
//创建wms
861 wm = WindowManagerService.main(context, inputManager,
862 mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
863 !mFirstBoot, mOnlyCore, new PhoneWindowManager());
864 ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
865 DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
866 ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
867 /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
868 traceEnd();
869
870 traceBeginAndSlog("SetWindowManagerService");
871 mActivityManagerService.setWindowManager(wm);
872 traceEnd();
873
874 traceBeginAndSlog("WindowManagerServiceOnInitReady");
875 wm.onInitReady();
876 traceEnd();
877
878 // Start receiving calls from HIDL services. Start in in a separate thread
879 // because it need to connect to SensorManager. This have to start
880 // after START_SENSOR_SERVICE is done.
881 SystemServerInitThreadPool.get().submit(() -> {
882 TimingsTraceLog traceLog = new TimingsTraceLog(
883 SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
884 traceLog.traceBegin(START_HIDL_SERVICES);
885 startHidlServices();
886 traceLog.traceEnd();
887 }, START_HIDL_SERVICES);
888
889 if (!isWatch) {
890 traceBeginAndSlog("StartVrManagerService");
891 mSystemServiceManager.startService(VrManagerService.class);
892 traceEnd();
893 }
894
//将wms的monitor传给ims作为回调
895 traceBeginAndSlog("StartInputManager");
896 inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
897 inputManager.start();
898 traceEnd();
899
这里可以看到systemserver创建了ims以及wms,并将wms中的monitor传给了ims,作为回调。
关键的两个操作就是新建ims以及ims的start操作。
然后就可以看一下ims初始化的时候具体是做了哪些操作:
314 public InputManagerService(Context context) {
// ...
322 mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
323
//...
330 }
关键内容就是调用jni方法init了native的函数。于是我们再来看一下ims的start操作
340 public void start() {
//...
342 nativeStart(mPtr);
343
//...
363 }
恩,同样很关键的调用了native的start方法。看来其实都是与native相关的内容。那么在native的具体内容。
1231static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
1232 jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
1233 sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
1234 if (messageQueue == NULL) {
1235 jniThrowRuntimeException(env, "MessageQueue is not initialized.");
1236 return 0;
1237 }
1238//很关键的创建了一个nativeinputmanager实例,并且和java层使用的是同一个looper
1239 NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
1240 messageQueue->getLooper());
1241 im->incStrong(0);
1242 return reinterpret_cast<jlong>(im);
1243}
1245static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
1246 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1247
1248 status_t result = im->getInputManager()->start();
1249 if (result) {
1250 jniThrowRuntimeException(env, "Input manager could not be started.");
1251 }
1252}
在init的时候创建了一个nativeinputmanager实例.
321NativeInputManager::NativeInputManager(jobject contextObj,
322 jobject serviceObj, const sp<Looper>& looper) :
323 mLooper(looper), mInteractive(true) {
...
339 sp<EventHub> eventHub = new EventHub(); //创建了一个eventhub,同时将这个eventhub传给新建的inputmanager
340 mInputManager = new InputManager(eventHub, this, this);
341}
eventhub就是将数据从硬件驱动上读出来然后传递上来的通道,同时,我们可以看到:
27InputManager::InputManager(
28 const sp<EventHubInterface>& eventHub,
29 const sp<InputReaderPolicyInterface>& readerPolicy,
30 const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
31 mDispatcher = new InputDispatcher(dispatcherPolicy);
32 mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
33 initialize();
34}
48void InputManager::initialize() {
49 mReaderThread = new InputReaderThread(mReader);
50 mDispatcherThread = new InputDispatcherThread(mDispatcher);
51}
创建了inputdispatcher和inputreader,但是这两者都是通过之前的nativeinputmanager,因为inputmanager实现了这两个接口。
189class NativeInputManager : public virtual RefBase,
190 public virtual InputReaderPolicyInterface,//重要接口
191 public virtual InputDispatcherPolicyInterface,//另一个重要接口
192 public virtual PointerControllerPolicyInterface {
好了,那么此时inputread和inputdispatch已经连接在一起了,那么我们可以看一下inputmanager->start是一个什么样的过程呢。
53status_t InputManager::start() {
54 status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
55 if (result) {
56 ALOGE("Could not start InputDispatcher thread due to error %d.", result);
57 return result;
58 }
59
60 result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
61 if (result) {
62 ALOGE("Could not start InputReader thread due to error %d.", result);
63
64 mDispatcherThread->requestExit();
65 return result;
66 }
67
68 return OK;
69}
所以inputmanager的start就是将这两个threadrun起来。那么现在我们就可以总结一下:
1.首先systemserver启动了ims
2.ims通过nativeinit初始化了nativeinputmanager和底层的inputmanager
3.inputmanager中有reader和dispatcher,在inputmanager中结合
4.ims通过nativestart方法将两个thread开始了循环
下面是对应的UML时序图: