summaryrefslogtreecommitdiffstats
path: root/libs/input
diff options
context:
space:
mode:
Diffstat (limited to 'libs/input')
-rw-r--r--libs/input/Android.mk2
-rw-r--r--libs/input/EventHub.cpp160
-rw-r--r--libs/input/EventHub.h10
-rw-r--r--libs/input/InputReader.cpp14
-rw-r--r--libs/input/InputReader.h2
-rw-r--r--libs/input/SpriteController.cpp4
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);