1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gonk/libui/EventHub.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1549 @@ 1.4 +/* 1.5 + * Copyright (C) 2005 The Android Open Source Project 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +#define LOG_TAG "EventHub" 1.21 + 1.22 +// #define LOG_NDEBUG 0 1.23 +#include "cutils_log.h" 1.24 + 1.25 +#include "EventHub.h" 1.26 + 1.27 +#include <hardware_legacy/power.h> 1.28 + 1.29 +#include <cutils/properties.h> 1.30 +#include "cutils_log.h" 1.31 +#include <utils/Timers.h> 1.32 +#include <utils/threads.h> 1.33 +#include <utils/Errors.h> 1.34 + 1.35 +#include <stdlib.h> 1.36 +#include <stdio.h> 1.37 +#include <unistd.h> 1.38 +#include <fcntl.h> 1.39 +#include <memory.h> 1.40 +#include <errno.h> 1.41 +#include <assert.h> 1.42 + 1.43 +#include "KeyLayoutMap.h" 1.44 +#include "KeyCharacterMap.h" 1.45 +#include "VirtualKeyMap.h" 1.46 + 1.47 +#include <string.h> 1.48 +#include <stdint.h> 1.49 +#include <dirent.h> 1.50 + 1.51 +#include <sys/inotify.h> 1.52 +#include <sys/epoll.h> 1.53 +#include <sys/ioctl.h> 1.54 +#include <sys/limits.h> 1.55 +#include <sha1.h> 1.56 + 1.57 +/* this macro is used to tell if "bit" is set in "array" 1.58 + * it selects a byte from the array, and does a boolean AND 1.59 + * operation with a byte that only has the relevant bit set. 1.60 + * eg. to check for the 12th bit, we do (array[1] & 1<<4) 1.61 + */ 1.62 +#define test_bit(bit, array) (array[bit/8] & (1<<(bit%8))) 1.63 + 1.64 +/* this macro computes the number of bytes needed to represent a bit array of the specified size */ 1.65 +#define sizeof_bit_array(bits) ((bits + 7) / 8) 1.66 + 1.67 +#define INDENT " " 1.68 +#define INDENT2 " " 1.69 +#define INDENT3 " " 1.70 + 1.71 +namespace android { 1.72 + 1.73 +static const char *WAKE_LOCK_ID = "KeyEvents"; 1.74 +static const char *DEVICE_PATH = "/dev/input"; 1.75 + 1.76 +/* return the larger integer */ 1.77 +static inline int max(int v1, int v2) 1.78 +{ 1.79 + return (v1 > v2) ? v1 : v2; 1.80 +} 1.81 + 1.82 +static inline const char* toString(bool value) { 1.83 + return value ? "true" : "false"; 1.84 +} 1.85 + 1.86 +static String8 sha1(const String8& in) { 1.87 + SHA1_CTX ctx; 1.88 + SHA1Init(&ctx); 1.89 + SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size()); 1.90 + u_char digest[SHA1_DIGEST_LENGTH]; 1.91 + SHA1Final(digest, &ctx); 1.92 + 1.93 + String8 out; 1.94 + for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) { 1.95 + out.appendFormat("%02x", digest[i]); 1.96 + } 1.97 + return out; 1.98 +} 1.99 + 1.100 +static void setDescriptor(InputDeviceIdentifier& identifier) { 1.101 + // Compute a device descriptor that uniquely identifies the device. 1.102 + // The descriptor is assumed to be a stable identifier. Its value should not 1.103 + // change between reboots, reconnections, firmware updates or new releases of Android. 1.104 + // Ideally, we also want the descriptor to be short and relatively opaque. 1.105 + String8 rawDescriptor; 1.106 + rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product); 1.107 + if (!identifier.uniqueId.isEmpty()) { 1.108 + rawDescriptor.append("uniqueId:"); 1.109 + rawDescriptor.append(identifier.uniqueId); 1.110 + } if (identifier.vendor == 0 && identifier.product == 0) { 1.111 + // If we don't know the vendor and product id, then the device is probably 1.112 + // built-in so we need to rely on other information to uniquely identify 1.113 + // the input device. Usually we try to avoid relying on the device name or 1.114 + // location but for built-in input device, they are unlikely to ever change. 1.115 + if (!identifier.name.isEmpty()) { 1.116 + rawDescriptor.append("name:"); 1.117 + rawDescriptor.append(identifier.name); 1.118 + } else if (!identifier.location.isEmpty()) { 1.119 + rawDescriptor.append("location:"); 1.120 + rawDescriptor.append(identifier.location); 1.121 + } 1.122 + } 1.123 + identifier.descriptor = sha1(rawDescriptor); 1.124 + ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(), 1.125 + identifier.descriptor.string()); 1.126 +} 1.127 + 1.128 +// --- Global Functions --- 1.129 + 1.130 +uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) { 1.131 + // Touch devices get dibs on touch-related axes. 1.132 + if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) { 1.133 + switch (axis) { 1.134 + case ABS_X: 1.135 + case ABS_Y: 1.136 + case ABS_PRESSURE: 1.137 + case ABS_TOOL_WIDTH: 1.138 + case ABS_DISTANCE: 1.139 + case ABS_TILT_X: 1.140 + case ABS_TILT_Y: 1.141 + case ABS_MT_SLOT: 1.142 + case ABS_MT_TOUCH_MAJOR: 1.143 + case ABS_MT_TOUCH_MINOR: 1.144 + case ABS_MT_WIDTH_MAJOR: 1.145 + case ABS_MT_WIDTH_MINOR: 1.146 + case ABS_MT_ORIENTATION: 1.147 + case ABS_MT_POSITION_X: 1.148 + case ABS_MT_POSITION_Y: 1.149 + case ABS_MT_TOOL_TYPE: 1.150 + case ABS_MT_BLOB_ID: 1.151 + case ABS_MT_TRACKING_ID: 1.152 + case ABS_MT_PRESSURE: 1.153 + case ABS_MT_DISTANCE: 1.154 + return INPUT_DEVICE_CLASS_TOUCH; 1.155 + } 1.156 + } 1.157 + 1.158 + // Joystick devices get the rest. 1.159 + return deviceClasses & INPUT_DEVICE_CLASS_JOYSTICK; 1.160 +} 1.161 + 1.162 +// --- EventHub::Device --- 1.163 + 1.164 +EventHub::Device::Device(int fd, int32_t id, const String8& path, 1.165 + const InputDeviceIdentifier& identifier) : 1.166 + next(NULL), 1.167 + fd(fd), id(id), path(path), identifier(identifier), 1.168 + classes(0), configuration(NULL), virtualKeyMap(NULL), 1.169 + ffEffectPlaying(false), ffEffectId(-1), 1.170 + timestampOverrideSec(0), timestampOverrideUsec(0) { 1.171 + memset(keyBitmask, 0, sizeof(keyBitmask)); 1.172 + memset(absBitmask, 0, sizeof(absBitmask)); 1.173 + memset(relBitmask, 0, sizeof(relBitmask)); 1.174 + memset(swBitmask, 0, sizeof(swBitmask)); 1.175 + memset(ledBitmask, 0, sizeof(ledBitmask)); 1.176 + memset(ffBitmask, 0, sizeof(ffBitmask)); 1.177 + memset(propBitmask, 0, sizeof(propBitmask)); 1.178 +} 1.179 + 1.180 +EventHub::Device::~Device() { 1.181 + close(); 1.182 + delete configuration; 1.183 + delete virtualKeyMap; 1.184 +} 1.185 + 1.186 +void EventHub::Device::close() { 1.187 + if (fd >= 0) { 1.188 + ::close(fd); 1.189 + fd = -1; 1.190 + } 1.191 +} 1.192 + 1.193 + 1.194 +// --- EventHub --- 1.195 + 1.196 +const uint32_t EventHub::EPOLL_ID_INOTIFY; 1.197 +const uint32_t EventHub::EPOLL_ID_WAKE; 1.198 +const int EventHub::EPOLL_SIZE_HINT; 1.199 +const int EventHub::EPOLL_MAX_EVENTS; 1.200 + 1.201 +EventHub::EventHub(void) : 1.202 + mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), 1.203 + mOpeningDevices(0), mClosingDevices(0), 1.204 + mNeedToSendFinishedDeviceScan(false), 1.205 + mNeedToReopenDevices(false), mNeedToScanDevices(true), 1.206 + mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) { 1.207 + acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); 1.208 + 1.209 + mEpollFd = epoll_create(EPOLL_SIZE_HINT); 1.210 + LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 1.211 + 1.212 + mINotifyFd = inotify_init(); 1.213 + int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE); 1.214 + LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s. errno=%d", 1.215 + DEVICE_PATH, errno); 1.216 + 1.217 + struct epoll_event eventItem; 1.218 + memset(&eventItem, 0, sizeof(eventItem)); 1.219 + eventItem.events = EPOLLIN; 1.220 + eventItem.data.u32 = EPOLL_ID_INOTIFY; 1.221 + result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem); 1.222 + LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance. errno=%d", errno); 1.223 + 1.224 + int wakeFds[2]; 1.225 + result = pipe(wakeFds); 1.226 + LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); 1.227 + 1.228 + mWakeReadPipeFd = wakeFds[0]; 1.229 + mWakeWritePipeFd = wakeFds[1]; 1.230 + 1.231 + result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); 1.232 + LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", 1.233 + errno); 1.234 + 1.235 + result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); 1.236 + LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", 1.237 + errno); 1.238 + 1.239 + eventItem.data.u32 = EPOLL_ID_WAKE; 1.240 + result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem); 1.241 + LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", 1.242 + errno); 1.243 +} 1.244 + 1.245 +EventHub::~EventHub(void) { 1.246 + closeAllDevicesLocked(); 1.247 + 1.248 + while (mClosingDevices) { 1.249 + Device* device = mClosingDevices; 1.250 + mClosingDevices = device->next; 1.251 + delete device; 1.252 + } 1.253 + 1.254 + ::close(mEpollFd); 1.255 + ::close(mINotifyFd); 1.256 + ::close(mWakeReadPipeFd); 1.257 + ::close(mWakeWritePipeFd); 1.258 + 1.259 + release_wake_lock(WAKE_LOCK_ID); 1.260 +} 1.261 + 1.262 +InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const { 1.263 + AutoMutex _l(mLock); 1.264 + Device* device = getDeviceLocked(deviceId); 1.265 + if (device == NULL) return InputDeviceIdentifier(); 1.266 + return device->identifier; 1.267 +} 1.268 + 1.269 +uint32_t EventHub::getDeviceClasses(int32_t deviceId) const { 1.270 + AutoMutex _l(mLock); 1.271 + Device* device = getDeviceLocked(deviceId); 1.272 + if (device == NULL) return 0; 1.273 + return device->classes; 1.274 +} 1.275 + 1.276 +void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { 1.277 + AutoMutex _l(mLock); 1.278 + Device* device = getDeviceLocked(deviceId); 1.279 + if (device && device->configuration) { 1.280 + *outConfiguration = *device->configuration; 1.281 + } else { 1.282 + outConfiguration->clear(); 1.283 + } 1.284 +} 1.285 + 1.286 +status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, 1.287 + RawAbsoluteAxisInfo* outAxisInfo) const { 1.288 + outAxisInfo->clear(); 1.289 + 1.290 + if (axis >= 0 && axis <= ABS_MAX) { 1.291 + AutoMutex _l(mLock); 1.292 + 1.293 + Device* device = getDeviceLocked(deviceId); 1.294 + if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) { 1.295 + struct input_absinfo info; 1.296 + if(ioctl(device->fd, EVIOCGABS(axis), &info)) { 1.297 + ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", 1.298 + axis, device->identifier.name.string(), device->fd, errno); 1.299 + return -errno; 1.300 + } 1.301 + 1.302 + if (info.minimum != info.maximum) { 1.303 + outAxisInfo->valid = true; 1.304 + outAxisInfo->minValue = info.minimum; 1.305 + outAxisInfo->maxValue = info.maximum; 1.306 + outAxisInfo->flat = info.flat; 1.307 + outAxisInfo->fuzz = info.fuzz; 1.308 + outAxisInfo->resolution = info.resolution; 1.309 + } 1.310 + return OK; 1.311 + } 1.312 + } 1.313 + return -1; 1.314 +} 1.315 + 1.316 +bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const { 1.317 + if (axis >= 0 && axis <= REL_MAX) { 1.318 + AutoMutex _l(mLock); 1.319 + 1.320 + Device* device = getDeviceLocked(deviceId); 1.321 + if (device) { 1.322 + return test_bit(axis, device->relBitmask); 1.323 + } 1.324 + } 1.325 + return false; 1.326 +} 1.327 + 1.328 +bool EventHub::hasInputProperty(int32_t deviceId, int property) const { 1.329 + if (property >= 0 && property <= INPUT_PROP_MAX) { 1.330 + AutoMutex _l(mLock); 1.331 + 1.332 + Device* device = getDeviceLocked(deviceId); 1.333 + if (device) { 1.334 + return test_bit(property, device->propBitmask); 1.335 + } 1.336 + } 1.337 + return false; 1.338 +} 1.339 + 1.340 +int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { 1.341 + if (scanCode >= 0 && scanCode <= KEY_MAX) { 1.342 + AutoMutex _l(mLock); 1.343 + 1.344 + Device* device = getDeviceLocked(deviceId); 1.345 + if (device && !device->isVirtual() && test_bit(scanCode, device->keyBitmask)) { 1.346 + uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)]; 1.347 + memset(keyState, 0, sizeof(keyState)); 1.348 + if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) { 1.349 + return test_bit(scanCode, keyState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; 1.350 + } 1.351 + } 1.352 + } 1.353 + return AKEY_STATE_UNKNOWN; 1.354 +} 1.355 + 1.356 +int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { 1.357 + AutoMutex _l(mLock); 1.358 + 1.359 + Device* device = getDeviceLocked(deviceId); 1.360 + if (device && !device->isVirtual() && device->keyMap.haveKeyLayout()) { 1.361 + Vector<int32_t> scanCodes; 1.362 + device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes); 1.363 + if (scanCodes.size() != 0) { 1.364 + uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)]; 1.365 + memset(keyState, 0, sizeof(keyState)); 1.366 + if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) { 1.367 + for (size_t i = 0; i < scanCodes.size(); i++) { 1.368 + int32_t sc = scanCodes.itemAt(i); 1.369 + if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, keyState)) { 1.370 + return AKEY_STATE_DOWN; 1.371 + } 1.372 + } 1.373 + return AKEY_STATE_UP; 1.374 + } 1.375 + } 1.376 + } 1.377 + return AKEY_STATE_UNKNOWN; 1.378 +} 1.379 + 1.380 +int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { 1.381 + if (sw >= 0 && sw <= SW_MAX) { 1.382 + AutoMutex _l(mLock); 1.383 + 1.384 + Device* device = getDeviceLocked(deviceId); 1.385 + if (device && !device->isVirtual() && test_bit(sw, device->swBitmask)) { 1.386 + uint8_t swState[sizeof_bit_array(SW_MAX + 1)]; 1.387 + memset(swState, 0, sizeof(swState)); 1.388 + if (ioctl(device->fd, EVIOCGSW(sizeof(swState)), swState) >= 0) { 1.389 + return test_bit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP; 1.390 + } 1.391 + } 1.392 + } 1.393 + return AKEY_STATE_UNKNOWN; 1.394 +} 1.395 + 1.396 +status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const { 1.397 + *outValue = 0; 1.398 + 1.399 + if (axis >= 0 && axis <= ABS_MAX) { 1.400 + AutoMutex _l(mLock); 1.401 + 1.402 + Device* device = getDeviceLocked(deviceId); 1.403 + if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) { 1.404 + struct input_absinfo info; 1.405 + if(ioctl(device->fd, EVIOCGABS(axis), &info)) { 1.406 + ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", 1.407 + axis, device->identifier.name.string(), device->fd, errno); 1.408 + return -errno; 1.409 + } 1.410 + 1.411 + *outValue = info.value; 1.412 + return OK; 1.413 + } 1.414 + } 1.415 + return -1; 1.416 +} 1.417 + 1.418 +bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, 1.419 + const int32_t* keyCodes, uint8_t* outFlags) const { 1.420 + AutoMutex _l(mLock); 1.421 + 1.422 + Device* device = getDeviceLocked(deviceId); 1.423 + if (device && device->keyMap.haveKeyLayout()) { 1.424 + Vector<int32_t> scanCodes; 1.425 + for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) { 1.426 + scanCodes.clear(); 1.427 + 1.428 + status_t err = device->keyMap.keyLayoutMap->findScanCodesForKey( 1.429 + keyCodes[codeIndex], &scanCodes); 1.430 + if (! err) { 1.431 + // check the possible scan codes identified by the layout map against the 1.432 + // map of codes actually emitted by the driver 1.433 + for (size_t sc = 0; sc < scanCodes.size(); sc++) { 1.434 + if (test_bit(scanCodes[sc], device->keyBitmask)) { 1.435 + outFlags[codeIndex] = 1; 1.436 + break; 1.437 + } 1.438 + } 1.439 + } 1.440 + } 1.441 + return true; 1.442 + } 1.443 + return false; 1.444 +} 1.445 + 1.446 +status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, 1.447 + int32_t* outKeycode, uint32_t* outFlags) const { 1.448 + AutoMutex _l(mLock); 1.449 + Device* device = getDeviceLocked(deviceId); 1.450 + 1.451 + if (device) { 1.452 + // Check the key character map first. 1.453 + sp<KeyCharacterMap> kcm = device->getKeyCharacterMap(); 1.454 + if (kcm != NULL) { 1.455 + if (!kcm->mapKey(scanCode, usageCode, outKeycode)) { 1.456 + *outFlags = 0; 1.457 + return NO_ERROR; 1.458 + } 1.459 + } 1.460 + 1.461 + // Check the key layout next. 1.462 + if (device->keyMap.haveKeyLayout()) { 1.463 + if (!device->keyMap.keyLayoutMap->mapKey( 1.464 + scanCode, usageCode, outKeycode, outFlags)) { 1.465 + return NO_ERROR; 1.466 + } 1.467 + } 1.468 + } 1.469 + 1.470 + *outKeycode = 0; 1.471 + *outFlags = 0; 1.472 + return NAME_NOT_FOUND; 1.473 +} 1.474 + 1.475 +status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const { 1.476 + AutoMutex _l(mLock); 1.477 + Device* device = getDeviceLocked(deviceId); 1.478 + 1.479 + if (device && device->keyMap.haveKeyLayout()) { 1.480 + status_t err = device->keyMap.keyLayoutMap->mapAxis(scanCode, outAxisInfo); 1.481 + if (err == NO_ERROR) { 1.482 + return NO_ERROR; 1.483 + } 1.484 + } 1.485 + 1.486 + return NAME_NOT_FOUND; 1.487 +} 1.488 + 1.489 +void EventHub::setExcludedDevices(const Vector<String8>& devices) { 1.490 + AutoMutex _l(mLock); 1.491 + 1.492 + mExcludedDevices = devices; 1.493 +} 1.494 + 1.495 +bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const { 1.496 + AutoMutex _l(mLock); 1.497 + Device* device = getDeviceLocked(deviceId); 1.498 + if (device && scanCode >= 0 && scanCode <= KEY_MAX) { 1.499 + if (test_bit(scanCode, device->keyBitmask)) { 1.500 + return true; 1.501 + } 1.502 + } 1.503 + return false; 1.504 +} 1.505 + 1.506 +bool EventHub::hasLed(int32_t deviceId, int32_t led) const { 1.507 + AutoMutex _l(mLock); 1.508 + Device* device = getDeviceLocked(deviceId); 1.509 + if (device && led >= 0 && led <= LED_MAX) { 1.510 + if (test_bit(led, device->ledBitmask)) { 1.511 + return true; 1.512 + } 1.513 + } 1.514 + return false; 1.515 +} 1.516 + 1.517 +void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) { 1.518 + AutoMutex _l(mLock); 1.519 + Device* device = getDeviceLocked(deviceId); 1.520 + if (device && !device->isVirtual() && led >= 0 && led <= LED_MAX) { 1.521 + struct input_event ev; 1.522 + ev.time.tv_sec = 0; 1.523 + ev.time.tv_usec = 0; 1.524 + ev.type = EV_LED; 1.525 + ev.code = led; 1.526 + ev.value = on ? 1 : 0; 1.527 + 1.528 + ssize_t nWrite; 1.529 + do { 1.530 + nWrite = write(device->fd, &ev, sizeof(struct input_event)); 1.531 + } while (nWrite == -1 && errno == EINTR); 1.532 + } 1.533 +} 1.534 + 1.535 +void EventHub::getVirtualKeyDefinitions(int32_t deviceId, 1.536 + Vector<VirtualKeyDefinition>& outVirtualKeys) const { 1.537 + outVirtualKeys.clear(); 1.538 + 1.539 + AutoMutex _l(mLock); 1.540 + Device* device = getDeviceLocked(deviceId); 1.541 + if (device && device->virtualKeyMap) { 1.542 + outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys()); 1.543 + } 1.544 +} 1.545 + 1.546 +sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { 1.547 + AutoMutex _l(mLock); 1.548 + Device* device = getDeviceLocked(deviceId); 1.549 + if (device) { 1.550 + return device->getKeyCharacterMap(); 1.551 + } 1.552 + return NULL; 1.553 +} 1.554 + 1.555 +bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId, 1.556 + const sp<KeyCharacterMap>& map) { 1.557 + AutoMutex _l(mLock); 1.558 + Device* device = getDeviceLocked(deviceId); 1.559 + if (device) { 1.560 + if (map != device->overlayKeyMap) { 1.561 + device->overlayKeyMap = map; 1.562 + device->combinedKeyMap = KeyCharacterMap::combine( 1.563 + device->keyMap.keyCharacterMap, map); 1.564 + return true; 1.565 + } 1.566 + } 1.567 + return false; 1.568 +} 1.569 + 1.570 +void EventHub::vibrate(int32_t deviceId, nsecs_t duration) { 1.571 + AutoMutex _l(mLock); 1.572 + Device* device = getDeviceLocked(deviceId); 1.573 + if (device && !device->isVirtual()) { 1.574 + ff_effect effect; 1.575 + memset(&effect, 0, sizeof(effect)); 1.576 + effect.type = FF_RUMBLE; 1.577 + effect.id = device->ffEffectId; 1.578 + effect.u.rumble.strong_magnitude = 0xc000; 1.579 + effect.u.rumble.weak_magnitude = 0xc000; 1.580 + effect.replay.length = (duration + 999999LL) / 1000000LL; 1.581 + effect.replay.delay = 0; 1.582 + if (ioctl(device->fd, EVIOCSFF, &effect)) { 1.583 + ALOGW("Could not upload force feedback effect to device %s due to error %d.", 1.584 + device->identifier.name.string(), errno); 1.585 + return; 1.586 + } 1.587 + device->ffEffectId = effect.id; 1.588 + 1.589 + struct input_event ev; 1.590 + ev.time.tv_sec = 0; 1.591 + ev.time.tv_usec = 0; 1.592 + ev.type = EV_FF; 1.593 + ev.code = device->ffEffectId; 1.594 + ev.value = 1; 1.595 + if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) { 1.596 + ALOGW("Could not start force feedback effect on device %s due to error %d.", 1.597 + device->identifier.name.string(), errno); 1.598 + return; 1.599 + } 1.600 + device->ffEffectPlaying = true; 1.601 + } 1.602 +} 1.603 + 1.604 +void EventHub::cancelVibrate(int32_t deviceId) { 1.605 + AutoMutex _l(mLock); 1.606 + Device* device = getDeviceLocked(deviceId); 1.607 + if (device && !device->isVirtual()) { 1.608 + if (device->ffEffectPlaying) { 1.609 + device->ffEffectPlaying = false; 1.610 + 1.611 + struct input_event ev; 1.612 + ev.time.tv_sec = 0; 1.613 + ev.time.tv_usec = 0; 1.614 + ev.type = EV_FF; 1.615 + ev.code = device->ffEffectId; 1.616 + ev.value = 0; 1.617 + if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) { 1.618 + ALOGW("Could not stop force feedback effect on device %s due to error %d.", 1.619 + device->identifier.name.string(), errno); 1.620 + return; 1.621 + } 1.622 + } 1.623 + } 1.624 +} 1.625 + 1.626 +EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const { 1.627 + if (deviceId == BUILT_IN_KEYBOARD_ID) { 1.628 + deviceId = mBuiltInKeyboardId; 1.629 + } 1.630 + ssize_t index = mDevices.indexOfKey(deviceId); 1.631 + return index >= 0 ? mDevices.valueAt(index) : NULL; 1.632 +} 1.633 + 1.634 +EventHub::Device* EventHub::getDeviceByPathLocked(const char* devicePath) const { 1.635 + for (size_t i = 0; i < mDevices.size(); i++) { 1.636 + Device* device = mDevices.valueAt(i); 1.637 + if (device->path == devicePath) { 1.638 + return device; 1.639 + } 1.640 + } 1.641 + return NULL; 1.642 +} 1.643 + 1.644 +size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { 1.645 + ALOG_ASSERT(bufferSize >= 1); 1.646 + 1.647 + AutoMutex _l(mLock); 1.648 + 1.649 + struct input_event readBuffer[bufferSize]; 1.650 + 1.651 + RawEvent* event = buffer; 1.652 + size_t capacity = bufferSize; 1.653 + bool awoken = false; 1.654 + for (;;) { 1.655 + nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 1.656 + 1.657 + // Reopen input devices if needed. 1.658 + if (mNeedToReopenDevices) { 1.659 + mNeedToReopenDevices = false; 1.660 + 1.661 + ALOGI("Reopening all input devices due to a configuration change."); 1.662 + 1.663 + closeAllDevicesLocked(); 1.664 + mNeedToScanDevices = true; 1.665 + break; // return to the caller before we actually rescan 1.666 + } 1.667 + 1.668 + // Report any devices that had last been added/removed. 1.669 + while (mClosingDevices) { 1.670 + Device* device = mClosingDevices; 1.671 + ALOGV("Reporting device closed: id=%d, name=%s\n", 1.672 + device->id, device->path.string()); 1.673 + mClosingDevices = device->next; 1.674 + event->when = now; 1.675 + event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id; 1.676 + event->type = DEVICE_REMOVED; 1.677 + event += 1; 1.678 + delete device; 1.679 + mNeedToSendFinishedDeviceScan = true; 1.680 + if (--capacity == 0) { 1.681 + break; 1.682 + } 1.683 + } 1.684 + 1.685 + if (mNeedToScanDevices) { 1.686 + mNeedToScanDevices = false; 1.687 + scanDevicesLocked(); 1.688 + mNeedToSendFinishedDeviceScan = true; 1.689 + } 1.690 + 1.691 + while (mOpeningDevices != NULL) { 1.692 + Device* device = mOpeningDevices; 1.693 + ALOGV("Reporting device opened: id=%d, name=%s\n", 1.694 + device->id, device->path.string()); 1.695 + mOpeningDevices = device->next; 1.696 + event->when = now; 1.697 + event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; 1.698 + event->type = DEVICE_ADDED; 1.699 + event += 1; 1.700 + mNeedToSendFinishedDeviceScan = true; 1.701 + if (--capacity == 0) { 1.702 + break; 1.703 + } 1.704 + } 1.705 + 1.706 + if (mNeedToSendFinishedDeviceScan) { 1.707 + mNeedToSendFinishedDeviceScan = false; 1.708 + event->when = now; 1.709 + event->type = FINISHED_DEVICE_SCAN; 1.710 + event += 1; 1.711 + if (--capacity == 0) { 1.712 + break; 1.713 + } 1.714 + } 1.715 + 1.716 + // Grab the next input event. 1.717 + bool deviceChanged = false; 1.718 + while (mPendingEventIndex < mPendingEventCount) { 1.719 + const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++]; 1.720 + if (eventItem.data.u32 == EPOLL_ID_INOTIFY) { 1.721 + if (eventItem.events & EPOLLIN) { 1.722 + mPendingINotify = true; 1.723 + } else { 1.724 + ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events); 1.725 + } 1.726 + continue; 1.727 + } 1.728 + 1.729 + if (eventItem.data.u32 == EPOLL_ID_WAKE) { 1.730 + if (eventItem.events & EPOLLIN) { 1.731 + ALOGV("awoken after wake()"); 1.732 + awoken = true; 1.733 + char buffer[16]; 1.734 + ssize_t nRead; 1.735 + do { 1.736 + nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); 1.737 + } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); 1.738 + } else { 1.739 + ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.", 1.740 + eventItem.events); 1.741 + } 1.742 + continue; 1.743 + } 1.744 + 1.745 + ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32); 1.746 + if (deviceIndex < 0) { 1.747 + ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.", 1.748 + eventItem.events, eventItem.data.u32); 1.749 + continue; 1.750 + } 1.751 + 1.752 + Device* device = mDevices.valueAt(deviceIndex); 1.753 + if (eventItem.events & EPOLLIN) { 1.754 + int32_t readSize = read(device->fd, readBuffer, 1.755 + sizeof(struct input_event) * capacity); 1.756 + if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { 1.757 + // Device was removed before INotify noticed. 1.758 + ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d " 1.759 + "capacity: %d errno: %d)\n", 1.760 + device->fd, readSize, bufferSize, capacity, errno); 1.761 + deviceChanged = true; 1.762 + closeDeviceLocked(device); 1.763 + } else if (readSize < 0) { 1.764 + if (errno != EAGAIN && errno != EINTR) { 1.765 + ALOGW("could not get event (errno=%d)", errno); 1.766 + } 1.767 + } else if ((readSize % sizeof(struct input_event)) != 0) { 1.768 + ALOGE("could not get event (wrong size: %d)", readSize); 1.769 + } else { 1.770 + int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; 1.771 + 1.772 + size_t count = size_t(readSize) / sizeof(struct input_event); 1.773 + for (size_t i = 0; i < count; i++) { 1.774 + struct input_event& iev = readBuffer[i]; 1.775 + ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d", 1.776 + device->path.string(), 1.777 + (int) iev.time.tv_sec, (int) iev.time.tv_usec, 1.778 + iev.type, iev.code, iev.value); 1.779 + 1.780 + // Some input devices may have a better concept of the time 1.781 + // when an input event was actually generated than the kernel 1.782 + // which simply timestamps all events on entry to evdev. 1.783 + // This is a custom Android extension of the input protocol 1.784 + // mainly intended for use with uinput based device drivers. 1.785 + if (iev.type == EV_MSC) { 1.786 + if (iev.code == MSC_ANDROID_TIME_SEC) { 1.787 + device->timestampOverrideSec = iev.value; 1.788 + continue; 1.789 + } else if (iev.code == MSC_ANDROID_TIME_USEC) { 1.790 + device->timestampOverrideUsec = iev.value; 1.791 + continue; 1.792 + } 1.793 + } 1.794 + if (device->timestampOverrideSec || device->timestampOverrideUsec) { 1.795 + iev.time.tv_sec = device->timestampOverrideSec; 1.796 + iev.time.tv_usec = device->timestampOverrideUsec; 1.797 + if (iev.type == EV_SYN && iev.code == SYN_REPORT) { 1.798 + device->timestampOverrideSec = 0; 1.799 + device->timestampOverrideUsec = 0; 1.800 + } 1.801 + ALOGV("applied override time %d.%06d", 1.802 + int(iev.time.tv_sec), int(iev.time.tv_usec)); 1.803 + } 1.804 + 1.805 +#ifdef HAVE_POSIX_CLOCKS 1.806 + // Use the time specified in the event instead of the current time 1.807 + // so that downstream code can get more accurate estimates of 1.808 + // event dispatch latency from the time the event is enqueued onto 1.809 + // the evdev client buffer. 1.810 + // 1.811 + // The event's timestamp fortuitously uses the same monotonic clock 1.812 + // time base as the rest of Android. The kernel event device driver 1.813 + // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts(). 1.814 + // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere 1.815 + // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a 1.816 + // system call that also queries ktime_get_ts(). 1.817 + event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL 1.818 + + nsecs_t(iev.time.tv_usec) * 1000LL; 1.819 + ALOGV("event time %lld, now %lld", event->when, now); 1.820 + 1.821 + // Bug 7291243: Add a guard in case the kernel generates timestamps 1.822 + // that appear to be far into the future because they were generated 1.823 + // using the wrong clock source. 1.824 + // 1.825 + // This can happen because when the input device is initially opened 1.826 + // it has a default clock source of CLOCK_REALTIME. Any input events 1.827 + // enqueued right after the device is opened will have timestamps 1.828 + // generated using CLOCK_REALTIME. We later set the clock source 1.829 + // to CLOCK_MONOTONIC but it is already too late. 1.830 + // 1.831 + // Invalid input event timestamps can result in ANRs, crashes and 1.832 + // and other issues that are hard to track down. We must not let them 1.833 + // propagate through the system. 1.834 + // 1.835 + // Log a warning so that we notice the problem and recover gracefully. 1.836 + if (event->when >= now + 10 * 1000000000LL) { 1.837 + // Double-check. Time may have moved on. 1.838 + nsecs_t time = systemTime(SYSTEM_TIME_MONOTONIC); 1.839 + if (event->when > time) { 1.840 + ALOGW("An input event from %s has a timestamp that appears to " 1.841 + "have been generated using the wrong clock source " 1.842 + "(expected CLOCK_MONOTONIC): " 1.843 + "event time %lld, current time %lld, call time %lld. " 1.844 + "Using current time instead.", 1.845 + device->path.string(), event->when, time, now); 1.846 + event->when = time; 1.847 + } else { 1.848 + ALOGV("Event time is ok but failed the fast path and required " 1.849 + "an extra call to systemTime: " 1.850 + "event time %lld, current time %lld, call time %lld.", 1.851 + event->when, time, now); 1.852 + } 1.853 + } 1.854 +#else 1.855 + event->when = now; 1.856 +#endif 1.857 + event->deviceId = deviceId; 1.858 + event->type = iev.type; 1.859 + event->code = iev.code; 1.860 + event->value = iev.value; 1.861 + event += 1; 1.862 + capacity -= 1; 1.863 + } 1.864 + if (capacity == 0) { 1.865 + // The result buffer is full. Reset the pending event index 1.866 + // so we will try to read the device again on the next iteration. 1.867 + mPendingEventIndex -= 1; 1.868 + break; 1.869 + } 1.870 + } 1.871 + } else if (eventItem.events & EPOLLHUP) { 1.872 + ALOGI("Removing device %s due to epoll hang-up event.", 1.873 + device->identifier.name.string()); 1.874 + deviceChanged = true; 1.875 + closeDeviceLocked(device); 1.876 + } else { 1.877 + ALOGW("Received unexpected epoll event 0x%08x for device %s.", 1.878 + eventItem.events, device->identifier.name.string()); 1.879 + } 1.880 + } 1.881 + 1.882 + // readNotify() will modify the list of devices so this must be done after 1.883 + // processing all other events to ensure that we read all remaining events 1.884 + // before closing the devices. 1.885 + if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) { 1.886 + mPendingINotify = false; 1.887 + readNotifyLocked(); 1.888 + deviceChanged = true; 1.889 + } 1.890 + 1.891 + // Report added or removed devices immediately. 1.892 + if (deviceChanged) { 1.893 + continue; 1.894 + } 1.895 + 1.896 + // Return now if we have collected any events or if we were explicitly awoken. 1.897 + if (event != buffer || awoken) { 1.898 + break; 1.899 + } 1.900 + 1.901 + // Poll for events. Mind the wake lock dance! 1.902 + // We hold a wake lock at all times except during epoll_wait(). This works due to some 1.903 + // subtle choreography. When a device driver has pending (unread) events, it acquires 1.904 + // a kernel wake lock. However, once the last pending event has been read, the device 1.905 + // driver will release the kernel wake lock. To prevent the system from going to sleep 1.906 + // when this happens, the EventHub holds onto its own user wake lock while the client 1.907 + // is processing events. Thus the system can only sleep if there are no events 1.908 + // pending or currently being processed. 1.909 + // 1.910 + // The timeout is advisory only. If the device is asleep, it will not wake just to 1.911 + // service the timeout. 1.912 + mPendingEventIndex = 0; 1.913 + 1.914 + mLock.unlock(); // release lock before poll, must be before release_wake_lock 1.915 + release_wake_lock(WAKE_LOCK_ID); 1.916 + 1.917 + int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis); 1.918 + 1.919 + acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); 1.920 + mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock 1.921 + 1.922 + if (pollResult == 0) { 1.923 + // Timed out. 1.924 + mPendingEventCount = 0; 1.925 + break; 1.926 + } 1.927 + 1.928 + if (pollResult < 0) { 1.929 + // An error occurred. 1.930 + mPendingEventCount = 0; 1.931 + 1.932 + // Sleep after errors to avoid locking up the system. 1.933 + // Hopefully the error is transient. 1.934 + if (errno != EINTR) { 1.935 + ALOGW("poll failed (errno=%d)\n", errno); 1.936 + usleep(100000); 1.937 + } 1.938 + } else { 1.939 + // Some events occurred. 1.940 + mPendingEventCount = size_t(pollResult); 1.941 + } 1.942 + } 1.943 + 1.944 + // All done, return the number of events we read. 1.945 + return event - buffer; 1.946 +} 1.947 + 1.948 +void EventHub::wake() { 1.949 + ALOGV("wake() called"); 1.950 + 1.951 + ssize_t nWrite; 1.952 + do { 1.953 + nWrite = write(mWakeWritePipeFd, "W", 1); 1.954 + } while (nWrite == -1 && errno == EINTR); 1.955 + 1.956 + if (nWrite != 1 && errno != EAGAIN) { 1.957 + ALOGW("Could not write wake signal, errno=%d", errno); 1.958 + } 1.959 +} 1.960 + 1.961 +void EventHub::scanDevicesLocked() { 1.962 + status_t res = scanDirLocked(DEVICE_PATH); 1.963 + if(res < 0) { 1.964 + ALOGE("scan dir failed for %s\n", DEVICE_PATH); 1.965 + } 1.966 + if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) { 1.967 + createVirtualKeyboardLocked(); 1.968 + } 1.969 +} 1.970 + 1.971 +// ---------------------------------------------------------------------------- 1.972 + 1.973 +static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) { 1.974 + const uint8_t* end = array + endIndex; 1.975 + array += startIndex; 1.976 + while (array != end) { 1.977 + if (*(array++) != 0) { 1.978 + return true; 1.979 + } 1.980 + } 1.981 + return false; 1.982 +} 1.983 + 1.984 +static const int32_t GAMEPAD_KEYCODES[] = { 1.985 + AKEYCODE_BUTTON_A, AKEYCODE_BUTTON_B, AKEYCODE_BUTTON_C, 1.986 + AKEYCODE_BUTTON_X, AKEYCODE_BUTTON_Y, AKEYCODE_BUTTON_Z, 1.987 + AKEYCODE_BUTTON_L1, AKEYCODE_BUTTON_R1, 1.988 + AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2, 1.989 + AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR, 1.990 + AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE, 1.991 + AKEYCODE_BUTTON_1, AKEYCODE_BUTTON_2, AKEYCODE_BUTTON_3, AKEYCODE_BUTTON_4, 1.992 + AKEYCODE_BUTTON_5, AKEYCODE_BUTTON_6, AKEYCODE_BUTTON_7, AKEYCODE_BUTTON_8, 1.993 + AKEYCODE_BUTTON_9, AKEYCODE_BUTTON_10, AKEYCODE_BUTTON_11, AKEYCODE_BUTTON_12, 1.994 + AKEYCODE_BUTTON_13, AKEYCODE_BUTTON_14, AKEYCODE_BUTTON_15, AKEYCODE_BUTTON_16, 1.995 +}; 1.996 + 1.997 +status_t EventHub::openDeviceLocked(const char *devicePath) { 1.998 + char buffer[80]; 1.999 + 1.1000 + ALOGV("Opening device: %s", devicePath); 1.1001 + 1.1002 + int fd = open(devicePath, O_RDWR | O_CLOEXEC); 1.1003 + if(fd < 0) { 1.1004 + ALOGE("could not open %s, %s\n", devicePath, strerror(errno)); 1.1005 + return -1; 1.1006 + } 1.1007 + 1.1008 + InputDeviceIdentifier identifier; 1.1009 + 1.1010 + // Get device name. 1.1011 + if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) { 1.1012 + //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno)); 1.1013 + } else { 1.1014 + buffer[sizeof(buffer) - 1] = '\0'; 1.1015 + identifier.name.setTo(buffer); 1.1016 + } 1.1017 + 1.1018 + // Check to see if the device is on our excluded list 1.1019 + for (size_t i = 0; i < mExcludedDevices.size(); i++) { 1.1020 + const String8& item = mExcludedDevices.itemAt(i); 1.1021 + if (identifier.name == item) { 1.1022 + ALOGI("ignoring event id %s driver %s\n", devicePath, item.string()); 1.1023 + close(fd); 1.1024 + return -1; 1.1025 + } 1.1026 + } 1.1027 + 1.1028 + // Get device driver version. 1.1029 + int driverVersion; 1.1030 + if(ioctl(fd, EVIOCGVERSION, &driverVersion)) { 1.1031 + ALOGE("could not get driver version for %s, %s\n", devicePath, strerror(errno)); 1.1032 + close(fd); 1.1033 + return -1; 1.1034 + } 1.1035 + 1.1036 + // Get device identifier. 1.1037 + struct input_id inputId; 1.1038 + if(ioctl(fd, EVIOCGID, &inputId)) { 1.1039 + ALOGE("could not get device input id for %s, %s\n", devicePath, strerror(errno)); 1.1040 + close(fd); 1.1041 + return -1; 1.1042 + } 1.1043 + identifier.bus = inputId.bustype; 1.1044 + identifier.product = inputId.product; 1.1045 + identifier.vendor = inputId.vendor; 1.1046 + identifier.version = inputId.version; 1.1047 + 1.1048 + // Get device physical location. 1.1049 + if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) { 1.1050 + //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno)); 1.1051 + } else { 1.1052 + buffer[sizeof(buffer) - 1] = '\0'; 1.1053 + identifier.location.setTo(buffer); 1.1054 + } 1.1055 + 1.1056 + // Get device unique id. 1.1057 + if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) { 1.1058 + //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno)); 1.1059 + } else { 1.1060 + buffer[sizeof(buffer) - 1] = '\0'; 1.1061 + identifier.uniqueId.setTo(buffer); 1.1062 + } 1.1063 + 1.1064 + // Fill in the descriptor. 1.1065 + setDescriptor(identifier); 1.1066 + 1.1067 + // Make file descriptor non-blocking for use with poll(). 1.1068 + if (fcntl(fd, F_SETFL, O_NONBLOCK)) { 1.1069 + ALOGE("Error %d making device file descriptor non-blocking.", errno); 1.1070 + close(fd); 1.1071 + return -1; 1.1072 + } 1.1073 + 1.1074 + // Allocate device. (The device object takes ownership of the fd at this point.) 1.1075 + int32_t deviceId = mNextDeviceId++; 1.1076 + Device* device = new Device(fd, deviceId, String8(devicePath), identifier); 1.1077 + 1.1078 + ALOGV("add device %d: %s\n", deviceId, devicePath); 1.1079 + ALOGV(" bus: %04x\n" 1.1080 + " vendor %04x\n" 1.1081 + " product %04x\n" 1.1082 + " version %04x\n", 1.1083 + identifier.bus, identifier.vendor, identifier.product, identifier.version); 1.1084 + ALOGV(" name: \"%s\"\n", identifier.name.string()); 1.1085 + ALOGV(" location: \"%s\"\n", identifier.location.string()); 1.1086 + ALOGV(" unique id: \"%s\"\n", identifier.uniqueId.string()); 1.1087 + ALOGV(" descriptor: \"%s\"\n", identifier.descriptor.string()); 1.1088 + ALOGV(" driver: v%d.%d.%d\n", 1.1089 + driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff); 1.1090 + 1.1091 + // Load the configuration file for the device. 1.1092 + loadConfigurationLocked(device); 1.1093 + 1.1094 + // Figure out the kinds of events the device reports. 1.1095 + ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device->keyBitmask)), device->keyBitmask); 1.1096 + ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(device->absBitmask)), device->absBitmask); 1.1097 + ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask); 1.1098 + ioctl(fd, EVIOCGBIT(EV_SW, sizeof(device->swBitmask)), device->swBitmask); 1.1099 + ioctl(fd, EVIOCGBIT(EV_LED, sizeof(device->ledBitmask)), device->ledBitmask); 1.1100 + ioctl(fd, EVIOCGBIT(EV_FF, sizeof(device->ffBitmask)), device->ffBitmask); 1.1101 + ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask); 1.1102 + 1.1103 + // See if this is a keyboard. Ignore everything in the button range except for 1.1104 + // joystick and gamepad buttons which are handled like keyboards for the most part. 1.1105 + bool haveKeyboardKeys = containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC)) 1.1106 + || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK), 1.1107 + sizeof_bit_array(KEY_MAX + 1)); 1.1108 + bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC), 1.1109 + sizeof_bit_array(BTN_MOUSE)) 1.1110 + || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_JOYSTICK), 1.1111 + sizeof_bit_array(BTN_DIGI)); 1.1112 + if (haveKeyboardKeys || haveGamepadButtons) { 1.1113 + device->classes |= INPUT_DEVICE_CLASS_KEYBOARD; 1.1114 + } 1.1115 + 1.1116 + // See if this is a cursor device such as a trackball or mouse. 1.1117 + if (test_bit(BTN_MOUSE, device->keyBitmask) 1.1118 + && test_bit(REL_X, device->relBitmask) 1.1119 + && test_bit(REL_Y, device->relBitmask)) { 1.1120 + device->classes |= INPUT_DEVICE_CLASS_CURSOR; 1.1121 + } 1.1122 + 1.1123 + // See if this is a touch pad. 1.1124 + // Is this a new modern multi-touch driver? 1.1125 + if (test_bit(ABS_MT_POSITION_X, device->absBitmask) 1.1126 + && test_bit(ABS_MT_POSITION_Y, device->absBitmask)) { 1.1127 + // Some joysticks such as the PS3 controller report axes that conflict 1.1128 + // with the ABS_MT range. Try to confirm that the device really is 1.1129 + // a touch screen. 1.1130 + if (test_bit(BTN_TOUCH, device->keyBitmask) || !haveGamepadButtons) { 1.1131 + device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT; 1.1132 + } 1.1133 + // Is this an old style single-touch driver? 1.1134 + } else if (test_bit(BTN_TOUCH, device->keyBitmask) 1.1135 + && test_bit(ABS_X, device->absBitmask) 1.1136 + && test_bit(ABS_Y, device->absBitmask)) { 1.1137 + device->classes |= INPUT_DEVICE_CLASS_TOUCH; 1.1138 + } 1.1139 + 1.1140 + // See if this device is a joystick. 1.1141 + // Assumes that joysticks always have gamepad buttons in order to distinguish them 1.1142 + // from other devices such as accelerometers that also have absolute axes. 1.1143 + if (haveGamepadButtons) { 1.1144 + uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK; 1.1145 + for (int i = 0; i <= ABS_MAX; i++) { 1.1146 + if (test_bit(i, device->absBitmask) 1.1147 + && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) { 1.1148 + device->classes = assumedClasses; 1.1149 + break; 1.1150 + } 1.1151 + } 1.1152 + } 1.1153 + 1.1154 + // Check whether this device has switches. 1.1155 + for (int i = 0; i <= SW_MAX; i++) { 1.1156 + if (test_bit(i, device->swBitmask)) { 1.1157 + device->classes |= INPUT_DEVICE_CLASS_SWITCH; 1.1158 + break; 1.1159 + } 1.1160 + } 1.1161 + 1.1162 + // Check whether this device supports the vibrator. 1.1163 + if (test_bit(FF_RUMBLE, device->ffBitmask)) { 1.1164 + device->classes |= INPUT_DEVICE_CLASS_VIBRATOR; 1.1165 + } 1.1166 + 1.1167 + // Configure virtual keys. 1.1168 + if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) { 1.1169 + // Load the virtual keys for the touch screen, if any. 1.1170 + // We do this now so that we can make sure to load the keymap if necessary. 1.1171 + status_t status = loadVirtualKeyMapLocked(device); 1.1172 + if (!status) { 1.1173 + device->classes |= INPUT_DEVICE_CLASS_KEYBOARD; 1.1174 + } 1.1175 + } 1.1176 + 1.1177 + // Load the key map. 1.1178 + // We need to do this for joysticks too because the key layout may specify axes. 1.1179 + status_t keyMapStatus = NAME_NOT_FOUND; 1.1180 + if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) { 1.1181 + // Load the keymap for the device. 1.1182 + keyMapStatus = loadKeyMapLocked(device); 1.1183 + } 1.1184 + 1.1185 + // Configure the keyboard, gamepad or virtual keyboard. 1.1186 + if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) { 1.1187 + // Register the keyboard as a built-in keyboard if it is eligible. 1.1188 + if (!keyMapStatus 1.1189 + && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD 1.1190 + && isEligibleBuiltInKeyboard(device->identifier, 1.1191 + device->configuration, &device->keyMap)) { 1.1192 + mBuiltInKeyboardId = device->id; 1.1193 + } 1.1194 + 1.1195 + // 'Q' key support = cheap test of whether this is an alpha-capable kbd 1.1196 + if (hasKeycodeLocked(device, AKEYCODE_Q)) { 1.1197 + device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; 1.1198 + } 1.1199 + 1.1200 + // See if this device has a DPAD. 1.1201 + if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) && 1.1202 + hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) && 1.1203 + hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) && 1.1204 + hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) && 1.1205 + hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) { 1.1206 + device->classes |= INPUT_DEVICE_CLASS_DPAD; 1.1207 + } 1.1208 + 1.1209 + // See if this device has a gamepad. 1.1210 + for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) { 1.1211 + if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) { 1.1212 + device->classes |= INPUT_DEVICE_CLASS_GAMEPAD; 1.1213 + break; 1.1214 + } 1.1215 + } 1.1216 + 1.1217 + // Disable kernel key repeat since we handle it ourselves 1.1218 + unsigned int repeatRate[] = {0,0}; 1.1219 + if (ioctl(fd, EVIOCSREP, repeatRate)) { 1.1220 + ALOGW("Unable to disable kernel key repeat for %s: %s", devicePath, strerror(errno)); 1.1221 + } 1.1222 + } 1.1223 + 1.1224 + // If the device isn't recognized as something we handle, don't monitor it. 1.1225 + if (device->classes == 0) { 1.1226 + ALOGV("Dropping device: id=%d, path='%s', name='%s'", 1.1227 + deviceId, devicePath, device->identifier.name.string()); 1.1228 + delete device; 1.1229 + return -1; 1.1230 + } 1.1231 + 1.1232 + // Determine whether the device is external or internal. 1.1233 + if (isExternalDeviceLocked(device)) { 1.1234 + device->classes |= INPUT_DEVICE_CLASS_EXTERNAL; 1.1235 + } 1.1236 + 1.1237 + // Register with epoll. 1.1238 + struct epoll_event eventItem; 1.1239 + memset(&eventItem, 0, sizeof(eventItem)); 1.1240 + eventItem.events = EPOLLIN; 1.1241 + eventItem.data.u32 = deviceId; 1.1242 + if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) { 1.1243 + ALOGE("Could not add device fd to epoll instance. errno=%d", errno); 1.1244 + delete device; 1.1245 + return -1; 1.1246 + } 1.1247 + 1.1248 + // Enable wake-lock behavior on kernels that support it. 1.1249 + // TODO: Only need this for devices that can really wake the system. 1.1250 + bool usingSuspendBlockIoctl = !ioctl(fd, EVIOCSSUSPENDBLOCK, 1); 1.1251 + 1.1252 + // Tell the kernel that we want to use the monotonic clock for reporting timestamps 1.1253 + // associated with input events. This is important because the input system 1.1254 + // uses the timestamps extensively and assumes they were recorded using the monotonic 1.1255 + // clock. 1.1256 + // 1.1257 + // In older kernel, before Linux 3.4, there was no way to tell the kernel which 1.1258 + // clock to use to input event timestamps. The standard kernel behavior was to 1.1259 + // record a real time timestamp, which isn't what we want. Android kernels therefore 1.1260 + // contained a patch to the evdev_event() function in drivers/input/evdev.c to 1.1261 + // replace the call to do_gettimeofday() with ktime_get_ts() to cause the monotonic 1.1262 + // clock to be used instead of the real time clock. 1.1263 + // 1.1264 + // As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock. 1.1265 + // Therefore, we no longer require the Android-specific kernel patch described above 1.1266 + // as long as we make sure to set select the monotonic clock. We do that here. 1.1267 + int clockId = CLOCK_MONOTONIC; 1.1268 + bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId); 1.1269 + 1.1270 + ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, " 1.1271 + "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, " 1.1272 + "usingSuspendBlockIoctl=%s, usingClockIoctl=%s", 1.1273 + deviceId, fd, devicePath, device->identifier.name.string(), 1.1274 + device->classes, 1.1275 + device->configurationFile.string(), 1.1276 + device->keyMap.keyLayoutFile.string(), 1.1277 + device->keyMap.keyCharacterMapFile.string(), 1.1278 + toString(mBuiltInKeyboardId == deviceId), 1.1279 + toString(usingSuspendBlockIoctl), toString(usingClockIoctl)); 1.1280 + 1.1281 + addDeviceLocked(device); 1.1282 + return 0; 1.1283 +} 1.1284 + 1.1285 +void EventHub::createVirtualKeyboardLocked() { 1.1286 + InputDeviceIdentifier identifier; 1.1287 + identifier.name = "Virtual"; 1.1288 + identifier.uniqueId = "<virtual>"; 1.1289 + setDescriptor(identifier); 1.1290 + 1.1291 + Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier); 1.1292 + device->classes = INPUT_DEVICE_CLASS_KEYBOARD 1.1293 + | INPUT_DEVICE_CLASS_ALPHAKEY 1.1294 + | INPUT_DEVICE_CLASS_DPAD 1.1295 + | INPUT_DEVICE_CLASS_VIRTUAL; 1.1296 + loadKeyMapLocked(device); 1.1297 + addDeviceLocked(device); 1.1298 +} 1.1299 + 1.1300 +void EventHub::addDeviceLocked(Device* device) { 1.1301 + mDevices.add(device->id, device); 1.1302 + device->next = mOpeningDevices; 1.1303 + mOpeningDevices = device; 1.1304 +} 1.1305 + 1.1306 +void EventHub::loadConfigurationLocked(Device* device) { 1.1307 + device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier( 1.1308 + device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION); 1.1309 + if (device->configurationFile.isEmpty()) { 1.1310 + ALOGD("No input device configuration file found for device '%s'.", 1.1311 + device->identifier.name.string()); 1.1312 + } else { 1.1313 + status_t status = PropertyMap::load(device->configurationFile, 1.1314 + &device->configuration); 1.1315 + if (status) { 1.1316 + ALOGE("Error loading input device configuration file for device '%s'. " 1.1317 + "Using default configuration.", 1.1318 + device->identifier.name.string()); 1.1319 + } 1.1320 + } 1.1321 +} 1.1322 + 1.1323 +status_t EventHub::loadVirtualKeyMapLocked(Device* device) { 1.1324 + // The virtual key map is supplied by the kernel as a system board property file. 1.1325 + String8 path; 1.1326 + path.append("/sys/board_properties/virtualkeys."); 1.1327 + path.append(device->identifier.name); 1.1328 + if (access(path.string(), R_OK)) { 1.1329 + return NAME_NOT_FOUND; 1.1330 + } 1.1331 + return VirtualKeyMap::load(path, &device->virtualKeyMap); 1.1332 +} 1.1333 + 1.1334 +status_t EventHub::loadKeyMapLocked(Device* device) { 1.1335 + return device->keyMap.load(device->identifier, device->configuration); 1.1336 +} 1.1337 + 1.1338 +bool EventHub::isExternalDeviceLocked(Device* device) { 1.1339 + if (device->configuration) { 1.1340 + bool value; 1.1341 + if (device->configuration->tryGetProperty(String8("device.internal"), value)) { 1.1342 + return !value; 1.1343 + } 1.1344 + } 1.1345 + return device->identifier.bus == BUS_USB || device->identifier.bus == BUS_BLUETOOTH; 1.1346 +} 1.1347 + 1.1348 +bool EventHub::hasKeycodeLocked(Device* device, int keycode) const { 1.1349 + if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) { 1.1350 + return false; 1.1351 + } 1.1352 + 1.1353 + Vector<int32_t> scanCodes; 1.1354 + device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes); 1.1355 + const size_t N = scanCodes.size(); 1.1356 + for (size_t i=0; i<N && i<=KEY_MAX; i++) { 1.1357 + int32_t sc = scanCodes.itemAt(i); 1.1358 + if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) { 1.1359 + return true; 1.1360 + } 1.1361 + } 1.1362 + 1.1363 + return false; 1.1364 +} 1.1365 + 1.1366 +status_t EventHub::closeDeviceByPathLocked(const char *devicePath) { 1.1367 + Device* device = getDeviceByPathLocked(devicePath); 1.1368 + if (device) { 1.1369 + closeDeviceLocked(device); 1.1370 + return 0; 1.1371 + } 1.1372 + ALOGV("Remove device: %s not found, device may already have been removed.", devicePath); 1.1373 + return -1; 1.1374 +} 1.1375 + 1.1376 +void EventHub::closeAllDevicesLocked() { 1.1377 + while (mDevices.size() > 0) { 1.1378 + closeDeviceLocked(mDevices.valueAt(mDevices.size() - 1)); 1.1379 + } 1.1380 +} 1.1381 + 1.1382 +void EventHub::closeDeviceLocked(Device* device) { 1.1383 + ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n", 1.1384 + device->path.string(), device->identifier.name.string(), device->id, 1.1385 + device->fd, device->classes); 1.1386 + 1.1387 + if (device->id == mBuiltInKeyboardId) { 1.1388 + ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this", 1.1389 + device->path.string(), mBuiltInKeyboardId); 1.1390 + mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD; 1.1391 + } 1.1392 + 1.1393 + if (!device->isVirtual()) { 1.1394 + if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) { 1.1395 + ALOGW("Could not remove device fd from epoll instance. errno=%d", errno); 1.1396 + } 1.1397 + } 1.1398 + 1.1399 + mDevices.removeItem(device->id); 1.1400 + device->close(); 1.1401 + 1.1402 + // Unlink for opening devices list if it is present. 1.1403 + Device* pred = NULL; 1.1404 + bool found = false; 1.1405 + for (Device* entry = mOpeningDevices; entry != NULL; ) { 1.1406 + if (entry == device) { 1.1407 + found = true; 1.1408 + break; 1.1409 + } 1.1410 + pred = entry; 1.1411 + entry = entry->next; 1.1412 + } 1.1413 + if (found) { 1.1414 + // Unlink the device from the opening devices list then delete it. 1.1415 + // We don't need to tell the client that the device was closed because 1.1416 + // it does not even know it was opened in the first place. 1.1417 + ALOGI("Device %s was immediately closed after opening.", device->path.string()); 1.1418 + if (pred) { 1.1419 + pred->next = device->next; 1.1420 + } else { 1.1421 + mOpeningDevices = device->next; 1.1422 + } 1.1423 + delete device; 1.1424 + } else { 1.1425 + // Link into closing devices list. 1.1426 + // The device will be deleted later after we have informed the client. 1.1427 + device->next = mClosingDevices; 1.1428 + mClosingDevices = device; 1.1429 + } 1.1430 +} 1.1431 + 1.1432 +status_t EventHub::readNotifyLocked() { 1.1433 + int res; 1.1434 + char devname[PATH_MAX]; 1.1435 + char *filename; 1.1436 + char event_buf[512]; 1.1437 + int event_size; 1.1438 + int event_pos = 0; 1.1439 + struct inotify_event *event; 1.1440 + 1.1441 + ALOGV("EventHub::readNotify nfd: %d\n", mINotifyFd); 1.1442 + res = read(mINotifyFd, event_buf, sizeof(event_buf)); 1.1443 + if(res < (int)sizeof(*event)) { 1.1444 + if(errno == EINTR) 1.1445 + return 0; 1.1446 + ALOGW("could not get event, %s\n", strerror(errno)); 1.1447 + return -1; 1.1448 + } 1.1449 + //printf("got %d bytes of event information\n", res); 1.1450 + 1.1451 + strcpy(devname, DEVICE_PATH); 1.1452 + filename = devname + strlen(devname); 1.1453 + *filename++ = '/'; 1.1454 + 1.1455 + while(res >= (int)sizeof(*event)) { 1.1456 + event = (struct inotify_event *)(event_buf + event_pos); 1.1457 + //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); 1.1458 + if(event->len) { 1.1459 + strcpy(filename, event->name); 1.1460 + if(event->mask & IN_CREATE) { 1.1461 + openDeviceLocked(devname); 1.1462 + } else { 1.1463 + ALOGI("Removing device '%s' due to inotify event\n", devname); 1.1464 + closeDeviceByPathLocked(devname); 1.1465 + } 1.1466 + } 1.1467 + event_size = sizeof(*event) + event->len; 1.1468 + res -= event_size; 1.1469 + event_pos += event_size; 1.1470 + } 1.1471 + return 0; 1.1472 +} 1.1473 + 1.1474 +status_t EventHub::scanDirLocked(const char *dirname) 1.1475 +{ 1.1476 + char devname[PATH_MAX]; 1.1477 + char *filename; 1.1478 + DIR *dir; 1.1479 + struct dirent *de; 1.1480 + dir = opendir(dirname); 1.1481 + if(dir == NULL) 1.1482 + return -1; 1.1483 + strcpy(devname, dirname); 1.1484 + filename = devname + strlen(devname); 1.1485 + *filename++ = '/'; 1.1486 + while((de = readdir(dir))) { 1.1487 + if(de->d_name[0] == '.' && 1.1488 + (de->d_name[1] == '\0' || 1.1489 + (de->d_name[1] == '.' && de->d_name[2] == '\0'))) 1.1490 + continue; 1.1491 + strcpy(filename, de->d_name); 1.1492 + openDeviceLocked(devname); 1.1493 + } 1.1494 + closedir(dir); 1.1495 + return 0; 1.1496 +} 1.1497 + 1.1498 +void EventHub::requestReopenDevices() { 1.1499 + ALOGV("requestReopenDevices() called"); 1.1500 + 1.1501 + AutoMutex _l(mLock); 1.1502 + mNeedToReopenDevices = true; 1.1503 +} 1.1504 + 1.1505 +void EventHub::dump(String8& dump) { 1.1506 + dump.append("Event Hub State:\n"); 1.1507 + 1.1508 + { // acquire lock 1.1509 + AutoMutex _l(mLock); 1.1510 + 1.1511 + dump.appendFormat(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId); 1.1512 + 1.1513 + dump.append(INDENT "Devices:\n"); 1.1514 + 1.1515 + for (size_t i = 0; i < mDevices.size(); i++) { 1.1516 + const Device* device = mDevices.valueAt(i); 1.1517 + if (mBuiltInKeyboardId == device->id) { 1.1518 + dump.appendFormat(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n", 1.1519 + device->id, device->identifier.name.string()); 1.1520 + } else { 1.1521 + dump.appendFormat(INDENT2 "%d: %s\n", device->id, 1.1522 + device->identifier.name.string()); 1.1523 + } 1.1524 + dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes); 1.1525 + dump.appendFormat(INDENT3 "Path: %s\n", device->path.string()); 1.1526 + dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string()); 1.1527 + dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string()); 1.1528 + dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string()); 1.1529 + dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, " 1.1530 + "product=0x%04x, version=0x%04x\n", 1.1531 + device->identifier.bus, device->identifier.vendor, 1.1532 + device->identifier.product, device->identifier.version); 1.1533 + dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n", 1.1534 + device->keyMap.keyLayoutFile.string()); 1.1535 + dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n", 1.1536 + device->keyMap.keyCharacterMapFile.string()); 1.1537 + dump.appendFormat(INDENT3 "ConfigurationFile: %s\n", 1.1538 + device->configurationFile.string()); 1.1539 + dump.appendFormat(INDENT3 "HaveKeyboardLayoutOverlay: %s\n", 1.1540 + toString(device->overlayKeyMap != NULL)); 1.1541 + } 1.1542 + } // release lock 1.1543 +} 1.1544 + 1.1545 +void EventHub::monitor() { 1.1546 + // Acquire and release the lock to ensure that the event hub has not deadlocked. 1.1547 + mLock.lock(); 1.1548 + mLock.unlock(); 1.1549 +} 1.1550 + 1.1551 + 1.1552 +}; // namespace android