1 // 2 // Copyright 2010 The Android Open Source Project 3 // 4 // The input reader. 5 // 6 #define LOG_TAG "InputReader" 7 8 //#define LOG_NDEBUG 0 9 10 // Log debug messages for each raw event received from the EventHub. 11 #define DEBUG_RAW_EVENTS 0 12 13 // Log debug messages about touch screen filtering hacks. 14 #define DEBUG_HACKS 0 15 16 // Log debug messages about virtual key processing. 17 #define DEBUG_VIRTUAL_KEYS 0 18 19 // Log debug messages about pointers. 20 #define DEBUG_POINTERS 0 21 22 // Log debug messages about pointer assignment calculations. 23 #define DEBUG_POINTER_ASSIGNMENT 0 24 25 #include <cutils/log.h> 26 #include <ui/InputReader.h> 27 28 #include <stddef.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <errno.h> 32 #include <limits.h> 33 #include <math.h> 34 35 #define INDENT " " 36 #define INDENT2 " " 37 #define INDENT3 " " 38 #define INDENT4 " " 39 40 namespace android { 41 42 // --- Static Functions --- 43 44 template<typename T> 45 inline static T abs(const T& value) { 46 return value < 0 ? - value : value; 47 } 48 49 template<typename T> 50 inline static T min(const T& a, const T& b) { 51 return a < b ? a : b; 52 } 53 54 template<typename T> 55 inline static void swap(T& a, T& b) { 56 T temp = a; 57 a = b; 58 b = temp; 59 } 60 61 inline static float avg(float x, float y) { 62 return (x + y) / 2; 63 } 64 65 inline static float pythag(float x, float y) { 66 return sqrtf(x * x + y * y); 67 } 68 69 static inline const char* toString(bool value) { 70 return value ? "true" : "false"; 71 } 72 73 74 int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) { 75 int32_t mask; 76 switch (keyCode) { 77 case AKEYCODE_ALT_LEFT: 78 mask = AMETA_ALT_LEFT_ON; 79 break; 80 case AKEYCODE_ALT_RIGHT: 81 mask = AMETA_ALT_RIGHT_ON; 82 break; 83 case AKEYCODE_SHIFT_LEFT: 84 mask = AMETA_SHIFT_LEFT_ON; 85 break; 86 case AKEYCODE_SHIFT_RIGHT: 87 mask = AMETA_SHIFT_RIGHT_ON; 88 break; 89 case AKEYCODE_SYM: 90 mask = AMETA_SYM_ON; 91 break; 92 default: 93 return oldMetaState; 94 } 95 96 int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask 97 & ~ (AMETA_ALT_ON | AMETA_SHIFT_ON); 98 99 if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { 100 newMetaState |= AMETA_ALT_ON; 101 } 102 103 if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) { 104 newMetaState |= AMETA_SHIFT_ON; 105 } 106 107 return newMetaState; 108 } 109 110 static const int32_t keyCodeRotationMap[][4] = { 111 // key codes enumerated counter-clockwise with the original (unrotated) key first 112 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation 113 { AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT }, 114 { AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN }, 115 { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT }, 116 { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP }, 117 }; 118 static const int keyCodeRotationMapSize = 119 sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]); 120 121 int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) { 122 if (orientation != InputReaderPolicyInterface::ROTATION_0) { 123 for (int i = 0; i < keyCodeRotationMapSize; i++) { 124 if (keyCode == keyCodeRotationMap[i][0]) { 125 return keyCodeRotationMap[i][orientation]; 126 } 127 } 128 } 129 return keyCode; 130 } 131 132 static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) { 133 return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0; 134 } 135 136 137 // --- InputDeviceCalibration --- 138 139 InputDeviceCalibration::InputDeviceCalibration() { 140 } 141 142 void InputDeviceCalibration::clear() { 143 mProperties.clear(); 144 } 145 146 void InputDeviceCalibration::addProperty(const String8& key, const String8& value) { 147 mProperties.add(key, value); 148 } 149 150 bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const { 151 ssize_t index = mProperties.indexOfKey(key); 152 if (index < 0) { 153 return false; 154 } 155 156 outValue = mProperties.valueAt(index); 157 return true; 158 } 159 160 bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const { 161 String8 stringValue; 162 if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { 163 return false; 164 } 165 166 char* end; 167 int value = strtol(stringValue.string(), & end, 10); 168 if (*end != '\0') { 169 LOGW("Input device calibration key '%s' has invalid value '%s'. Expected an integer.", 170 key.string(), stringValue.string()); 171 return false; 172 } 173 outValue = value; 174 return true; 175 } 176 177 bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const { 178 String8 stringValue; 179 if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) { 180 return false; 181 } 182 183 char* end; 184 float value = strtof(stringValue.string(), & end); 185 if (*end != '\0') { 186 LOGW("Input device calibration key '%s' has invalid value '%s'. Expected a float.", 187 key.string(), stringValue.string()); 188 return false; 189 } 190 outValue = value; 191 return true; 192 } 193 194 195 // --- InputReader --- 196 197 InputReader::InputReader(const sp<EventHubInterface>& eventHub, 198 const sp<InputReaderPolicyInterface>& policy, 199 const sp<InputDispatcherInterface>& dispatcher) : 200 mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher), 201 mGlobalMetaState(0) { 202 configureExcludedDevices(); 203 updateGlobalMetaState(); 204 updateInputConfiguration(); 205 } 206 207 InputReader::~InputReader() { 208 for (size_t i = 0; i < mDevices.size(); i++) { 209 delete mDevices.valueAt(i); 210 } 211 } 212 213 void InputReader::loopOnce() { 214 RawEvent rawEvent; 215 mEventHub->getEvent(& rawEvent); 216 217 #if DEBUG_RAW_EVENTS 218 LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d", 219 rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode, 220 rawEvent.value); 221 #endif 222 223 process(& rawEvent); 224 } 225 226 void InputReader::process(const RawEvent* rawEvent) { 227 switch (rawEvent->type) { 228 case EventHubInterface::DEVICE_ADDED: 229 addDevice(rawEvent->deviceId); 230 break; 231 232 case EventHubInterface::DEVICE_REMOVED: 233 removeDevice(rawEvent->deviceId); 234 break; 235 236 case EventHubInterface::FINISHED_DEVICE_SCAN: 237 handleConfigurationChanged(rawEvent->when); 238 break; 239 240 default: 241 consumeEvent(rawEvent); 242 break; 243 } 244 } 245 246 void InputReader::addDevice(int32_t deviceId) { 247 String8 name = mEventHub->getDeviceName(deviceId); 248 uint32_t classes = mEventHub->getDeviceClasses(deviceId); 249 250 InputDevice* device = createDevice(deviceId, name, classes); 251 device->configure(); 252 253 if (device->isIgnored()) { 254 LOGI("Device added: id=0x%x, name=%s (ignored non-input device)", deviceId, name.string()); 255 } else { 256 LOGI("Device added: id=0x%x, name=%s, sources=%08x", deviceId, name.string(), 257 device->getSources()); 258 } 259 260 bool added = false; 261 { // acquire device registry writer lock 262 RWLock::AutoWLock _wl(mDeviceRegistryLock); 263 264 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 265 if (deviceIndex < 0) { 266 mDevices.add(deviceId, device); 267 added = true; 268 } 269 } // release device registry writer lock 270 271 if (! added) { 272 LOGW("Ignoring spurious device added event for deviceId %d.", deviceId); 273 delete device; 274 return; 275 } 276 } 277 278 void InputReader::removeDevice(int32_t deviceId) { 279 bool removed = false; 280 InputDevice* device = NULL; 281 { // acquire device registry writer lock 282 RWLock::AutoWLock _wl(mDeviceRegistryLock); 283 284 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 285 if (deviceIndex >= 0) { 286 device = mDevices.valueAt(deviceIndex); 287 mDevices.removeItemsAt(deviceIndex, 1); 288 removed = true; 289 } 290 } // release device registry writer lock 291 292 if (! removed) { 293 LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId); 294 return; 295 } 296 297 if (device->isIgnored()) { 298 LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)", 299 device->getId(), device->getName().string()); 300 } else { 301 LOGI("Device removed: id=0x%x, name=%s, sources=%08x", 302 device->getId(), device->getName().string(), device->getSources()); 303 } 304 305 device->reset(); 306 307 delete device; 308 } 309 310 InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) { 311 InputDevice* device = new InputDevice(this, deviceId, name); 312 313 const int32_t associatedDisplayId = 0; // FIXME: hardcoded for current single-display devices 314 315 // Switch-like devices. 316 if (classes & INPUT_DEVICE_CLASS_SWITCH) { 317 device->addMapper(new SwitchInputMapper(device)); 318 } 319 320 // Keyboard-like devices. 321 uint32_t keyboardSources = 0; 322 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC; 323 if (classes & INPUT_DEVICE_CLASS_KEYBOARD) { 324 keyboardSources |= AINPUT_SOURCE_KEYBOARD; 325 } 326 if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) { 327 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC; 328 } 329 if (classes & INPUT_DEVICE_CLASS_DPAD) { 330 keyboardSources |= AINPUT_SOURCE_DPAD; 331 } 332 333 if (keyboardSources != 0) { 334 device->addMapper(new KeyboardInputMapper(device, 335 associatedDisplayId, keyboardSources, keyboardType)); 336 } 337 338 // Trackball-like devices. 339 if (classes & INPUT_DEVICE_CLASS_TRACKBALL) { 340 device->addMapper(new TrackballInputMapper(device, associatedDisplayId)); 341 } 342 343 // Touchscreen-like devices. 344 if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT) { 345 device->addMapper(new MultiTouchInputMapper(device, associatedDisplayId)); 346 } else if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN) { 347 device->addMapper(new SingleTouchInputMapper(device, associatedDisplayId)); 348 } 349 350 return device; 351 } 352 353 void InputReader::consumeEvent(const RawEvent* rawEvent) { 354 int32_t deviceId = rawEvent->deviceId; 355 356 { // acquire device registry reader lock 357 RWLock::AutoRLock _rl(mDeviceRegistryLock); 358 359 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 360 if (deviceIndex < 0) { 361 LOGW("Discarding event for unknown deviceId %d.", deviceId); 362 return; 363 } 364 365 InputDevice* device = mDevices.valueAt(deviceIndex); 366 if (device->isIgnored()) { 367 //LOGD("Discarding event for ignored deviceId %d.", deviceId); 368 return; 369 } 370 371 device->process(rawEvent); 372 } // release device registry reader lock 373 } 374 375 void InputReader::handleConfigurationChanged(nsecs_t when) { 376 // Reset global meta state because it depends on the list of all configured devices. 377 updateGlobalMetaState(); 378 379 // Update input configuration. 380 updateInputConfiguration(); 381 382 // Enqueue configuration changed. 383 mDispatcher->notifyConfigurationChanged(when); 384 } 385 386 void InputReader::configureExcludedDevices() { 387 Vector<String8> excludedDeviceNames; 388 mPolicy->getExcludedDeviceNames(excludedDeviceNames); 389 390 for (size_t i = 0; i < excludedDeviceNames.size(); i++) { 391 mEventHub->addExcludedDevice(excludedDeviceNames[i]); 392 } 393 } 394 395 void InputReader::updateGlobalMetaState() { 396 { // acquire state lock 397 AutoMutex _l(mStateLock); 398 399 mGlobalMetaState = 0; 400 401 { // acquire device registry reader lock 402 RWLock::AutoRLock _rl(mDeviceRegistryLock); 403 404 for (size_t i = 0; i < mDevices.size(); i++) { 405 InputDevice* device = mDevices.valueAt(i); 406 mGlobalMetaState |= device->getMetaState(); 407 } 408 } // release device registry reader lock 409 } // release state lock 410 } 411 412 int32_t InputReader::getGlobalMetaState() { 413 { // acquire state lock 414 AutoMutex _l(mStateLock); 415 416 return mGlobalMetaState; 417 } // release state lock 418 } 419 420 void InputReader::updateInputConfiguration() { 421 { // acquire state lock 422 AutoMutex _l(mStateLock); 423 424 int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH; 425 int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS; 426 int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV; 427 { // acquire device registry reader lock 428 RWLock::AutoRLock _rl(mDeviceRegistryLock); 429 430 InputDeviceInfo deviceInfo; 431 for (size_t i = 0; i < mDevices.size(); i++) { 432 InputDevice* device = mDevices.valueAt(i); 433 device->getDeviceInfo(& deviceInfo); 434 uint32_t sources = deviceInfo.getSources(); 435 436 if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) { 437 touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER; 438 } 439 if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) { 440 navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL; 441 } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) { 442 navigationConfig = InputConfiguration::NAVIGATION_DPAD; 443 } 444 if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) { 445 keyboardConfig = InputConfiguration::KEYBOARD_QWERTY; 446 } 447 } 448 } // release device registry reader lock 449 450 mInputConfiguration.touchScreen = touchScreenConfig; 451 mInputConfiguration.keyboard = keyboardConfig; 452 mInputConfiguration.navigation = navigationConfig; 453 } // release state lock 454 } 455 456 void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) { 457 { // acquire state lock 458 AutoMutex _l(mStateLock); 459 460 *outConfiguration = mInputConfiguration; 461 } // release state lock 462 } 463 464 status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) { 465 { // acquire device registry reader lock 466 RWLock::AutoRLock _rl(mDeviceRegistryLock); 467 468 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 469 if (deviceIndex < 0) { 470 return NAME_NOT_FOUND; 471 } 472 473 InputDevice* device = mDevices.valueAt(deviceIndex); 474 if (device->isIgnored()) { 475 return NAME_NOT_FOUND; 476 } 477 478 device->getDeviceInfo(outDeviceInfo); 479 return OK; 480 } // release device registy reader lock 481 } 482 483 void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) { 484 outDeviceIds.clear(); 485 486 { // acquire device registry reader lock 487 RWLock::AutoRLock _rl(mDeviceRegistryLock); 488 489 size_t numDevices = mDevices.size(); 490 for (size_t i = 0; i < numDevices; i++) { 491 InputDevice* device = mDevices.valueAt(i); 492 if (! device->isIgnored()) { 493 outDeviceIds.add(device->getId()); 494 } 495 } 496 } // release device registy reader lock 497 } 498 499 int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, 500 int32_t keyCode) { 501 return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState); 502 } 503 504 int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, 505 int32_t scanCode) { 506 return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState); 507 } 508 509 int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) { 510 return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState); 511 } 512 513 int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code, 514 GetStateFunc getStateFunc) { 515 { // acquire device registry reader lock 516 RWLock::AutoRLock _rl(mDeviceRegistryLock); 517 518 int32_t result = AKEY_STATE_UNKNOWN; 519 if (deviceId >= 0) { 520 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 521 if (deviceIndex >= 0) { 522 InputDevice* device = mDevices.valueAt(deviceIndex); 523 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 524 result = (device->*getStateFunc)(sourceMask, code); 525 } 526 } 527 } else { 528 size_t numDevices = mDevices.size(); 529 for (size_t i = 0; i < numDevices; i++) { 530 InputDevice* device = mDevices.valueAt(i); 531 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 532 result = (device->*getStateFunc)(sourceMask, code); 533 if (result >= AKEY_STATE_DOWN) { 534 return result; 535 } 536 } 537 } 538 } 539 return result; 540 } // release device registy reader lock 541 } 542 543 bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, 544 size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) { 545 memset(outFlags, 0, numCodes); 546 return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags); 547 } 548 549 bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes, 550 const int32_t* keyCodes, uint8_t* outFlags) { 551 { // acquire device registry reader lock 552 RWLock::AutoRLock _rl(mDeviceRegistryLock); 553 bool result = false; 554 if (deviceId >= 0) { 555 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 556 if (deviceIndex >= 0) { 557 InputDevice* device = mDevices.valueAt(deviceIndex); 558 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 559 result = device->markSupportedKeyCodes(sourceMask, 560 numCodes, keyCodes, outFlags); 561 } 562 } 563 } else { 564 size_t numDevices = mDevices.size(); 565 for (size_t i = 0; i < numDevices; i++) { 566 InputDevice* device = mDevices.valueAt(i); 567 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 568 result |= device->markSupportedKeyCodes(sourceMask, 569 numCodes, keyCodes, outFlags); 570 } 571 } 572 } 573 return result; 574 } // release device registy reader lock 575 } 576 577 void InputReader::dump(String8& dump) { 578 mEventHub->dump(dump); 579 dump.append("\n"); 580 581 dump.append("Input Reader State:\n"); 582 583 { // acquire device registry reader lock 584 RWLock::AutoRLock _rl(mDeviceRegistryLock); 585 586 for (size_t i = 0; i < mDevices.size(); i++) { 587 mDevices.valueAt(i)->dump(dump); 588 } 589 } // release device registy reader lock 590 } 591 592 593 // --- InputReaderThread --- 594 595 InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) : 596 Thread(/*canCallJava*/ true), mReader(reader) { 597 } 598 599 InputReaderThread::~InputReaderThread() { 600 } 601 602 bool InputReaderThread::threadLoop() { 603 mReader->loopOnce(); 604 return true; 605 } 606 607 608 // --- InputDevice --- 609 610 InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) : 611 mContext(context), mId(id), mName(name), mSources(0) { 612 } 613 614 InputDevice::~InputDevice() { 615 size_t numMappers = mMappers.size(); 616 for (size_t i = 0; i < numMappers; i++) { 617 delete mMappers[i]; 618 } 619 mMappers.clear(); 620 } 621 622 static void dumpMotionRange(String8& dump, const InputDeviceInfo& deviceInfo, 623 int32_t rangeType, const char* name) { 624 const InputDeviceInfo::MotionRange* range = deviceInfo.getMotionRange(rangeType); 625 if (range) { 626 dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n", 627 name, range->min, range->max, range->flat, range->fuzz); 628 } 629 } 630 631 void InputDevice::dump(String8& dump) { 632 InputDeviceInfo deviceInfo; 633 getDeviceInfo(& deviceInfo); 634 635 dump.appendFormat(INDENT "Device 0x%x: %s\n", deviceInfo.getId(), 636 deviceInfo.getName().string()); 637 dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); 638 dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType()); 639 if (!deviceInfo.getMotionRanges().isEmpty()) { 640 dump.append(INDENT2 "Motion Ranges:\n"); 641 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_X, "X"); 642 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_Y, "Y"); 643 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_PRESSURE, "Pressure"); 644 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_SIZE, "Size"); 645 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MAJOR, "TouchMajor"); 646 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MINOR, "TouchMinor"); 647 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MAJOR, "ToolMajor"); 648 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MINOR, "ToolMinor"); 649 dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_ORIENTATION, "Orientation"); 650 } 651 652 size_t numMappers = mMappers.size(); 653 for (size_t i = 0; i < numMappers; i++) { 654 InputMapper* mapper = mMappers[i]; 655 mapper->dump(dump); 656 } 657 } 658 659 void InputDevice::addMapper(InputMapper* mapper) { 660 mMappers.add(mapper); 661 } 662 663 void InputDevice::configure() { 664 if (! isIgnored()) { 665 mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration); 666 } 667 668 mSources = 0; 669 670 size_t numMappers = mMappers.size(); 671 for (size_t i = 0; i < numMappers; i++) { 672 InputMapper* mapper = mMappers[i]; 673 mapper->configure(); 674 mSources |= mapper->getSources(); 675 } 676 } 677 678 void InputDevice::reset() { 679 size_t numMappers = mMappers.size(); 680 for (size_t i = 0; i < numMappers; i++) { 681 InputMapper* mapper = mMappers[i]; 682 mapper->reset(); 683 } 684 } 685 686 void InputDevice::process(const RawEvent* rawEvent) { 687 size_t numMappers = mMappers.size(); 688 for (size_t i = 0; i < numMappers; i++) { 689 InputMapper* mapper = mMappers[i]; 690 mapper->process(rawEvent); 691 } 692 } 693 694 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { 695 outDeviceInfo->initialize(mId, mName); 696 697 size_t numMappers = mMappers.size(); 698 for (size_t i = 0; i < numMappers; i++) { 699 InputMapper* mapper = mMappers[i]; 700 mapper->populateDeviceInfo(outDeviceInfo); 701 } 702 } 703 704 int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 705 return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState); 706 } 707 708 int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 709 return getState(sourceMask, scanCode, & InputMapper::getScanCodeState); 710 } 711 712 int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 713 return getState(sourceMask, switchCode, & InputMapper::getSwitchState); 714 } 715 716 int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) { 717 int32_t result = AKEY_STATE_UNKNOWN; 718 size_t numMappers = mMappers.size(); 719 for (size_t i = 0; i < numMappers; i++) { 720 InputMapper* mapper = mMappers[i]; 721 if (sourcesMatchMask(mapper->getSources(), sourceMask)) { 722 result = (mapper->*getStateFunc)(sourceMask, code); 723 if (result >= AKEY_STATE_DOWN) { 724 return result; 725 } 726 } 727 } 728 return result; 729 } 730 731 bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 732 const int32_t* keyCodes, uint8_t* outFlags) { 733 bool result = false; 734 size_t numMappers = mMappers.size(); 735 for (size_t i = 0; i < numMappers; i++) { 736 InputMapper* mapper = mMappers[i]; 737 if (sourcesMatchMask(mapper->getSources(), sourceMask)) { 738 result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags); 739 } 740 } 741 return result; 742 } 743 744 int32_t InputDevice::getMetaState() { 745 int32_t result = 0; 746 size_t numMappers = mMappers.size(); 747 for (size_t i = 0; i < numMappers; i++) { 748 InputMapper* mapper = mMappers[i]; 749 result |= mapper->getMetaState(); 750 } 751 return result; 752 } 753 754 755 // --- InputMapper --- 756 757 InputMapper::InputMapper(InputDevice* device) : 758 mDevice(device), mContext(device->getContext()) { 759 } 760 761 InputMapper::~InputMapper() { 762 } 763 764 void InputMapper::populateDeviceInfo(InputDeviceInfo* info) { 765 info->addSource(getSources()); 766 } 767 768 void InputMapper::dump(String8& dump) { 769 } 770 771 void InputMapper::configure() { 772 } 773 774 void InputMapper::reset() { 775 } 776 777 int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 778 return AKEY_STATE_UNKNOWN; 779 } 780 781 int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 782 return AKEY_STATE_UNKNOWN; 783 } 784 785 int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 786 return AKEY_STATE_UNKNOWN; 787 } 788 789 bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 790 const int32_t* keyCodes, uint8_t* outFlags) { 791 return false; 792 } 793 794 int32_t InputMapper::getMetaState() { 795 return 0; 796 } 797 798 799 // --- SwitchInputMapper --- 800 801 SwitchInputMapper::SwitchInputMapper(InputDevice* device) : 802 InputMapper(device) { 803 } 804 805 SwitchInputMapper::~SwitchInputMapper() { 806 } 807 808 uint32_t SwitchInputMapper::getSources() { 809 return 0; 810 } 811 812 void SwitchInputMapper::process(const RawEvent* rawEvent) { 813 switch (rawEvent->type) { 814 case EV_SW: 815 processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value); 816 break; 817 } 818 } 819 820 void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) { 821 getDispatcher()->notifySwitch(when, switchCode, switchValue, 0); 822 } 823 824 int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 825 return getEventHub()->getSwitchState(getDeviceId(), switchCode); 826 } 827 828 829 // --- KeyboardInputMapper --- 830 831 KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, 832 uint32_t sources, int32_t keyboardType) : 833 InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources), 834 mKeyboardType(keyboardType) { 835 initializeLocked(); 836 } 837 838 KeyboardInputMapper::~KeyboardInputMapper() { 839 } 840 841 void KeyboardInputMapper::initializeLocked() { 842 mLocked.metaState = AMETA_NONE; 843 mLocked.downTime = 0; 844 } 845 846 uint32_t KeyboardInputMapper::getSources() { 847 return mSources; 848 } 849 850 void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 851 InputMapper::populateDeviceInfo(info); 852 853 info->setKeyboardType(mKeyboardType); 854 } 855 856 void KeyboardInputMapper::dump(String8& dump) { 857 { // acquire lock 858 AutoMutex _l(mLock); 859 dump.append(INDENT2 "Keyboard Input Mapper:\n"); 860 dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); 861 dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType); 862 dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size()); 863 dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState); 864 dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); 865 } // release lock 866 } 867 868 void KeyboardInputMapper::reset() { 869 for (;;) { 870 int32_t keyCode, scanCode; 871 { // acquire lock 872 AutoMutex _l(mLock); 873 874 // Synthesize key up event on reset if keys are currently down. 875 if (mLocked.keyDowns.isEmpty()) { 876 initializeLocked(); 877 break; // done 878 } 879 880 const KeyDown& keyDown = mLocked.keyDowns.top(); 881 keyCode = keyDown.keyCode; 882 scanCode = keyDown.scanCode; 883 } // release lock 884 885 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 886 processKey(when, false, keyCode, scanCode, 0); 887 } 888 889 InputMapper::reset(); 890 getContext()->updateGlobalMetaState(); 891 } 892 893 void KeyboardInputMapper::process(const RawEvent* rawEvent) { 894 switch (rawEvent->type) { 895 case EV_KEY: { 896 int32_t scanCode = rawEvent->scanCode; 897 if (isKeyboardOrGamepadKey(scanCode)) { 898 processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode, 899 rawEvent->flags); 900 } 901 break; 902 } 903 } 904 } 905 906 bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) { 907 return scanCode < BTN_MOUSE 908 || scanCode >= KEY_OK 909 || (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI); 910 } 911 912 void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, 913 int32_t scanCode, uint32_t policyFlags) { 914 int32_t newMetaState; 915 nsecs_t downTime; 916 bool metaStateChanged = false; 917 918 { // acquire lock 919 AutoMutex _l(mLock); 920 921 if (down) { 922 // Rotate key codes according to orientation if needed. 923 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 924 if (mAssociatedDisplayId >= 0) { 925 int32_t orientation; 926 if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) { 927 return; 928 } 929 930 keyCode = rotateKeyCode(keyCode, orientation); 931 } 932 933 // Add key down. 934 ssize_t keyDownIndex = findKeyDownLocked(scanCode); 935 if (keyDownIndex >= 0) { 936 // key repeat, be sure to use same keycode as before in case of rotation 937 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode; 938 } else { 939 // key down 940 mLocked.keyDowns.push(); 941 KeyDown& keyDown = mLocked.keyDowns.editTop(); 942 keyDown.keyCode = keyCode; 943 keyDown.scanCode = scanCode; 944 } 945 946 mLocked.downTime = when; 947 } else { 948 // Remove key down. 949 ssize_t keyDownIndex = findKeyDownLocked(scanCode); 950 if (keyDownIndex >= 0) { 951 // key up, be sure to use same keycode as before in case of rotation 952 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode; 953 mLocked.keyDowns.removeAt(size_t(keyDownIndex)); 954 } else { 955 // key was not actually down 956 LOGI("Dropping key up from device %s because the key was not down. " 957 "keyCode=%d, scanCode=%d", 958 getDeviceName().string(), keyCode, scanCode); 959 return; 960 } 961 } 962 963 int32_t oldMetaState = mLocked.metaState; 964 newMetaState = updateMetaState(keyCode, down, oldMetaState); 965 if (oldMetaState != newMetaState) { 966 mLocked.metaState = newMetaState; 967 metaStateChanged = true; 968 } 969 970 downTime = mLocked.downTime; 971 } // release lock 972 973 if (metaStateChanged) { 974 getContext()->updateGlobalMetaState(); 975 } 976 977 getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags, 978 down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, 979 AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime); 980 } 981 982 ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) { 983 size_t n = mLocked.keyDowns.size(); 984 for (size_t i = 0; i < n; i++) { 985 if (mLocked.keyDowns[i].scanCode == scanCode) { 986 return i; 987 } 988 } 989 return -1; 990 } 991 992 int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 993 return getEventHub()->getKeyCodeState(getDeviceId(), keyCode); 994 } 995 996 int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 997 return getEventHub()->getScanCodeState(getDeviceId(), scanCode); 998 } 999 1000 bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 1001 const int32_t* keyCodes, uint8_t* outFlags) { 1002 return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags); 1003 } 1004 1005 int32_t KeyboardInputMapper::getMetaState() { 1006 { // acquire lock 1007 AutoMutex _l(mLock); 1008 return mLocked.metaState; 1009 } // release lock 1010 } 1011 1012 1013 // --- TrackballInputMapper --- 1014 1015 TrackballInputMapper::TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId) : 1016 InputMapper(device), mAssociatedDisplayId(associatedDisplayId) { 1017 mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD; 1018 mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD; 1019 mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD; 1020 mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD; 1021 1022 initializeLocked(); 1023 } 1024 1025 TrackballInputMapper::~TrackballInputMapper() { 1026 } 1027 1028 uint32_t TrackballInputMapper::getSources() { 1029 return AINPUT_SOURCE_TRACKBALL; 1030 } 1031 1032 void TrackballInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1033 InputMapper::populateDeviceInfo(info); 1034 1035 info->addMotionRange(AINPUT_MOTION_RANGE_X, -1.0f, 1.0f, 0.0f, mXScale); 1036 info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale); 1037 } 1038 1039 void TrackballInputMapper::dump(String8& dump) { 1040 { // acquire lock 1041 AutoMutex _l(mLock); 1042 dump.append(INDENT2 "Trackball Input Mapper:\n"); 1043 dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); 1044 dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision); 1045 dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision); 1046 dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down)); 1047 dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); 1048 } // release lock 1049 } 1050 1051 void TrackballInputMapper::initializeLocked() { 1052 mAccumulator.clear(); 1053 1054 mLocked.down = false; 1055 mLocked.downTime = 0; 1056 } 1057 1058 void TrackballInputMapper::reset() { 1059 for (;;) { 1060 { // acquire lock 1061 AutoMutex _l(mLock); 1062 1063 if (! mLocked.down) { 1064 initializeLocked(); 1065 break; // done 1066 } 1067 } // release lock 1068 1069 // Synthesize trackball button up event on reset. 1070 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 1071 mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE; 1072 mAccumulator.btnMouse = false; 1073 sync(when); 1074 } 1075 1076 InputMapper::reset(); 1077 } 1078 1079 void TrackballInputMapper::process(const RawEvent* rawEvent) { 1080 switch (rawEvent->type) { 1081 case EV_KEY: 1082 switch (rawEvent->scanCode) { 1083 case BTN_MOUSE: 1084 mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE; 1085 mAccumulator.btnMouse = rawEvent->value != 0; 1086 // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and 1087 // we need to ensure that we report the up/down promptly. 1088 sync(rawEvent->when); 1089 break; 1090 } 1091 break; 1092 1093 case EV_REL: 1094 switch (rawEvent->scanCode) { 1095 case REL_X: 1096 mAccumulator.fields |= Accumulator::FIELD_REL_X; 1097 mAccumulator.relX = rawEvent->value; 1098 break; 1099 case REL_Y: 1100 mAccumulator.fields |= Accumulator::FIELD_REL_Y; 1101 mAccumulator.relY = rawEvent->value; 1102 break; 1103 } 1104 break; 1105 1106 case EV_SYN: 1107 switch (rawEvent->scanCode) { 1108 case SYN_REPORT: 1109 sync(rawEvent->when); 1110 break; 1111 } 1112 break; 1113 } 1114 } 1115 1116 void TrackballInputMapper::sync(nsecs_t when) { 1117 uint32_t fields = mAccumulator.fields; 1118 if (fields == 0) { 1119 return; // no new state changes, so nothing to do 1120 } 1121 1122 int motionEventAction; 1123 PointerCoords pointerCoords; 1124 nsecs_t downTime; 1125 { // acquire lock 1126 AutoMutex _l(mLock); 1127 1128 bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE; 1129 1130 if (downChanged) { 1131 if (mAccumulator.btnMouse) { 1132 mLocked.down = true; 1133 mLocked.downTime = when; 1134 } else { 1135 mLocked.down = false; 1136 } 1137 } 1138 1139 downTime = mLocked.downTime; 1140 float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f; 1141 float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f; 1142 1143 if (downChanged) { 1144 motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; 1145 } else { 1146 motionEventAction = AMOTION_EVENT_ACTION_MOVE; 1147 } 1148 1149 pointerCoords.x = x; 1150 pointerCoords.y = y; 1151 pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f; 1152 pointerCoords.size = 0; 1153 pointerCoords.touchMajor = 0; 1154 pointerCoords.touchMinor = 0; 1155 pointerCoords.toolMajor = 0; 1156 pointerCoords.toolMinor = 0; 1157 pointerCoords.orientation = 0; 1158 1159 if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) { 1160 // Rotate motion based on display orientation if needed. 1161 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1162 int32_t orientation; 1163 if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) { 1164 return; 1165 } 1166 1167 float temp; 1168 switch (orientation) { 1169 case InputReaderPolicyInterface::ROTATION_90: 1170 temp = pointerCoords.x; 1171 pointerCoords.x = pointerCoords.y; 1172 pointerCoords.y = - temp; 1173 break; 1174 1175 case InputReaderPolicyInterface::ROTATION_180: 1176 pointerCoords.x = - pointerCoords.x; 1177 pointerCoords.y = - pointerCoords.y; 1178 break; 1179 1180 case InputReaderPolicyInterface::ROTATION_270: 1181 temp = pointerCoords.x; 1182 pointerCoords.x = - pointerCoords.y; 1183 pointerCoords.y = temp; 1184 break; 1185 } 1186 } 1187 } // release lock 1188 1189 int32_t metaState = mContext->getGlobalMetaState(); 1190 int32_t pointerId = 0; 1191 getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, 0, 1192 motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, 1193 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime); 1194 1195 mAccumulator.clear(); 1196 } 1197 1198 int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 1199 if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) { 1200 return getEventHub()->getScanCodeState(getDeviceId(), scanCode); 1201 } else { 1202 return AKEY_STATE_UNKNOWN; 1203 } 1204 } 1205 1206 1207 // --- TouchInputMapper --- 1208 1209 TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) : 1210 InputMapper(device), mAssociatedDisplayId(associatedDisplayId) { 1211 mLocked.surfaceOrientation = -1; 1212 mLocked.surfaceWidth = -1; 1213 mLocked.surfaceHeight = -1; 1214 1215 initializeLocked(); 1216 } 1217 1218 TouchInputMapper::~TouchInputMapper() { 1219 } 1220 1221 uint32_t TouchInputMapper::getSources() { 1222 return mAssociatedDisplayId >= 0 ? AINPUT_SOURCE_TOUCHSCREEN : AINPUT_SOURCE_TOUCHPAD; 1223 } 1224 1225 void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1226 InputMapper::populateDeviceInfo(info); 1227 1228 { // acquire lock 1229 AutoMutex _l(mLock); 1230 1231 // Ensure surface information is up to date so that orientation changes are 1232 // noticed immediately. 1233 configureSurfaceLocked(); 1234 1235 info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x); 1236 info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y); 1237 1238 if (mLocked.orientedRanges.havePressure) { 1239 info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, 1240 mLocked.orientedRanges.pressure); 1241 } 1242 1243 if (mLocked.orientedRanges.haveSize) { 1244 info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, 1245 mLocked.orientedRanges.size); 1246 } 1247 1248 if (mLocked.orientedRanges.haveTouchSize) { 1249 info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, 1250 mLocked.orientedRanges.touchMajor); 1251 info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, 1252 mLocked.orientedRanges.touchMinor); 1253 } 1254 1255 if (mLocked.orientedRanges.haveToolSize) { 1256 info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, 1257 mLocked.orientedRanges.toolMajor); 1258 info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, 1259 mLocked.orientedRanges.toolMinor); 1260 } 1261 1262 if (mLocked.orientedRanges.haveOrientation) { 1263 info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, 1264 mLocked.orientedRanges.orientation); 1265 } 1266 } // release lock 1267 } 1268 1269 void TouchInputMapper::dump(String8& dump) { 1270 { // acquire lock 1271 AutoMutex _l(mLock); 1272 dump.append(INDENT2 "Touch Input Mapper:\n"); 1273 dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); 1274 dumpParameters(dump); 1275 dumpVirtualKeysLocked(dump); 1276 dumpRawAxes(dump); 1277 dumpCalibration(dump); 1278 dumpSurfaceLocked(dump); 1279 dump.appendFormat(INDENT3 "Translation and Scaling Factors:"); 1280 dump.appendFormat(INDENT4 "XOrigin: %d\n", mLocked.xOrigin); 1281 dump.appendFormat(INDENT4 "YOrigin: %d\n", mLocked.yOrigin); 1282 dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale); 1283 dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale); 1284 dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision); 1285 dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision); 1286 dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale); 1287 dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale); 1288 dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias); 1289 dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale); 1290 dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias); 1291 dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale); 1292 dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale); 1293 dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale); 1294 } // release lock 1295 } 1296 1297 void TouchInputMapper::initializeLocked() { 1298 mCurrentTouch.clear(); 1299 mLastTouch.clear(); 1300 mDownTime = 0; 1301 1302 for (uint32_t i = 0; i < MAX_POINTERS; i++) { 1303 mAveragingTouchFilter.historyStart[i] = 0; 1304 mAveragingTouchFilter.historyEnd[i] = 0; 1305 } 1306 1307 mJumpyTouchFilter.jumpyPointsDropped = 0; 1308 1309 mLocked.currentVirtualKey.down = false; 1310 1311 mLocked.orientedRanges.havePressure = false; 1312 mLocked.orientedRanges.haveSize = false; 1313 mLocked.orientedRanges.haveTouchSize = false; 1314 mLocked.orientedRanges.haveToolSize = false; 1315 mLocked.orientedRanges.haveOrientation = false; 1316 } 1317 1318 void TouchInputMapper::configure() { 1319 InputMapper::configure(); 1320 1321 // Configure basic parameters. 1322 configureParameters(); 1323 1324 // Configure absolute axis information. 1325 configureRawAxes(); 1326 1327 // Prepare input device calibration. 1328 parseCalibration(); 1329 resolveCalibration(); 1330 1331 { // acquire lock 1332 AutoMutex _l(mLock); 1333 1334 // Configure surface dimensions and orientation. 1335 configureSurfaceLocked(); 1336 } // release lock 1337 } 1338 1339 void TouchInputMapper::configureParameters() { 1340 mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents(); 1341 mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents(); 1342 mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents(); 1343 } 1344 1345 void TouchInputMapper::dumpParameters(String8& dump) { 1346 dump.appendFormat(INDENT3 "UseBadTouchFilter: %s\n", 1347 toString(mParameters.useBadTouchFilter)); 1348 dump.appendFormat(INDENT3 "UseAveragingTouchFilter: %s\n", 1349 toString(mParameters.useAveragingTouchFilter)); 1350 dump.appendFormat(INDENT3 "UseJumpyTouchFilter: %s\n", 1351 toString(mParameters.useJumpyTouchFilter)); 1352 } 1353 1354 void TouchInputMapper::configureRawAxes() { 1355 mRawAxes.x.clear(); 1356 mRawAxes.y.clear(); 1357 mRawAxes.pressure.clear(); 1358 mRawAxes.touchMajor.clear(); 1359 mRawAxes.touchMinor.clear(); 1360 mRawAxes.toolMajor.clear(); 1361 mRawAxes.toolMinor.clear(); 1362 mRawAxes.orientation.clear(); 1363 } 1364 1365 static void dumpAxisInfo(String8& dump, RawAbsoluteAxisInfo axis, const char* name) { 1366 if (axis.valid) { 1367 dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d\n", 1368 name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz); 1369 } else { 1370 dump.appendFormat(INDENT4 "%s: unknown range\n", name); 1371 } 1372 } 1373 1374 void TouchInputMapper::dumpRawAxes(String8& dump) { 1375 dump.append(INDENT3 "Raw Axes:\n"); 1376 dumpAxisInfo(dump, mRawAxes.x, "X"); 1377 dumpAxisInfo(dump, mRawAxes.y, "Y"); 1378 dumpAxisInfo(dump, mRawAxes.pressure, "Pressure"); 1379 dumpAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor"); 1380 dumpAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor"); 1381 dumpAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor"); 1382 dumpAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor"); 1383 dumpAxisInfo(dump, mRawAxes.orientation, "Orientation"); 1384 } 1385 1386 bool TouchInputMapper::configureSurfaceLocked() { 1387 // Update orientation and dimensions if needed. 1388 int32_t orientation; 1389 int32_t width, height; 1390 if (mAssociatedDisplayId >= 0) { 1391 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1392 if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) { 1393 return false; 1394 } 1395 } else { 1396 orientation = InputReaderPolicyInterface::ROTATION_0; 1397 width = mRawAxes.x.getRange(); 1398 height = mRawAxes.y.getRange(); 1399 } 1400 1401 bool orientationChanged = mLocked.surfaceOrientation != orientation; 1402 if (orientationChanged) { 1403 mLocked.surfaceOrientation = orientation; 1404 } 1405 1406 bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height; 1407 if (sizeChanged) { 1408 LOGI("Device reconfigured: id=0x%x, name=%s, display size is now %dx%d", 1409 getDeviceId(), getDeviceName().string(), width, height); 1410 1411 mLocked.surfaceWidth = width; 1412 mLocked.surfaceHeight = height; 1413 1414 // Configure X and Y factors. 1415 if (mRawAxes.x.valid && mRawAxes.y.valid) { 1416 mLocked.xOrigin = mRawAxes.x.minValue; 1417 mLocked.yOrigin = mRawAxes.y.minValue; 1418 mLocked.xScale = float(width) / mRawAxes.x.getRange(); 1419 mLocked.yScale = float(height) / mRawAxes.y.getRange(); 1420 mLocked.xPrecision = 1.0f / mLocked.xScale; 1421 mLocked.yPrecision = 1.0f / mLocked.yScale; 1422 1423 configureVirtualKeysLocked(); 1424 } else { 1425 LOGW(INDENT "Touch device did not report support for X or Y axis!"); 1426 mLocked.xOrigin = 0; 1427 mLocked.yOrigin = 0; 1428 mLocked.xScale = 1.0f; 1429 mLocked.yScale = 1.0f; 1430 mLocked.xPrecision = 1.0f; 1431 mLocked.yPrecision = 1.0f; 1432 } 1433 1434 // Scale factor for terms that are not oriented in a particular axis. 1435 // If the pixels are square then xScale == yScale otherwise we fake it 1436 // by choosing an average. 1437 mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale); 1438 1439 // Size of diagonal axis. 1440 float diagonalSize = pythag(width, height); 1441 1442 // TouchMajor and TouchMinor factors. 1443 if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) { 1444 mLocked.orientedRanges.haveTouchSize = true; 1445 mLocked.orientedRanges.touchMajor.min = 0; 1446 mLocked.orientedRanges.touchMajor.max = diagonalSize; 1447 mLocked.orientedRanges.touchMajor.flat = 0; 1448 mLocked.orientedRanges.touchMajor.fuzz = 0; 1449 mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor; 1450 } 1451 1452 // ToolMajor and ToolMinor factors. 1453 mLocked.toolSizeLinearScale = 0; 1454 mLocked.toolSizeLinearBias = 0; 1455 mLocked.toolSizeAreaScale = 0; 1456 mLocked.toolSizeAreaBias = 0; 1457 if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 1458 if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) { 1459 if (mCalibration.haveToolSizeLinearScale) { 1460 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 1461 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1462 mLocked.toolSizeLinearScale = float(min(width, height)) 1463 / mRawAxes.toolMajor.maxValue; 1464 } 1465 1466 if (mCalibration.haveToolSizeLinearBias) { 1467 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 1468 } 1469 } else if (mCalibration.toolSizeCalibration == 1470 Calibration::TOOL_SIZE_CALIBRATION_AREA) { 1471 if (mCalibration.haveToolSizeLinearScale) { 1472 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 1473 } else { 1474 mLocked.toolSizeLinearScale = min(width, height); 1475 } 1476 1477 if (mCalibration.haveToolSizeLinearBias) { 1478 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 1479 } 1480 1481 if (mCalibration.haveToolSizeAreaScale) { 1482 mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale; 1483 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1484 mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue; 1485 } 1486 1487 if (mCalibration.haveToolSizeAreaBias) { 1488 mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias; 1489 } 1490 } 1491 1492 mLocked.orientedRanges.haveToolSize = true; 1493 mLocked.orientedRanges.toolMajor.min = 0; 1494 mLocked.orientedRanges.toolMajor.max = diagonalSize; 1495 mLocked.orientedRanges.toolMajor.flat = 0; 1496 mLocked.orientedRanges.toolMajor.fuzz = 0; 1497 mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor; 1498 } 1499 1500 // Pressure factors. 1501 mLocked.pressureScale = 0; 1502 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) { 1503 RawAbsoluteAxisInfo rawPressureAxis; 1504 switch (mCalibration.pressureSource) { 1505 case Calibration::PRESSURE_SOURCE_PRESSURE: 1506 rawPressureAxis = mRawAxes.pressure; 1507 break; 1508 case Calibration::PRESSURE_SOURCE_TOUCH: 1509 rawPressureAxis = mRawAxes.touchMajor; 1510 break; 1511 default: 1512 rawPressureAxis.clear(); 1513 } 1514 1515 if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL 1516 || mCalibration.pressureCalibration 1517 == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) { 1518 if (mCalibration.havePressureScale) { 1519 mLocked.pressureScale = mCalibration.pressureScale; 1520 } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) { 1521 mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue; 1522 } 1523 } 1524 1525 mLocked.orientedRanges.havePressure = true; 1526 mLocked.orientedRanges.pressure.min = 0; 1527 mLocked.orientedRanges.pressure.max = 1.0; 1528 mLocked.orientedRanges.pressure.flat = 0; 1529 mLocked.orientedRanges.pressure.fuzz = 0; 1530 } 1531 1532 // Size factors. 1533 mLocked.sizeScale = 0; 1534 if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) { 1535 if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) { 1536 if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1537 mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue; 1538 } 1539 } 1540 1541 mLocked.orientedRanges.haveSize = true; 1542 mLocked.orientedRanges.size.min = 0; 1543 mLocked.orientedRanges.size.max = 1.0; 1544 mLocked.orientedRanges.size.flat = 0; 1545 mLocked.orientedRanges.size.fuzz = 0; 1546 } 1547 1548 // Orientation 1549 mLocked.orientationScale = 0; 1550 if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) { 1551 if (mCalibration.orientationCalibration 1552 == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) { 1553 if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) { 1554 mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue; 1555 } 1556 } 1557 1558 mLocked.orientedRanges.orientation.min = - M_PI_2; 1559 mLocked.orientedRanges.orientation.max = M_PI_2; 1560 mLocked.orientedRanges.orientation.flat = 0; 1561 mLocked.orientedRanges.orientation.fuzz = 0; 1562 } 1563 } 1564 1565 if (orientationChanged || sizeChanged) { 1566 // Compute oriented surface dimensions, precision, and scales. 1567 float orientedXScale, orientedYScale; 1568 switch (mLocked.surfaceOrientation) { 1569 case InputReaderPolicyInterface::ROTATION_90: 1570 case InputReaderPolicyInterface::ROTATION_270: 1571 mLocked.orientedSurfaceWidth = mLocked.surfaceHeight; 1572 mLocked.orientedSurfaceHeight = mLocked.surfaceWidth; 1573 mLocked.orientedXPrecision = mLocked.yPrecision; 1574 mLocked.orientedYPrecision = mLocked.xPrecision; 1575 orientedXScale = mLocked.yScale; 1576 orientedYScale = mLocked.xScale; 1577 break; 1578 default: 1579 mLocked.orientedSurfaceWidth = mLocked.surfaceWidth; 1580 mLocked.orientedSurfaceHeight = mLocked.surfaceHeight; 1581 mLocked.orientedXPrecision = mLocked.xPrecision; 1582 mLocked.orientedYPrecision = mLocked.yPrecision; 1583 orientedXScale = mLocked.xScale; 1584 orientedYScale = mLocked.yScale; 1585 break; 1586 } 1587 1588 // Configure position ranges. 1589 mLocked.orientedRanges.x.min = 0; 1590 mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth; 1591 mLocked.orientedRanges.x.flat = 0; 1592 mLocked.orientedRanges.x.fuzz = orientedXScale; 1593 1594 mLocked.orientedRanges.y.min = 0; 1595 mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight; 1596 mLocked.orientedRanges.y.flat = 0; 1597 mLocked.orientedRanges.y.fuzz = orientedYScale; 1598 } 1599 1600 return true; 1601 } 1602 1603 void TouchInputMapper::dumpSurfaceLocked(String8& dump) { 1604 dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth); 1605 dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight); 1606 dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation); 1607 } 1608 1609 void TouchInputMapper::configureVirtualKeysLocked() { 1610 assert(mRawAxes.x.valid && mRawAxes.y.valid); 1611 1612 // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock. 1613 Vector<VirtualKeyDefinition> virtualKeyDefinitions; 1614 getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions); 1615 1616 mLocked.virtualKeys.clear(); 1617 1618 if (virtualKeyDefinitions.size() == 0) { 1619 return; 1620 } 1621 1622 mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size()); 1623 1624 int32_t touchScreenLeft = mRawAxes.x.minValue; 1625 int32_t touchScreenTop = mRawAxes.y.minValue; 1626 int32_t touchScreenWidth = mRawAxes.x.getRange(); 1627 int32_t touchScreenHeight = mRawAxes.y.getRange(); 1628 1629 for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) { 1630 const VirtualKeyDefinition& virtualKeyDefinition = 1631 virtualKeyDefinitions[i]; 1632 1633 mLocked.virtualKeys.add(); 1634 VirtualKey& virtualKey = mLocked.virtualKeys.editTop(); 1635 1636 virtualKey.scanCode = virtualKeyDefinition.scanCode; 1637 int32_t keyCode; 1638 uint32_t flags; 1639 if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode, 1640 & keyCode, & flags)) { 1641 LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", 1642 virtualKey.scanCode); 1643 mLocked.virtualKeys.pop(); // drop the key 1644 continue; 1645 } 1646 1647 virtualKey.keyCode = keyCode; 1648 virtualKey.flags = flags; 1649 1650 // convert the key definition's display coordinates into touch coordinates for a hit box 1651 int32_t halfWidth = virtualKeyDefinition.width / 2; 1652 int32_t halfHeight = virtualKeyDefinition.height / 2; 1653 1654 virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth) 1655 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 1656 virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth) 1657 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 1658 virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight) 1659 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 1660 virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) 1661 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 1662 1663 } 1664 } 1665 1666 void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) { 1667 if (!mLocked.virtualKeys.isEmpty()) { 1668 dump.append(INDENT3 "Virtual Keys:\n"); 1669 1670 for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) { 1671 const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i); 1672 dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, " 1673 "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n", 1674 i, virtualKey.scanCode, virtualKey.keyCode, 1675 virtualKey.hitLeft, virtualKey.hitRight, 1676 virtualKey.hitTop, virtualKey.hitBottom); 1677 } 1678 } 1679 } 1680 1681 void TouchInputMapper::parseCalibration() { 1682 const InputDeviceCalibration& in = getDevice()->getCalibration(); 1683 Calibration& out = mCalibration; 1684 1685 // Touch Size 1686 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT; 1687 String8 touchSizeCalibrationString; 1688 if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) { 1689 if (touchSizeCalibrationString == "none") { 1690 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 1691 } else if (touchSizeCalibrationString == "geometric") { 1692 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC; 1693 } else if (touchSizeCalibrationString == "pressure") { 1694 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 1695 } else if (touchSizeCalibrationString != "default") { 1696 LOGW("Invalid value for touch.touchSize.calibration: '%s'", 1697 touchSizeCalibrationString.string()); 1698 } 1699 } 1700 1701 // Tool Size 1702 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT; 1703 String8 toolSizeCalibrationString; 1704 if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) { 1705 if (toolSizeCalibrationString == "none") { 1706 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 1707 } else if (toolSizeCalibrationString == "geometric") { 1708 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC; 1709 } else if (toolSizeCalibrationString == "linear") { 1710 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 1711 } else if (toolSizeCalibrationString == "area") { 1712 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA; 1713 } else if (toolSizeCalibrationString != "default") { 1714 LOGW("Invalid value for touch.toolSize.calibration: '%s'", 1715 toolSizeCalibrationString.string()); 1716 } 1717 } 1718 1719 out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"), 1720 out.toolSizeLinearScale); 1721 out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"), 1722 out.toolSizeLinearBias); 1723 out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"), 1724 out.toolSizeAreaScale); 1725 out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"), 1726 out.toolSizeAreaBias); 1727 out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"), 1728 out.toolSizeIsSummed); 1729 1730 // Pressure 1731 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT; 1732 String8 pressureCalibrationString; 1733 if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) { 1734 if (pressureCalibrationString == "none") { 1735 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 1736 } else if (pressureCalibrationString == "physical") { 1737 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL; 1738 } else if (pressureCalibrationString == "amplitude") { 1739 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 1740 } else if (pressureCalibrationString != "default") { 1741 LOGW("Invalid value for touch.pressure.calibration: '%s'", 1742 pressureCalibrationString.string()); 1743 } 1744 } 1745 1746 out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT; 1747 String8 pressureSourceString; 1748 if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) { 1749 if (pressureSourceString == "pressure") { 1750 out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 1751 } else if (pressureSourceString == "touch") { 1752 out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 1753 } else if (pressureSourceString != "default") { 1754 LOGW("Invalid value for touch.pressure.source: '%s'", 1755 pressureSourceString.string()); 1756 } 1757 } 1758 1759 out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"), 1760 out.pressureScale); 1761 1762 // Size 1763 out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT; 1764 String8 sizeCalibrationString; 1765 if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) { 1766 if (sizeCalibrationString == "none") { 1767 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 1768 } else if (sizeCalibrationString == "normalized") { 1769 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 1770 } else if (sizeCalibrationString != "default") { 1771 LOGW("Invalid value for touch.size.calibration: '%s'", 1772 sizeCalibrationString.string()); 1773 } 1774 } 1775 1776 // Orientation 1777 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT; 1778 String8 orientationCalibrationString; 1779 if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) { 1780 if (orientationCalibrationString == "none") { 1781 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 1782 } else if (orientationCalibrationString == "interpolated") { 1783 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 1784 } else if (orientationCalibrationString != "default") { 1785 LOGW("Invalid value for touch.orientation.calibration: '%s'", 1786 orientationCalibrationString.string()); 1787 } 1788 } 1789 } 1790 1791 void TouchInputMapper::resolveCalibration() { 1792 // Pressure 1793 switch (mCalibration.pressureSource) { 1794 case Calibration::PRESSURE_SOURCE_DEFAULT: 1795 if (mRawAxes.pressure.valid) { 1796 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 1797 } else if (mRawAxes.touchMajor.valid) { 1798 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 1799 } 1800 break; 1801 1802 case Calibration::PRESSURE_SOURCE_PRESSURE: 1803 if (! mRawAxes.pressure.valid) { 1804 LOGW("Calibration property touch.pressure.source is 'pressure' but " 1805 "the pressure axis is not available."); 1806 } 1807 break; 1808 1809 case Calibration::PRESSURE_SOURCE_TOUCH: 1810 if (! mRawAxes.touchMajor.valid) { 1811 LOGW("Calibration property touch.pressure.source is 'touch' but " 1812 "the touchMajor axis is not available."); 1813 } 1814 break; 1815 1816 default: 1817 break; 1818 } 1819 1820 switch (mCalibration.pressureCalibration) { 1821 case Calibration::PRESSURE_CALIBRATION_DEFAULT: 1822 if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) { 1823 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 1824 } else { 1825 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 1826 } 1827 break; 1828 1829 default: 1830 break; 1831 } 1832 1833 // Tool Size 1834 switch (mCalibration.toolSizeCalibration) { 1835 case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT: 1836 if (mRawAxes.toolMajor.valid) { 1837 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 1838 } else { 1839 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 1840 } 1841 break; 1842 1843 default: 1844 break; 1845 } 1846 1847 // Touch Size 1848 switch (mCalibration.touchSizeCalibration) { 1849 case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT: 1850 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE 1851 && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 1852 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 1853 } else { 1854 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 1855 } 1856 break; 1857 1858 default: 1859 break; 1860 } 1861 1862 // Size 1863 switch (mCalibration.sizeCalibration) { 1864 case Calibration::SIZE_CALIBRATION_DEFAULT: 1865 if (mRawAxes.toolMajor.valid) { 1866 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 1867 } else { 1868 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 1869 } 1870 break; 1871 1872 default: 1873 break; 1874 } 1875 1876 // Orientation 1877 switch (mCalibration.orientationCalibration) { 1878 case Calibration::ORIENTATION_CALIBRATION_DEFAULT: 1879 if (mRawAxes.orientation.valid) { 1880 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 1881 } else { 1882 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 1883 } 1884 break; 1885 1886 default: 1887 break; 1888 } 1889 } 1890 1891 void TouchInputMapper::dumpCalibration(String8& dump) { 1892 dump.append(INDENT3 "Calibration:\n"); 1893 1894 // Touch Size 1895 switch (mCalibration.touchSizeCalibration) { 1896 case Calibration::TOUCH_SIZE_CALIBRATION_NONE: 1897 dump.append(INDENT4 "touch.touchSize.calibration: none\n"); 1898 break; 1899 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 1900 dump.append(INDENT4 "touch.touchSize.calibration: geometric\n"); 1901 break; 1902 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 1903 dump.append(INDENT4 "touch.touchSize.calibration: pressure\n"); 1904 break; 1905 default: 1906 assert(false); 1907 } 1908 1909 // Tool Size 1910 switch (mCalibration.toolSizeCalibration) { 1911 case Calibration::TOOL_SIZE_CALIBRATION_NONE: 1912 dump.append(INDENT4 "touch.toolSize.calibration: none\n"); 1913 break; 1914 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 1915 dump.append(INDENT4 "touch.toolSize.calibration: geometric\n"); 1916 break; 1917 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 1918 dump.append(INDENT4 "touch.toolSize.calibration: linear\n"); 1919 break; 1920 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 1921 dump.append(INDENT4 "touch.toolSize.calibration: area\n"); 1922 break; 1923 default: 1924 assert(false); 1925 } 1926 1927 if (mCalibration.haveToolSizeLinearScale) { 1928 dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n", 1929 mCalibration.toolSizeLinearScale); 1930 } 1931 1932 if (mCalibration.haveToolSizeLinearBias) { 1933 dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n", 1934 mCalibration.toolSizeLinearBias); 1935 } 1936 1937 if (mCalibration.haveToolSizeAreaScale) { 1938 dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n", 1939 mCalibration.toolSizeAreaScale); 1940 } 1941 1942 if (mCalibration.haveToolSizeAreaBias) { 1943 dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n", 1944 mCalibration.toolSizeAreaBias); 1945 } 1946 1947 if (mCalibration.haveToolSizeIsSummed) { 1948 dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %d\n", 1949 mCalibration.toolSizeIsSummed); 1950 } 1951 1952 // Pressure 1953 switch (mCalibration.pressureCalibration) { 1954 case Calibration::PRESSURE_CALIBRATION_NONE: 1955 dump.append(INDENT4 "touch.pressure.calibration: none\n"); 1956 break; 1957 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 1958 dump.append(INDENT4 "touch.pressure.calibration: physical\n"); 1959 break; 1960 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 1961 dump.append(INDENT4 "touch.pressure.calibration: amplitude\n"); 1962 break; 1963 default: 1964 assert(false); 1965 } 1966 1967 switch (mCalibration.pressureSource) { 1968 case Calibration::PRESSURE_SOURCE_PRESSURE: 1969 dump.append(INDENT4 "touch.pressure.source: pressure\n"); 1970 break; 1971 case Calibration::PRESSURE_SOURCE_TOUCH: 1972 dump.append(INDENT4 "touch.pressure.source: touch\n"); 1973 break; 1974 case Calibration::PRESSURE_SOURCE_DEFAULT: 1975 break; 1976 default: 1977 assert(false); 1978 } 1979 1980 if (mCalibration.havePressureScale) { 1981 dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n", 1982 mCalibration.pressureScale); 1983 } 1984 1985 // Size 1986 switch (mCalibration.sizeCalibration) { 1987 case Calibration::SIZE_CALIBRATION_NONE: 1988 dump.append(INDENT4 "touch.size.calibration: none\n"); 1989 break; 1990 case Calibration::SIZE_CALIBRATION_NORMALIZED: 1991 dump.append(INDENT4 "touch.size.calibration: normalized\n"); 1992 break; 1993 default: 1994 assert(false); 1995 } 1996 1997 // Orientation 1998 switch (mCalibration.orientationCalibration) { 1999 case Calibration::ORIENTATION_CALIBRATION_NONE: 2000 dump.append(INDENT4 "touch.orientation.calibration: none\n"); 2001 break; 2002 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 2003 dump.append(INDENT4 "touch.orientation.calibration: interpolated\n"); 2004 break; 2005 default: 2006 assert(false); 2007 } 2008 } 2009 2010 void TouchInputMapper::reset() { 2011 // Synthesize touch up event if touch is currently down. 2012 // This will also take care of finishing virtual key processing if needed. 2013 if (mLastTouch.pointerCount != 0) { 2014 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 2015 mCurrentTouch.clear(); 2016 syncTouch(when, true); 2017 } 2018 2019 { // acquire lock 2020 AutoMutex _l(mLock); 2021 initializeLocked(); 2022 } // release lock 2023 2024 InputMapper::reset(); 2025 } 2026 2027 void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { 2028 uint32_t policyFlags = 0; 2029 2030 // Preprocess pointer data. 2031 2032 if (mParameters.useBadTouchFilter) { 2033 if (applyBadTouchFilter()) { 2034 havePointerIds = false; 2035 } 2036 } 2037 2038 if (mParameters.useJumpyTouchFilter) { 2039 if (applyJumpyTouchFilter()) { 2040 havePointerIds = false; 2041 } 2042 } 2043 2044 if (! havePointerIds) { 2045 calculatePointerIds(); 2046 } 2047 2048 TouchData temp; 2049 TouchData* savedTouch; 2050 if (mParameters.useAveragingTouchFilter) { 2051 temp.copyFrom(mCurrentTouch); 2052 savedTouch = & temp; 2053 2054 applyAveragingTouchFilter(); 2055 } else { 2056 savedTouch = & mCurrentTouch; 2057 } 2058 2059 // Process touches and virtual keys. 2060 2061 TouchResult touchResult = consumeOffScreenTouches(when, policyFlags); 2062 if (touchResult == DISPATCH_TOUCH) { 2063 dispatchTouches(when, policyFlags); 2064 } 2065 2066 // Copy current touch to last touch in preparation for the next cycle. 2067 2068 if (touchResult == DROP_STROKE) { 2069 mLastTouch.clear(); 2070 } else { 2071 mLastTouch.copyFrom(*savedTouch); 2072 } 2073 } 2074 2075 TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches( 2076 nsecs_t when, uint32_t policyFlags) { 2077 int32_t keyEventAction, keyEventFlags; 2078 int32_t keyCode, scanCode, downTime; 2079 TouchResult touchResult; 2080 2081 { // acquire lock 2082 AutoMutex _l(mLock); 2083 2084 // Update surface size and orientation, including virtual key positions. 2085 if (! configureSurfaceLocked()) { 2086 return DROP_STROKE; 2087 } 2088 2089 // Check for virtual key press. 2090 if (mLocked.currentVirtualKey.down) { 2091 if (mCurrentTouch.pointerCount == 0) { 2092 // Pointer went up while virtual key was down. 2093 mLocked.currentVirtualKey.down = false; 2094 #if DEBUG_VIRTUAL_KEYS 2095 LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d", 2096 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 2097 #endif 2098 keyEventAction = AKEY_EVENT_ACTION_UP; 2099 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 2100 touchResult = SKIP_TOUCH; 2101 goto DispatchVirtualKey; 2102 } 2103 2104 if (mCurrentTouch.pointerCount == 1) { 2105 int32_t x = mCurrentTouch.pointers[0].x; 2106 int32_t y = mCurrentTouch.pointers[0].y; 2107 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 2108 if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) { 2109 // Pointer is still within the space of the virtual key. 2110 return SKIP_TOUCH; 2111 } 2112 } 2113 2114 // Pointer left virtual key area or another pointer also went down. 2115 // Send key cancellation and drop the stroke so subsequent motions will be 2116 // considered fresh downs. This is useful when the user swipes away from the 2117 // virtual key area into the main display surface. 2118 mLocked.currentVirtualKey.down = false; 2119 #if DEBUG_VIRTUAL_KEYS 2120 LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d", 2121 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 2122 #endif 2123 keyEventAction = AKEY_EVENT_ACTION_UP; 2124 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY 2125 | AKEY_EVENT_FLAG_CANCELED; 2126 2127 // Check whether the pointer moved inside the display area where we should 2128 // start a new stroke. 2129 int32_t x = mCurrentTouch.pointers[0].x; 2130 int32_t y = mCurrentTouch.pointers[0].y; 2131 if (isPointInsideSurfaceLocked(x, y)) { 2132 mLastTouch.clear(); 2133 touchResult = DISPATCH_TOUCH; 2134 } else { 2135 touchResult = DROP_STROKE; 2136 } 2137 } else { 2138 if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) { 2139 // Pointer just went down. Handle off-screen touches, if needed. 2140 int32_t x = mCurrentTouch.pointers[0].x; 2141 int32_t y = mCurrentTouch.pointers[0].y; 2142 if (! isPointInsideSurfaceLocked(x, y)) { 2143 // If exactly one pointer went down, check for virtual key hit. 2144 // Otherwise we will drop the entire stroke. 2145 if (mCurrentTouch.pointerCount == 1) { 2146 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 2147 if (virtualKey) { 2148 mLocked.currentVirtualKey.down = true; 2149 mLocked.currentVirtualKey.downTime = when; 2150 mLocked.currentVirtualKey.keyCode = virtualKey->keyCode; 2151 mLocked.currentVirtualKey.scanCode = virtualKey->scanCode; 2152 #if DEBUG_VIRTUAL_KEYS 2153 LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d", 2154 mLocked.currentVirtualKey.keyCode, 2155 mLocked.currentVirtualKey.scanCode); 2156 #endif 2157 keyEventAction = AKEY_EVENT_ACTION_DOWN; 2158 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM 2159 | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 2160 touchResult = SKIP_TOUCH; 2161 goto DispatchVirtualKey; 2162 } 2163 } 2164 return DROP_STROKE; 2165 } 2166 } 2167 return DISPATCH_TOUCH; 2168 } 2169 2170 DispatchVirtualKey: 2171 // Collect remaining state needed to dispatch virtual key. 2172 keyCode = mLocked.currentVirtualKey.keyCode; 2173 scanCode = mLocked.currentVirtualKey.scanCode; 2174 downTime = mLocked.currentVirtualKey.downTime; 2175 } // release lock 2176 2177 // Dispatch virtual key. 2178 int32_t metaState = mContext->getGlobalMetaState(); 2179 policyFlags |= POLICY_FLAG_VIRTUAL; 2180 getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags, 2181 keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime); 2182 return touchResult; 2183 } 2184 2185 void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) { 2186 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 2187 uint32_t lastPointerCount = mLastTouch.pointerCount; 2188 if (currentPointerCount == 0 && lastPointerCount == 0) { 2189 return; // nothing to do! 2190 } 2191 2192 BitSet32 currentIdBits = mCurrentTouch.idBits; 2193 BitSet32 lastIdBits = mLastTouch.idBits; 2194 2195 if (currentIdBits == lastIdBits) { 2196 // No pointer id changes so this is a move event. 2197 // The dispatcher takes care of batching moves so we don't have to deal with that here. 2198 int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE; 2199 dispatchTouch(when, policyFlags, & mCurrentTouch, 2200 currentIdBits, -1, currentPointerCount, motionEventAction); 2201 } else { 2202 // There may be pointers going up and pointers going down and pointers moving 2203 // all at the same time. 2204 BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value); 2205 BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value); 2206 BitSet32 activeIdBits(lastIdBits.value); 2207 uint32_t pointerCount = lastPointerCount; 2208 2209 // Produce an intermediate representation of the touch data that consists of the 2210 // old location of pointers that have just gone up and the new location of pointers that 2211 // have just moved but omits the location of pointers that have just gone down. 2212 TouchData interimTouch; 2213 interimTouch.copyFrom(mLastTouch); 2214 2215 BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value); 2216 bool moveNeeded = false; 2217 while (!moveIdBits.isEmpty()) { 2218 uint32_t moveId = moveIdBits.firstMarkedBit(); 2219 moveIdBits.clearBit(moveId); 2220 2221 int32_t oldIndex = mLastTouch.idToIndex[moveId]; 2222 int32_t newIndex = mCurrentTouch.idToIndex[moveId]; 2223 if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) { 2224 interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex]; 2225 moveNeeded = true; 2226 } 2227 } 2228 2229 // Dispatch pointer up events using the interim pointer locations. 2230 while (!upIdBits.isEmpty()) { 2231 uint32_t upId = upIdBits.firstMarkedBit(); 2232 upIdBits.clearBit(upId); 2233 BitSet32 oldActiveIdBits = activeIdBits; 2234 activeIdBits.clearBit(upId); 2235 2236 int32_t motionEventAction; 2237 if (activeIdBits.isEmpty()) { 2238 motionEventAction = AMOTION_EVENT_ACTION_UP; 2239 } else { 2240 motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP; 2241 } 2242 2243 dispatchTouch(when, policyFlags, &interimTouch, 2244 oldActiveIdBits, upId, pointerCount, motionEventAction); 2245 pointerCount -= 1; 2246 } 2247 2248 // Dispatch move events if any of the remaining pointers moved from their old locations. 2249 // Although applications receive new locations as part of individual pointer up 2250 // events, they do not generally handle them except when presented in a move event. 2251 if (moveNeeded) { 2252 dispatchTouch(when, policyFlags, &mCurrentTouch, 2253 activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE); 2254 } 2255 2256 // Dispatch pointer down events using the new pointer locations. 2257 while (!downIdBits.isEmpty()) { 2258 uint32_t downId = downIdBits.firstMarkedBit(); 2259 downIdBits.clearBit(downId); 2260 BitSet32 oldActiveIdBits = activeIdBits; 2261 activeIdBits.markBit(downId); 2262 2263 int32_t motionEventAction; 2264 if (oldActiveIdBits.isEmpty()) { 2265 motionEventAction = AMOTION_EVENT_ACTION_DOWN; 2266 mDownTime = when; 2267 } else { 2268 motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN; 2269 } 2270 2271 pointerCount += 1; 2272 dispatchTouch(when, policyFlags, &mCurrentTouch, 2273 activeIdBits, downId, pointerCount, motionEventAction); 2274 } 2275 } 2276 } 2277 2278 void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, 2279 TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount, 2280 int32_t motionEventAction) { 2281 int32_t pointerIds[MAX_POINTERS]; 2282 PointerCoords pointerCoords[MAX_POINTERS]; 2283 int32_t motionEventEdgeFlags = 0; 2284 float xPrecision, yPrecision; 2285 2286 { // acquire lock 2287 AutoMutex _l(mLock); 2288 2289 // Walk through the the active pointers and map touch screen coordinates (TouchData) into 2290 // display coordinates (PointerCoords) and adjust for display orientation. 2291 for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) { 2292 uint32_t id = idBits.firstMarkedBit(); 2293 idBits.clearBit(id); 2294 uint32_t inIndex = touch->idToIndex[id]; 2295 2296 const PointerData& in = touch->pointers[inIndex]; 2297 2298 // X and Y 2299 float x = float(in.x - mLocked.xOrigin) * mLocked.xScale; 2300 float y = float(in.y - mLocked.yOrigin) * mLocked.yScale; 2301 2302 // ToolMajor and ToolMinor 2303 float toolMajor, toolMinor; 2304 switch (mCalibration.toolSizeCalibration) { 2305 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 2306 toolMajor = in.toolMajor * mLocked.geometricScale; 2307 if (mRawAxes.toolMinor.valid) { 2308 toolMinor = in.toolMinor * mLocked.geometricScale; 2309 } else { 2310 toolMinor = toolMajor; 2311 } 2312 break; 2313 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 2314 toolMajor = in.toolMajor != 0 2315 ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias 2316 : 0; 2317 if (mRawAxes.toolMinor.valid) { 2318 toolMinor = in.toolMinor != 0 2319 ? in.toolMinor * mLocked.toolSizeLinearScale 2320 + mLocked.toolSizeLinearBias 2321 : 0; 2322 } else { 2323 toolMinor = toolMajor; 2324 } 2325 break; 2326 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 2327 if (in.toolMajor != 0) { 2328 float diameter = sqrtf(in.toolMajor 2329 * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias); 2330 toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias; 2331 } else { 2332 toolMajor = 0; 2333 } 2334 toolMinor = toolMajor; 2335 break; 2336 default: 2337 toolMajor = 0; 2338 toolMinor = 0; 2339 break; 2340 } 2341 2342 if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) { 2343 toolMajor /= pointerCount; 2344 toolMinor /= pointerCount; 2345 } 2346 2347 // Pressure 2348 float rawPressure; 2349 switch (mCalibration.pressureSource) { 2350 case Calibration::PRESSURE_SOURCE_PRESSURE: 2351 rawPressure = in.pressure; 2352 break; 2353 case Calibration::PRESSURE_SOURCE_TOUCH: 2354 rawPressure = in.touchMajor; 2355 break; 2356 default: 2357 rawPressure = 0; 2358 } 2359 2360 float pressure; 2361 switch (mCalibration.pressureCalibration) { 2362 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 2363 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 2364 pressure = rawPressure * mLocked.pressureScale; 2365 break; 2366 default: 2367 pressure = 1; 2368 break; 2369 } 2370 2371 // TouchMajor and TouchMinor 2372 float touchMajor, touchMinor; 2373 switch (mCalibration.touchSizeCalibration) { 2374 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 2375 touchMajor = in.touchMajor * mLocked.geometricScale; 2376 if (mRawAxes.touchMinor.valid) { 2377 touchMinor = in.touchMinor * mLocked.geometricScale; 2378 } else { 2379 touchMinor = touchMajor; 2380 } 2381 break; 2382 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 2383 touchMajor = toolMajor * pressure; 2384 touchMinor = toolMinor * pressure; 2385 break; 2386 default: 2387 touchMajor = 0; 2388 touchMinor = 0; 2389 break; 2390 } 2391 2392 if (touchMajor > toolMajor) { 2393 touchMajor = toolMajor; 2394 } 2395 if (touchMinor > toolMinor) { 2396 touchMinor = toolMinor; 2397 } 2398 2399 // Size 2400 float size; 2401 switch (mCalibration.sizeCalibration) { 2402 case Calibration::SIZE_CALIBRATION_NORMALIZED: { 2403 float rawSize = mRawAxes.toolMinor.valid 2404 ? avg(in.toolMajor, in.toolMinor) 2405 : in.toolMajor; 2406 size = rawSize * mLocked.sizeScale; 2407 break; 2408 } 2409 default: 2410 size = 0; 2411 break; 2412 } 2413 2414 // Orientation 2415 float orientation; 2416 switch (mCalibration.orientationCalibration) { 2417 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 2418 orientation = in.orientation * mLocked.orientationScale; 2419 break; 2420 default: 2421 orientation = 0; 2422 } 2423 2424 // Adjust coords for orientation. 2425 switch (mLocked.surfaceOrientation) { 2426 case InputReaderPolicyInterface::ROTATION_90: { 2427 float xTemp = x; 2428 x = y; 2429 y = mLocked.surfaceWidth - xTemp; 2430 orientation -= M_PI_2; 2431 if (orientation < - M_PI_2) { 2432 orientation += M_PI; 2433 } 2434 break; 2435 } 2436 case InputReaderPolicyInterface::ROTATION_180: { 2437 x = mLocked.surfaceWidth - x; 2438 y = mLocked.surfaceHeight - y; 2439 orientation = - orientation; 2440 break; 2441 } 2442 case InputReaderPolicyInterface::ROTATION_270: { 2443 float xTemp = x; 2444 x = mLocked.surfaceHeight - y; 2445 y = xTemp; 2446 orientation += M_PI_2; 2447 if (orientation > M_PI_2) { 2448 orientation -= M_PI; 2449 } 2450 break; 2451 } 2452 } 2453 2454 // Write output coords. 2455 PointerCoords& out = pointerCoords[outIndex]; 2456 out.x = x; 2457 out.y = y; 2458 out.pressure = pressure; 2459 out.size = size; 2460 out.touchMajor = touchMajor; 2461 out.touchMinor = touchMinor; 2462 out.toolMajor = toolMajor; 2463 out.toolMinor = toolMinor; 2464 out.orientation = orientation; 2465 2466 pointerIds[outIndex] = int32_t(id); 2467 2468 if (id == changedId) { 2469 motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 2470 } 2471 } 2472 2473 // Check edge flags by looking only at the first pointer since the flags are 2474 // global to the event. 2475 if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { 2476 if (pointerCoords[0].x <= 0) { 2477 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; 2478 } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) { 2479 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; 2480 } 2481 if (pointerCoords[0].y <= 0) { 2482 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; 2483 } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) { 2484 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; 2485 } 2486 } 2487 2488 xPrecision = mLocked.orientedXPrecision; 2489 yPrecision = mLocked.orientedYPrecision; 2490 } // release lock 2491 2492 getDispatcher()->notifyMotion(when, getDeviceId(), getSources(), policyFlags, 2493 motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags, 2494 pointerCount, pointerIds, pointerCoords, 2495 xPrecision, yPrecision, mDownTime); 2496 } 2497 2498 bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) { 2499 if (mRawAxes.x.valid && mRawAxes.y.valid) { 2500 return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue 2501 && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue; 2502 } 2503 return true; 2504 } 2505 2506 const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked( 2507 int32_t x, int32_t y) { 2508 size_t numVirtualKeys = mLocked.virtualKeys.size(); 2509 for (size_t i = 0; i < numVirtualKeys; i++) { 2510 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 2511 2512 #if DEBUG_VIRTUAL_KEYS 2513 LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, " 2514 "left=%d, top=%d, right=%d, bottom=%d", 2515 x, y, 2516 virtualKey.keyCode, virtualKey.scanCode, 2517 virtualKey.hitLeft, virtualKey.hitTop, 2518 virtualKey.hitRight, virtualKey.hitBottom); 2519 #endif 2520 2521 if (virtualKey.isHit(x, y)) { 2522 return & virtualKey; 2523 } 2524 } 2525 2526 return NULL; 2527 } 2528 2529 void TouchInputMapper::calculatePointerIds() { 2530 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 2531 uint32_t lastPointerCount = mLastTouch.pointerCount; 2532 2533 if (currentPointerCount == 0) { 2534 // No pointers to assign. 2535 mCurrentTouch.idBits.clear(); 2536 } else if (lastPointerCount == 0) { 2537 // All pointers are new. 2538 mCurrentTouch.idBits.clear(); 2539 for (uint32_t i = 0; i < currentPointerCount; i++) { 2540 mCurrentTouch.pointers[i].id = i; 2541 mCurrentTouch.idToIndex[i] = i; 2542 mCurrentTouch.idBits.markBit(i); 2543 } 2544 } else if (currentPointerCount == 1 && lastPointerCount == 1) { 2545 // Only one pointer and no change in count so it must have the same id as before. 2546 uint32_t id = mLastTouch.pointers[0].id; 2547 mCurrentTouch.pointers[0].id = id; 2548 mCurrentTouch.idToIndex[id] = 0; 2549 mCurrentTouch.idBits.value = BitSet32::valueForBit(id); 2550 } else { 2551 // General case. 2552 // We build a heap of squared euclidean distances between current and last pointers 2553 // associated with the current and last pointer indices. Then, we find the best 2554 // match (by distance) for each current pointer. 2555 PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS]; 2556 2557 uint32_t heapSize = 0; 2558 for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount; 2559 currentPointerIndex++) { 2560 for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount; 2561 lastPointerIndex++) { 2562 int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x 2563 - mLastTouch.pointers[lastPointerIndex].x; 2564 int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y 2565 - mLastTouch.pointers[lastPointerIndex].y; 2566 2567 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); 2568 2569 // Insert new element into the heap (sift up). 2570 heap[heapSize].currentPointerIndex = currentPointerIndex; 2571 heap[heapSize].lastPointerIndex = lastPointerIndex; 2572 heap[heapSize].distance = distance; 2573 heapSize += 1; 2574 } 2575 } 2576 2577 // Heapify 2578 for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) { 2579 startIndex -= 1; 2580 for (uint32_t parentIndex = startIndex; ;) { 2581 uint32_t childIndex = parentIndex * 2 + 1; 2582 if (childIndex >= heapSize) { 2583 break; 2584 } 2585 2586 if (childIndex + 1 < heapSize 2587 && heap[childIndex + 1].distance < heap[childIndex].distance) { 2588 childIndex += 1; 2589 } 2590 2591 if (heap[parentIndex].distance <= heap[childIndex].distance) { 2592 break; 2593 } 2594 2595 swap(heap[parentIndex], heap[childIndex]); 2596 parentIndex = childIndex; 2597 } 2598 } 2599 2600 #if DEBUG_POINTER_ASSIGNMENT 2601 LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize); 2602 for (size_t i = 0; i < heapSize; i++) { 2603 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 2604 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 2605 heap[i].distance); 2606 } 2607 #endif 2608 2609 // Pull matches out by increasing order of distance. 2610 // To avoid reassigning pointers that have already been matched, the loop keeps track 2611 // of which last and current pointers have been matched using the matchedXXXBits variables. 2612 // It also tracks the used pointer id bits. 2613 BitSet32 matchedLastBits(0); 2614 BitSet32 matchedCurrentBits(0); 2615 BitSet32 usedIdBits(0); 2616 bool first = true; 2617 for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) { 2618 for (;;) { 2619 if (first) { 2620 // The first time through the loop, we just consume the root element of 2621 // the heap (the one with smallest distance). 2622 first = false; 2623 } else { 2624 // Previous iterations consumed the root element of the heap. 2625 // Pop root element off of the heap (sift down). 2626 heapSize -= 1; 2627 assert(heapSize > 0); 2628 2629 // Sift down. 2630 heap[0] = heap[heapSize]; 2631 for (uint32_t parentIndex = 0; ;) { 2632 uint32_t childIndex = parentIndex * 2 + 1; 2633 if (childIndex >= heapSize) { 2634 break; 2635 } 2636 2637 if (childIndex + 1 < heapSize 2638 && heap[childIndex + 1].distance < heap[childIndex].distance) { 2639 childIndex += 1; 2640 } 2641 2642 if (heap[parentIndex].distance <= heap[childIndex].distance) { 2643 break; 2644 } 2645 2646 swap(heap[parentIndex], heap[childIndex]); 2647 parentIndex = childIndex; 2648 } 2649 2650 #if DEBUG_POINTER_ASSIGNMENT 2651 LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize); 2652 for (size_t i = 0; i < heapSize; i++) { 2653 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 2654 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 2655 heap[i].distance); 2656 } 2657 #endif 2658 } 2659 2660 uint32_t currentPointerIndex = heap[0].currentPointerIndex; 2661 if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched 2662 2663 uint32_t lastPointerIndex = heap[0].lastPointerIndex; 2664 if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched 2665 2666 matchedCurrentBits.markBit(currentPointerIndex); 2667 matchedLastBits.markBit(lastPointerIndex); 2668 2669 uint32_t id = mLastTouch.pointers[lastPointerIndex].id; 2670 mCurrentTouch.pointers[currentPointerIndex].id = id; 2671 mCurrentTouch.idToIndex[id] = currentPointerIndex; 2672 usedIdBits.markBit(id); 2673 2674 #if DEBUG_POINTER_ASSIGNMENT 2675 LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld", 2676 lastPointerIndex, currentPointerIndex, id, heap[0].distance); 2677 #endif 2678 break; 2679 } 2680 } 2681 2682 // Assign fresh ids to new pointers. 2683 if (currentPointerCount > lastPointerCount) { 2684 for (uint32_t i = currentPointerCount - lastPointerCount; ;) { 2685 uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit(); 2686 uint32_t id = usedIdBits.firstUnmarkedBit(); 2687 2688 mCurrentTouch.pointers[currentPointerIndex].id = id; 2689 mCurrentTouch.idToIndex[id] = currentPointerIndex; 2690 usedIdBits.markBit(id); 2691 2692 #if DEBUG_POINTER_ASSIGNMENT 2693 LOGD("calculatePointerIds - assigned: cur=%d, id=%d", 2694 currentPointerIndex, id); 2695 #endif 2696 2697 if (--i == 0) break; // done 2698 matchedCurrentBits.markBit(currentPointerIndex); 2699 } 2700 } 2701 2702 // Fix id bits. 2703 mCurrentTouch.idBits = usedIdBits; 2704 } 2705 } 2706 2707 /* Special hack for devices that have bad screen data: if one of the 2708 * points has moved more than a screen height from the last position, 2709 * then drop it. */ 2710 bool TouchInputMapper::applyBadTouchFilter() { 2711 // This hack requires valid axis parameters. 2712 if (! mRawAxes.y.valid) { 2713 return false; 2714 } 2715 2716 uint32_t pointerCount = mCurrentTouch.pointerCount; 2717 2718 // Nothing to do if there are no points. 2719 if (pointerCount == 0) { 2720 return false; 2721 } 2722 2723 // Don't do anything if a finger is going down or up. We run 2724 // here before assigning pointer IDs, so there isn't a good 2725 // way to do per-finger matching. 2726 if (pointerCount != mLastTouch.pointerCount) { 2727 return false; 2728 } 2729 2730 // We consider a single movement across more than a 7/16 of 2731 // the long size of the screen to be bad. This was a magic value 2732 // determined by looking at the maximum distance it is feasible 2733 // to actually move in one sample. 2734 int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16; 2735 2736 // XXX The original code in InputDevice.java included commented out 2737 // code for testing the X axis. Note that when we drop a point 2738 // we don't actually restore the old X either. Strange. 2739 // The old code also tries to track when bad points were previously 2740 // detected but it turns out that due to the placement of a "break" 2741 // at the end of the loop, we never set mDroppedBadPoint to true 2742 // so it is effectively dead code. 2743 // Need to figure out if the old code is busted or just overcomplicated 2744 // but working as intended. 2745 2746 // Look through all new points and see if any are farther than 2747 // acceptable from all previous points. 2748 for (uint32_t i = pointerCount; i-- > 0; ) { 2749 int32_t y = mCurrentTouch.pointers[i].y; 2750 int32_t closestY = INT_MAX; 2751 int32_t closestDeltaY = 0; 2752 2753 #if DEBUG_HACKS 2754 LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y); 2755 #endif 2756 2757 for (uint32_t j = pointerCount; j-- > 0; ) { 2758 int32_t lastY = mLastTouch.pointers[j].y; 2759 int32_t deltaY = abs(y - lastY); 2760 2761 #if DEBUG_HACKS 2762 LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d", 2763 j, lastY, deltaY); 2764 #endif 2765 2766 if (deltaY < maxDeltaY) { 2767 goto SkipSufficientlyClosePoint; 2768 } 2769 if (deltaY < closestDeltaY) { 2770 closestDeltaY = deltaY; 2771 closestY = lastY; 2772 } 2773 } 2774 2775 // Must not have found a close enough match. 2776 #if DEBUG_HACKS 2777 LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d", 2778 i, y, closestY, closestDeltaY, maxDeltaY); 2779 #endif 2780 2781 mCurrentTouch.pointers[i].y = closestY; 2782 return true; // XXX original code only corrects one point 2783 2784 SkipSufficientlyClosePoint: ; 2785 } 2786 2787 // No change. 2788 return false; 2789 } 2790 2791 /* Special hack for devices that have bad screen data: drop points where 2792 * the coordinate value for one axis has jumped to the other pointer's location. 2793 */ 2794 bool TouchInputMapper::applyJumpyTouchFilter() { 2795 // This hack requires valid axis parameters. 2796 if (! mRawAxes.y.valid) { 2797 return false; 2798 } 2799 2800 uint32_t pointerCount = mCurrentTouch.pointerCount; 2801 if (mLastTouch.pointerCount != pointerCount) { 2802 #if DEBUG_HACKS 2803 LOGD("JumpyTouchFilter: Different pointer count %d -> %d", 2804 mLastTouch.pointerCount, pointerCount); 2805 for (uint32_t i = 0; i < pointerCount; i++) { 2806 LOGD(" Pointer %d (%d, %d)", i, 2807 mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); 2808 } 2809 #endif 2810 2811 if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) { 2812 if (mLastTouch.pointerCount == 1 && pointerCount == 2) { 2813 // Just drop the first few events going from 1 to 2 pointers. 2814 // They're bad often enough that they're not worth considering. 2815 mCurrentTouch.pointerCount = 1; 2816 mJumpyTouchFilter.jumpyPointsDropped += 1; 2817 2818 #if DEBUG_HACKS 2819 LOGD("JumpyTouchFilter: Pointer 2 dropped"); 2820 #endif 2821 return true; 2822 } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) { 2823 // The event when we go from 2 -> 1 tends to be messed up too 2824 mCurrentTouch.pointerCount = 2; 2825 mCurrentTouch.pointers[0] = mLastTouch.pointers[0]; 2826 mCurrentTouch.pointers[1] = mLastTouch.pointers[1]; 2827 mJumpyTouchFilter.jumpyPointsDropped += 1; 2828 2829 #if DEBUG_HACKS 2830 for (int32_t i = 0; i < 2; i++) { 2831 LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i, 2832 mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); 2833 } 2834 #endif 2835 return true; 2836 } 2837 } 2838 // Reset jumpy points dropped on other transitions or if limit exceeded. 2839 mJumpyTouchFilter.jumpyPointsDropped = 0; 2840 2841 #if DEBUG_HACKS 2842 LOGD("JumpyTouchFilter: Transition - drop limit reset"); 2843 #endif 2844 return false; 2845 } 2846 2847 // We have the same number of pointers as last time. 2848 // A 'jumpy' point is one where the coordinate value for one axis 2849 // has jumped to the other pointer's location. No need to do anything 2850 // else if we only have one pointer. 2851 if (pointerCount < 2) { 2852 return false; 2853 } 2854 2855 if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) { 2856 int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR; 2857 2858 // We only replace the single worst jumpy point as characterized by pointer distance 2859 // in a single axis. 2860 int32_t badPointerIndex = -1; 2861 int32_t badPointerReplacementIndex = -1; 2862 int32_t badPointerDistance = INT_MIN; // distance to be corrected 2863 2864 for (uint32_t i = pointerCount; i-- > 0; ) { 2865 int32_t x = mCurrentTouch.pointers[i].x; 2866 int32_t y = mCurrentTouch.pointers[i].y; 2867 2868 #if DEBUG_HACKS 2869 LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y); 2870 #endif 2871 2872 // Check if a touch point is too close to another's coordinates 2873 bool dropX = false, dropY = false; 2874 for (uint32_t j = 0; j < pointerCount; j++) { 2875 if (i == j) { 2876 continue; 2877 } 2878 2879 if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) { 2880 dropX = true; 2881 break; 2882 } 2883 2884 if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) { 2885 dropY = true; 2886 break; 2887 } 2888 } 2889 if (! dropX && ! dropY) { 2890 continue; // not jumpy 2891 } 2892 2893 // Find a replacement candidate by comparing with older points on the 2894 // complementary (non-jumpy) axis. 2895 int32_t distance = INT_MIN; // distance to be corrected 2896 int32_t replacementIndex = -1; 2897 2898 if (dropX) { 2899 // X looks too close. Find an older replacement point with a close Y. 2900 int32_t smallestDeltaY = INT_MAX; 2901 for (uint32_t j = 0; j < pointerCount; j++) { 2902 int32_t deltaY = abs(y - mLastTouch.pointers[j].y); 2903 if (deltaY < smallestDeltaY) { 2904 smallestDeltaY = deltaY; 2905 replacementIndex = j; 2906 } 2907 } 2908 distance = abs(x - mLastTouch.pointers[replacementIndex].x); 2909 } else { 2910 // Y looks too close. Find an older replacement point with a close X. 2911 int32_t smallestDeltaX = INT_MAX; 2912 for (uint32_t j = 0; j < pointerCount; j++) { 2913 int32_t deltaX = abs(x - mLastTouch.pointers[j].x); 2914 if (deltaX < smallestDeltaX) { 2915 smallestDeltaX = deltaX; 2916 replacementIndex = j; 2917 } 2918 } 2919 distance = abs(y - mLastTouch.pointers[replacementIndex].y); 2920 } 2921 2922 // If replacing this pointer would correct a worse error than the previous ones 2923 // considered, then use this replacement instead. 2924 if (distance > badPointerDistance) { 2925 badPointerIndex = i; 2926 badPointerReplacementIndex = replacementIndex; 2927 badPointerDistance = distance; 2928 } 2929 } 2930 2931 // Correct the jumpy pointer if one was found. 2932 if (badPointerIndex >= 0) { 2933 #if DEBUG_HACKS 2934 LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)", 2935 badPointerIndex, 2936 mLastTouch.pointers[badPointerReplacementIndex].x, 2937 mLastTouch.pointers[badPointerReplacementIndex].y); 2938 #endif 2939 2940 mCurrentTouch.pointers[badPointerIndex].x = 2941 mLastTouch.pointers[badPointerReplacementIndex].x; 2942 mCurrentTouch.pointers[badPointerIndex].y = 2943 mLastTouch.pointers[badPointerReplacementIndex].y; 2944 mJumpyTouchFilter.jumpyPointsDropped += 1; 2945 return true; 2946 } 2947 } 2948 2949 mJumpyTouchFilter.jumpyPointsDropped = 0; 2950 return false; 2951 } 2952 2953 /* Special hack for devices that have bad screen data: aggregate and 2954 * compute averages of the coordinate data, to reduce the amount of 2955 * jitter seen by applications. */ 2956 void TouchInputMapper::applyAveragingTouchFilter() { 2957 for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) { 2958 uint32_t id = mCurrentTouch.pointers[currentIndex].id; 2959 int32_t x = mCurrentTouch.pointers[currentIndex].x; 2960 int32_t y = mCurrentTouch.pointers[currentIndex].y; 2961 int32_t pressure; 2962 switch (mCalibration.pressureSource) { 2963 case Calibration::PRESSURE_SOURCE_PRESSURE: 2964 pressure = mCurrentTouch.pointers[currentIndex].pressure; 2965 break; 2966 case Calibration::PRESSURE_SOURCE_TOUCH: 2967 pressure = mCurrentTouch.pointers[currentIndex].touchMajor; 2968 break; 2969 default: 2970 pressure = 1; 2971 break; 2972 } 2973 2974 if (mLastTouch.idBits.hasBit(id)) { 2975 // Pointer was down before and is still down now. 2976 // Compute average over history trace. 2977 uint32_t start = mAveragingTouchFilter.historyStart[id]; 2978 uint32_t end = mAveragingTouchFilter.historyEnd[id]; 2979 2980 int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x; 2981 int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y; 2982 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); 2983 2984 #if DEBUG_HACKS 2985 LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld", 2986 id, distance); 2987 #endif 2988 2989 if (distance < AVERAGING_DISTANCE_LIMIT) { 2990 // Increment end index in preparation for recording new historical data. 2991 end += 1; 2992 if (end > AVERAGING_HISTORY_SIZE) { 2993 end = 0; 2994 } 2995 2996 // If the end index has looped back to the start index then we have filled 2997 // the historical trace up to the desired size so we drop the historical 2998 // data at the start of the trace. 2999 if (end == start) { 3000 start += 1; 3001 if (start > AVERAGING_HISTORY_SIZE) { 3002 start = 0; 3003 } 3004 } 3005 3006 // Add the raw data to the historical trace. 3007 mAveragingTouchFilter.historyStart[id] = start; 3008 mAveragingTouchFilter.historyEnd[id] = end; 3009 mAveragingTouchFilter.historyData[end].pointers[id].x = x; 3010 mAveragingTouchFilter.historyData[end].pointers[id].y = y; 3011 mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure; 3012 3013 // Average over all historical positions in the trace by total pressure. 3014 int32_t averagedX = 0; 3015 int32_t averagedY = 0; 3016 int32_t totalPressure = 0; 3017 for (;;) { 3018 int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x; 3019 int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y; 3020 int32_t historicalPressure = mAveragingTouchFilter.historyData[start] 3021 .pointers[id].pressure; 3022 3023 averagedX += historicalX * historicalPressure; 3024 averagedY += historicalY * historicalPressure; 3025 totalPressure += historicalPressure; 3026 3027 if (start == end) { 3028 break; 3029 } 3030 3031 start += 1; 3032 if (start > AVERAGING_HISTORY_SIZE) { 3033 start = 0; 3034 } 3035 } 3036 3037 if (totalPressure != 0) { 3038 averagedX /= totalPressure; 3039 averagedY /= totalPressure; 3040 3041 #if DEBUG_HACKS 3042 LOGD("AveragingTouchFilter: Pointer id %d - " 3043 "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure, 3044 averagedX, averagedY); 3045 #endif 3046 3047 mCurrentTouch.pointers[currentIndex].x = averagedX; 3048 mCurrentTouch.pointers[currentIndex].y = averagedY; 3049 } 3050 } else { 3051 #if DEBUG_HACKS 3052 LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id); 3053 #endif 3054 } 3055 } else { 3056 #if DEBUG_HACKS 3057 LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id); 3058 #endif 3059 } 3060 3061 // Reset pointer history. 3062 mAveragingTouchFilter.historyStart[id] = 0; 3063 mAveragingTouchFilter.historyEnd[id] = 0; 3064 mAveragingTouchFilter.historyData[0].pointers[id].x = x; 3065 mAveragingTouchFilter.historyData[0].pointers[id].y = y; 3066 mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure; 3067 } 3068 } 3069 3070 int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 3071 { // acquire lock 3072 AutoMutex _l(mLock); 3073 3074 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) { 3075 return AKEY_STATE_VIRTUAL; 3076 } 3077 3078 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3079 for (size_t i = 0; i < numVirtualKeys; i++) { 3080 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3081 if (virtualKey.keyCode == keyCode) { 3082 return AKEY_STATE_UP; 3083 } 3084 } 3085 } // release lock 3086 3087 return AKEY_STATE_UNKNOWN; 3088 } 3089 3090 int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 3091 { // acquire lock 3092 AutoMutex _l(mLock); 3093 3094 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) { 3095 return AKEY_STATE_VIRTUAL; 3096 } 3097 3098 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3099 for (size_t i = 0; i < numVirtualKeys; i++) { 3100 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3101 if (virtualKey.scanCode == scanCode) { 3102 return AKEY_STATE_UP; 3103 } 3104 } 3105 } // release lock 3106 3107 return AKEY_STATE_UNKNOWN; 3108 } 3109 3110 bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 3111 const int32_t* keyCodes, uint8_t* outFlags) { 3112 { // acquire lock 3113 AutoMutex _l(mLock); 3114 3115 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3116 for (size_t i = 0; i < numVirtualKeys; i++) { 3117 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3118 3119 for (size_t i = 0; i < numCodes; i++) { 3120 if (virtualKey.keyCode == keyCodes[i]) { 3121 outFlags[i] = 1; 3122 } 3123 } 3124 } 3125 } // release lock 3126 3127 return true; 3128 } 3129 3130 3131 // --- SingleTouchInputMapper --- 3132 3133 SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) : 3134 TouchInputMapper(device, associatedDisplayId) { 3135 initialize(); 3136 } 3137 3138 SingleTouchInputMapper::~SingleTouchInputMapper() { 3139 } 3140 3141 void SingleTouchInputMapper::initialize() { 3142 mAccumulator.clear(); 3143 3144 mDown = false; 3145 mX = 0; 3146 mY = 0; 3147 mPressure = 0; // default to 0 for devices that don't report pressure 3148 mToolWidth = 0; // default to 0 for devices that don't report tool width 3149 } 3150 3151 void SingleTouchInputMapper::reset() { 3152 TouchInputMapper::reset(); 3153 3154 initialize(); 3155 } 3156 3157 void SingleTouchInputMapper::process(const RawEvent* rawEvent) { 3158 switch (rawEvent->type) { 3159 case EV_KEY: 3160 switch (rawEvent->scanCode) { 3161 case BTN_TOUCH: 3162 mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH; 3163 mAccumulator.btnTouch = rawEvent->value != 0; 3164 // Don't sync immediately. Wait until the next SYN_REPORT since we might 3165 // not have received valid position information yet. This logic assumes that 3166 // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet. 3167 break; 3168 } 3169 break; 3170 3171 case EV_ABS: 3172 switch (rawEvent->scanCode) { 3173 case ABS_X: 3174 mAccumulator.fields |= Accumulator::FIELD_ABS_X; 3175 mAccumulator.absX = rawEvent->value; 3176 break; 3177 case ABS_Y: 3178 mAccumulator.fields |= Accumulator::FIELD_ABS_Y; 3179 mAccumulator.absY = rawEvent->value; 3180 break; 3181 case ABS_PRESSURE: 3182 mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE; 3183 mAccumulator.absPressure = rawEvent->value; 3184 break; 3185 case ABS_TOOL_WIDTH: 3186 mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH; 3187 mAccumulator.absToolWidth = rawEvent->value; 3188 break; 3189 } 3190 break; 3191 3192 case EV_SYN: 3193 switch (rawEvent->scanCode) { 3194 case SYN_REPORT: 3195 sync(rawEvent->when); 3196 break; 3197 } 3198 break; 3199 } 3200 } 3201 3202 void SingleTouchInputMapper::sync(nsecs_t when) { 3203 uint32_t fields = mAccumulator.fields; 3204 if (fields == 0) { 3205 return; // no new state changes, so nothing to do 3206 } 3207 3208 if (fields & Accumulator::FIELD_BTN_TOUCH) { 3209 mDown = mAccumulator.btnTouch; 3210 } 3211 3212 if (fields & Accumulator::FIELD_ABS_X) { 3213 mX = mAccumulator.absX; 3214 } 3215 3216 if (fields & Accumulator::FIELD_ABS_Y) { 3217 mY = mAccumulator.absY; 3218 } 3219 3220 if (fields & Accumulator::FIELD_ABS_PRESSURE) { 3221 mPressure = mAccumulator.absPressure; 3222 } 3223 3224 if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) { 3225 mToolWidth = mAccumulator.absToolWidth; 3226 } 3227 3228 mCurrentTouch.clear(); 3229 3230 if (mDown) { 3231 mCurrentTouch.pointerCount = 1; 3232 mCurrentTouch.pointers[0].id = 0; 3233 mCurrentTouch.pointers[0].x = mX; 3234 mCurrentTouch.pointers[0].y = mY; 3235 mCurrentTouch.pointers[0].pressure = mPressure; 3236 mCurrentTouch.pointers[0].touchMajor = 0; 3237 mCurrentTouch.pointers[0].touchMinor = 0; 3238 mCurrentTouch.pointers[0].toolMajor = mToolWidth; 3239 mCurrentTouch.pointers[0].toolMinor = mToolWidth; 3240 mCurrentTouch.pointers[0].orientation = 0; 3241 mCurrentTouch.idToIndex[0] = 0; 3242 mCurrentTouch.idBits.markBit(0); 3243 } 3244 3245 syncTouch(when, true); 3246 3247 mAccumulator.clear(); 3248 } 3249 3250 void SingleTouchInputMapper::configureRawAxes() { 3251 TouchInputMapper::configureRawAxes(); 3252 3253 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x); 3254 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y); 3255 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure); 3256 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor); 3257 } 3258 3259 3260 // --- MultiTouchInputMapper --- 3261 3262 MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) : 3263 TouchInputMapper(device, associatedDisplayId) { 3264 initialize(); 3265 } 3266 3267 MultiTouchInputMapper::~MultiTouchInputMapper() { 3268 } 3269 3270 void MultiTouchInputMapper::initialize() { 3271 mAccumulator.clear(); 3272 } 3273 3274 void MultiTouchInputMapper::reset() { 3275 TouchInputMapper::reset(); 3276 3277 initialize(); 3278 } 3279 3280 void MultiTouchInputMapper::process(const RawEvent* rawEvent) { 3281 switch (rawEvent->type) { 3282 case EV_ABS: { 3283 uint32_t pointerIndex = mAccumulator.pointerCount; 3284 Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex]; 3285 3286 switch (rawEvent->scanCode) { 3287 case ABS_MT_POSITION_X: 3288 pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X; 3289 pointer->absMTPositionX = rawEvent->value; 3290 break; 3291 case ABS_MT_POSITION_Y: 3292 pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y; 3293 pointer->absMTPositionY = rawEvent->value; 3294 break; 3295 case ABS_MT_TOUCH_MAJOR: 3296 pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR; 3297 pointer->absMTTouchMajor = rawEvent->value; 3298 break; 3299 case ABS_MT_TOUCH_MINOR: 3300 pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR; 3301 pointer->absMTTouchMinor = rawEvent->value; 3302 break; 3303 case ABS_MT_WIDTH_MAJOR: 3304 pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR; 3305 pointer->absMTWidthMajor = rawEvent->value; 3306 break; 3307 case ABS_MT_WIDTH_MINOR: 3308 pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR; 3309 pointer->absMTWidthMinor = rawEvent->value; 3310 break; 3311 case ABS_MT_ORIENTATION: 3312 pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION; 3313 pointer->absMTOrientation = rawEvent->value; 3314 break; 3315 case ABS_MT_TRACKING_ID: 3316 pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID; 3317 pointer->absMTTrackingId = rawEvent->value; 3318 break; 3319 case ABS_MT_PRESSURE: 3320 pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE; 3321 pointer->absMTPressure = rawEvent->value; 3322 break; 3323 } 3324 break; 3325 } 3326 3327 case EV_SYN: 3328 switch (rawEvent->scanCode) { 3329 case SYN_MT_REPORT: { 3330 // MultiTouch Sync: The driver has returned all data for *one* of the pointers. 3331 uint32_t pointerIndex = mAccumulator.pointerCount; 3332 3333 if (mAccumulator.pointers[pointerIndex].fields) { 3334 if (pointerIndex == MAX_POINTERS) { 3335 LOGW("MultiTouch device driver returned more than maximum of %d pointers.", 3336 MAX_POINTERS); 3337 } else { 3338 pointerIndex += 1; 3339 mAccumulator.pointerCount = pointerIndex; 3340 } 3341 } 3342 3343 mAccumulator.pointers[pointerIndex].clear(); 3344 break; 3345 } 3346 3347 case SYN_REPORT: 3348 sync(rawEvent->when); 3349 break; 3350 } 3351 break; 3352 } 3353 } 3354 3355 void MultiTouchInputMapper::sync(nsecs_t when) { 3356 static const uint32_t REQUIRED_FIELDS = 3357 Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y; 3358 3359 uint32_t inCount = mAccumulator.pointerCount; 3360 uint32_t outCount = 0; 3361 bool havePointerIds = true; 3362 3363 mCurrentTouch.clear(); 3364 3365 for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) { 3366 const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex]; 3367 uint32_t fields = inPointer.fields; 3368 3369 if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) { 3370 // Some drivers send empty MT sync packets without X / Y to indicate a pointer up. 3371 // Drop this finger. 3372 continue; 3373 } 3374 3375 PointerData& outPointer = mCurrentTouch.pointers[outCount]; 3376 outPointer.x = inPointer.absMTPositionX; 3377 outPointer.y = inPointer.absMTPositionY; 3378 3379 if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) { 3380 if (inPointer.absMTPressure <= 0) { 3381 // Some devices send sync packets with X / Y but with a 0 pressure to indicate 3382 // a pointer going up. Drop this finger. 3383 continue; 3384 } 3385 outPointer.pressure = inPointer.absMTPressure; 3386 } else { 3387 // Default pressure to 0 if absent. 3388 outPointer.pressure = 0; 3389 } 3390 3391 if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) { 3392 if (inPointer.absMTTouchMajor <= 0) { 3393 // Some devices send sync packets with X / Y but with a 0 touch major to indicate 3394 // a pointer going up. Drop this finger. 3395 continue; 3396 } 3397 outPointer.touchMajor = inPointer.absMTTouchMajor; 3398 } else { 3399 // Default touch area to 0 if absent. 3400 outPointer.touchMajor = 0; 3401 } 3402 3403 if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) { 3404 outPointer.touchMinor = inPointer.absMTTouchMinor; 3405 } else { 3406 // Assume touch area is circular. 3407 outPointer.touchMinor = outPointer.touchMajor; 3408 } 3409 3410 if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) { 3411 outPointer.toolMajor = inPointer.absMTWidthMajor; 3412 } else { 3413 // Default tool area to 0 if absent. 3414 outPointer.toolMajor = 0; 3415 } 3416 3417 if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) { 3418 outPointer.toolMinor = inPointer.absMTWidthMinor; 3419 } else { 3420 // Assume tool area is circular. 3421 outPointer.toolMinor = outPointer.toolMajor; 3422 } 3423 3424 if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) { 3425 outPointer.orientation = inPointer.absMTOrientation; 3426 } else { 3427 // Default orientation to vertical if absent. 3428 outPointer.orientation = 0; 3429 } 3430 3431 // Assign pointer id using tracking id if available. 3432 if (havePointerIds) { 3433 if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) { 3434 uint32_t id = uint32_t(inPointer.absMTTrackingId); 3435 3436 if (id > MAX_POINTER_ID) { 3437 #if DEBUG_POINTERS 3438 LOGD("Pointers: Ignoring driver provided pointer id %d because " 3439 "it is larger than max supported id %d", 3440 id, MAX_POINTER_ID); 3441 #endif 3442 havePointerIds = false; 3443 } 3444 else { 3445 outPointer.id = id; 3446 mCurrentTouch.idToIndex[id] = outCount; 3447 mCurrentTouch.idBits.markBit(id); 3448 } 3449 } else { 3450 havePointerIds = false; 3451 } 3452 } 3453 3454 outCount += 1; 3455 } 3456 3457 mCurrentTouch.pointerCount = outCount; 3458 3459 syncTouch(when, havePointerIds); 3460 3461 mAccumulator.clear(); 3462 } 3463 3464 void MultiTouchInputMapper::configureRawAxes() { 3465 TouchInputMapper::configureRawAxes(); 3466 3467 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x); 3468 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y); 3469 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor); 3470 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor); 3471 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor); 3472 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor); 3473 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation); 3474 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure); 3475 } 3476 3477 3478 } // namespace android 3479