diff options
Diffstat (limited to 'libs/input')
-rw-r--r-- | libs/input/Android.mk | 2 | ||||
-rw-r--r-- | libs/input/EventHub.cpp | 160 | ||||
-rw-r--r-- | libs/input/EventHub.h | 10 | ||||
-rw-r--r-- | libs/input/InputReader.cpp | 14 | ||||
-rw-r--r-- | libs/input/InputReader.h | 2 | ||||
-rw-r--r-- | libs/input/SpriteController.cpp | 4 |
6 files changed, 142 insertions, 50 deletions
diff --git a/libs/input/Android.mk b/libs/input/Android.mk index 6e944ef..eb2bebe 100644 --- a/libs/input/Android.mk +++ b/libs/input/Android.mk @@ -42,6 +42,8 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_C_INCLUDES := \ external/skia/include/core +LOCAL_CFLAGS += -Wno-unused-parameter + LOCAL_MODULE:= libinputservice LOCAL_MODULE_TAGS := optional diff --git a/libs/input/EventHub.cpp b/libs/input/EventHub.cpp index fc64656..e2efd17 100644 --- a/libs/input/EventHub.cpp +++ b/libs/input/EventHub.cpp @@ -49,6 +49,7 @@ #include <sys/ioctl.h> #include <sys/limits.h> #include <sys/sha1.h> +#include <sys/utsname.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 @@ -93,32 +94,12 @@ static String8 sha1(const String8& in) { return out; } -static void setDescriptor(InputDeviceIdentifier& identifier) { - // Compute a device descriptor that uniquely identifies the device. - // The descriptor is assumed to be a stable identifier. Its value should not - // change between reboots, reconnections, firmware updates or new releases of Android. - // Ideally, we also want the descriptor to be short and relatively opaque. - String8 rawDescriptor; - rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product); - if (!identifier.uniqueId.isEmpty()) { - rawDescriptor.append("uniqueId:"); - rawDescriptor.append(identifier.uniqueId); - } if (identifier.vendor == 0 && identifier.product == 0) { - // If we don't know the vendor and product id, then the device is probably - // built-in so we need to rely on other information to uniquely identify - // the input device. Usually we try to avoid relying on the device name or - // location but for built-in input device, they are unlikely to ever change. - if (!identifier.name.isEmpty()) { - rawDescriptor.append("name:"); - rawDescriptor.append(identifier.name); - } else if (!identifier.location.isEmpty()) { - rawDescriptor.append("location:"); - rawDescriptor.append(identifier.location); - } +static void getLinuxRelease(int* major, int* minor) { + struct utsname info; + if (uname(&info) || sscanf(info.release, "%d.%d", major, minor) <= 0) { + *major = 0, *minor = 0; + ALOGE("Could not get linux version: %s", strerror(errno)); } - identifier.descriptor = sha1(rawDescriptor); - ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(), - identifier.descriptor.string()); } // --- Global Functions --- @@ -236,6 +217,11 @@ EventHub::EventHub(void) : result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem); LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", errno); + + int major, minor; + getLinuxRelease(&major, &minor); + // EPOLLWAKEUP was introduced in kernel 3.5 + mUsingEpollWakeup = major > 3 || (major == 3 && minor >= 5); } EventHub::~EventHub(void) { @@ -509,8 +495,9 @@ bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const { bool EventHub::hasLed(int32_t deviceId, int32_t led) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && led >= 0 && led <= LED_MAX) { - if (test_bit(led, device->ledBitmask)) { + int32_t sc; + if (device && mapLed(device, led, &sc) == NO_ERROR) { + if (test_bit(sc, device->ledBitmask)) { return true; } } @@ -520,12 +507,17 @@ bool EventHub::hasLed(int32_t deviceId, int32_t led) const { void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device && !device->isVirtual() && led >= 0 && led <= LED_MAX) { + setLedStateLocked(device, led, on); +} + +void EventHub::setLedStateLocked(Device* device, int32_t led, bool on) { + int32_t sc; + if (device && !device->isVirtual() && mapLed(device, led, &sc) != NAME_NOT_FOUND) { struct input_event ev; ev.time.tv_sec = 0; ev.time.tv_usec = 0; ev.type = EV_LED; - ev.code = led; + ev.code = sc; ev.value = on ? 1 : 0; ssize_t nWrite; @@ -570,6 +562,57 @@ bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId, return false; } +static String8 generateDescriptor(InputDeviceIdentifier& identifier) { + String8 rawDescriptor; + rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, + identifier.product); + // TODO add handling for USB devices to not uniqueify kbs that show up twice + if (!identifier.uniqueId.isEmpty()) { + rawDescriptor.append("uniqueId:"); + rawDescriptor.append(identifier.uniqueId); + } else if (identifier.nonce != 0) { + rawDescriptor.appendFormat("nonce:%04x", identifier.nonce); + } + + if (identifier.vendor == 0 && identifier.product == 0) { + // If we don't know the vendor and product id, then the device is probably + // built-in so we need to rely on other information to uniquely identify + // the input device. Usually we try to avoid relying on the device name or + // location but for built-in input device, they are unlikely to ever change. + if (!identifier.name.isEmpty()) { + rawDescriptor.append("name:"); + rawDescriptor.append(identifier.name); + } else if (!identifier.location.isEmpty()) { + rawDescriptor.append("location:"); + rawDescriptor.append(identifier.location); + } + } + identifier.descriptor = sha1(rawDescriptor); + return rawDescriptor; +} + +void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) { + // Compute a device descriptor that uniquely identifies the device. + // The descriptor is assumed to be a stable identifier. Its value should not + // change between reboots, reconnections, firmware updates or new releases + // of Android. In practice we sometimes get devices that cannot be uniquely + // identified. In this case we enforce uniqueness between connected devices. + // Ideally, we also want the descriptor to be short and relatively opaque. + + identifier.nonce = 0; + String8 rawDescriptor = generateDescriptor(identifier); + if (identifier.uniqueId.isEmpty()) { + // If it didn't have a unique id check for conflicts and enforce + // uniqueness if necessary. + while(getDeviceByDescriptorLocked(identifier.descriptor) != NULL) { + identifier.nonce++; + rawDescriptor = generateDescriptor(identifier); + } + } + ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(), + identifier.descriptor.string()); +} + void EventHub::vibrate(int32_t deviceId, nsecs_t duration) { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); @@ -626,6 +669,17 @@ void EventHub::cancelVibrate(int32_t deviceId) { } } +EventHub::Device* EventHub::getDeviceByDescriptorLocked(String8& descriptor) const { + size_t size = mDevices.size(); + for (size_t i = 0; i < size; i++) { + Device* device = mDevices.valueAt(i); + if (descriptor.compare(device->identifier.descriptor) == 0) { + return device; + } + } + return NULL; +} + EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const { if (deviceId == BUILT_IN_KEYBOARD_ID) { deviceId = mBuiltInKeyboardId; @@ -1065,7 +1119,7 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { } // Fill in the descriptor. - setDescriptor(identifier); + assignDescriptorLocked(identifier); // Make file descriptor non-blocking for use with poll(). if (fcntl(fd, F_SETFL, O_NONBLOCK)) { @@ -1239,12 +1293,13 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_GAMEPAD)) { device->controllerNumber = getNextControllerNumberLocked(device); + setLedForController(device); } // Register with epoll. struct epoll_event eventItem; memset(&eventItem, 0, sizeof(eventItem)); - eventItem.events = EPOLLIN; + eventItem.events = mUsingEpollWakeup ? EPOLLIN : EPOLLIN | EPOLLWAKEUP; eventItem.data.u32 = deviceId; if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) { ALOGE("Could not add device fd to epoll instance. errno=%d", errno); @@ -1252,15 +1307,20 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { return -1; } - // Enable wake-lock behavior on kernels that support it. - // TODO: Only need this for devices that can really wake the system. + String8 wakeMechanism("EPOLLWAKEUP"); + if (!mUsingEpollWakeup) { #ifndef EVIOCSSUSPENDBLOCK - // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels - // will use an epoll flag instead, so as long as we want to support - // this feature, we need to be prepared to define the ioctl ourselves. + // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels + // will use an epoll flag instead, so as long as we want to support + // this feature, we need to be prepared to define the ioctl ourselves. #define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int) #endif - bool usingSuspendBlockIoctl = !ioctl(fd, EVIOCSSUSPENDBLOCK, 1); + if (ioctl(fd, EVIOCSSUSPENDBLOCK, 1)) { + wakeMechanism = "<none>"; + } else { + wakeMechanism = "EVIOCSSUSPENDBLOCK"; + } + } // Tell the kernel that we want to use the monotonic clock for reporting timestamps // associated with input events. This is important because the input system @@ -1282,14 +1342,14 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, " "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, " - "usingSuspendBlockIoctl=%s, usingClockIoctl=%s", + "wakeMechanism=%s, usingClockIoctl=%s", deviceId, fd, devicePath, device->identifier.name.string(), device->classes, device->configurationFile.string(), device->keyMap.keyLayoutFile.string(), device->keyMap.keyCharacterMapFile.string(), toString(mBuiltInKeyboardId == deviceId), - toString(usingSuspendBlockIoctl), toString(usingClockIoctl)); + wakeMechanism.string(), toString(usingClockIoctl)); addDeviceLocked(device); return 0; @@ -1299,7 +1359,7 @@ void EventHub::createVirtualKeyboardLocked() { InputDeviceIdentifier identifier; identifier.name = "Virtual"; identifier.uniqueId = "<virtual>"; - setDescriptor(identifier); + assignDescriptorLocked(identifier); Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier); device->classes = INPUT_DEVICE_CLASS_KEYBOARD @@ -1378,6 +1438,11 @@ void EventHub::releaseControllerNumberLocked(Device* device) { mControllerNumbers.clearBit(static_cast<uint32_t>(num - 1)); } +void EventHub::setLedForController(Device* device) { + for (int i = 0; i < MAX_CONTROLLER_LEDS; i++) { + setLedStateLocked(device, ALED_CONTROLLER_1 + i, device->controllerNumber == i + 1); + } +} bool EventHub::hasKeycodeLocked(Device* device, int keycode) const { if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) { @@ -1397,6 +1462,21 @@ bool EventHub::hasKeycodeLocked(Device* device, int keycode) const { return false; } +status_t EventHub::mapLed(Device* device, int32_t led, int32_t* outScanCode) const { + if (!device->keyMap.haveKeyLayout() || !device->ledBitmask) { + return NAME_NOT_FOUND; + } + + int32_t scanCode; + if(device->keyMap.keyLayoutMap->findScanCodeForLed(led, &scanCode) != NAME_NOT_FOUND) { + if(scanCode >= 0 && scanCode <= LED_MAX && test_bit(scanCode, device->ledBitmask)) { + *outScanCode = scanCode; + return NO_ERROR; + } + } + return NAME_NOT_FOUND; +} + status_t EventHub::closeDeviceByPathLocked(const char *devicePath) { Device* device = getDeviceByPathLocked(devicePath); if (device) { diff --git a/libs/input/EventHub.h b/libs/input/EventHub.h index ae28f01..20179ae 100644 --- a/libs/input/EventHub.h +++ b/libs/input/EventHub.h @@ -231,6 +231,8 @@ public: uint8_t* outFlags) const = 0; virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const = 0; + + /* LED related functions expect Android LED constants, not scan codes or HID usages */ virtual bool hasLed(int32_t deviceId, int32_t led) const = 0; virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0; @@ -371,6 +373,7 @@ private: status_t openDeviceLocked(const char *devicePath); void createVirtualKeyboardLocked(); void addDeviceLocked(Device* device); + void assignDescriptorLocked(InputDeviceIdentifier& identifier); status_t closeDeviceByPathLocked(const char *devicePath); void closeDeviceLocked(Device* device); @@ -380,6 +383,7 @@ private: void scanDevicesLocked(); status_t readNotifyLocked(); + Device* getDeviceByDescriptorLocked(String8& descriptor) const; Device* getDeviceLocked(int32_t deviceId) const; Device* getDeviceByPathLocked(const char* devicePath) const; @@ -393,6 +397,10 @@ private: int32_t getNextControllerNumberLocked(Device* device); void releaseControllerNumberLocked(Device* device); + void setLedForController(Device* device); + + status_t mapLed(Device* device, int32_t led, int32_t* outScanCode) const; + void setLedStateLocked(Device* device, int32_t led, bool on); // Protect all internal state. mutable Mutex mLock; @@ -440,6 +448,8 @@ private: size_t mPendingEventCount; size_t mPendingEventIndex; bool mPendingINotify; + + bool mUsingEpollWakeup; }; }; // namespace android diff --git a/libs/input/InputReader.cpp b/libs/input/InputReader.cpp index 03852a5..a683c4b 100644 --- a/libs/input/InputReader.cpp +++ b/libs/input/InputReader.cpp @@ -2197,9 +2197,9 @@ int32_t KeyboardInputMapper::getMetaState() { } void KeyboardInputMapper::resetLedState() { - initializeLedState(mCapsLockLedState, LED_CAPSL); - initializeLedState(mNumLockLedState, LED_NUML); - initializeLedState(mScrollLockLedState, LED_SCROLLL); + initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK); + initializeLedState(mNumLockLedState, ALED_NUM_LOCK); + initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK); updateLedState(true); } @@ -2210,11 +2210,11 @@ void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) { } void KeyboardInputMapper::updateLedState(bool reset) { - updateLedStateForModifier(mCapsLockLedState, LED_CAPSL, + updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK, AMETA_CAPS_LOCK_ON, reset); - updateLedStateForModifier(mNumLockLedState, LED_NUML, + updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK, AMETA_NUM_LOCK_ON, reset); - updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL, + updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK, AMETA_SCROLL_LOCK_ON, reset); } @@ -6283,7 +6283,7 @@ void JoystickInputMapper::configure(nsecs_t when, // To eliminate noise while the joystick is at rest, filter out small variations // in axis values up front. - axis.filter = axis.flat * 0.25f; + axis.filter = axis.fuzz ? axis.fuzz : axis.flat * 0.25f; mAxes.add(abs, axis); } diff --git a/libs/input/InputReader.h b/libs/input/InputReader.h index a8bb636..e6f45b6 100644 --- a/libs/input/InputReader.h +++ b/libs/input/InputReader.h @@ -574,8 +574,8 @@ public: private: InputReaderContext* mContext; int32_t mId; - int32_t mControllerNumber; int32_t mGeneration; + int32_t mControllerNumber; InputDeviceIdentifier mIdentifier; String8 mAlias; uint32_t mClasses; diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp index fd9c66b..2667a72 100644 --- a/libs/input/SpriteController.cpp +++ b/libs/input/SpriteController.cpp @@ -216,12 +216,12 @@ void SpriteController::doUpdateSprites() { paint.setXfermodeMode(SkXfermode::kSrc_Mode); surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint); - if (outBuffer.width > uint32_t(update.state.icon.bitmap.width())) { + if (outBuffer.width > update.state.icon.bitmap.width()) { paint.setColor(0); // transparent fill color surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0, outBuffer.width, update.state.icon.bitmap.height(), paint); } - if (outBuffer.height > uint32_t(update.state.icon.bitmap.height())) { + if (outBuffer.height > update.state.icon.bitmap.height()) { paint.setColor(0); // transparent fill color surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(), outBuffer.width, outBuffer.height, paint); |