InputReader读取底层事件

执行getevent可以看到上报到/dev/input/eventX设备节点的各种事件,下面是点击了power键输出,0074是system上报的scancode,可以在system/usr/keylayout/mtk-kpd.kl中找到,74是16进制,刚好对应116,Linux input子系统负责读取/dev/input/eventX所有设备节点的事件封装成NotifyKeyArgs,再由InputDispatcher分发给上层应用。

djtang:/data1/localProject/Tokyo_TF$adb shell
Seoul_TF:/ $ getevent
add device 1: /dev/input/event2
  name:     "mtk-tpd"
add device 2: /dev/input/event0
  name:     "ACCDET"
add device 3: /dev/input/event1
  name:     "mtk-kpd"

/dev/input/event1: 0001 0074 00000001
/dev/input/event1: 0000 0000 00000000
/dev/input/event1: 0001 0074 00000000
/dev/input/event1: 0000 0000 00000000

Seoul_TF:/ $ cat  system/usr/keylayout/mtk-kpd.kl |grep -i power                                                                         
key 116   POWER
Seoul_TF:/ $ 

SystemServer进程创建InputManagerService服务并注册到ServiceManager
frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {
       ......
       traceBeginAndSlog("StartInputManagerService");
       inputManager = new InputManagerService(context);
       traceEnd();
       traceBeginAndSlog("StartWindowManagerService");
       // WMS needs sensor service ready
       ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
        mSensorServiceStart = null;
        wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
             new PhoneWindowManager(), 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();
        ......
    }

frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

// Pointer to native input manager service object.
private final long mPtr;
public InputManagerService(Context context) {
    this.mContext = context;
    this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
    mUseDevInputEventForAudioJack =    context.getResources().getBoolean(R.bool.config_useDevInputEventForAudioJack);
    mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
    ......
    }

InputManagerService的构造方法调用了nativeInit方法,创建了一个NativeInputManager
/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

1317  static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
1318          jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
1319      sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
1320      if (messageQueue == nullptr) {
1321          jniThrowRuntimeException(env, "MessageQueue is not initialized.");
1322          return 0;
1323      }
1324      //用java层传下来的InputManagerService,context,以及Looper创建NativeInputManager对象,共用同一个Looper
1325      NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
1326              messageQueue->getLooper());
1327      im->incStrong(0);
1328      return reinterpret_cast<jlong>(im);
1329  }

NativeInputMnager构造函数中创建了InputManager对象并添加到Native层的ServiceManager,叫"inputflinger"
/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

333  NativeInputManager::NativeInputManager(jobject contextObj,
334          jobject serviceObj, const sp<Looper>& looper) :
335          mLooper(looper), mInteractive(true) {
336      JNIEnv* env = jniEnv();
338      mServiceObj = env->NewGlobalRef(serviceObj);
340      {
341          AutoMutex _l(mLock);
342          mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
343          mLocked.pointerSpeed = 0;
344          mLocked.pointerGesturesEnabled = true;
345          mLocked.showTouches = false;
346          mLocked.pointerCapture = false;
347          mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
348      }
349      mInteractive = true;
351      mInputManager = new InputManager(this, this);
352      defaultServiceManager()->addService(String16("inputflinger"),
353              mInputManager, false);
354  }

InputManager中创建了一个InputDispatcher和一个InputReader
/frameworks/native/services/inputflinger/InputManager.cpp

33  InputManager::InputManager(
34          const sp<InputReaderPolicyInterface>& readerPolicy,
35          const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
36      mDispatcher = new InputDispatcher(dispatcherPolicy);
37      mClassifier = new InputClassifier(mDispatcher);
        //创建InputReader
38      mReader = createInputReader(readerPolicy, mClassifier);
39      initialize();
40  }

/frameworks/native/services/inputflinger/InputReaderFactory.cpp

22  sp<InputReaderInterface> createInputReader(
23          const sp<InputReaderPolicyInterface>& policy,
24          const sp<InputListenerInterface>& listener) {
        //参数中传入了一个EventHub
25      return new InputReader(new EventHub(), policy, listener);
26  }

之后调用initialize方法初始化了两个线程InputReaderThread和InputDispatcherThread

46  void InputManager::initialize() {
47      mReaderThread = new InputReaderThread(mReader);
48      mDispatcherThread = new InputDispatcherThread(mDispatcher);
49  }

到这里java层的InputManagerService构造函数中的nativeInit方法执行完了,
再看SystemServer在创建完InputManagerService之后会调用inputManager.start();
/frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

337      public void start() {
338          Slog.i(TAG, "Starting input manager");
339          nativeStart(mPtr);
340            ......
360      }

看native层的实现
/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

1331  static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
1332      NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1333      //调用InputManager的start方法
1334      status_t result = im->getInputManager()->start();
1335      if (result) {
1336          jniThrowRuntimeException(env, "Input manager could not be started.");
1337      }
1338  }

im->getInputManager()->start(),这个方法主要就是启动两个线程mDispatcherThread->run和mReaderThread->run

51  status_t InputManager::start() {
52      status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
53      if (result) {
54          ALOGE("Could not start InputDispatcher thread due to error %d.", result);
55          return result;
56      }
58      result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
59      if (result) {
60          ALOGE("Could not start InputReader thread due to error %d.", result);
62          mDispatcherThread->requestExit();
63          return result;
64      }
66      return OK;
67  }

接着看InputReaderThread启动之后做了什么
/frameworks/native/services/inputflinger/InputReaderBase.cpp

45  bool InputReaderThread::threadLoop() {
46      mReader->loopOnce();
47      return true;
48  }

省略了一些代码,mEventHub->getEvents读取事件,processEventsLocked处理事件,先看读取事件,传入了一个mEventBuffer和EVENT_BUFFER_SIZE,mEventBuffer放原始事件的数组大小256
/frameworks/native/services/inputflinger/InputReader.cpp

321  void InputReader::loopOnce() {
322      int32_t oldGeneration;
323      int32_t timeoutMillis;
324      bool inputDevicesChanged = false;
         ......
343      size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
344  
345      { // acquire lock
346          AutoMutex _l(mLock);
347          mReaderIsAliveCondition.broadcast();
349          if (count) {
350              processEventsLocked(mEventBuffer, count);
351          }
             ......
383  }

/frameworks/native/services/inputflinger/InputReader.h

193      // The event queue.
194      static const int EVENT_BUFFER_SIZE = 256;
195      RawEvent mEventBuffer[EVENT_BUFFER_SIZE];

mEventHub->getEvents
/frameworks/native/services/inputflinger/EventHub.cpp

851  size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
852      ALOG_ASSERT(bufferSize >= 1);
854      AutoMutex _l(mLock);
         //放事件的数组
856      struct input_event readBuffer[bufferSize];
857      //原始事件
858      RawEvent* event = buffer;
859      size_t capacity = bufferSize;
860      bool awoken = false;
861      for (;;) {
862          nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
863          ......
875          // Report any devices that had last been added/removed.
876          while (mClosingDevices) {
877              ......
893          if (mNeedToScanDevices) {
894              mNeedToScanDevices = false;
                 //打开dev/input/设备节点
895              scanDevicesLocked();
896              mNeedToSendFinishedDeviceScan = true;
897          }
             ......
             // This must be an input event
981      if (eventItem.events & EPOLLIN) {
            //不断读取事件放入readBuffer
982         int32_t readSize = read(device->fd, readBuffer,
983                          sizeof(struct input_event) * capacity);
984          if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
988           device->fd, readSize, bufferSize, capacity, errno);
989           deviceChanged = true;
990           closeDeviceLocked(device);
991           } else if (readSize < 0) {
992              if (errno != EAGAIN && errno != EINTR) {
993              ALOGW("could not get event (errno=%d)", errno);
994                     }
995                 } else if ((readSize % sizeof(struct input_event)) != 0) {
996          ALOGE("could not get event (wrong size: %d)", readSize);
997               } else {
998                 int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
1000         size_t count = size_t(readSize) / sizeof(struct input_event);
1001        for (size_t i = 0; i < count; i++) {
               //从readBuffer中取出全部读到的事件,封装成RawEvent
1002           struct input_event& iev = readBuffer[i];
1003            event->when = processEventTimestamp(iev);
1004            event->deviceId = deviceId;
1005            event->type = iev.type;
1006            event->code = iev.code;
1008            ......
1022            }
1023    }

上面的mEventHub->getEvents主要做的事有,打开设备节点/dev/input/,不断的读取事件,放入readBuffer,再将readBuffer中的所有input_event封装成RawEvent

52  struct RawEvent {
53      nsecs_t when;
54      int32_t deviceId;
55      int32_t type;
56      int32_t code;
57      int32_t value;
58  };

接着对获取到的RawEvent开始处理
/frameworks/native/services/inputflinger/EventHub.cpp

343      size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
344  
345      { // acquire lock
346          AutoMutex _l(mLock);
347          mReaderIsAliveCondition.broadcast();
348  
349          if (count) {
350              processEventsLocked(mEventBuffer, count);
351          }
            //正式处理事件
385  void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
386      for (const RawEvent* rawEvent = rawEvents; count;) {
387          int32_t type = rawEvent->type;
388          size_t batchSize = 1;
389          if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
390              int32_t deviceId = rawEvent->deviceId;
391              while (batchSize < count) {
392                  if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
393                          || rawEvent[batchSize].deviceId != deviceId) {
394                      break;
395                  }
396                  batchSize += 1;
397              }
                 //具体事件处理
401              processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
402          } else {
403              switch (rawEvent->type) {
404              case EventHubInterface::DEVICE_ADDED:
405                  addDeviceLocked(rawEvent->when, rawEvent->deviceId);
406                  break;
407              case EventHubInterface::DEVICE_REMOVED:
408                  removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
409                  break;
410              case EventHubInterface::FINISHED_DEVICE_SCAN:
411                  handleConfigurationChangedLocked(rawEvent->when);
412                  break;
413              default:
414                  ALOG_ASSERT(false); // can't happen
415                  break;
416              }
417          }
418          count -= batchSize;
419          rawEvent += batchSize;
420      }
421  }

具体看processEventsForDeviceLocked函数

557  void InputReader::processEventsForDeviceLocked(int32_t deviceId,
558          const RawEvent* rawEvents, size_t count) {
559      ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
560      if (deviceIndex < 0) {
561          ALOGW("Discarding event for unknown deviceId %d.", deviceId);
562          return;
563      }
565      InputDevice* device = mDevices.valueAt(deviceIndex);
566      if (device->isIgnored()) {
567          //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
568          return;
569      }
570       //事件继续传递
571      device->process(rawEvents, count);
572  }

接着看device->process,device是InputDevice
/frameworks/native/services/inputflinger/InputReader.cpp

1167  void InputDevice::process(const RawEvent* rawEvents, size_t count) {
1168      // Process all of the events in order for each mapper.
1169      // We cannot simply ask each mapper to process them in bulk because mappers may
1170      // have side-effects that must be interleaved.  For example, joystick movement events and
1171      // gamepad button presses are handled by different mappers but they should be dispatched
1172      // in the order received.
1173  for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) { 
1180        if (mDropUntilNextSync) {
1181          if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
1182              mDropUntilNextSync = false;
                   ......
1190              }
1191          } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
1192              ALOGI("Detected input event buffer overrun for device %s.", getName().c_str());
1193              mDropUntilNextSync = true;
1194              reset(rawEvent->when);
1195          } else {
1196              for (InputMapper* mapper : mMappers) {
1197                  mapper->process(rawEvent);
1198              }
1199          }
1200          --count;
1201      }
1202  }

上面函数主要是将RawEvents中的所有事件拿出来调用
mapper->process(rawEvent);
让mMappers里面的所有InputMapper都能对事件进行处理,mMappers中添加了各种类型的InputMapper,这就是根据事件的类型来的,键盘事件,触摸事件等

/frameworks/native/services/inputflinger/InputReader.cpp

1098  void InputDevice::addMapper(InputMapper* mapper) {
1099      mMappers.push_back(mapper);
1100  }
482  InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
483          const InputDeviceIdentifier& identifier, uint32_t classes) {
496      .......
497      // Switch-like devices.
498      if (classes & INPUT_DEVICE_CLASS_SWITCH) {
499          device->addMapper(new SwitchInputMapper(device));
500      }
502      // Scroll wheel-like devices.
503      if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
504          device->addMapper(new RotaryEncoderInputMapper(device));
505      }
507      // Vibrator-like devices.
508      if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
509          device->addMapper(new VibratorInputMapper(device));
510      }
515      ......
528      if (keyboardSource != 0) {
529          device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
530      }
532      // Cursor-like devices.
533      if (classes & INPUT_DEVICE_CLASS_CURSOR) {
534          device->addMapper(new CursorInputMapper(device));
535      }
537      // Touchscreens and touchpad devices.
538      if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
539          device->addMapper(new MultiTouchInputMapper(device));
540      } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
541          device->addMapper(new SingleTouchInputMapper(device));
542      }
544      // Joystick-like devices.
545      if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
546          device->addMapper(new JoystickInputMapper(device));
547      }
549      // External stylus-like devices.
550      if (classes & INPUT_DEVICE_CLASS_EXTERNAL_STYLUS) {
551          device->addMapper(new ExternalStylusInputMapper(device));
552      }
554      return device;
555  }

我们基于按键事件进行分析,使用的KeyboardInputMapper
/frameworks/native/services/inputflinger/InputReader.cpp

2331  void KeyboardInputMapper::process(const RawEvent* rawEvent) {
2332      switch (rawEvent->type) {
2333      case EV_KEY: {
2334          int32_t scanCode = rawEvent->code;
2335          int32_t usageCode = mCurrentHidUsage;
2336          mCurrentHidUsage = 0;
2337  
2338          if (isKeyboardOrGamepadKey(scanCode)) {
2339              processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode);
2340          }
2341          break;
2342      }
2343      case EV_MSC: {
2344          if (rawEvent->code == MSC_SCAN) {
2345              mCurrentHidUsage = rawEvent->value;
2346          }
2347          break;
2348      }
2349      case EV_SYN: {
2350          if (rawEvent->code == SYN_REPORT) {
2351              mCurrentHidUsage = 0;
2352          }
2353      }
2354      }
2355  }

看这个方法processKey
/frameworks/native/services/inputflinger/InputReader.cpp

2393  void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode,
2394          int32_t usageCode) {
2395      int32_t keyCode;
2396      int32_t keyMetaState;
2397      uint32_t policyFlags;
2398      //该方法里面会根据/dev/input/eventX获取到的scancode得到keycode
2399      if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState,
2400                                &keyCode, &keyMetaState, &policyFlags)) {
2401          keyCode = AKEYCODE_UNKNOWN;
2402          keyMetaState = mMetaState;
2403          policyFlags = 0;
2404      }
2406      if (down) {
2407       .......
2472       ......
2473      //创建NotifyKeyArgs
2474      NotifyKeyArgs args(mContext->getNextSequenceNum(), when, getDeviceId(), mSource,
2475              getDisplayId(), policyFlags, down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
2476              AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
          //调用InputDispatcher将NotifyKeyArgs分发出去
2477      getListener()->notifyKey(&args);
2478  }

该方法主要做的事,将scancode映射为keycode,创建NotifyKeyArgs,调用InputDispatcher的notifyKey进行进一步事件分发

这篇文章还有很多细节没有分析,只是从一个大概来看InputReader是如何读取事件,封装事件,然后给到InputDispatcher的,后续会对InputDispatcher进行分析

发布了28 篇原创文章 · 获赞 40 · 访问量 4830

猜你喜欢

转载自blog.csdn.net/qq_34211365/article/details/103162869
今日推荐