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
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 @@
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 @@
}
}
+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 @@
}
// 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 @@
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 @@
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 @@
void scanDevicesLocked();
status_t readNotifyLocked();
+ Device* getDeviceByDescriptorLocked(String8& descriptor) const;
Device* getDeviceLocked(int32_t deviceId) const;
Device* getDeviceByPathLocked(const char* devicePath) const;