Exemple #1
0
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
        int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
        int32_t* outValue, nsecs_t* outWhen)
{
    *outDeviceId = 0;
    *outType = 0;
    *outScancode = 0;
    *outKeycode = 0;
    *outFlags = 0;
    *outValue = 0;
    *outWhen = 0;

    status_t err;

    fd_set readfds;
    int maxFd = -1;
    int cc;
    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.

    if (!mOpened) {
        mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
        mOpened = true;
    }

    while(1) {
#ifdef HAVE_TSLIB
        //Checks if we have to send any more events read by input-raw plugin.
        if(!samp.total_events) {
#endif
            // First, 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",
                     device->id, device->path.string());
                mClosingDevices = device->next;
                *outDeviceId = device->id;
                if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
                *outType = DEVICE_REMOVED;
                delete device;
                return true;
            }
            if (mOpeningDevices != NULL) {
                device_t* device = mOpeningDevices;
                LOGV("Reporting device opened: id=0x%x, name=%s\n",
                     device->id, device->path.string());
                mOpeningDevices = device->next;
                *outDeviceId = device->id;
                if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
                *outType = DEVICE_ADDED;
                return true;
            }

            release_wake_lock(WAKE_LOCK_ID);

            pollres = poll(mFDs, mFDCount, -1);

            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);

            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) {
#ifdef HAVE_TSLIB
                        LOGV("Inside EventHub.cpp with mFDs[i].fd=%d \n", mFDs[i].fd);
                        if (mTS != NULL) {
                            if (mFDs[i].fd != mTS->fd ) {
                                LOGV("mFDs[%d].fd = %d and mTS->fd = %d", i, mFDs[i].fd, mTS->fd);
#endif
                                res = read(mFDs[i].fd, &iev, sizeof(iev));
#ifdef HAVE_TSLIB
                            }
                            else{
                                LOGV("mTS->fd = %d", mTS->fd);
                                LOGV("tslib: calling ts_read from eventhub\n");
                                res = ts_read(mTS, &samp, 1);

                                if (res < 0) {
                                    LOGE("[EventHub.cpp:: After Poll] Error in ts_read()\n");
                                }
                                else {
                                    numOfEventsSent = 0;
                                    samp.tsIndex = i;
                                    break;
                                }
                            }
                        }
                        else {
                            LOGE("ERROR in setup of mTS: mTS is NULL!\n");
                        }
#endif
                        if (res == sizeof(iev)
#ifdef HAVE_TSLIB
                            || ((iev.code == 0x1d || iev.code == 0x1e) && res >= 0)
#endif
                        ) {
                        LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
                             mDevices[i]->path.string(),
                             (int) iev.time.tv_sec, (int) iev.time.tv_usec,
                             iev.type, iev.code, iev.value);
                        *outDeviceId = mDevices[i]->id;
                        if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
                        *outType = iev.type;
                        *outScancode = iev.code;
                        if (iev.type == EV_KEY) {
                            err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
                            LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n",
                                iev.code, *outKeycode, *outFlags, err);
                            if (err != 0) {
                                *outKeycode = 0;
                                *outFlags = 0;
                            }
                        } else {
                            *outKeycode = iev.code;
                        }
                        *outValue = iev.value;
                        *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
                        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;
                        }
                    }
                }
            }

        // read_notify() will modify mFDs and mFDCount, so this must be done after
        // processing all other events.
            if(mFDs[0].revents & POLLIN) {
                read_notify(mFDs[0].fd);
            }
#ifdef HAVE_TSLIB
        }

        if(samp.total_events) {
            *outDeviceId = mDevices[samp.tsIndex]->id;
            *outType = samp.ev[numOfEventsSent].type;
            *outScancode = samp.ev[numOfEventsSent].code;
            if (samp.ev[numOfEventsSent].type == EV_KEY) {
                err = mDevices[samp.tsIndex]->layoutMap->map(samp.ev[numOfEventsSent].code, outKeycode, outFlags);
                if (err != 0) {
                    *outKeycode = 0;
                    *outFlags = 0;
                }
            }
            else {
                *outKeycode =  samp.ev[numOfEventsSent].code;
            }
            if(*outType == EV_ABS) {
                if(*outScancode == ABS_X)
                    *outValue = samp.x;
                if(*outScancode == ABS_Y)
                    *outValue = samp.y;
                if(*outScancode == ABS_PRESSURE)
                    *outValue = samp.pressure;
            }
            else {
                *outValue = samp.ev[numOfEventsSent].value;
                *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
            }
            if(++numOfEventsSent == samp.total_events)
                samp.total_events = 0;
            return true;
        }
#endif
    }
}
Exemple #2
0
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
        int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
        int32_t* outValue, nsecs_t* outWhen)
{
    *outDeviceId = 0;
    *outType = 0;
    *outScancode = 0;
    *outKeycode = 0;
    *outFlags = 0;
    *outValue = 0;
    *outWhen = 0;

    status_t err;

    fd_set readfds;
    int maxFd = -1;
    int cc;
    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.

    if (!mOpened) {
        mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
        mOpened = true;
    }

    while(1) {

        // First, 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",
                 device->id, device->path.string());
            mClosingDevices = device->next;
            *outDeviceId = device->id;
            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
            *outType = DEVICE_REMOVED;
            delete device;
            return true;
        }
        if (mOpeningDevices != NULL) {
            device_t* device = mOpeningDevices;
            LOGV("Reporting device opened: id=0x%x, name=%s\n",
                 device->id, device->path.string());
            mOpeningDevices = device->next;
            *outDeviceId = device->id;
            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
            *outType = DEVICE_ADDED;
            return true;
        }

        release_wake_lock(WAKE_LOCK_ID);

        pollres = poll(mFDs, mFDCount, -1);

        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);

        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)) {
                        LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
                             mDevices[i]->path.string(),
                             (int) iev.time.tv_sec, (int) iev.time.tv_usec,
                             iev.type, iev.code, iev.value);
                        *outDeviceId = mDevices[i]->id;
                        if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
                        *outType = iev.type;
                        *outScancode = iev.code;
                        if (iev.type == EV_KEY) {
                            err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
                            LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n",
                                iev.code, *outKeycode, *outFlags, err);
                            if (err != 0) {
                                *outKeycode = 0;
                                *outFlags = 0;
                            }
                        } else {
                            *outKeycode = iev.code;
                        }
                        *outValue = iev.value;
                        *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
                        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;
                    }
                }
            }
        }
        
        // read_notify() will modify mFDs and mFDCount, so this must be done after
        // processing all other events.
        if(mFDs[0].revents & POLLIN) {
            read_notify(mFDs[0].fd);
        }
    }
}
Exemple #3
0
bool EventHub::getEvent(RawEvent* outEvent)
{
    outEvent->deviceId = 0;
    outEvent->type = 0;
    outEvent->scanCode = 0;
    outEvent->keyCode = 0;
    outEvent->flags = 0;
    outEvent->value = 0;
    outEvent->when = 0;

    status_t err;
    LOGV("EventHub::getEvent() enter");

    // Note that we only allow one caller to getEvent(), so don't need
    // to do locking here...  only when adding/removing devices.

    if (!mOpened) {
        mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
        mOpened = true;
        mNeedToSendFinishedDeviceScan = true;
    }

    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",
                 device->id, device->path.string());
            mClosingDevices = device->next;
            if (device->id == mFirstKeyboardId) {
                outEvent->deviceId = 0;
            } else {
                outEvent->deviceId = device->id;
            }
            outEvent->type = DEVICE_REMOVED;
            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
            delete device;
            mNeedToSendFinishedDeviceScan = true;
            return true;
        }

        if (mOpeningDevices != NULL) {
            device_t* device = mOpeningDevices;
            LOGV("Reporting device opened: id=0x%x, name=%s\n",
                 device->id, device->path.string());
            mOpeningDevices = device->next;
            if (device->id == mFirstKeyboardId) {
                outEvent->deviceId = 0;
            } else {
                outEvent->deviceId = device->id;
            }
            outEvent->type = DEVICE_ADDED;
            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
            mNeedToSendFinishedDeviceScan = true;
            return true;
        }

        if (mNeedToSendFinishedDeviceScan) {
            mNeedToSendFinishedDeviceScan = false;
            outEvent->type = FINISHED_DEVICE_SCAN;
            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
            return true;
        }

        // Grab the next input event for device mDevices[mInputDeviceIndex].
        for (;;) {
#ifdef HAVE_TSLIB
            //Checks if we have to send any more TS events read by input-raw plugin
            //else we process other events

            if (tsSamp.total_events && tsSamp.tsSampleReady) {
                LOGV("Processing TS Event");
                outEvent->deviceId = mDevices[tsSamp.tsIndex]->id;
                outEvent->type = tsSamp.ev[numOfEventsSent].type;
                outEvent->scanCode = tsSamp.ev[numOfEventsSent].code;
                outEvent->keyCode = tsSamp.ev[numOfEventsSent].code;
                outEvent->value = tsSamp.ev[numOfEventsSent].value;
                outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);

                switch (outEvent->type) {
                    case EV_KEY:
                        outEvent->keyCode = AKEYCODE_UNKNOWN;
                        outEvent->flags = 0;
                    break;
                    case EV_ABS:
                        switch (outEvent->scanCode) {
                            case ABS_X:
                            outEvent->value = tsSamp.x;
                            LOGV("outEvent->valueX=%d",outEvent->value);
                            break;
                            case ABS_Y:
                            outEvent->value = tsSamp.y;
                            LOGV("outEvent->valueY=%d",outEvent->value);
                            break;
                            case ABS_PRESSURE:
                            outEvent->value = tsSamp.pressure;
                            LOGV("outEvent->valueP=%d",outEvent->value);
                            break;
                        }
                    break;

                }

                LOGV("%s (id: 0x%x) got: t0=%d, t1=%d, type=%d, code=%d, v=%d,"
                        " keyCode=%d, flags=0x%08x",
                        mDevices[tsSamp.tsIndex]->path.string(),
                        outEvent->deviceId,
                        (int) tsSamp.ev[numOfEventsSent].time.tv_sec,
                        (int) tsSamp.ev[numOfEventsSent].time.tv_usec,
                        outEvent->type,outEvent->scanCode, outEvent->value,
                        outEvent->keyCode,outEvent->flags);

                numOfEventsSent++;

                LOGV("numOfEventsSent: %d, tsSamp.total_events: %d",
                        numOfEventsSent, tsSamp.total_events);
                LOGV("EventHub::getEvent() exit");

                if (numOfEventsSent == tsSamp.total_events){
                    //All the events from the read call have been dealt with,
                    //clearing tsSamp for next call.
                    tsSamp.total_events = 0;
                    tsSamp.tsSampleReady = 0;
                    numOfEventsSent = 0;
                }

                return true;
            }

    #endif
            // Consume buffered input events, if any.
            if (mInputBufferIndex < mInputBufferCount) {
                const struct input_event& iev = mInputBufferData[mInputBufferIndex++];
                const device_t* device = mDevices[mInputDeviceIndex];

                LOGV("%s (id: 0x%x) got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
                        device->id,(int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);
                if (device->id == mFirstKeyboardId) {
                     outEvent->deviceId = 0;
                } else {
                     outEvent->deviceId = device->id;
                }
                outEvent->type = iev.type;
                outEvent->scanCode = iev.code;
                if (iev.type == EV_KEY) {
                     err = device->layoutMap->map(iev.code,& outEvent->keyCode, & outEvent->flags);

                    if (err != 0) {
                      LOGV("EV_KEY event, error (%d) accessing device layout map \n",err);
                        outEvent->keyCode = AKEYCODE_UNKNOWN;
                        outEvent->flags = 0;
                    }
                } else {
                outEvent->keyCode = iev.code;
                }
                LOGV("iev.code=%d keyCode=%d flags=0x%08x \n",iev.code, outEvent->keyCode, outEvent->flags);
                outEvent->value = iev.value;

                // Use an event timestamp in the same timebase as
                // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
                // as expected by the rest of the system.
                outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
                LOGV("EventHub::getEvent() exit");
                return true;
            }

            // 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) {
              LOGV("Done processing events received in last poll for all devices.");
              break;
            }

            const struct pollfd& pfd = mFDs[mInputDeviceIndex];

            if (pfd.revents & POLLIN) {
#ifdef HAVE_TSLIB
                LOGV("Reading events from device. id: 0x%x , mInputDeviceIndex: %d, fd: %d, mTS->fd: %d",
                        mDevices[mInputDeviceIndex]->id,mInputDeviceIndex, mFDs[mInputDeviceIndex].fd, mTS->fd);

                if (mTS != NULL) {
                    if (mFDs[mInputDeviceIndex].fd != mTS->fd ) {
#endif
                        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;
                                LOGV("Buffered %d events from device", mInputBufferCount);
                            }
#ifdef HAVE_TSLIB
                    }
                    else{

                        int res = ts_read(mTS, &tsSamp, 1);

                        if (res < 0) {
                            LOGE("[EventHub::after poll] Error in ts_read()");
                        }
                        else {
                            tsSamp.tsIndex = mInputDeviceIndex;
                            LOGV("After ts_read call: tsSamp[total_events: %d,"
                                    " tsIndex: %d tsSampleReady: %d] res:%d ",
                                    tsSamp.total_events,tsSamp.tsIndex,
                                    tsSamp.tsSampleReady,res);
                            //we have read a TS event, we want to process this now.
                        }
                    }
                }
                else {
                    LOGE("EventHub:: ERROR in setup of mTS: mTS is NULL!");
                }
#endif
            }//end of if (pfd.revents & POLLIN)
        }    //end of for(;;) get next input event


#if HAVE_INOTIFY
        // readNotify() will modify mFDs and mFDCount, so this must be done after
        // processing all other events.
        if(mFDs[0].revents & POLLIN) {
            readNotify(mFDs[0].fd);
            mFDs[0].revents = 0;
            LOGV("After readNotify()");
            continue; // report added or removed devices immediately
        }
#endif

        mInputDeviceIndex = 0;

        // 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);

        LOGV("Calling Poll()");

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

        LOGV("After calling Poll()");

        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);

        if (pollResult <= 0) {
            if (errno != EINTR) {
                LOGW("poll failed (errno=%d)\n", errno);
                usleep(100000);
            }
        }
    }//end of for(;;)
}//end of getEvent()
bool EventHub::getEvent(RawEvent* outEvent)
{
    outEvent->deviceId = 0;
    outEvent->type = 0;
    outEvent->scanCode = 0;
    outEvent->keyCode = 0;
    outEvent->flags = 0;
    outEvent->value = 0;
    outEvent->when = 0;

    // Note that we only allow one caller to getEvent(), so don't need
    // to do locking here...  only when adding/removing devices.

    if (!mOpened) {
        mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
        mOpened = true;
        mNeedToSendFinishedDeviceScan = true;
    }

    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",
                 device->id, device->path.string());
            mClosingDevices = device->next;
            if (device->id == mFirstKeyboardId) {
                outEvent->deviceId = 0;
            } else {
                outEvent->deviceId = device->id;
            }
            outEvent->type = DEVICE_REMOVED;
            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
            delete device;
            mNeedToSendFinishedDeviceScan = true;
            return true;
        }

        if (mOpeningDevices != NULL) {
            device_t* device = mOpeningDevices;
            LOGV("Reporting device opened: id=0x%x, name=%s\n",
                 device->id, device->path.string());
            mOpeningDevices = device->next;
            if (device->id == mFirstKeyboardId) {
                outEvent->deviceId = 0;
            } else {
                outEvent->deviceId = device->id;
            }
            outEvent->type = DEVICE_ADDED;
            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
            mNeedToSendFinishedDeviceScan = true;
            return true;
        }

        if (mNeedToSendFinishedDeviceScan) {
            mNeedToSendFinishedDeviceScan = false;
            outEvent->type = FINISHED_DEVICE_SCAN;
            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
            return true;
        }

        // 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];

                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 {
                    outEvent->deviceId = device->id;
                }
                outEvent->type = iev.type;
                outEvent->scanCode = iev.code;
                if (iev.type == EV_KEY) {
                    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);
                    if (err != 0) {
                        outEvent->keyCode = AKEYCODE_UNKNOWN;
                        outEvent->flags = 0;
                    }
                } else {
                    outEvent->keyCode = iev.code;
                }
                outEvent->value = iev.value;

                // Use an event timestamp in the same timebase as
                // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
                // as expected by the rest of the system.
                outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
                return true;
            }

            // 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) {
                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;
                }
            }
        }

#if HAVE_INOTIFY
        // readNotify() will modify mFDs and mFDCount, so this must be done after
        // processing all other events.
        if(mFDs[0].revents & POLLIN) {
            readNotify(mFDs[0].fd);
            mFDs[0].revents = 0;
            continue; // report added or removed devices immediately
        }
#endif

        mInputDeviceIndex = 0;

        // 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("poll failed (errno=%d)\n", errno);
                usleep(100000);
            }
        }
    }
}