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