diff options
author | RoboErik <epastern@google.com> | 2013-12-11 17:02:46 -0800 |
---|---|---|
committer | RoboErik <epastern@google.com> | 2014-03-12 13:20:57 -0700 |
commit | c1e0015ec3dfacc137cb500066020b25f18ecbb7 (patch) | |
tree | 49ddcf95b7dfd66fe0bf04ffe570f40cc5e80b8b /libs | |
parent | 0575b185c618a79ede771389ed9a78436b5636bd (diff) | |
download | frameworks_base-c1e0015ec3dfacc137cb500066020b25f18ecbb7.zip frameworks_base-c1e0015ec3dfacc137cb500066020b25f18ecbb7.tar.gz frameworks_base-c1e0015ec3dfacc137cb500066020b25f18ecbb7.tar.bz2 |
b/12068020 Add a way to add uniqueness to device descriptors. Do not merge
Cherry pick from https://googleplex-android-review.git.corp.google.com/#/c/398226/
This adds an integer to the descriptor of devices without uniqely
identifying information. It will reuse values that are no longer
in use, so if you remove a single device and attach a different
identical device it will appear to be the same device.
TODO: Derive uniqueness from USB port when possible. This version
will generate different descriptors for each half of a USB keyboard
that shows up twice.
Change-Id: Ie628f19c01469f6ec2d354cd00000898ac6432fa
Diffstat (limited to 'libs')
-rw-r--r-- | libs/input/EventHub.cpp | 66 | ||||
-rw-r--r-- | libs/input/EventHub.h | 2 |
2 files changed, 66 insertions, 2 deletions
diff --git a/libs/input/EventHub.cpp b/libs/input/EventHub.cpp index 0f1da51..c1f41db 100644 --- a/libs/input/EventHub.cpp +++ b/libs/input/EventHub.cpp @@ -576,6 +576,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); @@ -632,6 +683,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; @@ -1071,7 +1133,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)) { @@ -1306,7 +1368,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 diff --git a/libs/input/EventHub.h b/libs/input/EventHub.h index 0d63849..86c05af 100644 --- a/libs/input/EventHub.h +++ b/libs/input/EventHub.h @@ -373,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); @@ -382,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; |