Loading include/ui/EventHub.h +6 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,12 @@ private: #ifdef EV_SW int32_t mSwitches[SW_MAX + 1]; #endif static const int INPUT_BUFFER_SIZE = 64; struct input_event mInputBufferData[INPUT_BUFFER_SIZE]; int32_t mInputBufferIndex; int32_t mInputBufferCount; int32_t mInputDeviceIndex; }; }; // namespace android Loading libs/ui/EventHub.cpp +88 −68 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ EventHub::EventHub(void) , mDevicesById(0), mNumDevicesById(0) , mOpeningDevices(0), mClosingDevices(0) , mDevices(0), mFDs(0), mFDCount(0), mOpened(false) , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0) { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); #ifdef EV_SW Loading Loading @@ -341,13 +342,6 @@ bool EventHub::getEvent(RawEvent* outEvent) outEvent->value = 0; outEvent->when = 0; status_t err; int i; int res; int pollres; struct input_event iev; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. Loading @@ -356,9 +350,8 @@ bool EventHub::getEvent(RawEvent* outEvent) mOpened = true; } while(1) { // First, report any devices that had last been added/removed. for (;;) { // Report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", Loading Loading @@ -388,34 +381,15 @@ bool EventHub::getEvent(RawEvent* outEvent) return true; } release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); // Grab the next input event. for (;;) { // Consume buffered input events, if any. if (mInputBufferIndex < mInputBufferCount) { const struct input_event& iev = mInputBufferData[mInputBufferIndex++]; const device_t* device = mDevices[mInputDeviceIndex]; if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { if(mFDs[i].revents) { LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); if(mFDs[i].revents & POLLIN) { res = read(mFDs[i].fd, &iev, sizeof(iev)); if (res == sizeof(iev)) { device_t* device = mDevices[i]; LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { Loading @@ -424,7 +398,7 @@ bool EventHub::getEvent(RawEvent* outEvent) outEvent->type = iev.type; outEvent->scanCode = iev.code; if (iev.type == EV_KEY) { err = device->layoutMap->map(iev.code, status_t err = device->layoutMap->map(iev.code, & outEvent->keyCode, & outEvent->flags); LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", iev.code, outEvent->keyCode, outEvent->flags, err); Loading @@ -442,14 +416,31 @@ bool EventHub::getEvent(RawEvent* outEvent) // as expected by the rest of the system. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); return true; } else { if (res<0) { LOGW("could not get event (errno=%d)", errno); } else { LOGE("could not get event (wrong size: %d)", res); } continue; // Finish reading all events from devices identified in previous poll(). // This code assumes that mInputDeviceIndex is initially 0 and that the // revents member of pollfd is initialized to 0 when the device is first added. // Since mFDs[0] is used for inotify, we process regular events starting at index 1. mInputDeviceIndex += 1; if (mInputDeviceIndex >= mFDCount) { mInputDeviceIndex = 0; break; } const struct pollfd &pfd = mFDs[mInputDeviceIndex]; if (pfd.revents & POLLIN) { int32_t readSize = read(pfd.fd, mInputBufferData, sizeof(struct input_event) * INPUT_BUFFER_SIZE); if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { LOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { mInputBufferCount = readSize / sizeof(struct input_event); mInputBufferIndex = 0; } } } Loading @@ -459,6 +450,27 @@ bool EventHub::getEvent(RawEvent* outEvent) if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } // Poll for events. Mind the wake lock dance! // We hold a wake lock at all times except during poll(). This works due to some // subtle choreography. When a device driver has pending (unread) events, it acquires // a kernel wake lock. However, once the last pending event has been read, the device // driver will release the kernel wake lock. To prevent the system from going to sleep // when this happens, the EventHub holds onto its own user wake lock while the client // is processing events. Thus the system can only sleep if there are no events // pending or currently being processed. release_wake_lock(WAKE_LOCK_ID); int pollResult = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollResult <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } } } } Loading @@ -476,6 +488,7 @@ bool EventHub::openPlatformInput(void) mFDs = (pollfd *)calloc(1, sizeof(mFDs[0])); mDevices = (device_t **)calloc(1, sizeof(mDevices[0])); mFDs[0].events = POLLIN; mFDs[0].revents = 0; mDevices[0] = NULL; #ifdef HAVE_INOTIFY mFDs[0].fd = inotify_init(); Loading Loading @@ -582,6 +595,12 @@ int EventHub::open_device(const char *deviceName) idstr[0] = '\0'; } if (fcntl(fd, F_SETFL, O_NONBLOCK)) { LOGE("Error %d making device file descriptor non-blocking.", errno); close(fd); return -1; } int devid = 0; while (devid < mNumDevicesById) { if (mDevicesById[devid].device == NULL) { Loading Loading @@ -639,6 +658,7 @@ int EventHub::open_device(const char *deviceName) device->fd = fd; mFDs[mFDCount].fd = fd; mFDs[mFDCount].events = POLLIN; mFDs[mFDCount].revents = 0; // Figure out the kinds of events the device reports. Loading Loading
include/ui/EventHub.h +6 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,12 @@ private: #ifdef EV_SW int32_t mSwitches[SW_MAX + 1]; #endif static const int INPUT_BUFFER_SIZE = 64; struct input_event mInputBufferData[INPUT_BUFFER_SIZE]; int32_t mInputBufferIndex; int32_t mInputBufferCount; int32_t mInputDeviceIndex; }; }; // namespace android Loading
libs/ui/EventHub.cpp +88 −68 Original line number Diff line number Diff line Loading @@ -99,6 +99,7 @@ EventHub::EventHub(void) , mDevicesById(0), mNumDevicesById(0) , mOpeningDevices(0), mClosingDevices(0) , mDevices(0), mFDs(0), mFDCount(0), mOpened(false) , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0) { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); #ifdef EV_SW Loading Loading @@ -341,13 +342,6 @@ bool EventHub::getEvent(RawEvent* outEvent) outEvent->value = 0; outEvent->when = 0; status_t err; int i; int res; int pollres; struct input_event iev; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. Loading @@ -356,9 +350,8 @@ bool EventHub::getEvent(RawEvent* outEvent) mOpened = true; } while(1) { // First, report any devices that had last been added/removed. for (;;) { // Report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", Loading Loading @@ -388,34 +381,15 @@ bool EventHub::getEvent(RawEvent* outEvent) return true; } release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); // Grab the next input event. for (;;) { // Consume buffered input events, if any. if (mInputBufferIndex < mInputBufferCount) { const struct input_event& iev = mInputBufferData[mInputBufferIndex++]; const device_t* device = mDevices[mInputDeviceIndex]; if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { if(mFDs[i].revents) { LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); if(mFDs[i].revents & POLLIN) { res = read(mFDs[i].fd, &iev, sizeof(iev)); if (res == sizeof(iev)) { device_t* device = mDevices[i]; LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { Loading @@ -424,7 +398,7 @@ bool EventHub::getEvent(RawEvent* outEvent) outEvent->type = iev.type; outEvent->scanCode = iev.code; if (iev.type == EV_KEY) { err = device->layoutMap->map(iev.code, status_t err = device->layoutMap->map(iev.code, & outEvent->keyCode, & outEvent->flags); LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", iev.code, outEvent->keyCode, outEvent->flags, err); Loading @@ -442,14 +416,31 @@ bool EventHub::getEvent(RawEvent* outEvent) // as expected by the rest of the system. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); return true; } else { if (res<0) { LOGW("could not get event (errno=%d)", errno); } else { LOGE("could not get event (wrong size: %d)", res); } continue; // Finish reading all events from devices identified in previous poll(). // This code assumes that mInputDeviceIndex is initially 0 and that the // revents member of pollfd is initialized to 0 when the device is first added. // Since mFDs[0] is used for inotify, we process regular events starting at index 1. mInputDeviceIndex += 1; if (mInputDeviceIndex >= mFDCount) { mInputDeviceIndex = 0; break; } const struct pollfd &pfd = mFDs[mInputDeviceIndex]; if (pfd.revents & POLLIN) { int32_t readSize = read(pfd.fd, mInputBufferData, sizeof(struct input_event) * INPUT_BUFFER_SIZE); if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { LOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { mInputBufferCount = readSize / sizeof(struct input_event); mInputBufferIndex = 0; } } } Loading @@ -459,6 +450,27 @@ bool EventHub::getEvent(RawEvent* outEvent) if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } // Poll for events. Mind the wake lock dance! // We hold a wake lock at all times except during poll(). This works due to some // subtle choreography. When a device driver has pending (unread) events, it acquires // a kernel wake lock. However, once the last pending event has been read, the device // driver will release the kernel wake lock. To prevent the system from going to sleep // when this happens, the EventHub holds onto its own user wake lock while the client // is processing events. Thus the system can only sleep if there are no events // pending or currently being processed. release_wake_lock(WAKE_LOCK_ID); int pollResult = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollResult <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } } } } Loading @@ -476,6 +488,7 @@ bool EventHub::openPlatformInput(void) mFDs = (pollfd *)calloc(1, sizeof(mFDs[0])); mDevices = (device_t **)calloc(1, sizeof(mDevices[0])); mFDs[0].events = POLLIN; mFDs[0].revents = 0; mDevices[0] = NULL; #ifdef HAVE_INOTIFY mFDs[0].fd = inotify_init(); Loading Loading @@ -582,6 +595,12 @@ int EventHub::open_device(const char *deviceName) idstr[0] = '\0'; } if (fcntl(fd, F_SETFL, O_NONBLOCK)) { LOGE("Error %d making device file descriptor non-blocking.", errno); close(fd); return -1; } int devid = 0; while (devid < mNumDevicesById) { if (mDevicesById[devid].device == NULL) { Loading Loading @@ -639,6 +658,7 @@ int EventHub::open_device(const char *deviceName) device->fd = fd; mFDs[mFDCount].fd = fd; mFDs[mFDCount].events = POLLIN; mFDs[mFDCount].revents = 0; // Figure out the kinds of events the device reports. Loading