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
This commit is contained in:
RoboErik
2013-12-11 17:02:46 -08:00
parent 0575b185c6
commit c1e0015ec3
2 changed files with 66 additions and 2 deletions

View File

@@ -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

View File

@@ -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;