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