diff options
Diffstat (limited to 'services/input/EventHub.cpp')
-rw-r--r-- | services/input/EventHub.cpp | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index 0773afb..376de96 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -40,7 +40,6 @@ #include <androidfw/KeyCharacterMap.h> #include <androidfw/VirtualKeyMap.h> -#include <sha1.h> #include <string.h> #include <stdint.h> #include <dirent.h> @@ -49,6 +48,7 @@ #include <sys/epoll.h> #include <sys/ioctl.h> #include <sys/limits.h> +#include <sys/sha1.h> /* this macro is used to tell if "bit" is set in "array" * it selects a byte from the array, and does a boolean AND @@ -162,7 +162,8 @@ EventHub::Device::Device(int fd, int32_t id, const String8& path, next(NULL), fd(fd), id(id), path(path), identifier(identifier), classes(0), configuration(NULL), virtualKeyMap(NULL), - ffEffectPlaying(false), ffEffectId(-1) { + ffEffectPlaying(false), ffEffectId(-1), + timestampOverrideSec(0), timestampOverrideUsec(0) { memset(keyBitmask, 0, sizeof(keyBitmask)); memset(absBitmask, 0, sizeof(absBitmask)); memset(relBitmask, 0, sizeof(relBitmask)); @@ -766,12 +767,37 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz size_t count = size_t(readSize) / sizeof(struct input_event); for (size_t i = 0; i < count; i++) { - const struct input_event& iev = readBuffer[i]; - ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d", + struct input_event& iev = readBuffer[i]; + ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); + // Some input devices may have a better concept of the time + // when an input event was actually generated than the kernel + // which simply timestamps all events on entry to evdev. + // This is a custom Android extension of the input protocol + // mainly intended for use with uinput based device drivers. + if (iev.type == EV_MSC) { + if (iev.code == MSC_ANDROID_TIME_SEC) { + device->timestampOverrideSec = iev.value; + continue; + } else if (iev.code == MSC_ANDROID_TIME_USEC) { + device->timestampOverrideUsec = iev.value; + continue; + } + } + if (device->timestampOverrideSec || device->timestampOverrideUsec) { + iev.time.tv_sec = device->timestampOverrideSec; + iev.time.tv_usec = device->timestampOverrideUsec; + if (iev.type == EV_SYN && iev.code == SYN_REPORT) { + device->timestampOverrideSec = 0; + device->timestampOverrideUsec = 0; + } + ALOGV("applied override time %d.%06d", + int(iev.time.tv_sec), int(iev.time.tv_usec)); + } + #ifdef HAVE_POSIX_CLOCKS // Use the time specified in the event instead of the current time // so that downstream code can get more accurate estimates of @@ -829,8 +855,8 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz event->code = iev.code; event->value = iev.value; event += 1; + capacity -= 1; } - capacity -= count; if (capacity == 0) { // The result buffer is full. Reset the pending event index // so we will try to read the device again on the next iteration. @@ -1162,11 +1188,6 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { mBuiltInKeyboardId = device->id; } - // 'Q' key support = cheap test of whether this is an alpha-capable kbd - if (hasKeycodeLocked(device, AKEYCODE_Q)) { - device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; - } - // See if this device has a DPAD. if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) && hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) && @@ -1184,6 +1205,14 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { } } + // 'Q' key support = cheap test of whether this is an alpha-capable kbd. Many gamepads will + // report a broader set of HID usages than they need, however, so we only want to mark this + // device as a keyboard if it is not a gamepad. + if (hasKeycodeLocked(device, AKEYCODE_Q) && + !(device->classes & INPUT_DEVICE_CLASS_GAMEPAD)) { + device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; + } + // Disable kernel key repeat since we handle it ourselves unsigned int repeatRate[] = {0,0}; if (ioctl(fd, EVIOCSREP, repeatRate)) { |