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