|
1 /* |
|
2 * Copyright (C) 2005 The Android Open Source Project |
|
3 * |
|
4 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 * you may not use this file except in compliance with the License. |
|
6 * You may obtain a copy of the License at |
|
7 * |
|
8 * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 * |
|
10 * Unless required by applicable law or agreed to in writing, software |
|
11 * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 * See the License for the specific language governing permissions and |
|
14 * limitations under the License. |
|
15 */ |
|
16 |
|
17 #define LOG_TAG "EventHub" |
|
18 |
|
19 // #define LOG_NDEBUG 0 |
|
20 #include "cutils_log.h" |
|
21 |
|
22 #include "EventHub.h" |
|
23 |
|
24 #include <hardware_legacy/power.h> |
|
25 |
|
26 #include <cutils/properties.h> |
|
27 #include "cutils_log.h" |
|
28 #include <utils/Timers.h> |
|
29 #include <utils/threads.h> |
|
30 #include <utils/Errors.h> |
|
31 |
|
32 #include <stdlib.h> |
|
33 #include <stdio.h> |
|
34 #include <unistd.h> |
|
35 #include <fcntl.h> |
|
36 #include <memory.h> |
|
37 #include <errno.h> |
|
38 #include <assert.h> |
|
39 |
|
40 #include "KeyLayoutMap.h" |
|
41 #include "KeyCharacterMap.h" |
|
42 #include "VirtualKeyMap.h" |
|
43 |
|
44 #include <string.h> |
|
45 #include <stdint.h> |
|
46 #include <dirent.h> |
|
47 |
|
48 #include <sys/inotify.h> |
|
49 #include <sys/epoll.h> |
|
50 #include <sys/ioctl.h> |
|
51 #include <sys/limits.h> |
|
52 #include <sha1.h> |
|
53 |
|
54 /* this macro is used to tell if "bit" is set in "array" |
|
55 * it selects a byte from the array, and does a boolean AND |
|
56 * operation with a byte that only has the relevant bit set. |
|
57 * eg. to check for the 12th bit, we do (array[1] & 1<<4) |
|
58 */ |
|
59 #define test_bit(bit, array) (array[bit/8] & (1<<(bit%8))) |
|
60 |
|
61 /* this macro computes the number of bytes needed to represent a bit array of the specified size */ |
|
62 #define sizeof_bit_array(bits) ((bits + 7) / 8) |
|
63 |
|
64 #define INDENT " " |
|
65 #define INDENT2 " " |
|
66 #define INDENT3 " " |
|
67 |
|
68 namespace android { |
|
69 |
|
70 static const char *WAKE_LOCK_ID = "KeyEvents"; |
|
71 static const char *DEVICE_PATH = "/dev/input"; |
|
72 |
|
73 /* return the larger integer */ |
|
74 static inline int max(int v1, int v2) |
|
75 { |
|
76 return (v1 > v2) ? v1 : v2; |
|
77 } |
|
78 |
|
79 static inline const char* toString(bool value) { |
|
80 return value ? "true" : "false"; |
|
81 } |
|
82 |
|
83 static String8 sha1(const String8& in) { |
|
84 SHA1_CTX ctx; |
|
85 SHA1Init(&ctx); |
|
86 SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size()); |
|
87 u_char digest[SHA1_DIGEST_LENGTH]; |
|
88 SHA1Final(digest, &ctx); |
|
89 |
|
90 String8 out; |
|
91 for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) { |
|
92 out.appendFormat("%02x", digest[i]); |
|
93 } |
|
94 return out; |
|
95 } |
|
96 |
|
97 static void setDescriptor(InputDeviceIdentifier& identifier) { |
|
98 // Compute a device descriptor that uniquely identifies the device. |
|
99 // The descriptor is assumed to be a stable identifier. Its value should not |
|
100 // change between reboots, reconnections, firmware updates or new releases of Android. |
|
101 // Ideally, we also want the descriptor to be short and relatively opaque. |
|
102 String8 rawDescriptor; |
|
103 rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product); |
|
104 if (!identifier.uniqueId.isEmpty()) { |
|
105 rawDescriptor.append("uniqueId:"); |
|
106 rawDescriptor.append(identifier.uniqueId); |
|
107 } if (identifier.vendor == 0 && identifier.product == 0) { |
|
108 // If we don't know the vendor and product id, then the device is probably |
|
109 // built-in so we need to rely on other information to uniquely identify |
|
110 // the input device. Usually we try to avoid relying on the device name or |
|
111 // location but for built-in input device, they are unlikely to ever change. |
|
112 if (!identifier.name.isEmpty()) { |
|
113 rawDescriptor.append("name:"); |
|
114 rawDescriptor.append(identifier.name); |
|
115 } else if (!identifier.location.isEmpty()) { |
|
116 rawDescriptor.append("location:"); |
|
117 rawDescriptor.append(identifier.location); |
|
118 } |
|
119 } |
|
120 identifier.descriptor = sha1(rawDescriptor); |
|
121 ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(), |
|
122 identifier.descriptor.string()); |
|
123 } |
|
124 |
|
125 // --- Global Functions --- |
|
126 |
|
127 uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) { |
|
128 // Touch devices get dibs on touch-related axes. |
|
129 if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) { |
|
130 switch (axis) { |
|
131 case ABS_X: |
|
132 case ABS_Y: |
|
133 case ABS_PRESSURE: |
|
134 case ABS_TOOL_WIDTH: |
|
135 case ABS_DISTANCE: |
|
136 case ABS_TILT_X: |
|
137 case ABS_TILT_Y: |
|
138 case ABS_MT_SLOT: |
|
139 case ABS_MT_TOUCH_MAJOR: |
|
140 case ABS_MT_TOUCH_MINOR: |
|
141 case ABS_MT_WIDTH_MAJOR: |
|
142 case ABS_MT_WIDTH_MINOR: |
|
143 case ABS_MT_ORIENTATION: |
|
144 case ABS_MT_POSITION_X: |
|
145 case ABS_MT_POSITION_Y: |
|
146 case ABS_MT_TOOL_TYPE: |
|
147 case ABS_MT_BLOB_ID: |
|
148 case ABS_MT_TRACKING_ID: |
|
149 case ABS_MT_PRESSURE: |
|
150 case ABS_MT_DISTANCE: |
|
151 return INPUT_DEVICE_CLASS_TOUCH; |
|
152 } |
|
153 } |
|
154 |
|
155 // Joystick devices get the rest. |
|
156 return deviceClasses & INPUT_DEVICE_CLASS_JOYSTICK; |
|
157 } |
|
158 |
|
159 // --- EventHub::Device --- |
|
160 |
|
161 EventHub::Device::Device(int fd, int32_t id, const String8& path, |
|
162 const InputDeviceIdentifier& identifier) : |
|
163 next(NULL), |
|
164 fd(fd), id(id), path(path), identifier(identifier), |
|
165 classes(0), configuration(NULL), virtualKeyMap(NULL), |
|
166 ffEffectPlaying(false), ffEffectId(-1), |
|
167 timestampOverrideSec(0), timestampOverrideUsec(0) { |
|
168 memset(keyBitmask, 0, sizeof(keyBitmask)); |
|
169 memset(absBitmask, 0, sizeof(absBitmask)); |
|
170 memset(relBitmask, 0, sizeof(relBitmask)); |
|
171 memset(swBitmask, 0, sizeof(swBitmask)); |
|
172 memset(ledBitmask, 0, sizeof(ledBitmask)); |
|
173 memset(ffBitmask, 0, sizeof(ffBitmask)); |
|
174 memset(propBitmask, 0, sizeof(propBitmask)); |
|
175 } |
|
176 |
|
177 EventHub::Device::~Device() { |
|
178 close(); |
|
179 delete configuration; |
|
180 delete virtualKeyMap; |
|
181 } |
|
182 |
|
183 void EventHub::Device::close() { |
|
184 if (fd >= 0) { |
|
185 ::close(fd); |
|
186 fd = -1; |
|
187 } |
|
188 } |
|
189 |
|
190 |
|
191 // --- EventHub --- |
|
192 |
|
193 const uint32_t EventHub::EPOLL_ID_INOTIFY; |
|
194 const uint32_t EventHub::EPOLL_ID_WAKE; |
|
195 const int EventHub::EPOLL_SIZE_HINT; |
|
196 const int EventHub::EPOLL_MAX_EVENTS; |
|
197 |
|
198 EventHub::EventHub(void) : |
|
199 mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), |
|
200 mOpeningDevices(0), mClosingDevices(0), |
|
201 mNeedToSendFinishedDeviceScan(false), |
|
202 mNeedToReopenDevices(false), mNeedToScanDevices(true), |
|
203 mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) { |
|
204 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); |
|
205 |
|
206 mEpollFd = epoll_create(EPOLL_SIZE_HINT); |
|
207 LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); |
|
208 |
|
209 mINotifyFd = inotify_init(); |
|
210 int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE); |
|
211 LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s. errno=%d", |
|
212 DEVICE_PATH, errno); |
|
213 |
|
214 struct epoll_event eventItem; |
|
215 memset(&eventItem, 0, sizeof(eventItem)); |
|
216 eventItem.events = EPOLLIN; |
|
217 eventItem.data.u32 = EPOLL_ID_INOTIFY; |
|
218 result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem); |
|
219 LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno); |
|
220 |
|
221 int wakeFds[2]; |
|
222 result = pipe(wakeFds); |
|
223 LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); |
|
224 |
|
225 mWakeReadPipeFd = wakeFds[0]; |
|
226 mWakeWritePipeFd = wakeFds[1]; |
|
227 |
|
228 result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); |
|
229 LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", |
|
230 errno); |
|
231 |
|
232 result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); |
|
233 LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", |
|
234 errno); |
|
235 |
|
236 eventItem.data.u32 = EPOLL_ID_WAKE; |
|
237 result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem); |
|
238 LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", |
|
239 errno); |
|
240 } |
|
241 |
|
242 EventHub::~EventHub(void) { |
|
243 closeAllDevicesLocked(); |
|
244 |
|
245 while (mClosingDevices) { |
|
246 Device* device = mClosingDevices; |
|
247 mClosingDevices = device->next; |
|
248 delete device; |
|
249 } |
|
250 |
|
251 ::close(mEpollFd); |
|
252 ::close(mINotifyFd); |
|
253 ::close(mWakeReadPipeFd); |
|
254 ::close(mWakeWritePipeFd); |
|
255 |
|
256 release_wake_lock(WAKE_LOCK_ID); |
|
257 } |
|
258 |
|
259 InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const { |
|
260 AutoMutex _l(mLock); |
|
261 Device* device = getDeviceLocked(deviceId); |
|
262 if (device == NULL) return InputDeviceIdentifier(); |
|
263 return device->identifier; |
|
264 } |
|
265 |
|
266 uint32_t EventHub::getDeviceClasses(int32_t deviceId) const { |
|
267 AutoMutex _l(mLock); |
|
268 Device* device = getDeviceLocked(deviceId); |
|
269 if (device == NULL) return 0; |
|
270 return device->classes; |
|
271 } |
|
272 |
|
273 void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { |
|
274 AutoMutex _l(mLock); |
|
275 Device* device = getDeviceLocked(deviceId); |
|
276 if (device && device->configuration) { |
|
277 *outConfiguration = *device->configuration; |
|
278 } else { |
|
279 outConfiguration->clear(); |
|
280 } |
|
281 } |
|
282 |
|
283 status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, |
|
284 RawAbsoluteAxisInfo* outAxisInfo) const { |
|
285 outAxisInfo->clear(); |
|
286 |
|
287 if (axis >= 0 && axis <= ABS_MAX) { |
|
288 AutoMutex _l(mLock); |
|
289 |
|
290 Device* device = getDeviceLocked(deviceId); |
|
291 if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) { |
|
292 struct input_absinfo info; |
|
293 if(ioctl(device->fd, EVIOCGABS(axis), &info)) { |
|
294 ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", |
|
295 axis, device->identifier.name.string(), device->fd, errno); |
|
296 return -errno; |
|
297 } |
|
298 |
|
299 if (info.minimum != info.maximum) { |
|
300 outAxisInfo->valid = true; |
|
301 outAxisInfo->minValue = info.minimum; |
|
302 outAxisInfo->maxValue = info.maximum; |
|
303 outAxisInfo->flat = info.flat; |
|
304 outAxisInfo->fuzz = info.fuzz; |
|
305 outAxisInfo->resolution = info.resolution; |
|
306 } |
|
307 return OK; |
|
308 } |
|
309 } |
|
310 return -1; |
|
311 } |
|
312 |
|
313 bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const { |
|
314 if (axis >= 0 && axis <= REL_MAX) { |
|
315 AutoMutex _l(mLock); |
|
316 |
|
317 Device* device = getDeviceLocked(deviceId); |
|
318 if (device) { |
|
319 return test_bit(axis, device->relBitmask); |
|
320 } |
|
321 } |
|
322 return false; |
|
323 } |
|
324 |
|
325 bool EventHub::hasInputProperty(int32_t deviceId, int property) const { |
|
326 if (property >= 0 && property <= INPUT_PROP_MAX) { |
|
327 AutoMutex _l(mLock); |
|
328 |
|
329 Device* device = getDeviceLocked(deviceId); |
|
330 if (device) { |
|
331 return test_bit(property, device->propBitmask); |
|
332 } |
|
333 } |
|
334 return false; |
|
335 } |
|
336 |
|
337 int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { |
|
338 if (scanCode >= 0 && scanCode <= KEY_MAX) { |
|
339 AutoMutex _l(mLock); |
|
340 |
|
341 Device* device = getDeviceLocked(deviceId); |
|
342 if (device && !device->isVirtual() && test_bit(scanCode, device->keyBitmask)) { |
|
343 uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)]; |
|
344 memset(keyState, 0, sizeof(keyState)); |
|
345 if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) { |
|
346 return test_bit(scanCode, keyState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; |
|
347 } |
|
348 } |
|
349 } |
|
350 return AKEY_STATE_UNKNOWN; |
|
351 } |
|
352 |
|
353 int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { |
|
354 AutoMutex _l(mLock); |
|
355 |
|
356 Device* device = getDeviceLocked(deviceId); |
|
357 if (device && !device->isVirtual() && device->keyMap.haveKeyLayout()) { |
|
358 Vector<int32_t> scanCodes; |
|
359 device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes); |
|
360 if (scanCodes.size() != 0) { |
|
361 uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)]; |
|
362 memset(keyState, 0, sizeof(keyState)); |
|
363 if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) { |
|
364 for (size_t i = 0; i < scanCodes.size(); i++) { |
|
365 int32_t sc = scanCodes.itemAt(i); |
|
366 if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, keyState)) { |
|
367 return AKEY_STATE_DOWN; |
|
368 } |
|
369 } |
|
370 return AKEY_STATE_UP; |
|
371 } |
|
372 } |
|
373 } |
|
374 return AKEY_STATE_UNKNOWN; |
|
375 } |
|
376 |
|
377 int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { |
|
378 if (sw >= 0 && sw <= SW_MAX) { |
|
379 AutoMutex _l(mLock); |
|
380 |
|
381 Device* device = getDeviceLocked(deviceId); |
|
382 if (device && !device->isVirtual() && test_bit(sw, device->swBitmask)) { |
|
383 uint8_t swState[sizeof_bit_array(SW_MAX + 1)]; |
|
384 memset(swState, 0, sizeof(swState)); |
|
385 if (ioctl(device->fd, EVIOCGSW(sizeof(swState)), swState) >= 0) { |
|
386 return test_bit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; |
|
387 } |
|
388 } |
|
389 } |
|
390 return AKEY_STATE_UNKNOWN; |
|
391 } |
|
392 |
|
393 status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const { |
|
394 *outValue = 0; |
|
395 |
|
396 if (axis >= 0 && axis <= ABS_MAX) { |
|
397 AutoMutex _l(mLock); |
|
398 |
|
399 Device* device = getDeviceLocked(deviceId); |
|
400 if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) { |
|
401 struct input_absinfo info; |
|
402 if(ioctl(device->fd, EVIOCGABS(axis), &info)) { |
|
403 ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", |
|
404 axis, device->identifier.name.string(), device->fd, errno); |
|
405 return -errno; |
|
406 } |
|
407 |
|
408 *outValue = info.value; |
|
409 return OK; |
|
410 } |
|
411 } |
|
412 return -1; |
|
413 } |
|
414 |
|
415 bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, |
|
416 const int32_t* keyCodes, uint8_t* outFlags) const { |
|
417 AutoMutex _l(mLock); |
|
418 |
|
419 Device* device = getDeviceLocked(deviceId); |
|
420 if (device && device->keyMap.haveKeyLayout()) { |
|
421 Vector<int32_t> scanCodes; |
|
422 for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) { |
|
423 scanCodes.clear(); |
|
424 |
|
425 status_t err = device->keyMap.keyLayoutMap->findScanCodesForKey( |
|
426 keyCodes[codeIndex], &scanCodes); |
|
427 if (! err) { |
|
428 // check the possible scan codes identified by the layout map against the |
|
429 // map of codes actually emitted by the driver |
|
430 for (size_t sc = 0; sc < scanCodes.size(); sc++) { |
|
431 if (test_bit(scanCodes[sc], device->keyBitmask)) { |
|
432 outFlags[codeIndex] = 1; |
|
433 break; |
|
434 } |
|
435 } |
|
436 } |
|
437 } |
|
438 return true; |
|
439 } |
|
440 return false; |
|
441 } |
|
442 |
|
443 status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, |
|
444 int32_t* outKeycode, uint32_t* outFlags) const { |
|
445 AutoMutex _l(mLock); |
|
446 Device* device = getDeviceLocked(deviceId); |
|
447 |
|
448 if (device) { |
|
449 // Check the key character map first. |
|
450 sp<KeyCharacterMap> kcm = device->getKeyCharacterMap(); |
|
451 if (kcm != NULL) { |
|
452 if (!kcm->mapKey(scanCode, usageCode, outKeycode)) { |
|
453 *outFlags = 0; |
|
454 return NO_ERROR; |
|
455 } |
|
456 } |
|
457 |
|
458 // Check the key layout next. |
|
459 if (device->keyMap.haveKeyLayout()) { |
|
460 if (!device->keyMap.keyLayoutMap->mapKey( |
|
461 scanCode, usageCode, outKeycode, outFlags)) { |
|
462 return NO_ERROR; |
|
463 } |
|
464 } |
|
465 } |
|
466 |
|
467 *outKeycode = 0; |
|
468 *outFlags = 0; |
|
469 return NAME_NOT_FOUND; |
|
470 } |
|
471 |
|
472 status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const { |
|
473 AutoMutex _l(mLock); |
|
474 Device* device = getDeviceLocked(deviceId); |
|
475 |
|
476 if (device && device->keyMap.haveKeyLayout()) { |
|
477 status_t err = device->keyMap.keyLayoutMap->mapAxis(scanCode, outAxisInfo); |
|
478 if (err == NO_ERROR) { |
|
479 return NO_ERROR; |
|
480 } |
|
481 } |
|
482 |
|
483 return NAME_NOT_FOUND; |
|
484 } |
|
485 |
|
486 void EventHub::setExcludedDevices(const Vector<String8>& devices) { |
|
487 AutoMutex _l(mLock); |
|
488 |
|
489 mExcludedDevices = devices; |
|
490 } |
|
491 |
|
492 bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const { |
|
493 AutoMutex _l(mLock); |
|
494 Device* device = getDeviceLocked(deviceId); |
|
495 if (device && scanCode >= 0 && scanCode <= KEY_MAX) { |
|
496 if (test_bit(scanCode, device->keyBitmask)) { |
|
497 return true; |
|
498 } |
|
499 } |
|
500 return false; |
|
501 } |
|
502 |
|
503 bool EventHub::hasLed(int32_t deviceId, int32_t led) const { |
|
504 AutoMutex _l(mLock); |
|
505 Device* device = getDeviceLocked(deviceId); |
|
506 if (device && led >= 0 && led <= LED_MAX) { |
|
507 if (test_bit(led, device->ledBitmask)) { |
|
508 return true; |
|
509 } |
|
510 } |
|
511 return false; |
|
512 } |
|
513 |
|
514 void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) { |
|
515 AutoMutex _l(mLock); |
|
516 Device* device = getDeviceLocked(deviceId); |
|
517 if (device && !device->isVirtual() && led >= 0 && led <= LED_MAX) { |
|
518 struct input_event ev; |
|
519 ev.time.tv_sec = 0; |
|
520 ev.time.tv_usec = 0; |
|
521 ev.type = EV_LED; |
|
522 ev.code = led; |
|
523 ev.value = on ? 1 : 0; |
|
524 |
|
525 ssize_t nWrite; |
|
526 do { |
|
527 nWrite = write(device->fd, &ev, sizeof(struct input_event)); |
|
528 } while (nWrite == -1 && errno == EINTR); |
|
529 } |
|
530 } |
|
531 |
|
532 void EventHub::getVirtualKeyDefinitions(int32_t deviceId, |
|
533 Vector<VirtualKeyDefinition>& outVirtualKeys) const { |
|
534 outVirtualKeys.clear(); |
|
535 |
|
536 AutoMutex _l(mLock); |
|
537 Device* device = getDeviceLocked(deviceId); |
|
538 if (device && device->virtualKeyMap) { |
|
539 outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys()); |
|
540 } |
|
541 } |
|
542 |
|
543 sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { |
|
544 AutoMutex _l(mLock); |
|
545 Device* device = getDeviceLocked(deviceId); |
|
546 if (device) { |
|
547 return device->getKeyCharacterMap(); |
|
548 } |
|
549 return NULL; |
|
550 } |
|
551 |
|
552 bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId, |
|
553 const sp<KeyCharacterMap>& map) { |
|
554 AutoMutex _l(mLock); |
|
555 Device* device = getDeviceLocked(deviceId); |
|
556 if (device) { |
|
557 if (map != device->overlayKeyMap) { |
|
558 device->overlayKeyMap = map; |
|
559 device->combinedKeyMap = KeyCharacterMap::combine( |
|
560 device->keyMap.keyCharacterMap, map); |
|
561 return true; |
|
562 } |
|
563 } |
|
564 return false; |
|
565 } |
|
566 |
|
567 void EventHub::vibrate(int32_t deviceId, nsecs_t duration) { |
|
568 AutoMutex _l(mLock); |
|
569 Device* device = getDeviceLocked(deviceId); |
|
570 if (device && !device->isVirtual()) { |
|
571 ff_effect effect; |
|
572 memset(&effect, 0, sizeof(effect)); |
|
573 effect.type = FF_RUMBLE; |
|
574 effect.id = device->ffEffectId; |
|
575 effect.u.rumble.strong_magnitude = 0xc000; |
|
576 effect.u.rumble.weak_magnitude = 0xc000; |
|
577 effect.replay.length = (duration + 999999LL) / 1000000LL; |
|
578 effect.replay.delay = 0; |
|
579 if (ioctl(device->fd, EVIOCSFF, &effect)) { |
|
580 ALOGW("Could not upload force feedback effect to device %s due to error %d.", |
|
581 device->identifier.name.string(), errno); |
|
582 return; |
|
583 } |
|
584 device->ffEffectId = effect.id; |
|
585 |
|
586 struct input_event ev; |
|
587 ev.time.tv_sec = 0; |
|
588 ev.time.tv_usec = 0; |
|
589 ev.type = EV_FF; |
|
590 ev.code = device->ffEffectId; |
|
591 ev.value = 1; |
|
592 if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) { |
|
593 ALOGW("Could not start force feedback effect on device %s due to error %d.", |
|
594 device->identifier.name.string(), errno); |
|
595 return; |
|
596 } |
|
597 device->ffEffectPlaying = true; |
|
598 } |
|
599 } |
|
600 |
|
601 void EventHub::cancelVibrate(int32_t deviceId) { |
|
602 AutoMutex _l(mLock); |
|
603 Device* device = getDeviceLocked(deviceId); |
|
604 if (device && !device->isVirtual()) { |
|
605 if (device->ffEffectPlaying) { |
|
606 device->ffEffectPlaying = false; |
|
607 |
|
608 struct input_event ev; |
|
609 ev.time.tv_sec = 0; |
|
610 ev.time.tv_usec = 0; |
|
611 ev.type = EV_FF; |
|
612 ev.code = device->ffEffectId; |
|
613 ev.value = 0; |
|
614 if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) { |
|
615 ALOGW("Could not stop force feedback effect on device %s due to error %d.", |
|
616 device->identifier.name.string(), errno); |
|
617 return; |
|
618 } |
|
619 } |
|
620 } |
|
621 } |
|
622 |
|
623 EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const { |
|
624 if (deviceId == BUILT_IN_KEYBOARD_ID) { |
|
625 deviceId = mBuiltInKeyboardId; |
|
626 } |
|
627 ssize_t index = mDevices.indexOfKey(deviceId); |
|
628 return index >= 0 ? mDevices.valueAt(index) : NULL; |
|
629 } |
|
630 |
|
631 EventHub::Device* EventHub::getDeviceByPathLocked(const char* devicePath) const { |
|
632 for (size_t i = 0; i < mDevices.size(); i++) { |
|
633 Device* device = mDevices.valueAt(i); |
|
634 if (device->path == devicePath) { |
|
635 return device; |
|
636 } |
|
637 } |
|
638 return NULL; |
|
639 } |
|
640 |
|
641 size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { |
|
642 ALOG_ASSERT(bufferSize >= 1); |
|
643 |
|
644 AutoMutex _l(mLock); |
|
645 |
|
646 struct input_event readBuffer[bufferSize]; |
|
647 |
|
648 RawEvent* event = buffer; |
|
649 size_t capacity = bufferSize; |
|
650 bool awoken = false; |
|
651 for (;;) { |
|
652 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); |
|
653 |
|
654 // Reopen input devices if needed. |
|
655 if (mNeedToReopenDevices) { |
|
656 mNeedToReopenDevices = false; |
|
657 |
|
658 ALOGI("Reopening all input devices due to a configuration change."); |
|
659 |
|
660 closeAllDevicesLocked(); |
|
661 mNeedToScanDevices = true; |
|
662 break; // return to the caller before we actually rescan |
|
663 } |
|
664 |
|
665 // Report any devices that had last been added/removed. |
|
666 while (mClosingDevices) { |
|
667 Device* device = mClosingDevices; |
|
668 ALOGV("Reporting device closed: id=%d, name=%s\n", |
|
669 device->id, device->path.string()); |
|
670 mClosingDevices = device->next; |
|
671 event->when = now; |
|
672 event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id; |
|
673 event->type = DEVICE_REMOVED; |
|
674 event += 1; |
|
675 delete device; |
|
676 mNeedToSendFinishedDeviceScan = true; |
|
677 if (--capacity == 0) { |
|
678 break; |
|
679 } |
|
680 } |
|
681 |
|
682 if (mNeedToScanDevices) { |
|
683 mNeedToScanDevices = false; |
|
684 scanDevicesLocked(); |
|
685 mNeedToSendFinishedDeviceScan = true; |
|
686 } |
|
687 |
|
688 while (mOpeningDevices != NULL) { |
|
689 Device* device = mOpeningDevices; |
|
690 ALOGV("Reporting device opened: id=%d, name=%s\n", |
|
691 device->id, device->path.string()); |
|
692 mOpeningDevices = device->next; |
|
693 event->when = now; |
|
694 event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; |
|
695 event->type = DEVICE_ADDED; |
|
696 event += 1; |
|
697 mNeedToSendFinishedDeviceScan = true; |
|
698 if (--capacity == 0) { |
|
699 break; |
|
700 } |
|
701 } |
|
702 |
|
703 if (mNeedToSendFinishedDeviceScan) { |
|
704 mNeedToSendFinishedDeviceScan = false; |
|
705 event->when = now; |
|
706 event->type = FINISHED_DEVICE_SCAN; |
|
707 event += 1; |
|
708 if (--capacity == 0) { |
|
709 break; |
|
710 } |
|
711 } |
|
712 |
|
713 // Grab the next input event. |
|
714 bool deviceChanged = false; |
|
715 while (mPendingEventIndex < mPendingEventCount) { |
|
716 const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++]; |
|
717 if (eventItem.data.u32 == EPOLL_ID_INOTIFY) { |
|
718 if (eventItem.events & EPOLLIN) { |
|
719 mPendingINotify = true; |
|
720 } else { |
|
721 ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events); |
|
722 } |
|
723 continue; |
|
724 } |
|
725 |
|
726 if (eventItem.data.u32 == EPOLL_ID_WAKE) { |
|
727 if (eventItem.events & EPOLLIN) { |
|
728 ALOGV("awoken after wake()"); |
|
729 awoken = true; |
|
730 char buffer[16]; |
|
731 ssize_t nRead; |
|
732 do { |
|
733 nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); |
|
734 } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); |
|
735 } else { |
|
736 ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.", |
|
737 eventItem.events); |
|
738 } |
|
739 continue; |
|
740 } |
|
741 |
|
742 ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32); |
|
743 if (deviceIndex < 0) { |
|
744 ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.", |
|
745 eventItem.events, eventItem.data.u32); |
|
746 continue; |
|
747 } |
|
748 |
|
749 Device* device = mDevices.valueAt(deviceIndex); |
|
750 if (eventItem.events & EPOLLIN) { |
|
751 int32_t readSize = read(device->fd, readBuffer, |
|
752 sizeof(struct input_event) * capacity); |
|
753 if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { |
|
754 // Device was removed before INotify noticed. |
|
755 ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d " |
|
756 "capacity: %d errno: %d)\n", |
|
757 device->fd, readSize, bufferSize, capacity, errno); |
|
758 deviceChanged = true; |
|
759 closeDeviceLocked(device); |
|
760 } else if (readSize < 0) { |
|
761 if (errno != EAGAIN && errno != EINTR) { |
|
762 ALOGW("could not get event (errno=%d)", errno); |
|
763 } |
|
764 } else if ((readSize % sizeof(struct input_event)) != 0) { |
|
765 ALOGE("could not get event (wrong size: %d)", readSize); |
|
766 } else { |
|
767 int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; |
|
768 |
|
769 size_t count = size_t(readSize) / sizeof(struct input_event); |
|
770 for (size_t i = 0; i < count; i++) { |
|
771 struct input_event& iev = readBuffer[i]; |
|
772 ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d", |
|
773 device->path.string(), |
|
774 (int) iev.time.tv_sec, (int) iev.time.tv_usec, |
|
775 iev.type, iev.code, iev.value); |
|
776 |
|
777 // Some input devices may have a better concept of the time |
|
778 // when an input event was actually generated than the kernel |
|
779 // which simply timestamps all events on entry to evdev. |
|
780 // This is a custom Android extension of the input protocol |
|
781 // mainly intended for use with uinput based device drivers. |
|
782 if (iev.type == EV_MSC) { |
|
783 if (iev.code == MSC_ANDROID_TIME_SEC) { |
|
784 device->timestampOverrideSec = iev.value; |
|
785 continue; |
|
786 } else if (iev.code == MSC_ANDROID_TIME_USEC) { |
|
787 device->timestampOverrideUsec = iev.value; |
|
788 continue; |
|
789 } |
|
790 } |
|
791 if (device->timestampOverrideSec || device->timestampOverrideUsec) { |
|
792 iev.time.tv_sec = device->timestampOverrideSec; |
|
793 iev.time.tv_usec = device->timestampOverrideUsec; |
|
794 if (iev.type == EV_SYN && iev.code == SYN_REPORT) { |
|
795 device->timestampOverrideSec = 0; |
|
796 device->timestampOverrideUsec = 0; |
|
797 } |
|
798 ALOGV("applied override time %d.%06d", |
|
799 int(iev.time.tv_sec), int(iev.time.tv_usec)); |
|
800 } |
|
801 |
|
802 #ifdef HAVE_POSIX_CLOCKS |
|
803 // Use the time specified in the event instead of the current time |
|
804 // so that downstream code can get more accurate estimates of |
|
805 // event dispatch latency from the time the event is enqueued onto |
|
806 // the evdev client buffer. |
|
807 // |
|
808 // The event's timestamp fortuitously uses the same monotonic clock |
|
809 // time base as the rest of Android. The kernel event device driver |
|
810 // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts(). |
|
811 // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere |
|
812 // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a |
|
813 // system call that also queries ktime_get_ts(). |
|
814 event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL |
|
815 + nsecs_t(iev.time.tv_usec) * 1000LL; |
|
816 ALOGV("event time %lld, now %lld", event->when, now); |
|
817 |
|
818 // Bug 7291243: Add a guard in case the kernel generates timestamps |
|
819 // that appear to be far into the future because they were generated |
|
820 // using the wrong clock source. |
|
821 // |
|
822 // This can happen because when the input device is initially opened |
|
823 // it has a default clock source of CLOCK_REALTIME. Any input events |
|
824 // enqueued right after the device is opened will have timestamps |
|
825 // generated using CLOCK_REALTIME. We later set the clock source |
|
826 // to CLOCK_MONOTONIC but it is already too late. |
|
827 // |
|
828 // Invalid input event timestamps can result in ANRs, crashes and |
|
829 // and other issues that are hard to track down. We must not let them |
|
830 // propagate through the system. |
|
831 // |
|
832 // Log a warning so that we notice the problem and recover gracefully. |
|
833 if (event->when >= now + 10 * 1000000000LL) { |
|
834 // Double-check. Time may have moved on. |
|
835 nsecs_t time = systemTime(SYSTEM_TIME_MONOTONIC); |
|
836 if (event->when > time) { |
|
837 ALOGW("An input event from %s has a timestamp that appears to " |
|
838 "have been generated using the wrong clock source " |
|
839 "(expected CLOCK_MONOTONIC): " |
|
840 "event time %lld, current time %lld, call time %lld. " |
|
841 "Using current time instead.", |
|
842 device->path.string(), event->when, time, now); |
|
843 event->when = time; |
|
844 } else { |
|
845 ALOGV("Event time is ok but failed the fast path and required " |
|
846 "an extra call to systemTime: " |
|
847 "event time %lld, current time %lld, call time %lld.", |
|
848 event->when, time, now); |
|
849 } |
|
850 } |
|
851 #else |
|
852 event->when = now; |
|
853 #endif |
|
854 event->deviceId = deviceId; |
|
855 event->type = iev.type; |
|
856 event->code = iev.code; |
|
857 event->value = iev.value; |
|
858 event += 1; |
|
859 capacity -= 1; |
|
860 } |
|
861 if (capacity == 0) { |
|
862 // The result buffer is full. Reset the pending event index |
|
863 // so we will try to read the device again on the next iteration. |
|
864 mPendingEventIndex -= 1; |
|
865 break; |
|
866 } |
|
867 } |
|
868 } else if (eventItem.events & EPOLLHUP) { |
|
869 ALOGI("Removing device %s due to epoll hang-up event.", |
|
870 device->identifier.name.string()); |
|
871 deviceChanged = true; |
|
872 closeDeviceLocked(device); |
|
873 } else { |
|
874 ALOGW("Received unexpected epoll event 0x%08x for device %s.", |
|
875 eventItem.events, device->identifier.name.string()); |
|
876 } |
|
877 } |
|
878 |
|
879 // readNotify() will modify the list of devices so this must be done after |
|
880 // processing all other events to ensure that we read all remaining events |
|
881 // before closing the devices. |
|
882 if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) { |
|
883 mPendingINotify = false; |
|
884 readNotifyLocked(); |
|
885 deviceChanged = true; |
|
886 } |
|
887 |
|
888 // Report added or removed devices immediately. |
|
889 if (deviceChanged) { |
|
890 continue; |
|
891 } |
|
892 |
|
893 // Return now if we have collected any events or if we were explicitly awoken. |
|
894 if (event != buffer || awoken) { |
|
895 break; |
|
896 } |
|
897 |
|
898 // Poll for events. Mind the wake lock dance! |
|
899 // We hold a wake lock at all times except during epoll_wait(). This works due to some |
|
900 // subtle choreography. When a device driver has pending (unread) events, it acquires |
|
901 // a kernel wake lock. However, once the last pending event has been read, the device |
|
902 // driver will release the kernel wake lock. To prevent the system from going to sleep |
|
903 // when this happens, the EventHub holds onto its own user wake lock while the client |
|
904 // is processing events. Thus the system can only sleep if there are no events |
|
905 // pending or currently being processed. |
|
906 // |
|
907 // The timeout is advisory only. If the device is asleep, it will not wake just to |
|
908 // service the timeout. |
|
909 mPendingEventIndex = 0; |
|
910 |
|
911 mLock.unlock(); // release lock before poll, must be before release_wake_lock |
|
912 release_wake_lock(WAKE_LOCK_ID); |
|
913 |
|
914 int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis); |
|
915 |
|
916 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); |
|
917 mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock |
|
918 |
|
919 if (pollResult == 0) { |
|
920 // Timed out. |
|
921 mPendingEventCount = 0; |
|
922 break; |
|
923 } |
|
924 |
|
925 if (pollResult < 0) { |
|
926 // An error occurred. |
|
927 mPendingEventCount = 0; |
|
928 |
|
929 // Sleep after errors to avoid locking up the system. |
|
930 // Hopefully the error is transient. |
|
931 if (errno != EINTR) { |
|
932 ALOGW("poll failed (errno=%d)\n", errno); |
|
933 usleep(100000); |
|
934 } |
|
935 } else { |
|
936 // Some events occurred. |
|
937 mPendingEventCount = size_t(pollResult); |
|
938 } |
|
939 } |
|
940 |
|
941 // All done, return the number of events we read. |
|
942 return event - buffer; |
|
943 } |
|
944 |
|
945 void EventHub::wake() { |
|
946 ALOGV("wake() called"); |
|
947 |
|
948 ssize_t nWrite; |
|
949 do { |
|
950 nWrite = write(mWakeWritePipeFd, "W", 1); |
|
951 } while (nWrite == -1 && errno == EINTR); |
|
952 |
|
953 if (nWrite != 1 && errno != EAGAIN) { |
|
954 ALOGW("Could not write wake signal, errno=%d", errno); |
|
955 } |
|
956 } |
|
957 |
|
958 void EventHub::scanDevicesLocked() { |
|
959 status_t res = scanDirLocked(DEVICE_PATH); |
|
960 if(res < 0) { |
|
961 ALOGE("scan dir failed for %s\n", DEVICE_PATH); |
|
962 } |
|
963 if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) { |
|
964 createVirtualKeyboardLocked(); |
|
965 } |
|
966 } |
|
967 |
|
968 // ---------------------------------------------------------------------------- |
|
969 |
|
970 static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) { |
|
971 const uint8_t* end = array + endIndex; |
|
972 array += startIndex; |
|
973 while (array != end) { |
|
974 if (*(array++) != 0) { |
|
975 return true; |
|
976 } |
|
977 } |
|
978 return false; |
|
979 } |
|
980 |
|
981 static const int32_t GAMEPAD_KEYCODES[] = { |
|
982 AKEYCODE_BUTTON_A, AKEYCODE_BUTTON_B, AKEYCODE_BUTTON_C, |
|
983 AKEYCODE_BUTTON_X, AKEYCODE_BUTTON_Y, AKEYCODE_BUTTON_Z, |
|
984 AKEYCODE_BUTTON_L1, AKEYCODE_BUTTON_R1, |
|
985 AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2, |
|
986 AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR, |
|
987 AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE, |
|
988 AKEYCODE_BUTTON_1, AKEYCODE_BUTTON_2, AKEYCODE_BUTTON_3, AKEYCODE_BUTTON_4, |
|
989 AKEYCODE_BUTTON_5, AKEYCODE_BUTTON_6, AKEYCODE_BUTTON_7, AKEYCODE_BUTTON_8, |
|
990 AKEYCODE_BUTTON_9, AKEYCODE_BUTTON_10, AKEYCODE_BUTTON_11, AKEYCODE_BUTTON_12, |
|
991 AKEYCODE_BUTTON_13, AKEYCODE_BUTTON_14, AKEYCODE_BUTTON_15, AKEYCODE_BUTTON_16, |
|
992 }; |
|
993 |
|
994 status_t EventHub::openDeviceLocked(const char *devicePath) { |
|
995 char buffer[80]; |
|
996 |
|
997 ALOGV("Opening device: %s", devicePath); |
|
998 |
|
999 int fd = open(devicePath, O_RDWR | O_CLOEXEC); |
|
1000 if(fd < 0) { |
|
1001 ALOGE("could not open %s, %s\n", devicePath, strerror(errno)); |
|
1002 return -1; |
|
1003 } |
|
1004 |
|
1005 InputDeviceIdentifier identifier; |
|
1006 |
|
1007 // Get device name. |
|
1008 if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) { |
|
1009 //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno)); |
|
1010 } else { |
|
1011 buffer[sizeof(buffer) - 1] = '\0'; |
|
1012 identifier.name.setTo(buffer); |
|
1013 } |
|
1014 |
|
1015 // Check to see if the device is on our excluded list |
|
1016 for (size_t i = 0; i < mExcludedDevices.size(); i++) { |
|
1017 const String8& item = mExcludedDevices.itemAt(i); |
|
1018 if (identifier.name == item) { |
|
1019 ALOGI("ignoring event id %s driver %s\n", devicePath, item.string()); |
|
1020 close(fd); |
|
1021 return -1; |
|
1022 } |
|
1023 } |
|
1024 |
|
1025 // Get device driver version. |
|
1026 int driverVersion; |
|
1027 if(ioctl(fd, EVIOCGVERSION, &driverVersion)) { |
|
1028 ALOGE("could not get driver version for %s, %s\n", devicePath, strerror(errno)); |
|
1029 close(fd); |
|
1030 return -1; |
|
1031 } |
|
1032 |
|
1033 // Get device identifier. |
|
1034 struct input_id inputId; |
|
1035 if(ioctl(fd, EVIOCGID, &inputId)) { |
|
1036 ALOGE("could not get device input id for %s, %s\n", devicePath, strerror(errno)); |
|
1037 close(fd); |
|
1038 return -1; |
|
1039 } |
|
1040 identifier.bus = inputId.bustype; |
|
1041 identifier.product = inputId.product; |
|
1042 identifier.vendor = inputId.vendor; |
|
1043 identifier.version = inputId.version; |
|
1044 |
|
1045 // Get device physical location. |
|
1046 if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) { |
|
1047 //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno)); |
|
1048 } else { |
|
1049 buffer[sizeof(buffer) - 1] = '\0'; |
|
1050 identifier.location.setTo(buffer); |
|
1051 } |
|
1052 |
|
1053 // Get device unique id. |
|
1054 if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) { |
|
1055 //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno)); |
|
1056 } else { |
|
1057 buffer[sizeof(buffer) - 1] = '\0'; |
|
1058 identifier.uniqueId.setTo(buffer); |
|
1059 } |
|
1060 |
|
1061 // Fill in the descriptor. |
|
1062 setDescriptor(identifier); |
|
1063 |
|
1064 // Make file descriptor non-blocking for use with poll(). |
|
1065 if (fcntl(fd, F_SETFL, O_NONBLOCK)) { |
|
1066 ALOGE("Error %d making device file descriptor non-blocking.", errno); |
|
1067 close(fd); |
|
1068 return -1; |
|
1069 } |
|
1070 |
|
1071 // Allocate device. (The device object takes ownership of the fd at this point.) |
|
1072 int32_t deviceId = mNextDeviceId++; |
|
1073 Device* device = new Device(fd, deviceId, String8(devicePath), identifier); |
|
1074 |
|
1075 ALOGV("add device %d: %s\n", deviceId, devicePath); |
|
1076 ALOGV(" bus: %04x\n" |
|
1077 " vendor %04x\n" |
|
1078 " product %04x\n" |
|
1079 " version %04x\n", |
|
1080 identifier.bus, identifier.vendor, identifier.product, identifier.version); |
|
1081 ALOGV(" name: \"%s\"\n", identifier.name.string()); |
|
1082 ALOGV(" location: \"%s\"\n", identifier.location.string()); |
|
1083 ALOGV(" unique id: \"%s\"\n", identifier.uniqueId.string()); |
|
1084 ALOGV(" descriptor: \"%s\"\n", identifier.descriptor.string()); |
|
1085 ALOGV(" driver: v%d.%d.%d\n", |
|
1086 driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff); |
|
1087 |
|
1088 // Load the configuration file for the device. |
|
1089 loadConfigurationLocked(device); |
|
1090 |
|
1091 // Figure out the kinds of events the device reports. |
|
1092 ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device->keyBitmask)), device->keyBitmask); |
|
1093 ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(device->absBitmask)), device->absBitmask); |
|
1094 ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask); |
|
1095 ioctl(fd, EVIOCGBIT(EV_SW, sizeof(device->swBitmask)), device->swBitmask); |
|
1096 ioctl(fd, EVIOCGBIT(EV_LED, sizeof(device->ledBitmask)), device->ledBitmask); |
|
1097 ioctl(fd, EVIOCGBIT(EV_FF, sizeof(device->ffBitmask)), device->ffBitmask); |
|
1098 ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask); |
|
1099 |
|
1100 // See if this is a keyboard. Ignore everything in the button range except for |
|
1101 // joystick and gamepad buttons which are handled like keyboards for the most part. |
|
1102 bool haveKeyboardKeys = containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC)) |
|
1103 || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK), |
|
1104 sizeof_bit_array(KEY_MAX + 1)); |
|
1105 bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC), |
|
1106 sizeof_bit_array(BTN_MOUSE)) |
|
1107 || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_JOYSTICK), |
|
1108 sizeof_bit_array(BTN_DIGI)); |
|
1109 if (haveKeyboardKeys || haveGamepadButtons) { |
|
1110 device->classes |= INPUT_DEVICE_CLASS_KEYBOARD; |
|
1111 } |
|
1112 |
|
1113 // See if this is a cursor device such as a trackball or mouse. |
|
1114 if (test_bit(BTN_MOUSE, device->keyBitmask) |
|
1115 && test_bit(REL_X, device->relBitmask) |
|
1116 && test_bit(REL_Y, device->relBitmask)) { |
|
1117 device->classes |= INPUT_DEVICE_CLASS_CURSOR; |
|
1118 } |
|
1119 |
|
1120 // See if this is a touch pad. |
|
1121 // Is this a new modern multi-touch driver? |
|
1122 if (test_bit(ABS_MT_POSITION_X, device->absBitmask) |
|
1123 && test_bit(ABS_MT_POSITION_Y, device->absBitmask)) { |
|
1124 // Some joysticks such as the PS3 controller report axes that conflict |
|
1125 // with the ABS_MT range. Try to confirm that the device really is |
|
1126 // a touch screen. |
|
1127 if (test_bit(BTN_TOUCH, device->keyBitmask) || !haveGamepadButtons) { |
|
1128 device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT; |
|
1129 } |
|
1130 // Is this an old style single-touch driver? |
|
1131 } else if (test_bit(BTN_TOUCH, device->keyBitmask) |
|
1132 && test_bit(ABS_X, device->absBitmask) |
|
1133 && test_bit(ABS_Y, device->absBitmask)) { |
|
1134 device->classes |= INPUT_DEVICE_CLASS_TOUCH; |
|
1135 } |
|
1136 |
|
1137 // See if this device is a joystick. |
|
1138 // Assumes that joysticks always have gamepad buttons in order to distinguish them |
|
1139 // from other devices such as accelerometers that also have absolute axes. |
|
1140 if (haveGamepadButtons) { |
|
1141 uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK; |
|
1142 for (int i = 0; i <= ABS_MAX; i++) { |
|
1143 if (test_bit(i, device->absBitmask) |
|
1144 && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) { |
|
1145 device->classes = assumedClasses; |
|
1146 break; |
|
1147 } |
|
1148 } |
|
1149 } |
|
1150 |
|
1151 // Check whether this device has switches. |
|
1152 for (int i = 0; i <= SW_MAX; i++) { |
|
1153 if (test_bit(i, device->swBitmask)) { |
|
1154 device->classes |= INPUT_DEVICE_CLASS_SWITCH; |
|
1155 break; |
|
1156 } |
|
1157 } |
|
1158 |
|
1159 // Check whether this device supports the vibrator. |
|
1160 if (test_bit(FF_RUMBLE, device->ffBitmask)) { |
|
1161 device->classes |= INPUT_DEVICE_CLASS_VIBRATOR; |
|
1162 } |
|
1163 |
|
1164 // Configure virtual keys. |
|
1165 if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) { |
|
1166 // Load the virtual keys for the touch screen, if any. |
|
1167 // We do this now so that we can make sure to load the keymap if necessary. |
|
1168 status_t status = loadVirtualKeyMapLocked(device); |
|
1169 if (!status) { |
|
1170 device->classes |= INPUT_DEVICE_CLASS_KEYBOARD; |
|
1171 } |
|
1172 } |
|
1173 |
|
1174 // Load the key map. |
|
1175 // We need to do this for joysticks too because the key layout may specify axes. |
|
1176 status_t keyMapStatus = NAME_NOT_FOUND; |
|
1177 if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) { |
|
1178 // Load the keymap for the device. |
|
1179 keyMapStatus = loadKeyMapLocked(device); |
|
1180 } |
|
1181 |
|
1182 // Configure the keyboard, gamepad or virtual keyboard. |
|
1183 if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) { |
|
1184 // Register the keyboard as a built-in keyboard if it is eligible. |
|
1185 if (!keyMapStatus |
|
1186 && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD |
|
1187 && isEligibleBuiltInKeyboard(device->identifier, |
|
1188 device->configuration, &device->keyMap)) { |
|
1189 mBuiltInKeyboardId = device->id; |
|
1190 } |
|
1191 |
|
1192 // 'Q' key support = cheap test of whether this is an alpha-capable kbd |
|
1193 if (hasKeycodeLocked(device, AKEYCODE_Q)) { |
|
1194 device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; |
|
1195 } |
|
1196 |
|
1197 // See if this device has a DPAD. |
|
1198 if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) && |
|
1199 hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) && |
|
1200 hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) && |
|
1201 hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) && |
|
1202 hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) { |
|
1203 device->classes |= INPUT_DEVICE_CLASS_DPAD; |
|
1204 } |
|
1205 |
|
1206 // See if this device has a gamepad. |
|
1207 for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) { |
|
1208 if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) { |
|
1209 device->classes |= INPUT_DEVICE_CLASS_GAMEPAD; |
|
1210 break; |
|
1211 } |
|
1212 } |
|
1213 |
|
1214 // Disable kernel key repeat since we handle it ourselves |
|
1215 unsigned int repeatRate[] = {0,0}; |
|
1216 if (ioctl(fd, EVIOCSREP, repeatRate)) { |
|
1217 ALOGW("Unable to disable kernel key repeat for %s: %s", devicePath, strerror(errno)); |
|
1218 } |
|
1219 } |
|
1220 |
|
1221 // If the device isn't recognized as something we handle, don't monitor it. |
|
1222 if (device->classes == 0) { |
|
1223 ALOGV("Dropping device: id=%d, path='%s', name='%s'", |
|
1224 deviceId, devicePath, device->identifier.name.string()); |
|
1225 delete device; |
|
1226 return -1; |
|
1227 } |
|
1228 |
|
1229 // Determine whether the device is external or internal. |
|
1230 if (isExternalDeviceLocked(device)) { |
|
1231 device->classes |= INPUT_DEVICE_CLASS_EXTERNAL; |
|
1232 } |
|
1233 |
|
1234 // Register with epoll. |
|
1235 struct epoll_event eventItem; |
|
1236 memset(&eventItem, 0, sizeof(eventItem)); |
|
1237 eventItem.events = EPOLLIN; |
|
1238 eventItem.data.u32 = deviceId; |
|
1239 if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) { |
|
1240 ALOGE("Could not add device fd to epoll instance. errno=%d", errno); |
|
1241 delete device; |
|
1242 return -1; |
|
1243 } |
|
1244 |
|
1245 // Enable wake-lock behavior on kernels that support it. |
|
1246 // TODO: Only need this for devices that can really wake the system. |
|
1247 bool usingSuspendBlockIoctl = !ioctl(fd, EVIOCSSUSPENDBLOCK, 1); |
|
1248 |
|
1249 // Tell the kernel that we want to use the monotonic clock for reporting timestamps |
|
1250 // associated with input events. This is important because the input system |
|
1251 // uses the timestamps extensively and assumes they were recorded using the monotonic |
|
1252 // clock. |
|
1253 // |
|
1254 // In older kernel, before Linux 3.4, there was no way to tell the kernel which |
|
1255 // clock to use to input event timestamps. The standard kernel behavior was to |
|
1256 // record a real time timestamp, which isn't what we want. Android kernels therefore |
|
1257 // contained a patch to the evdev_event() function in drivers/input/evdev.c to |
|
1258 // replace the call to do_gettimeofday() with ktime_get_ts() to cause the monotonic |
|
1259 // clock to be used instead of the real time clock. |
|
1260 // |
|
1261 // As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock. |
|
1262 // Therefore, we no longer require the Android-specific kernel patch described above |
|
1263 // as long as we make sure to set select the monotonic clock. We do that here. |
|
1264 int clockId = CLOCK_MONOTONIC; |
|
1265 bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId); |
|
1266 |
|
1267 ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, " |
|
1268 "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, " |
|
1269 "usingSuspendBlockIoctl=%s, usingClockIoctl=%s", |
|
1270 deviceId, fd, devicePath, device->identifier.name.string(), |
|
1271 device->classes, |
|
1272 device->configurationFile.string(), |
|
1273 device->keyMap.keyLayoutFile.string(), |
|
1274 device->keyMap.keyCharacterMapFile.string(), |
|
1275 toString(mBuiltInKeyboardId == deviceId), |
|
1276 toString(usingSuspendBlockIoctl), toString(usingClockIoctl)); |
|
1277 |
|
1278 addDeviceLocked(device); |
|
1279 return 0; |
|
1280 } |
|
1281 |
|
1282 void EventHub::createVirtualKeyboardLocked() { |
|
1283 InputDeviceIdentifier identifier; |
|
1284 identifier.name = "Virtual"; |
|
1285 identifier.uniqueId = "<virtual>"; |
|
1286 setDescriptor(identifier); |
|
1287 |
|
1288 Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier); |
|
1289 device->classes = INPUT_DEVICE_CLASS_KEYBOARD |
|
1290 | INPUT_DEVICE_CLASS_ALPHAKEY |
|
1291 | INPUT_DEVICE_CLASS_DPAD |
|
1292 | INPUT_DEVICE_CLASS_VIRTUAL; |
|
1293 loadKeyMapLocked(device); |
|
1294 addDeviceLocked(device); |
|
1295 } |
|
1296 |
|
1297 void EventHub::addDeviceLocked(Device* device) { |
|
1298 mDevices.add(device->id, device); |
|
1299 device->next = mOpeningDevices; |
|
1300 mOpeningDevices = device; |
|
1301 } |
|
1302 |
|
1303 void EventHub::loadConfigurationLocked(Device* device) { |
|
1304 device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier( |
|
1305 device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION); |
|
1306 if (device->configurationFile.isEmpty()) { |
|
1307 ALOGD("No input device configuration file found for device '%s'.", |
|
1308 device->identifier.name.string()); |
|
1309 } else { |
|
1310 status_t status = PropertyMap::load(device->configurationFile, |
|
1311 &device->configuration); |
|
1312 if (status) { |
|
1313 ALOGE("Error loading input device configuration file for device '%s'. " |
|
1314 "Using default configuration.", |
|
1315 device->identifier.name.string()); |
|
1316 } |
|
1317 } |
|
1318 } |
|
1319 |
|
1320 status_t EventHub::loadVirtualKeyMapLocked(Device* device) { |
|
1321 // The virtual key map is supplied by the kernel as a system board property file. |
|
1322 String8 path; |
|
1323 path.append("/sys/board_properties/virtualkeys."); |
|
1324 path.append(device->identifier.name); |
|
1325 if (access(path.string(), R_OK)) { |
|
1326 return NAME_NOT_FOUND; |
|
1327 } |
|
1328 return VirtualKeyMap::load(path, &device->virtualKeyMap); |
|
1329 } |
|
1330 |
|
1331 status_t EventHub::loadKeyMapLocked(Device* device) { |
|
1332 return device->keyMap.load(device->identifier, device->configuration); |
|
1333 } |
|
1334 |
|
1335 bool EventHub::isExternalDeviceLocked(Device* device) { |
|
1336 if (device->configuration) { |
|
1337 bool value; |
|
1338 if (device->configuration->tryGetProperty(String8("device.internal"), value)) { |
|
1339 return !value; |
|
1340 } |
|
1341 } |
|
1342 return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH; |
|
1343 } |
|
1344 |
|
1345 bool EventHub::hasKeycodeLocked(Device* device, int keycode) const { |
|
1346 if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) { |
|
1347 return false; |
|
1348 } |
|
1349 |
|
1350 Vector<int32_t> scanCodes; |
|
1351 device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes); |
|
1352 const size_t N = scanCodes.size(); |
|
1353 for (size_t i=0; i<N && i<=KEY_MAX; i++) { |
|
1354 int32_t sc = scanCodes.itemAt(i); |
|
1355 if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) { |
|
1356 return true; |
|
1357 } |
|
1358 } |
|
1359 |
|
1360 return false; |
|
1361 } |
|
1362 |
|
1363 status_t EventHub::closeDeviceByPathLocked(const char *devicePath) { |
|
1364 Device* device = getDeviceByPathLocked(devicePath); |
|
1365 if (device) { |
|
1366 closeDeviceLocked(device); |
|
1367 return 0; |
|
1368 } |
|
1369 ALOGV("Remove device: %s not found, device may already have been removed.", devicePath); |
|
1370 return -1; |
|
1371 } |
|
1372 |
|
1373 void EventHub::closeAllDevicesLocked() { |
|
1374 while (mDevices.size() > 0) { |
|
1375 closeDeviceLocked(mDevices.valueAt(mDevices.size() - 1)); |
|
1376 } |
|
1377 } |
|
1378 |
|
1379 void EventHub::closeDeviceLocked(Device* device) { |
|
1380 ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n", |
|
1381 device->path.string(), device->identifier.name.string(), device->id, |
|
1382 device->fd, device->classes); |
|
1383 |
|
1384 if (device->id == mBuiltInKeyboardId) { |
|
1385 ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this", |
|
1386 device->path.string(), mBuiltInKeyboardId); |
|
1387 mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD; |
|
1388 } |
|
1389 |
|
1390 if (!device->isVirtual()) { |
|
1391 if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) { |
|
1392 ALOGW("Could not remove device fd from epoll instance. errno=%d", errno); |
|
1393 } |
|
1394 } |
|
1395 |
|
1396 mDevices.removeItem(device->id); |
|
1397 device->close(); |
|
1398 |
|
1399 // Unlink for opening devices list if it is present. |
|
1400 Device* pred = NULL; |
|
1401 bool found = false; |
|
1402 for (Device* entry = mOpeningDevices; entry != NULL; ) { |
|
1403 if (entry == device) { |
|
1404 found = true; |
|
1405 break; |
|
1406 } |
|
1407 pred = entry; |
|
1408 entry = entry->next; |
|
1409 } |
|
1410 if (found) { |
|
1411 // Unlink the device from the opening devices list then delete it. |
|
1412 // We don't need to tell the client that the device was closed because |
|
1413 // it does not even know it was opened in the first place. |
|
1414 ALOGI("Device %s was immediately closed after opening.", device->path.string()); |
|
1415 if (pred) { |
|
1416 pred->next = device->next; |
|
1417 } else { |
|
1418 mOpeningDevices = device->next; |
|
1419 } |
|
1420 delete device; |
|
1421 } else { |
|
1422 // Link into closing devices list. |
|
1423 // The device will be deleted later after we have informed the client. |
|
1424 device->next = mClosingDevices; |
|
1425 mClosingDevices = device; |
|
1426 } |
|
1427 } |
|
1428 |
|
1429 status_t EventHub::readNotifyLocked() { |
|
1430 int res; |
|
1431 char devname[PATH_MAX]; |
|
1432 char *filename; |
|
1433 char event_buf[512]; |
|
1434 int event_size; |
|
1435 int event_pos = 0; |
|
1436 struct inotify_event *event; |
|
1437 |
|
1438 ALOGV("EventHub::readNotify nfd: %d\n", mINotifyFd); |
|
1439 res = read(mINotifyFd, event_buf, sizeof(event_buf)); |
|
1440 if(res < (int)sizeof(*event)) { |
|
1441 if(errno == EINTR) |
|
1442 return 0; |
|
1443 ALOGW("could not get event, %s\n", strerror(errno)); |
|
1444 return -1; |
|
1445 } |
|
1446 //printf("got %d bytes of event information\n", res); |
|
1447 |
|
1448 strcpy(devname, DEVICE_PATH); |
|
1449 filename = devname + strlen(devname); |
|
1450 *filename++ = '/'; |
|
1451 |
|
1452 while(res >= (int)sizeof(*event)) { |
|
1453 event = (struct inotify_event *)(event_buf + event_pos); |
|
1454 //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); |
|
1455 if(event->len) { |
|
1456 strcpy(filename, event->name); |
|
1457 if(event->mask & IN_CREATE) { |
|
1458 openDeviceLocked(devname); |
|
1459 } else { |
|
1460 ALOGI("Removing device '%s' due to inotify event\n", devname); |
|
1461 closeDeviceByPathLocked(devname); |
|
1462 } |
|
1463 } |
|
1464 event_size = sizeof(*event) + event->len; |
|
1465 res -= event_size; |
|
1466 event_pos += event_size; |
|
1467 } |
|
1468 return 0; |
|
1469 } |
|
1470 |
|
1471 status_t EventHub::scanDirLocked(const char *dirname) |
|
1472 { |
|
1473 char devname[PATH_MAX]; |
|
1474 char *filename; |
|
1475 DIR *dir; |
|
1476 struct dirent *de; |
|
1477 dir = opendir(dirname); |
|
1478 if(dir == NULL) |
|
1479 return -1; |
|
1480 strcpy(devname, dirname); |
|
1481 filename = devname + strlen(devname); |
|
1482 *filename++ = '/'; |
|
1483 while((de = readdir(dir))) { |
|
1484 if(de->d_name[0] == '.' && |
|
1485 (de->d_name[1] == '\0' || |
|
1486 (de->d_name[1] == '.' && de->d_name[2] == '\0'))) |
|
1487 continue; |
|
1488 strcpy(filename, de->d_name); |
|
1489 openDeviceLocked(devname); |
|
1490 } |
|
1491 closedir(dir); |
|
1492 return 0; |
|
1493 } |
|
1494 |
|
1495 void EventHub::requestReopenDevices() { |
|
1496 ALOGV("requestReopenDevices() called"); |
|
1497 |
|
1498 AutoMutex _l(mLock); |
|
1499 mNeedToReopenDevices = true; |
|
1500 } |
|
1501 |
|
1502 void EventHub::dump(String8& dump) { |
|
1503 dump.append("Event Hub State:\n"); |
|
1504 |
|
1505 { // acquire lock |
|
1506 AutoMutex _l(mLock); |
|
1507 |
|
1508 dump.appendFormat(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId); |
|
1509 |
|
1510 dump.append(INDENT "Devices:\n"); |
|
1511 |
|
1512 for (size_t i = 0; i < mDevices.size(); i++) { |
|
1513 const Device* device = mDevices.valueAt(i); |
|
1514 if (mBuiltInKeyboardId == device->id) { |
|
1515 dump.appendFormat(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n", |
|
1516 device->id, device->identifier.name.string()); |
|
1517 } else { |
|
1518 dump.appendFormat(INDENT2 "%d: %s\n", device->id, |
|
1519 device->identifier.name.string()); |
|
1520 } |
|
1521 dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes); |
|
1522 dump.appendFormat(INDENT3 "Path: %s\n", device->path.string()); |
|
1523 dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string()); |
|
1524 dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string()); |
|
1525 dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string()); |
|
1526 dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, " |
|
1527 "product=0x%04x, version=0x%04x\n", |
|
1528 device->identifier.bus, device->identifier.vendor, |
|
1529 device->identifier.product, device->identifier.version); |
|
1530 dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n", |
|
1531 device->keyMap.keyLayoutFile.string()); |
|
1532 dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n", |
|
1533 device->keyMap.keyCharacterMapFile.string()); |
|
1534 dump.appendFormat(INDENT3 "ConfigurationFile: %s\n", |
|
1535 device->configurationFile.string()); |
|
1536 dump.appendFormat(INDENT3 "HaveKeyboardLayoutOverlay: %s\n", |
|
1537 toString(device->overlayKeyMap != NULL)); |
|
1538 } |
|
1539 } // release lock |
|
1540 } |
|
1541 |
|
1542 void EventHub::monitor() { |
|
1543 // Acquire and release the lock to ensure that the event hub has not deadlocked. |
|
1544 mLock.lock(); |
|
1545 mLock.unlock(); |
|
1546 } |
|
1547 |
|
1548 |
|
1549 }; // namespace android |