Android应用程序键盘(Keyboard)消息处理机制分析(8)

回到Step 18中,我们继续分析EventHub.getEvent函数的实现。
在中间的for循环里面,首先会检查当前是否有输入设备被关闭,如果有,就返回一个设备移除的事件给调用方:
  1. // Report any devices that had last been added/removed.  
  2. if (mClosingDevices != NULL) {  
  3.     device_t* device = mClosingDevices;  
  4.     LOGV("Reporting device closed: id=0x%x, name=%s\n",  
  5.         device->id, device->path.string());  
  6.     mClosingDevices = device->next;  
  7.     if (device->id == mFirstKeyboardId) {  
  8.         outEvent->deviceId = 0;  
  9.     } else {  
  10.         outEvent->deviceId = device->id;  
  11.     }  
  12.     outEvent->type = DEVICE_REMOVED;  
  13.     outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);  
  14.     delete device;  
  15.     mNeedToSendFinishedDeviceScan = true;  
  16.     return true;  
  17. }  
接着,检查当前是否有新的输入设备加入进来:
  1. if (mOpeningDevices != NULL) {  
  2.     device_t* device = mOpeningDevices;  
  3.     LOGV("Reporting device opened: id=0x%x, name=%s\n",  
  4.         device->id, device->path.string());  
  5.     mOpeningDevices = device->next;  
  6.     if (device->id == mFirstKeyboardId) {  
  7.         outEvent->deviceId = 0;  
  8.     } else {  
  9.         outEvent->deviceId = device->id;  
  10.     }  
  11.     outEvent->type = DEVICE_ADDED;  
  12.     outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);  
  13.     mNeedToSendFinishedDeviceScan = true;  
  14.     return true;  
  15. }  

        接着,再检查是否需要结束监控输入事件:

  1. if (mNeedToSendFinishedDeviceScan) {  
  2.     mNeedToSendFinishedDeviceScan = false;  
  3.     outEvent->type = FINISHED_DEVICE_SCAN;  
  4.     outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);  
  5.     return true;  
  6. }  

        最后,就是要检查当前是否有还未处理的输入设备事件发生了:

  1. // Grab the next input event.  
  2. for (;;) {  
  3.     // Consume buffered input events, if any.  
  4.     if (mInputBufferIndex < mInputBufferCount) {  
  5.         const struct input_event& iev = mInputBufferData[mInputBufferIndex++];  
  6.         const device_t* device = mDevices[mInputDeviceIndex];  
  7.   
  8.         LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),  
  9.             (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);  
  10.         if (device->id == mFirstKeyboardId) {  
  11.             outEvent->deviceId = 0;  
  12.         } else {  
  13.             outEvent->deviceId = device->id;  
  14.         }  
  15.         outEvent->type = iev.type;  
  16.         outEvent->scanCode = iev.code;  
  17.         if (iev.type == EV_KEY) {  
  18.             status_t err = device->layoutMap->map(iev.code,  
  19.                 & outEvent->keyCode, & outEvent->flags);  
  20.             LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",  
  21.                 iev.code, outEvent->keyCode, outEvent->flags, err);  
  22.             if (err != 0) {  
  23.                 outEvent->keyCode = AKEYCODE_UNKNOWN;  
  24.                 outEvent->flags = 0;  
  25.             }  
  26.         } else {  
  27.             outEvent->keyCode = iev.code;  
  28.         }  
  29.         outEvent->value = iev.value;  
  30.   
  31.         // Use an event timestamp in the same timebase as  
  32.         // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()  
  33.         // as expected by the rest of the system.  
  34.         outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);  
  35.         return true;  
  36.     }  
  37.   
  38.     // Finish reading all events from devices identified in previous poll().  
  39.     // This code assumes that mInputDeviceIndex is initially 0 and that the  
  40.     // revents member of pollfd is initialized to 0 when the device is first added.  
  41.     // Since mFDs[0] is used for inotify, we process regular events starting at index 1.  
  42.     mInputDeviceIndex += 1;  
  43.     if (mInputDeviceIndex >= mFDCount) {  
  44.         break;  
  45.     }  
  46.   
  47.     const struct pollfd& pfd = mFDs[mInputDeviceIndex];  
  48.     if (pfd.revents & POLLIN) {  
  49.         int32_t readSize = read(pfd.fd, mInputBufferData,  
  50.             sizeof(struct input_event) * INPUT_BUFFER_SIZE);  
  51.         if (readSize < 0) {  
  52.             if (errno != EAGAIN && errno != EINTR) {  
  53.                 LOGW("could not get event (errno=%d)", errno);  
  54.             }  
  55.         } else if ((readSize % sizeof(struct input_event)) != 0) {  
  56.             LOGE("could not get event (wrong size: %d)", readSize);  
  57.         } else {  
  58.             mInputBufferCount = readSize / sizeof(struct input_event);  
  59.             mInputBufferIndex = 0;  
  60.         }  
  61.     }  
  62. }  

        未处理的输入事件保存在成员变量mInputBufferData中,如果有的话,就可以直接返回了,否则的话,就要通过系统调用poll来等待输入设备上发生新的事件了,在我们这个场景中,就是等待键盘有键被按下或者松开了。:

  1. int pollResult = poll(mFDs, mFDCount, -1);  

 

        这里的mFDs包含了我们所要监控的输入设备的打开文件描述符,这是在前面的openPlatformInput函数中初始化的。

你可能感兴趣的:(android,keyboard,消息处理机制分析)