InputReader.cpp revision bc68a59c024bdb745dac8e2ec7408a9f30595f1a
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// Log debug messages about gesture detection. 37#define DEBUG_GESTURES 0 38 39#include "InputReader.h" 40 41#include <cutils/log.h> 42#include <ui/Keyboard.h> 43#include <ui/VirtualKeyMap.h> 44 45#include <stddef.h> 46#include <stdlib.h> 47#include <unistd.h> 48#include <errno.h> 49#include <limits.h> 50#include <math.h> 51 52#define INDENT " " 53#define INDENT2 " " 54#define INDENT3 " " 55#define INDENT4 " " 56#define INDENT5 " " 57 58namespace android { 59 60// --- Constants --- 61 62// Maximum number of slots supported when using the slot-based Multitouch Protocol B. 63static const size_t MAX_SLOTS = 32; 64 65// --- Static Functions --- 66 67template<typename T> 68inline static T abs(const T& value) { 69 return value < 0 ? - value : value; 70} 71 72template<typename T> 73inline static T min(const T& a, const T& b) { 74 return a < b ? a : b; 75} 76 77template<typename T> 78inline static void swap(T& a, T& b) { 79 T temp = a; 80 a = b; 81 b = temp; 82} 83 84inline static float avg(float x, float y) { 85 return (x + y) / 2; 86} 87 88inline static float distance(float x1, float y1, float x2, float y2) { 89 return hypotf(x1 - x2, y1 - y2); 90} 91 92inline static int32_t signExtendNybble(int32_t value) { 93 return value >= 8 ? value - 16 : value; 94} 95 96static inline const char* toString(bool value) { 97 return value ? "true" : "false"; 98} 99 100static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation, 101 const int32_t map[][4], size_t mapSize) { 102 if (orientation != DISPLAY_ORIENTATION_0) { 103 for (size_t i = 0; i < mapSize; i++) { 104 if (value == map[i][0]) { 105 return map[i][orientation]; 106 } 107 } 108 } 109 return value; 110} 111 112static const int32_t keyCodeRotationMap[][4] = { 113 // key codes enumerated counter-clockwise with the original (unrotated) key first 114 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation 115 { AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT }, 116 { AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN }, 117 { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT }, 118 { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP }, 119}; 120static const size_t keyCodeRotationMapSize = 121 sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]); 122 123static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) { 124 return rotateValueUsingRotationMap(keyCode, orientation, 125 keyCodeRotationMap, keyCodeRotationMapSize); 126} 127 128static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) { 129 float temp; 130 switch (orientation) { 131 case DISPLAY_ORIENTATION_90: 132 temp = *deltaX; 133 *deltaX = *deltaY; 134 *deltaY = -temp; 135 break; 136 137 case DISPLAY_ORIENTATION_180: 138 *deltaX = -*deltaX; 139 *deltaY = -*deltaY; 140 break; 141 142 case DISPLAY_ORIENTATION_270: 143 temp = *deltaX; 144 *deltaX = -*deltaY; 145 *deltaY = temp; 146 break; 147 } 148} 149 150static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) { 151 return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0; 152} 153 154// Returns true if the pointer should be reported as being down given the specified 155// button states. This determines whether the event is reported as a touch event. 156static bool isPointerDown(int32_t buttonState) { 157 return buttonState & 158 (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY 159 | AMOTION_EVENT_BUTTON_TERTIARY); 160} 161 162static float calculateCommonVector(float a, float b) { 163 if (a > 0 && b > 0) { 164 return a < b ? a : b; 165 } else if (a < 0 && b < 0) { 166 return a > b ? a : b; 167 } else { 168 return 0; 169 } 170} 171 172static void synthesizeButtonKey(InputReaderContext* context, int32_t action, 173 nsecs_t when, int32_t deviceId, uint32_t source, 174 uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState, 175 int32_t buttonState, int32_t keyCode) { 176 if ( 177 (action == AKEY_EVENT_ACTION_DOWN 178 && !(lastButtonState & buttonState) 179 && (currentButtonState & buttonState)) 180 || (action == AKEY_EVENT_ACTION_UP 181 && (lastButtonState & buttonState) 182 && !(currentButtonState & buttonState))) { 183 context->getDispatcher()->notifyKey(when, deviceId, source, policyFlags, 184 action, 0, keyCode, 0, context->getGlobalMetaState(), when); 185 } 186} 187 188static void synthesizeButtonKeys(InputReaderContext* context, int32_t action, 189 nsecs_t when, int32_t deviceId, uint32_t source, 190 uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) { 191 synthesizeButtonKey(context, action, when, deviceId, source, policyFlags, 192 lastButtonState, currentButtonState, 193 AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK); 194 synthesizeButtonKey(context, action, when, deviceId, source, policyFlags, 195 lastButtonState, currentButtonState, 196 AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD); 197} 198 199 200// --- InputReader --- 201 202InputReader::InputReader(const sp<EventHubInterface>& eventHub, 203 const sp<InputReaderPolicyInterface>& policy, 204 const sp<InputDispatcherInterface>& dispatcher) : 205 mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher), 206 mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX), 207 mConfigurationChangesToRefresh(0) { 208 refreshConfiguration(0); 209 updateGlobalMetaState(); 210 updateInputConfiguration(); 211} 212 213InputReader::~InputReader() { 214 for (size_t i = 0; i < mDevices.size(); i++) { 215 delete mDevices.valueAt(i); 216 } 217} 218 219void InputReader::loopOnce() { 220 uint32_t changes; 221 { // acquire lock 222 AutoMutex _l(mStateLock); 223 224 changes = mConfigurationChangesToRefresh; 225 mConfigurationChangesToRefresh = 0; 226 } // release lock 227 228 if (changes) { 229 refreshConfiguration(changes); 230 } 231 232 int32_t timeoutMillis = -1; 233 if (mNextTimeout != LLONG_MAX) { 234 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 235 timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout); 236 } 237 238 size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); 239 if (count) { 240 processEvents(mEventBuffer, count); 241 } 242 if (!count || timeoutMillis == 0) { 243 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 244#if DEBUG_RAW_EVENTS 245 LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f); 246#endif 247 mNextTimeout = LLONG_MAX; 248 timeoutExpired(now); 249 } 250} 251 252void InputReader::processEvents(const RawEvent* rawEvents, size_t count) { 253 for (const RawEvent* rawEvent = rawEvents; count;) { 254 int32_t type = rawEvent->type; 255 size_t batchSize = 1; 256 if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) { 257 int32_t deviceId = rawEvent->deviceId; 258 while (batchSize < count) { 259 if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT 260 || rawEvent[batchSize].deviceId != deviceId) { 261 break; 262 } 263 batchSize += 1; 264 } 265#if DEBUG_RAW_EVENTS 266 LOGD("BatchSize: %d Count: %d", batchSize, count); 267#endif 268 processEventsForDevice(deviceId, rawEvent, batchSize); 269 } else { 270 switch (rawEvent->type) { 271 case EventHubInterface::DEVICE_ADDED: 272 addDevice(rawEvent->deviceId); 273 break; 274 case EventHubInterface::DEVICE_REMOVED: 275 removeDevice(rawEvent->deviceId); 276 break; 277 case EventHubInterface::FINISHED_DEVICE_SCAN: 278 handleConfigurationChanged(rawEvent->when); 279 break; 280 default: 281 LOG_ASSERT(false); // can't happen 282 break; 283 } 284 } 285 count -= batchSize; 286 rawEvent += batchSize; 287 } 288} 289 290void InputReader::addDevice(int32_t deviceId) { 291 String8 name = mEventHub->getDeviceName(deviceId); 292 uint32_t classes = mEventHub->getDeviceClasses(deviceId); 293 294 InputDevice* device = createDevice(deviceId, name, classes); 295 device->configure(&mConfig, 0); 296 297 if (device->isIgnored()) { 298 LOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, name.string()); 299 } else { 300 LOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, name.string(), 301 device->getSources()); 302 } 303 304 bool added = false; 305 { // acquire device registry writer lock 306 RWLock::AutoWLock _wl(mDeviceRegistryLock); 307 308 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 309 if (deviceIndex < 0) { 310 mDevices.add(deviceId, device); 311 added = true; 312 } 313 } // release device registry writer lock 314 315 if (! added) { 316 LOGW("Ignoring spurious device added event for deviceId %d.", deviceId); 317 delete device; 318 return; 319 } 320} 321 322void InputReader::removeDevice(int32_t deviceId) { 323 bool removed = false; 324 InputDevice* device = NULL; 325 { // acquire device registry writer lock 326 RWLock::AutoWLock _wl(mDeviceRegistryLock); 327 328 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 329 if (deviceIndex >= 0) { 330 device = mDevices.valueAt(deviceIndex); 331 mDevices.removeItemsAt(deviceIndex, 1); 332 removed = true; 333 } 334 } // release device registry writer lock 335 336 if (! removed) { 337 LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId); 338 return; 339 } 340 341 if (device->isIgnored()) { 342 LOGI("Device removed: id=%d, name='%s' (ignored non-input device)", 343 device->getId(), device->getName().string()); 344 } else { 345 LOGI("Device removed: id=%d, name='%s', sources=0x%08x", 346 device->getId(), device->getName().string(), device->getSources()); 347 } 348 349 device->reset(); 350 351 delete device; 352} 353 354InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) { 355 InputDevice* device = new InputDevice(this, deviceId, name); 356 357 // External devices. 358 if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { 359 device->setExternal(true); 360 } 361 362 // Switch-like devices. 363 if (classes & INPUT_DEVICE_CLASS_SWITCH) { 364 device->addMapper(new SwitchInputMapper(device)); 365 } 366 367 // Keyboard-like devices. 368 uint32_t keyboardSource = 0; 369 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC; 370 if (classes & INPUT_DEVICE_CLASS_KEYBOARD) { 371 keyboardSource |= AINPUT_SOURCE_KEYBOARD; 372 } 373 if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) { 374 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC; 375 } 376 if (classes & INPUT_DEVICE_CLASS_DPAD) { 377 keyboardSource |= AINPUT_SOURCE_DPAD; 378 } 379 if (classes & INPUT_DEVICE_CLASS_GAMEPAD) { 380 keyboardSource |= AINPUT_SOURCE_GAMEPAD; 381 } 382 383 if (keyboardSource != 0) { 384 device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType)); 385 } 386 387 // Cursor-like devices. 388 if (classes & INPUT_DEVICE_CLASS_CURSOR) { 389 device->addMapper(new CursorInputMapper(device)); 390 } 391 392 // Touchscreens and touchpad devices. 393 if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) { 394 device->addMapper(new MultiTouchInputMapper(device)); 395 } else if (classes & INPUT_DEVICE_CLASS_TOUCH) { 396 device->addMapper(new SingleTouchInputMapper(device)); 397 } 398 399 // Joystick-like devices. 400 if (classes & INPUT_DEVICE_CLASS_JOYSTICK) { 401 device->addMapper(new JoystickInputMapper(device)); 402 } 403 404 return device; 405} 406 407void InputReader::processEventsForDevice(int32_t deviceId, 408 const RawEvent* rawEvents, size_t count) { 409 { // acquire device registry reader lock 410 RWLock::AutoRLock _rl(mDeviceRegistryLock); 411 412 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 413 if (deviceIndex < 0) { 414 LOGW("Discarding event for unknown deviceId %d.", deviceId); 415 return; 416 } 417 418 InputDevice* device = mDevices.valueAt(deviceIndex); 419 if (device->isIgnored()) { 420 //LOGD("Discarding event for ignored deviceId %d.", deviceId); 421 return; 422 } 423 424 device->process(rawEvents, count); 425 } // release device registry reader lock 426} 427 428void InputReader::timeoutExpired(nsecs_t when) { 429 { // acquire device registry reader lock 430 RWLock::AutoRLock _rl(mDeviceRegistryLock); 431 432 for (size_t i = 0; i < mDevices.size(); i++) { 433 InputDevice* device = mDevices.valueAt(i); 434 if (!device->isIgnored()) { 435 device->timeoutExpired(when); 436 } 437 } 438 } // release device registry reader lock 439} 440 441void InputReader::handleConfigurationChanged(nsecs_t when) { 442 // Reset global meta state because it depends on the list of all configured devices. 443 updateGlobalMetaState(); 444 445 // Update input configuration. 446 updateInputConfiguration(); 447 448 // Enqueue configuration changed. 449 mDispatcher->notifyConfigurationChanged(when); 450} 451 452void InputReader::refreshConfiguration(uint32_t changes) { 453 mPolicy->getReaderConfiguration(&mConfig); 454 mEventHub->setExcludedDevices(mConfig.excludedDeviceNames); 455 456 if (changes) { 457 LOGI("Reconfiguring input devices. changes=0x%08x", changes); 458 459 if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) { 460 mEventHub->requestReopenDevices(); 461 } else { 462 { // acquire device registry reader lock 463 RWLock::AutoRLock _rl(mDeviceRegistryLock); 464 465 for (size_t i = 0; i < mDevices.size(); i++) { 466 InputDevice* device = mDevices.valueAt(i); 467 device->configure(&mConfig, changes); 468 } 469 } // release device registry reader lock 470 } 471 } 472} 473 474void InputReader::updateGlobalMetaState() { 475 { // acquire state lock 476 AutoMutex _l(mStateLock); 477 478 mGlobalMetaState = 0; 479 480 { // acquire device registry reader lock 481 RWLock::AutoRLock _rl(mDeviceRegistryLock); 482 483 for (size_t i = 0; i < mDevices.size(); i++) { 484 InputDevice* device = mDevices.valueAt(i); 485 mGlobalMetaState |= device->getMetaState(); 486 } 487 } // release device registry reader lock 488 } // release state lock 489} 490 491int32_t InputReader::getGlobalMetaState() { 492 { // acquire state lock 493 AutoMutex _l(mStateLock); 494 495 return mGlobalMetaState; 496 } // release state lock 497} 498 499void InputReader::updateInputConfiguration() { 500 { // acquire state lock 501 AutoMutex _l(mStateLock); 502 503 int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH; 504 int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS; 505 int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV; 506 { // acquire device registry reader lock 507 RWLock::AutoRLock _rl(mDeviceRegistryLock); 508 509 InputDeviceInfo deviceInfo; 510 for (size_t i = 0; i < mDevices.size(); i++) { 511 InputDevice* device = mDevices.valueAt(i); 512 device->getDeviceInfo(& deviceInfo); 513 uint32_t sources = deviceInfo.getSources(); 514 515 if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) { 516 touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER; 517 } 518 if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) { 519 navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL; 520 } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) { 521 navigationConfig = InputConfiguration::NAVIGATION_DPAD; 522 } 523 if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) { 524 keyboardConfig = InputConfiguration::KEYBOARD_QWERTY; 525 } 526 } 527 } // release device registry reader lock 528 529 mInputConfiguration.touchScreen = touchScreenConfig; 530 mInputConfiguration.keyboard = keyboardConfig; 531 mInputConfiguration.navigation = navigationConfig; 532 } // release state lock 533} 534 535void InputReader::disableVirtualKeysUntil(nsecs_t time) { 536 mDisableVirtualKeysTimeout = time; 537} 538 539bool InputReader::shouldDropVirtualKey(nsecs_t now, 540 InputDevice* device, int32_t keyCode, int32_t scanCode) { 541 if (now < mDisableVirtualKeysTimeout) { 542 LOGI("Dropping virtual key from device %s because virtual keys are " 543 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d", 544 device->getName().string(), 545 (mDisableVirtualKeysTimeout - now) * 0.000001, 546 keyCode, scanCode); 547 return true; 548 } else { 549 return false; 550 } 551} 552 553void InputReader::fadePointer() { 554 { // acquire device registry reader lock 555 RWLock::AutoRLock _rl(mDeviceRegistryLock); 556 557 for (size_t i = 0; i < mDevices.size(); i++) { 558 InputDevice* device = mDevices.valueAt(i); 559 device->fadePointer(); 560 } 561 } // release device registry reader lock 562} 563 564void InputReader::requestTimeoutAtTime(nsecs_t when) { 565 if (when < mNextTimeout) { 566 mNextTimeout = when; 567 } 568} 569 570void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) { 571 { // acquire state lock 572 AutoMutex _l(mStateLock); 573 574 *outConfiguration = mInputConfiguration; 575 } // release state lock 576} 577 578status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) { 579 { // acquire device registry reader lock 580 RWLock::AutoRLock _rl(mDeviceRegistryLock); 581 582 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 583 if (deviceIndex < 0) { 584 return NAME_NOT_FOUND; 585 } 586 587 InputDevice* device = mDevices.valueAt(deviceIndex); 588 if (device->isIgnored()) { 589 return NAME_NOT_FOUND; 590 } 591 592 device->getDeviceInfo(outDeviceInfo); 593 return OK; 594 } // release device registy reader lock 595} 596 597void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) { 598 outDeviceIds.clear(); 599 600 { // acquire device registry reader lock 601 RWLock::AutoRLock _rl(mDeviceRegistryLock); 602 603 size_t numDevices = mDevices.size(); 604 for (size_t i = 0; i < numDevices; i++) { 605 InputDevice* device = mDevices.valueAt(i); 606 if (! device->isIgnored()) { 607 outDeviceIds.add(device->getId()); 608 } 609 } 610 } // release device registy reader lock 611} 612 613int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, 614 int32_t keyCode) { 615 return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState); 616} 617 618int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, 619 int32_t scanCode) { 620 return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState); 621} 622 623int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) { 624 return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState); 625} 626 627int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code, 628 GetStateFunc getStateFunc) { 629 { // acquire device registry reader lock 630 RWLock::AutoRLock _rl(mDeviceRegistryLock); 631 632 int32_t result = AKEY_STATE_UNKNOWN; 633 if (deviceId >= 0) { 634 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 635 if (deviceIndex >= 0) { 636 InputDevice* device = mDevices.valueAt(deviceIndex); 637 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 638 result = (device->*getStateFunc)(sourceMask, code); 639 } 640 } 641 } else { 642 size_t numDevices = mDevices.size(); 643 for (size_t i = 0; i < numDevices; i++) { 644 InputDevice* device = mDevices.valueAt(i); 645 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 646 result = (device->*getStateFunc)(sourceMask, code); 647 if (result >= AKEY_STATE_DOWN) { 648 return result; 649 } 650 } 651 } 652 } 653 return result; 654 } // release device registy reader lock 655} 656 657bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, 658 size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) { 659 memset(outFlags, 0, numCodes); 660 return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags); 661} 662 663bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes, 664 const int32_t* keyCodes, uint8_t* outFlags) { 665 { // acquire device registry reader lock 666 RWLock::AutoRLock _rl(mDeviceRegistryLock); 667 bool result = false; 668 if (deviceId >= 0) { 669 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 670 if (deviceIndex >= 0) { 671 InputDevice* device = mDevices.valueAt(deviceIndex); 672 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 673 result = device->markSupportedKeyCodes(sourceMask, 674 numCodes, keyCodes, outFlags); 675 } 676 } 677 } else { 678 size_t numDevices = mDevices.size(); 679 for (size_t i = 0; i < numDevices; i++) { 680 InputDevice* device = mDevices.valueAt(i); 681 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 682 result |= device->markSupportedKeyCodes(sourceMask, 683 numCodes, keyCodes, outFlags); 684 } 685 } 686 } 687 return result; 688 } // release device registy reader lock 689} 690 691void InputReader::requestRefreshConfiguration(uint32_t changes) { 692 if (changes) { 693 bool needWake; 694 { // acquire lock 695 AutoMutex _l(mStateLock); 696 697 needWake = !mConfigurationChangesToRefresh; 698 mConfigurationChangesToRefresh |= changes; 699 } // release lock 700 701 if (needWake) { 702 mEventHub->wake(); 703 } 704 } 705} 706 707void InputReader::dump(String8& dump) { 708 mEventHub->dump(dump); 709 dump.append("\n"); 710 711 dump.append("Input Reader State:\n"); 712 713 { // acquire device registry reader lock 714 RWLock::AutoRLock _rl(mDeviceRegistryLock); 715 716 for (size_t i = 0; i < mDevices.size(); i++) { 717 mDevices.valueAt(i)->dump(dump); 718 } 719 } // release device registy reader lock 720 721 dump.append(INDENT "Configuration:\n"); 722 dump.append(INDENT2 "ExcludedDeviceNames: ["); 723 for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) { 724 if (i != 0) { 725 dump.append(", "); 726 } 727 dump.append(mConfig.excludedDeviceNames.itemAt(i).string()); 728 } 729 dump.append("]\n"); 730 dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n", 731 mConfig.virtualKeyQuietTime * 0.000001f); 732 733 dump.appendFormat(INDENT2 "PointerVelocityControlParameters: " 734 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n", 735 mConfig.pointerVelocityControlParameters.scale, 736 mConfig.pointerVelocityControlParameters.lowThreshold, 737 mConfig.pointerVelocityControlParameters.highThreshold, 738 mConfig.pointerVelocityControlParameters.acceleration); 739 740 dump.appendFormat(INDENT2 "WheelVelocityControlParameters: " 741 "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n", 742 mConfig.wheelVelocityControlParameters.scale, 743 mConfig.wheelVelocityControlParameters.lowThreshold, 744 mConfig.wheelVelocityControlParameters.highThreshold, 745 mConfig.wheelVelocityControlParameters.acceleration); 746 747 dump.appendFormat(INDENT2 "PointerGesture:\n"); 748 dump.appendFormat(INDENT3 "Enabled: %s\n", 749 toString(mConfig.pointerGesturesEnabled)); 750 dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n", 751 mConfig.pointerGestureQuietInterval * 0.000001f); 752 dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n", 753 mConfig.pointerGestureDragMinSwitchSpeed); 754 dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n", 755 mConfig.pointerGestureTapInterval * 0.000001f); 756 dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n", 757 mConfig.pointerGestureTapDragInterval * 0.000001f); 758 dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n", 759 mConfig.pointerGestureTapSlop); 760 dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n", 761 mConfig.pointerGestureMultitouchSettleInterval * 0.000001f); 762 dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n", 763 mConfig.pointerGestureMultitouchMinDistance); 764 dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n", 765 mConfig.pointerGestureSwipeTransitionAngleCosine); 766 dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n", 767 mConfig.pointerGestureSwipeMaxWidthRatio); 768 dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n", 769 mConfig.pointerGestureMovementSpeedRatio); 770 dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n", 771 mConfig.pointerGestureZoomSpeedRatio); 772} 773 774 775// --- InputReaderThread --- 776 777InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) : 778 Thread(/*canCallJava*/ true), mReader(reader) { 779} 780 781InputReaderThread::~InputReaderThread() { 782} 783 784bool InputReaderThread::threadLoop() { 785 mReader->loopOnce(); 786 return true; 787} 788 789 790// --- InputDevice --- 791 792InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) : 793 mContext(context), mId(id), mName(name), mSources(0), 794 mIsExternal(false), mDropUntilNextSync(false) { 795} 796 797InputDevice::~InputDevice() { 798 size_t numMappers = mMappers.size(); 799 for (size_t i = 0; i < numMappers; i++) { 800 delete mMappers[i]; 801 } 802 mMappers.clear(); 803} 804 805void InputDevice::dump(String8& dump) { 806 InputDeviceInfo deviceInfo; 807 getDeviceInfo(& deviceInfo); 808 809 dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(), 810 deviceInfo.getName().string()); 811 dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); 812 dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); 813 dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType()); 814 815 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges(); 816 if (!ranges.isEmpty()) { 817 dump.append(INDENT2 "Motion Ranges:\n"); 818 for (size_t i = 0; i < ranges.size(); i++) { 819 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i); 820 const char* label = getAxisLabel(range.axis); 821 char name[32]; 822 if (label) { 823 strncpy(name, label, sizeof(name)); 824 name[sizeof(name) - 1] = '\0'; 825 } else { 826 snprintf(name, sizeof(name), "%d", range.axis); 827 } 828 dump.appendFormat(INDENT3 "%s: source=0x%08x, " 829 "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n", 830 name, range.source, range.min, range.max, range.flat, range.fuzz); 831 } 832 } 833 834 size_t numMappers = mMappers.size(); 835 for (size_t i = 0; i < numMappers; i++) { 836 InputMapper* mapper = mMappers[i]; 837 mapper->dump(dump); 838 } 839} 840 841void InputDevice::addMapper(InputMapper* mapper) { 842 mMappers.add(mapper); 843} 844 845void InputDevice::configure(const InputReaderConfiguration* config, uint32_t changes) { 846 mSources = 0; 847 848 if (!isIgnored()) { 849 if (!changes) { // first time only 850 mContext->getEventHub()->getConfiguration(mId, &mConfiguration); 851 } 852 853 size_t numMappers = mMappers.size(); 854 for (size_t i = 0; i < numMappers; i++) { 855 InputMapper* mapper = mMappers[i]; 856 mapper->configure(config, changes); 857 mSources |= mapper->getSources(); 858 } 859 } 860} 861 862void InputDevice::reset() { 863 size_t numMappers = mMappers.size(); 864 for (size_t i = 0; i < numMappers; i++) { 865 InputMapper* mapper = mMappers[i]; 866 mapper->reset(); 867 } 868} 869 870void InputDevice::process(const RawEvent* rawEvents, size_t count) { 871 // Process all of the events in order for each mapper. 872 // We cannot simply ask each mapper to process them in bulk because mappers may 873 // have side-effects that must be interleaved. For example, joystick movement events and 874 // gamepad button presses are handled by different mappers but they should be dispatched 875 // in the order received. 876 size_t numMappers = mMappers.size(); 877 for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) { 878#if DEBUG_RAW_EVENTS 879 LOGD("Input event: device=%d type=0x%04x scancode=0x%04x " 880 "keycode=0x%04x value=0x%08x flags=0x%08x", 881 rawEvent->deviceId, rawEvent->type, rawEvent->scanCode, rawEvent->keyCode, 882 rawEvent->value, rawEvent->flags); 883#endif 884 885 if (mDropUntilNextSync) { 886 if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) { 887 mDropUntilNextSync = false; 888#if DEBUG_RAW_EVENTS 889 LOGD("Recovered from input event buffer overrun."); 890#endif 891 } else { 892#if DEBUG_RAW_EVENTS 893 LOGD("Dropped input event while waiting for next input sync."); 894#endif 895 } 896 } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_DROPPED) { 897 LOGI("Detected input event buffer overrun for device %s.", mName.string()); 898 mDropUntilNextSync = true; 899 reset(); 900 } else { 901 for (size_t i = 0; i < numMappers; i++) { 902 InputMapper* mapper = mMappers[i]; 903 mapper->process(rawEvent); 904 } 905 } 906 } 907} 908 909void InputDevice::timeoutExpired(nsecs_t when) { 910 size_t numMappers = mMappers.size(); 911 for (size_t i = 0; i < numMappers; i++) { 912 InputMapper* mapper = mMappers[i]; 913 mapper->timeoutExpired(when); 914 } 915} 916 917void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { 918 outDeviceInfo->initialize(mId, mName); 919 920 size_t numMappers = mMappers.size(); 921 for (size_t i = 0; i < numMappers; i++) { 922 InputMapper* mapper = mMappers[i]; 923 mapper->populateDeviceInfo(outDeviceInfo); 924 } 925} 926 927int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 928 return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState); 929} 930 931int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 932 return getState(sourceMask, scanCode, & InputMapper::getScanCodeState); 933} 934 935int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 936 return getState(sourceMask, switchCode, & InputMapper::getSwitchState); 937} 938 939int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) { 940 int32_t result = AKEY_STATE_UNKNOWN; 941 size_t numMappers = mMappers.size(); 942 for (size_t i = 0; i < numMappers; i++) { 943 InputMapper* mapper = mMappers[i]; 944 if (sourcesMatchMask(mapper->getSources(), sourceMask)) { 945 result = (mapper->*getStateFunc)(sourceMask, code); 946 if (result >= AKEY_STATE_DOWN) { 947 return result; 948 } 949 } 950 } 951 return result; 952} 953 954bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 955 const int32_t* keyCodes, uint8_t* outFlags) { 956 bool result = false; 957 size_t numMappers = mMappers.size(); 958 for (size_t i = 0; i < numMappers; i++) { 959 InputMapper* mapper = mMappers[i]; 960 if (sourcesMatchMask(mapper->getSources(), sourceMask)) { 961 result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags); 962 } 963 } 964 return result; 965} 966 967int32_t InputDevice::getMetaState() { 968 int32_t result = 0; 969 size_t numMappers = mMappers.size(); 970 for (size_t i = 0; i < numMappers; i++) { 971 InputMapper* mapper = mMappers[i]; 972 result |= mapper->getMetaState(); 973 } 974 return result; 975} 976 977void InputDevice::fadePointer() { 978 size_t numMappers = mMappers.size(); 979 for (size_t i = 0; i < numMappers; i++) { 980 InputMapper* mapper = mMappers[i]; 981 mapper->fadePointer(); 982 } 983} 984 985 986// --- CursorButtonAccumulator --- 987 988CursorButtonAccumulator::CursorButtonAccumulator() { 989 clearButtons(); 990} 991 992void CursorButtonAccumulator::clearButtons() { 993 mBtnLeft = 0; 994 mBtnRight = 0; 995 mBtnMiddle = 0; 996 mBtnBack = 0; 997 mBtnSide = 0; 998 mBtnForward = 0; 999 mBtnExtra = 0; 1000 mBtnTask = 0; 1001} 1002 1003void CursorButtonAccumulator::process(const RawEvent* rawEvent) { 1004 if (rawEvent->type == EV_KEY) { 1005 switch (rawEvent->scanCode) { 1006 case BTN_LEFT: 1007 mBtnLeft = rawEvent->value; 1008 break; 1009 case BTN_RIGHT: 1010 mBtnRight = rawEvent->value; 1011 break; 1012 case BTN_MIDDLE: 1013 mBtnMiddle = rawEvent->value; 1014 break; 1015 case BTN_BACK: 1016 mBtnBack = rawEvent->value; 1017 break; 1018 case BTN_SIDE: 1019 mBtnSide = rawEvent->value; 1020 break; 1021 case BTN_FORWARD: 1022 mBtnForward = rawEvent->value; 1023 break; 1024 case BTN_EXTRA: 1025 mBtnExtra = rawEvent->value; 1026 break; 1027 case BTN_TASK: 1028 mBtnTask = rawEvent->value; 1029 break; 1030 } 1031 } 1032} 1033 1034uint32_t CursorButtonAccumulator::getButtonState() const { 1035 uint32_t result = 0; 1036 if (mBtnLeft) { 1037 result |= AMOTION_EVENT_BUTTON_PRIMARY; 1038 } 1039 if (mBtnRight) { 1040 result |= AMOTION_EVENT_BUTTON_SECONDARY; 1041 } 1042 if (mBtnMiddle) { 1043 result |= AMOTION_EVENT_BUTTON_TERTIARY; 1044 } 1045 if (mBtnBack || mBtnSide) { 1046 result |= AMOTION_EVENT_BUTTON_BACK; 1047 } 1048 if (mBtnForward || mBtnExtra) { 1049 result |= AMOTION_EVENT_BUTTON_FORWARD; 1050 } 1051 return result; 1052} 1053 1054 1055// --- CursorMotionAccumulator --- 1056 1057CursorMotionAccumulator::CursorMotionAccumulator() : 1058 mHaveRelWheel(false), mHaveRelHWheel(false) { 1059 clearRelativeAxes(); 1060} 1061 1062void CursorMotionAccumulator::configure(InputDevice* device) { 1063 mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL); 1064 mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL); 1065} 1066 1067void CursorMotionAccumulator::clearRelativeAxes() { 1068 mRelX = 0; 1069 mRelY = 0; 1070 mRelWheel = 0; 1071 mRelHWheel = 0; 1072} 1073 1074void CursorMotionAccumulator::process(const RawEvent* rawEvent) { 1075 if (rawEvent->type == EV_REL) { 1076 switch (rawEvent->scanCode) { 1077 case REL_X: 1078 mRelX = rawEvent->value; 1079 break; 1080 case REL_Y: 1081 mRelY = rawEvent->value; 1082 break; 1083 case REL_WHEEL: 1084 mRelWheel = rawEvent->value; 1085 break; 1086 case REL_HWHEEL: 1087 mRelHWheel = rawEvent->value; 1088 break; 1089 } 1090 } 1091} 1092 1093 1094// --- TouchButtonAccumulator --- 1095 1096TouchButtonAccumulator::TouchButtonAccumulator() : 1097 mHaveBtnTouch(false) { 1098 clearButtons(); 1099} 1100 1101void TouchButtonAccumulator::configure(InputDevice* device) { 1102 mHaveBtnTouch = device->getEventHub()->hasScanCode(device->getId(), BTN_TOUCH); 1103} 1104 1105void TouchButtonAccumulator::clearButtons() { 1106 mBtnTouch = 0; 1107 mBtnStylus = 0; 1108 mBtnStylus2 = 0; 1109 mBtnToolFinger = 0; 1110 mBtnToolPen = 0; 1111 mBtnToolRubber = 0; 1112} 1113 1114void TouchButtonAccumulator::process(const RawEvent* rawEvent) { 1115 if (rawEvent->type == EV_KEY) { 1116 switch (rawEvent->scanCode) { 1117 case BTN_TOUCH: 1118 mBtnTouch = rawEvent->value; 1119 break; 1120 case BTN_STYLUS: 1121 mBtnStylus = rawEvent->value; 1122 break; 1123 case BTN_STYLUS2: 1124 mBtnStylus2 = rawEvent->value; 1125 break; 1126 case BTN_TOOL_FINGER: 1127 mBtnToolFinger = rawEvent->value; 1128 break; 1129 case BTN_TOOL_PEN: 1130 mBtnToolPen = rawEvent->value; 1131 break; 1132 case BTN_TOOL_RUBBER: 1133 mBtnToolRubber = rawEvent->value; 1134 break; 1135 } 1136 } 1137} 1138 1139uint32_t TouchButtonAccumulator::getButtonState() const { 1140 uint32_t result = 0; 1141 if (mBtnStylus) { 1142 result |= AMOTION_EVENT_BUTTON_SECONDARY; 1143 } 1144 if (mBtnStylus2) { 1145 result |= AMOTION_EVENT_BUTTON_TERTIARY; 1146 } 1147 return result; 1148} 1149 1150int32_t TouchButtonAccumulator::getToolType() const { 1151 if (mBtnToolRubber) { 1152 return AMOTION_EVENT_TOOL_TYPE_ERASER; 1153 } 1154 if (mBtnToolPen) { 1155 return AMOTION_EVENT_TOOL_TYPE_STYLUS; 1156 } 1157 if (mBtnToolFinger) { 1158 return AMOTION_EVENT_TOOL_TYPE_FINGER; 1159 } 1160 return AMOTION_EVENT_TOOL_TYPE_UNKNOWN; 1161} 1162 1163bool TouchButtonAccumulator::isActive() const { 1164 return mBtnTouch || mBtnToolFinger || mBtnToolPen 1165 || mBtnToolRubber || mBtnStylus || mBtnStylus2; 1166} 1167 1168bool TouchButtonAccumulator::isHovering() const { 1169 return mHaveBtnTouch && !mBtnTouch; 1170} 1171 1172 1173// --- SingleTouchMotionAccumulator --- 1174 1175SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() { 1176 clearAbsoluteAxes(); 1177} 1178 1179void SingleTouchMotionAccumulator::clearAbsoluteAxes() { 1180 mAbsX = 0; 1181 mAbsY = 0; 1182 mAbsPressure = 0; 1183 mAbsToolWidth = 0; 1184 mAbsDistance = 0; 1185} 1186 1187void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) { 1188 if (rawEvent->type == EV_ABS) { 1189 switch (rawEvent->scanCode) { 1190 case ABS_X: 1191 mAbsX = rawEvent->value; 1192 break; 1193 case ABS_Y: 1194 mAbsY = rawEvent->value; 1195 break; 1196 case ABS_PRESSURE: 1197 mAbsPressure = rawEvent->value; 1198 break; 1199 case ABS_TOOL_WIDTH: 1200 mAbsToolWidth = rawEvent->value; 1201 break; 1202 case ABS_DISTANCE: 1203 mAbsDistance = rawEvent->value; 1204 break; 1205 } 1206 } 1207} 1208 1209 1210// --- MultiTouchMotionAccumulator --- 1211 1212MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() : 1213 mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false) { 1214} 1215 1216MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() { 1217 delete[] mSlots; 1218} 1219 1220void MultiTouchMotionAccumulator::configure(size_t slotCount, bool usingSlotsProtocol) { 1221 mSlotCount = slotCount; 1222 mUsingSlotsProtocol = usingSlotsProtocol; 1223 1224 delete[] mSlots; 1225 mSlots = new Slot[slotCount]; 1226} 1227 1228void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) { 1229 for (size_t i = 0; i < mSlotCount; i++) { 1230 mSlots[i].clearIfInUse(); 1231 } 1232 mCurrentSlot = initialSlot; 1233} 1234 1235void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) { 1236 if (rawEvent->type == EV_ABS) { 1237 bool newSlot = false; 1238 if (mUsingSlotsProtocol) { 1239 if (rawEvent->scanCode == ABS_MT_SLOT) { 1240 mCurrentSlot = rawEvent->value; 1241 newSlot = true; 1242 } 1243 } else if (mCurrentSlot < 0) { 1244 mCurrentSlot = 0; 1245 } 1246 1247 if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) { 1248#if DEBUG_POINTERS 1249 if (newSlot) { 1250 LOGW("MultiTouch device emitted invalid slot index %d but it " 1251 "should be between 0 and %d; ignoring this slot.", 1252 mCurrentSlot, mSlotCount - 1); 1253 } 1254#endif 1255 } else { 1256 Slot* slot = &mSlots[mCurrentSlot]; 1257 1258 switch (rawEvent->scanCode) { 1259 case ABS_MT_POSITION_X: 1260 slot->mInUse = true; 1261 slot->mAbsMTPositionX = rawEvent->value; 1262 break; 1263 case ABS_MT_POSITION_Y: 1264 slot->mInUse = true; 1265 slot->mAbsMTPositionY = rawEvent->value; 1266 break; 1267 case ABS_MT_TOUCH_MAJOR: 1268 slot->mInUse = true; 1269 slot->mAbsMTTouchMajor = rawEvent->value; 1270 break; 1271 case ABS_MT_TOUCH_MINOR: 1272 slot->mInUse = true; 1273 slot->mAbsMTTouchMinor = rawEvent->value; 1274 slot->mHaveAbsMTTouchMinor = true; 1275 break; 1276 case ABS_MT_WIDTH_MAJOR: 1277 slot->mInUse = true; 1278 slot->mAbsMTWidthMajor = rawEvent->value; 1279 break; 1280 case ABS_MT_WIDTH_MINOR: 1281 slot->mInUse = true; 1282 slot->mAbsMTWidthMinor = rawEvent->value; 1283 slot->mHaveAbsMTWidthMinor = true; 1284 break; 1285 case ABS_MT_ORIENTATION: 1286 slot->mInUse = true; 1287 slot->mAbsMTOrientation = rawEvent->value; 1288 break; 1289 case ABS_MT_TRACKING_ID: 1290 if (mUsingSlotsProtocol && rawEvent->value < 0) { 1291 slot->clearIfInUse(); 1292 } else { 1293 slot->mInUse = true; 1294 slot->mAbsMTTrackingId = rawEvent->value; 1295 } 1296 break; 1297 case ABS_MT_PRESSURE: 1298 slot->mInUse = true; 1299 slot->mAbsMTPressure = rawEvent->value; 1300 break; 1301 case ABS_MT_TOOL_TYPE: 1302 slot->mInUse = true; 1303 slot->mAbsMTToolType = rawEvent->value; 1304 slot->mHaveAbsMTToolType = true; 1305 break; 1306 } 1307 } 1308 } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_MT_REPORT) { 1309 // MultiTouch Sync: The driver has returned all data for *one* of the pointers. 1310 mCurrentSlot += 1; 1311 } 1312} 1313 1314 1315// --- MultiTouchMotionAccumulator::Slot --- 1316 1317MultiTouchMotionAccumulator::Slot::Slot() { 1318 clear(); 1319} 1320 1321void MultiTouchMotionAccumulator::Slot::clearIfInUse() { 1322 if (mInUse) { 1323 clear(); 1324 } 1325} 1326 1327void MultiTouchMotionAccumulator::Slot::clear() { 1328 mInUse = false; 1329 mHaveAbsMTTouchMinor = false; 1330 mHaveAbsMTWidthMinor = false; 1331 mHaveAbsMTToolType = false; 1332 mAbsMTPositionX = 0; 1333 mAbsMTPositionY = 0; 1334 mAbsMTTouchMajor = 0; 1335 mAbsMTTouchMinor = 0; 1336 mAbsMTWidthMajor = 0; 1337 mAbsMTWidthMinor = 0; 1338 mAbsMTOrientation = 0; 1339 mAbsMTTrackingId = -1; 1340 mAbsMTPressure = 0; 1341 mAbsMTToolType = 0; 1342 mAbsMTDistance = 0; 1343} 1344 1345int32_t MultiTouchMotionAccumulator::Slot::getToolType() const { 1346 if (mHaveAbsMTToolType) { 1347 switch (mAbsMTToolType) { 1348 case MT_TOOL_FINGER: 1349 return AMOTION_EVENT_TOOL_TYPE_FINGER; 1350 case MT_TOOL_PEN: 1351 return AMOTION_EVENT_TOOL_TYPE_STYLUS; 1352 } 1353 } 1354 return AMOTION_EVENT_TOOL_TYPE_UNKNOWN; 1355} 1356 1357 1358// --- InputMapper --- 1359 1360InputMapper::InputMapper(InputDevice* device) : 1361 mDevice(device), mContext(device->getContext()) { 1362} 1363 1364InputMapper::~InputMapper() { 1365} 1366 1367void InputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1368 info->addSource(getSources()); 1369} 1370 1371void InputMapper::dump(String8& dump) { 1372} 1373 1374void InputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { 1375} 1376 1377void InputMapper::reset() { 1378} 1379 1380void InputMapper::timeoutExpired(nsecs_t when) { 1381} 1382 1383int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 1384 return AKEY_STATE_UNKNOWN; 1385} 1386 1387int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 1388 return AKEY_STATE_UNKNOWN; 1389} 1390 1391int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 1392 return AKEY_STATE_UNKNOWN; 1393} 1394 1395bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 1396 const int32_t* keyCodes, uint8_t* outFlags) { 1397 return false; 1398} 1399 1400int32_t InputMapper::getMetaState() { 1401 return 0; 1402} 1403 1404void InputMapper::fadePointer() { 1405} 1406 1407void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump, 1408 const RawAbsoluteAxisInfo& axis, const char* name) { 1409 if (axis.valid) { 1410 dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n", 1411 name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution); 1412 } else { 1413 dump.appendFormat(INDENT4 "%s: unknown range\n", name); 1414 } 1415} 1416 1417 1418// --- SwitchInputMapper --- 1419 1420SwitchInputMapper::SwitchInputMapper(InputDevice* device) : 1421 InputMapper(device) { 1422} 1423 1424SwitchInputMapper::~SwitchInputMapper() { 1425} 1426 1427uint32_t SwitchInputMapper::getSources() { 1428 return AINPUT_SOURCE_SWITCH; 1429} 1430 1431void SwitchInputMapper::process(const RawEvent* rawEvent) { 1432 switch (rawEvent->type) { 1433 case EV_SW: 1434 processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value); 1435 break; 1436 } 1437} 1438 1439void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) { 1440 getDispatcher()->notifySwitch(when, switchCode, switchValue, 0); 1441} 1442 1443int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 1444 return getEventHub()->getSwitchState(getDeviceId(), switchCode); 1445} 1446 1447 1448// --- KeyboardInputMapper --- 1449 1450KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, 1451 uint32_t source, int32_t keyboardType) : 1452 InputMapper(device), mSource(source), 1453 mKeyboardType(keyboardType) { 1454 initializeLocked(); 1455} 1456 1457KeyboardInputMapper::~KeyboardInputMapper() { 1458} 1459 1460void KeyboardInputMapper::initializeLocked() { 1461 mLocked.metaState = AMETA_NONE; 1462 mLocked.downTime = 0; 1463} 1464 1465uint32_t KeyboardInputMapper::getSources() { 1466 return mSource; 1467} 1468 1469void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1470 InputMapper::populateDeviceInfo(info); 1471 1472 info->setKeyboardType(mKeyboardType); 1473} 1474 1475void KeyboardInputMapper::dump(String8& dump) { 1476 { // acquire lock 1477 AutoMutex _l(mLock); 1478 dump.append(INDENT2 "Keyboard Input Mapper:\n"); 1479 dumpParameters(dump); 1480 dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType); 1481 dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size()); 1482 dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState); 1483 dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); 1484 } // release lock 1485} 1486 1487 1488void KeyboardInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { 1489 InputMapper::configure(config, changes); 1490 1491 if (!changes) { // first time only 1492 // Configure basic parameters. 1493 configureParameters(); 1494 1495 // Reset LEDs. 1496 { 1497 AutoMutex _l(mLock); 1498 resetLedStateLocked(); 1499 } 1500 } 1501} 1502 1503void KeyboardInputMapper::configureParameters() { 1504 mParameters.orientationAware = false; 1505 getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"), 1506 mParameters.orientationAware); 1507 1508 mParameters.associatedDisplayId = -1; 1509 if (mParameters.orientationAware) { 1510 mParameters.associatedDisplayId = 0; 1511 } 1512} 1513 1514void KeyboardInputMapper::dumpParameters(String8& dump) { 1515 dump.append(INDENT3 "Parameters:\n"); 1516 dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", 1517 mParameters.associatedDisplayId); 1518 dump.appendFormat(INDENT4 "OrientationAware: %s\n", 1519 toString(mParameters.orientationAware)); 1520} 1521 1522void KeyboardInputMapper::reset() { 1523 for (;;) { 1524 int32_t keyCode, scanCode; 1525 { // acquire lock 1526 AutoMutex _l(mLock); 1527 1528 // Synthesize key up event on reset if keys are currently down. 1529 if (mLocked.keyDowns.isEmpty()) { 1530 initializeLocked(); 1531 resetLedStateLocked(); 1532 break; // done 1533 } 1534 1535 const KeyDown& keyDown = mLocked.keyDowns.top(); 1536 keyCode = keyDown.keyCode; 1537 scanCode = keyDown.scanCode; 1538 } // release lock 1539 1540 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 1541 processKey(when, false, keyCode, scanCode, 0); 1542 } 1543 1544 InputMapper::reset(); 1545 getContext()->updateGlobalMetaState(); 1546} 1547 1548void KeyboardInputMapper::process(const RawEvent* rawEvent) { 1549 switch (rawEvent->type) { 1550 case EV_KEY: { 1551 int32_t scanCode = rawEvent->scanCode; 1552 if (isKeyboardOrGamepadKey(scanCode)) { 1553 processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode, 1554 rawEvent->flags); 1555 } 1556 break; 1557 } 1558 } 1559} 1560 1561bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) { 1562 return scanCode < BTN_MOUSE 1563 || scanCode >= KEY_OK 1564 || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE) 1565 || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI); 1566} 1567 1568void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, 1569 int32_t scanCode, uint32_t policyFlags) { 1570 int32_t newMetaState; 1571 nsecs_t downTime; 1572 bool metaStateChanged = false; 1573 1574 { // acquire lock 1575 AutoMutex _l(mLock); 1576 1577 if (down) { 1578 // Rotate key codes according to orientation if needed. 1579 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1580 if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) { 1581 int32_t orientation; 1582 if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 1583 false /*external*/, NULL, NULL, & orientation)) { 1584 orientation = DISPLAY_ORIENTATION_0; 1585 } 1586 1587 keyCode = rotateKeyCode(keyCode, orientation); 1588 } 1589 1590 // Add key down. 1591 ssize_t keyDownIndex = findKeyDownLocked(scanCode); 1592 if (keyDownIndex >= 0) { 1593 // key repeat, be sure to use same keycode as before in case of rotation 1594 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode; 1595 } else { 1596 // key down 1597 if ((policyFlags & POLICY_FLAG_VIRTUAL) 1598 && mContext->shouldDropVirtualKey(when, 1599 getDevice(), keyCode, scanCode)) { 1600 return; 1601 } 1602 1603 mLocked.keyDowns.push(); 1604 KeyDown& keyDown = mLocked.keyDowns.editTop(); 1605 keyDown.keyCode = keyCode; 1606 keyDown.scanCode = scanCode; 1607 } 1608 1609 mLocked.downTime = when; 1610 } else { 1611 // Remove key down. 1612 ssize_t keyDownIndex = findKeyDownLocked(scanCode); 1613 if (keyDownIndex >= 0) { 1614 // key up, be sure to use same keycode as before in case of rotation 1615 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode; 1616 mLocked.keyDowns.removeAt(size_t(keyDownIndex)); 1617 } else { 1618 // key was not actually down 1619 LOGI("Dropping key up from device %s because the key was not down. " 1620 "keyCode=%d, scanCode=%d", 1621 getDeviceName().string(), keyCode, scanCode); 1622 return; 1623 } 1624 } 1625 1626 int32_t oldMetaState = mLocked.metaState; 1627 newMetaState = updateMetaState(keyCode, down, oldMetaState); 1628 if (oldMetaState != newMetaState) { 1629 mLocked.metaState = newMetaState; 1630 metaStateChanged = true; 1631 updateLedStateLocked(false); 1632 } 1633 1634 downTime = mLocked.downTime; 1635 } // release lock 1636 1637 // Key down on external an keyboard should wake the device. 1638 // We don't do this for internal keyboards to prevent them from waking up in your pocket. 1639 // For internal keyboards, the key layout file should specify the policy flags for 1640 // each wake key individually. 1641 // TODO: Use the input device configuration to control this behavior more finely. 1642 if (down && getDevice()->isExternal() 1643 && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) { 1644 policyFlags |= POLICY_FLAG_WAKE_DROPPED; 1645 } 1646 1647 if (metaStateChanged) { 1648 getContext()->updateGlobalMetaState(); 1649 } 1650 1651 if (down && !isMetaKey(keyCode)) { 1652 getContext()->fadePointer(); 1653 } 1654 1655 getDispatcher()->notifyKey(when, getDeviceId(), mSource, policyFlags, 1656 down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, 1657 AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime); 1658} 1659 1660ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) { 1661 size_t n = mLocked.keyDowns.size(); 1662 for (size_t i = 0; i < n; i++) { 1663 if (mLocked.keyDowns[i].scanCode == scanCode) { 1664 return i; 1665 } 1666 } 1667 return -1; 1668} 1669 1670int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 1671 return getEventHub()->getKeyCodeState(getDeviceId(), keyCode); 1672} 1673 1674int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 1675 return getEventHub()->getScanCodeState(getDeviceId(), scanCode); 1676} 1677 1678bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 1679 const int32_t* keyCodes, uint8_t* outFlags) { 1680 return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags); 1681} 1682 1683int32_t KeyboardInputMapper::getMetaState() { 1684 { // acquire lock 1685 AutoMutex _l(mLock); 1686 return mLocked.metaState; 1687 } // release lock 1688} 1689 1690void KeyboardInputMapper::resetLedStateLocked() { 1691 initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL); 1692 initializeLedStateLocked(mLocked.numLockLedState, LED_NUML); 1693 initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL); 1694 1695 updateLedStateLocked(true); 1696} 1697 1698void KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) { 1699 ledState.avail = getEventHub()->hasLed(getDeviceId(), led); 1700 ledState.on = false; 1701} 1702 1703void KeyboardInputMapper::updateLedStateLocked(bool reset) { 1704 updateLedStateForModifierLocked(mLocked.capsLockLedState, LED_CAPSL, 1705 AMETA_CAPS_LOCK_ON, reset); 1706 updateLedStateForModifierLocked(mLocked.numLockLedState, LED_NUML, 1707 AMETA_NUM_LOCK_ON, reset); 1708 updateLedStateForModifierLocked(mLocked.scrollLockLedState, LED_SCROLLL, 1709 AMETA_SCROLL_LOCK_ON, reset); 1710} 1711 1712void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState& ledState, 1713 int32_t led, int32_t modifier, bool reset) { 1714 if (ledState.avail) { 1715 bool desiredState = (mLocked.metaState & modifier) != 0; 1716 if (reset || ledState.on != desiredState) { 1717 getEventHub()->setLedState(getDeviceId(), led, desiredState); 1718 ledState.on = desiredState; 1719 } 1720 } 1721} 1722 1723 1724// --- CursorInputMapper --- 1725 1726CursorInputMapper::CursorInputMapper(InputDevice* device) : 1727 InputMapper(device) { 1728 initializeLocked(); 1729} 1730 1731CursorInputMapper::~CursorInputMapper() { 1732} 1733 1734uint32_t CursorInputMapper::getSources() { 1735 return mSource; 1736} 1737 1738void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1739 InputMapper::populateDeviceInfo(info); 1740 1741 if (mParameters.mode == Parameters::MODE_POINTER) { 1742 float minX, minY, maxX, maxY; 1743 if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { 1744 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f); 1745 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f); 1746 } 1747 } else { 1748 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale); 1749 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale); 1750 } 1751 info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f); 1752 1753 if (mCursorMotionAccumulator.haveRelativeVWheel()) { 1754 info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f); 1755 } 1756 if (mCursorMotionAccumulator.haveRelativeHWheel()) { 1757 info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f); 1758 } 1759} 1760 1761void CursorInputMapper::dump(String8& dump) { 1762 { // acquire lock 1763 AutoMutex _l(mLock); 1764 dump.append(INDENT2 "Cursor Input Mapper:\n"); 1765 dumpParameters(dump); 1766 dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale); 1767 dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale); 1768 dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision); 1769 dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision); 1770 dump.appendFormat(INDENT3 "HaveVWheel: %s\n", 1771 toString(mCursorMotionAccumulator.haveRelativeVWheel())); 1772 dump.appendFormat(INDENT3 "HaveHWheel: %s\n", 1773 toString(mCursorMotionAccumulator.haveRelativeHWheel())); 1774 dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale); 1775 dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale); 1776 dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mLocked.buttonState); 1777 dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mLocked.buttonState))); 1778 dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); 1779 } // release lock 1780} 1781 1782void CursorInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { 1783 InputMapper::configure(config, changes); 1784 1785 if (!changes) { // first time only 1786 mCursorMotionAccumulator.configure(getDevice()); 1787 1788 // Configure basic parameters. 1789 configureParameters(); 1790 1791 // Configure device mode. 1792 switch (mParameters.mode) { 1793 case Parameters::MODE_POINTER: 1794 mSource = AINPUT_SOURCE_MOUSE; 1795 mXPrecision = 1.0f; 1796 mYPrecision = 1.0f; 1797 mXScale = 1.0f; 1798 mYScale = 1.0f; 1799 mPointerController = getPolicy()->obtainPointerController(getDeviceId()); 1800 break; 1801 case Parameters::MODE_NAVIGATION: 1802 mSource = AINPUT_SOURCE_TRACKBALL; 1803 mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD; 1804 mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD; 1805 mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD; 1806 mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD; 1807 break; 1808 } 1809 1810 mVWheelScale = 1.0f; 1811 mHWheelScale = 1.0f; 1812 } 1813 1814 if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { 1815 mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters); 1816 mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters); 1817 mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters); 1818 } 1819} 1820 1821void CursorInputMapper::configureParameters() { 1822 mParameters.mode = Parameters::MODE_POINTER; 1823 String8 cursorModeString; 1824 if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) { 1825 if (cursorModeString == "navigation") { 1826 mParameters.mode = Parameters::MODE_NAVIGATION; 1827 } else if (cursorModeString != "pointer" && cursorModeString != "default") { 1828 LOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string()); 1829 } 1830 } 1831 1832 mParameters.orientationAware = false; 1833 getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"), 1834 mParameters.orientationAware); 1835 1836 mParameters.associatedDisplayId = -1; 1837 if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) { 1838 mParameters.associatedDisplayId = 0; 1839 } 1840} 1841 1842void CursorInputMapper::dumpParameters(String8& dump) { 1843 dump.append(INDENT3 "Parameters:\n"); 1844 dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", 1845 mParameters.associatedDisplayId); 1846 1847 switch (mParameters.mode) { 1848 case Parameters::MODE_POINTER: 1849 dump.append(INDENT4 "Mode: pointer\n"); 1850 break; 1851 case Parameters::MODE_NAVIGATION: 1852 dump.append(INDENT4 "Mode: navigation\n"); 1853 break; 1854 default: 1855 LOG_ASSERT(false); 1856 } 1857 1858 dump.appendFormat(INDENT4 "OrientationAware: %s\n", 1859 toString(mParameters.orientationAware)); 1860} 1861 1862void CursorInputMapper::initializeLocked() { 1863 mCursorButtonAccumulator.clearButtons(); 1864 mCursorMotionAccumulator.clearRelativeAxes(); 1865 1866 mLocked.buttonState = 0; 1867 mLocked.downTime = 0; 1868} 1869 1870void CursorInputMapper::reset() { 1871 for (;;) { 1872 int32_t buttonState; 1873 { // acquire lock 1874 AutoMutex _l(mLock); 1875 1876 buttonState = mLocked.buttonState; 1877 if (!buttonState) { 1878 initializeLocked(); 1879 break; // done 1880 } 1881 } // release lock 1882 1883 // Reset velocity. 1884 mPointerVelocityControl.reset(); 1885 mWheelXVelocityControl.reset(); 1886 mWheelYVelocityControl.reset(); 1887 1888 // Synthesize button up event on reset. 1889 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 1890 mCursorButtonAccumulator.clearButtons(); 1891 mCursorMotionAccumulator.clearRelativeAxes(); 1892 sync(when); 1893 } 1894 1895 InputMapper::reset(); 1896} 1897 1898void CursorInputMapper::process(const RawEvent* rawEvent) { 1899 mCursorButtonAccumulator.process(rawEvent); 1900 mCursorMotionAccumulator.process(rawEvent); 1901 1902 if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) { 1903 sync(rawEvent->when); 1904 } 1905} 1906 1907void CursorInputMapper::sync(nsecs_t when) { 1908 int32_t motionEventAction; 1909 int32_t lastButtonState, currentButtonState; 1910 PointerProperties pointerProperties; 1911 PointerCoords pointerCoords; 1912 nsecs_t downTime; 1913 float vscroll, hscroll; 1914 { // acquire lock 1915 AutoMutex _l(mLock); 1916 1917 lastButtonState = mLocked.buttonState; 1918 currentButtonState = mCursorButtonAccumulator.getButtonState(); 1919 mLocked.buttonState = currentButtonState; 1920 1921 bool wasDown = isPointerDown(lastButtonState); 1922 bool down = isPointerDown(currentButtonState); 1923 bool downChanged; 1924 if (!wasDown && down) { 1925 mLocked.downTime = when; 1926 downChanged = true; 1927 } else if (wasDown && !down) { 1928 downChanged = true; 1929 } else { 1930 downChanged = false; 1931 } 1932 downTime = mLocked.downTime; 1933 1934 if (downChanged) { 1935 motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; 1936 } else if (down || mPointerController == NULL) { 1937 motionEventAction = AMOTION_EVENT_ACTION_MOVE; 1938 } else { 1939 motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE; 1940 } 1941 1942 float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale; 1943 float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale; 1944 1945 if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0 1946 && (deltaX != 0.0f || deltaY != 0.0f)) { 1947 // Rotate motion based on display orientation if needed. 1948 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1949 int32_t orientation; 1950 if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 1951 false /*external*/, NULL, NULL, & orientation)) { 1952 orientation = DISPLAY_ORIENTATION_0; 1953 } 1954 1955 rotateDelta(orientation, &deltaX, &deltaY); 1956 } 1957 1958 pointerProperties.clear(); 1959 pointerProperties.id = 0; 1960 pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE; 1961 1962 pointerCoords.clear(); 1963 1964 vscroll = mCursorMotionAccumulator.getRelativeVWheel(); 1965 hscroll = mCursorMotionAccumulator.getRelativeHWheel(); 1966 1967 mWheelYVelocityControl.move(when, NULL, &vscroll); 1968 mWheelXVelocityControl.move(when, &hscroll, NULL); 1969 1970 mPointerVelocityControl.move(when, &deltaX, &deltaY); 1971 1972 if (mPointerController != NULL) { 1973 if (deltaX != 0 || deltaY != 0 || vscroll != 0 || hscroll != 0 1974 || currentButtonState != lastButtonState) { 1975 mPointerController->setPresentation( 1976 PointerControllerInterface::PRESENTATION_POINTER); 1977 1978 if (deltaX != 0 || deltaY != 0) { 1979 mPointerController->move(deltaX, deltaY); 1980 } 1981 1982 if (currentButtonState != lastButtonState) { 1983 mPointerController->setButtonState(currentButtonState); 1984 } 1985 1986 mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); 1987 } 1988 1989 float x, y; 1990 mPointerController->getPosition(&x, &y); 1991 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); 1992 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); 1993 } else { 1994 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); 1995 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY); 1996 } 1997 1998 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f); 1999 } // release lock 2000 2001 // Moving an external trackball or mouse should wake the device. 2002 // We don't do this for internal cursor devices to prevent them from waking up 2003 // the device in your pocket. 2004 // TODO: Use the input device configuration to control this behavior more finely. 2005 uint32_t policyFlags = 0; 2006 if (getDevice()->isExternal()) { 2007 policyFlags |= POLICY_FLAG_WAKE_DROPPED; 2008 } 2009 2010 // Synthesize key down from buttons if needed. 2011 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource, 2012 policyFlags, lastButtonState, currentButtonState); 2013 2014 // Send motion event. 2015 int32_t metaState = mContext->getGlobalMetaState(); 2016 getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags, 2017 motionEventAction, 0, metaState, currentButtonState, 0, 2018 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime); 2019 2020 // Send hover move after UP to tell the application that the mouse is hovering now. 2021 if (motionEventAction == AMOTION_EVENT_ACTION_UP 2022 && mPointerController != NULL) { 2023 getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags, 2024 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 2025 metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE, 2026 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime); 2027 } 2028 2029 // Send scroll events. 2030 if (vscroll != 0 || hscroll != 0) { 2031 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll); 2032 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll); 2033 2034 getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags, 2035 AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState, 2036 AMOTION_EVENT_EDGE_FLAG_NONE, 2037 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime); 2038 } 2039 2040 // Synthesize key up from buttons if needed. 2041 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource, 2042 policyFlags, lastButtonState, currentButtonState); 2043 2044 mCursorMotionAccumulator.clearRelativeAxes(); 2045} 2046 2047int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 2048 if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) { 2049 return getEventHub()->getScanCodeState(getDeviceId(), scanCode); 2050 } else { 2051 return AKEY_STATE_UNKNOWN; 2052 } 2053} 2054 2055void CursorInputMapper::fadePointer() { 2056 { // acquire lock 2057 AutoMutex _l(mLock); 2058 if (mPointerController != NULL) { 2059 mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); 2060 } 2061 } // release lock 2062} 2063 2064 2065// --- TouchInputMapper --- 2066 2067TouchInputMapper::TouchInputMapper(InputDevice* device) : 2068 InputMapper(device) { 2069 mLocked.surfaceOrientation = -1; 2070 mLocked.surfaceWidth = -1; 2071 mLocked.surfaceHeight = -1; 2072 2073 initializeLocked(); 2074} 2075 2076TouchInputMapper::~TouchInputMapper() { 2077} 2078 2079uint32_t TouchInputMapper::getSources() { 2080 return mTouchSource | mPointerSource; 2081} 2082 2083void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 2084 InputMapper::populateDeviceInfo(info); 2085 2086 { // acquire lock 2087 AutoMutex _l(mLock); 2088 2089 // Ensure surface information is up to date so that orientation changes are 2090 // noticed immediately. 2091 if (!configureSurfaceLocked()) { 2092 return; 2093 } 2094 2095 info->addMotionRange(mLocked.orientedRanges.x); 2096 info->addMotionRange(mLocked.orientedRanges.y); 2097 2098 if (mLocked.orientedRanges.havePressure) { 2099 info->addMotionRange(mLocked.orientedRanges.pressure); 2100 } 2101 2102 if (mLocked.orientedRanges.haveSize) { 2103 info->addMotionRange(mLocked.orientedRanges.size); 2104 } 2105 2106 if (mLocked.orientedRanges.haveTouchSize) { 2107 info->addMotionRange(mLocked.orientedRanges.touchMajor); 2108 info->addMotionRange(mLocked.orientedRanges.touchMinor); 2109 } 2110 2111 if (mLocked.orientedRanges.haveToolSize) { 2112 info->addMotionRange(mLocked.orientedRanges.toolMajor); 2113 info->addMotionRange(mLocked.orientedRanges.toolMinor); 2114 } 2115 2116 if (mLocked.orientedRanges.haveOrientation) { 2117 info->addMotionRange(mLocked.orientedRanges.orientation); 2118 } 2119 2120 if (mLocked.orientedRanges.haveDistance) { 2121 info->addMotionRange(mLocked.orientedRanges.distance); 2122 } 2123 2124 if (mPointerController != NULL) { 2125 float minX, minY, maxX, maxY; 2126 if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { 2127 info->addMotionRange(AMOTION_EVENT_AXIS_X, mPointerSource, 2128 minX, maxX, 0.0f, 0.0f); 2129 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mPointerSource, 2130 minY, maxY, 0.0f, 0.0f); 2131 } 2132 info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mPointerSource, 2133 0.0f, 1.0f, 0.0f, 0.0f); 2134 } 2135 } // release lock 2136} 2137 2138void TouchInputMapper::dump(String8& dump) { 2139 { // acquire lock 2140 AutoMutex _l(mLock); 2141 dump.append(INDENT2 "Touch Input Mapper:\n"); 2142 dumpParameters(dump); 2143 dumpVirtualKeysLocked(dump); 2144 dumpRawAxes(dump); 2145 dumpCalibration(dump); 2146 dumpSurfaceLocked(dump); 2147 2148 dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n"); 2149 dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale); 2150 dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale); 2151 dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision); 2152 dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision); 2153 dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale); 2154 dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale); 2155 dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias); 2156 dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale); 2157 dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias); 2158 dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale); 2159 dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale); 2160 dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mLocked.orientationScale); 2161 dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mLocked.distanceScale); 2162 2163 dump.appendFormat(INDENT3 "Last Touch:\n"); 2164 dump.appendFormat(INDENT4 "Button State: 0x%08x\n", mLastTouch.buttonState); 2165 dump.appendFormat(INDENT4 "Pointer Count: %d\n", mLastTouch.pointerCount); 2166 for (uint32_t i = 0; i < mLastTouch.pointerCount; i++) { 2167 const PointerData& pointer = mLastTouch.pointers[i]; 2168 dump.appendFormat(INDENT5 "[%d]: id=%d, x=%d, y=%d, pressure=%d, " 2169 "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, " 2170 "orientation=%d, distance=%d, toolType=%d, isHovering=%s\n", i, 2171 pointer.id, pointer.x, pointer.y, pointer.pressure, 2172 pointer.touchMajor, pointer.touchMinor, pointer.toolMajor, pointer.toolMinor, 2173 pointer.orientation, pointer.distance, 2174 pointer.toolType, toString(pointer.isHovering)); 2175 } 2176 2177 if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) { 2178 dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n"); 2179 dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n", 2180 mLocked.pointerGestureXMovementScale); 2181 dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n", 2182 mLocked.pointerGestureYMovementScale); 2183 dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n", 2184 mLocked.pointerGestureXZoomScale); 2185 dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n", 2186 mLocked.pointerGestureYZoomScale); 2187 dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n", 2188 mLocked.pointerGestureMaxSwipeWidth); 2189 } 2190 } // release lock 2191} 2192 2193void TouchInputMapper::initializeLocked() { 2194 mCurrentTouch.clear(); 2195 mLastTouch.clear(); 2196 mDownTime = 0; 2197 2198 mLocked.currentVirtualKey.down = false; 2199 2200 mLocked.orientedRanges.havePressure = false; 2201 mLocked.orientedRanges.haveSize = false; 2202 mLocked.orientedRanges.haveTouchSize = false; 2203 mLocked.orientedRanges.haveToolSize = false; 2204 mLocked.orientedRanges.haveOrientation = false; 2205 mLocked.orientedRanges.haveDistance = false; 2206 2207 mPointerGesture.reset(); 2208} 2209 2210void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { 2211 InputMapper::configure(config, changes); 2212 2213 mConfig = *config; 2214 2215 if (!changes) { // first time only 2216 // Configure basic parameters. 2217 configureParameters(); 2218 2219 // Configure sources. 2220 switch (mParameters.deviceType) { 2221 case Parameters::DEVICE_TYPE_TOUCH_SCREEN: 2222 mTouchSource = AINPUT_SOURCE_TOUCHSCREEN; 2223 mPointerSource = 0; 2224 break; 2225 case Parameters::DEVICE_TYPE_TOUCH_PAD: 2226 mTouchSource = AINPUT_SOURCE_TOUCHPAD; 2227 mPointerSource = 0; 2228 break; 2229 case Parameters::DEVICE_TYPE_POINTER: 2230 mTouchSource = AINPUT_SOURCE_TOUCHPAD; 2231 mPointerSource = AINPUT_SOURCE_MOUSE; 2232 break; 2233 default: 2234 LOG_ASSERT(false); 2235 } 2236 2237 // Configure absolute axis information. 2238 configureRawAxes(); 2239 2240 // Prepare input device calibration. 2241 parseCalibration(); 2242 resolveCalibration(); 2243 2244 { // acquire lock 2245 AutoMutex _l(mLock); 2246 2247 // Configure surface dimensions and orientation. 2248 configureSurfaceLocked(); 2249 } // release lock 2250 } 2251 2252 if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) { 2253 mPointerGesture.pointerVelocityControl.setParameters( 2254 mConfig.pointerVelocityControlParameters); 2255 } 2256 2257 if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT)) { 2258 // Reset the touch screen when pointer gesture enablement changes. 2259 reset(); 2260 } 2261} 2262 2263void TouchInputMapper::configureParameters() { 2264 // Use the pointer presentation mode for devices that do not support distinct 2265 // multitouch. The spot-based presentation relies on being able to accurately 2266 // locate two or more fingers on the touch pad. 2267 mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT) 2268 ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS; 2269 2270 String8 gestureModeString; 2271 if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"), 2272 gestureModeString)) { 2273 if (gestureModeString == "pointer") { 2274 mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER; 2275 } else if (gestureModeString == "spots") { 2276 mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS; 2277 } else if (gestureModeString != "default") { 2278 LOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string()); 2279 } 2280 } 2281 2282 if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X) 2283 || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) { 2284 // The device is a cursor device with a touch pad attached. 2285 // By default don't use the touch pad to move the pointer. 2286 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD; 2287 } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) { 2288 // The device is a pointing device like a track pad. 2289 mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER; 2290 } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) { 2291 // The device is a touch screen. 2292 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN; 2293 } else { 2294 // The device is a touch pad of unknown purpose. 2295 mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER; 2296 } 2297 2298 String8 deviceTypeString; 2299 if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"), 2300 deviceTypeString)) { 2301 if (deviceTypeString == "touchScreen") { 2302 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN; 2303 } else if (deviceTypeString == "touchPad") { 2304 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD; 2305 } else if (deviceTypeString == "pointer") { 2306 mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER; 2307 } else if (deviceTypeString != "default") { 2308 LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string()); 2309 } 2310 } 2311 2312 mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; 2313 getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"), 2314 mParameters.orientationAware); 2315 2316 mParameters.associatedDisplayId = -1; 2317 mParameters.associatedDisplayIsExternal = false; 2318 if (mParameters.orientationAware 2319 || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN 2320 || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) { 2321 mParameters.associatedDisplayIsExternal = 2322 mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN 2323 && getDevice()->isExternal(); 2324 mParameters.associatedDisplayId = 0; 2325 } 2326} 2327 2328void TouchInputMapper::dumpParameters(String8& dump) { 2329 dump.append(INDENT3 "Parameters:\n"); 2330 2331 switch (mParameters.gestureMode) { 2332 case Parameters::GESTURE_MODE_POINTER: 2333 dump.append(INDENT4 "GestureMode: pointer\n"); 2334 break; 2335 case Parameters::GESTURE_MODE_SPOTS: 2336 dump.append(INDENT4 "GestureMode: spots\n"); 2337 break; 2338 default: 2339 assert(false); 2340 } 2341 2342 switch (mParameters.deviceType) { 2343 case Parameters::DEVICE_TYPE_TOUCH_SCREEN: 2344 dump.append(INDENT4 "DeviceType: touchScreen\n"); 2345 break; 2346 case Parameters::DEVICE_TYPE_TOUCH_PAD: 2347 dump.append(INDENT4 "DeviceType: touchPad\n"); 2348 break; 2349 case Parameters::DEVICE_TYPE_POINTER: 2350 dump.append(INDENT4 "DeviceType: pointer\n"); 2351 break; 2352 default: 2353 LOG_ASSERT(false); 2354 } 2355 2356 dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", 2357 mParameters.associatedDisplayId); 2358 dump.appendFormat(INDENT4 "OrientationAware: %s\n", 2359 toString(mParameters.orientationAware)); 2360} 2361 2362void TouchInputMapper::configureRawAxes() { 2363 mRawAxes.x.clear(); 2364 mRawAxes.y.clear(); 2365 mRawAxes.pressure.clear(); 2366 mRawAxes.touchMajor.clear(); 2367 mRawAxes.touchMinor.clear(); 2368 mRawAxes.toolMajor.clear(); 2369 mRawAxes.toolMinor.clear(); 2370 mRawAxes.orientation.clear(); 2371 mRawAxes.distance.clear(); 2372 mRawAxes.trackingId.clear(); 2373 mRawAxes.slot.clear(); 2374} 2375 2376void TouchInputMapper::dumpRawAxes(String8& dump) { 2377 dump.append(INDENT3 "Raw Axes:\n"); 2378 dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X"); 2379 dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y"); 2380 dumpRawAbsoluteAxisInfo(dump, mRawAxes.pressure, "Pressure"); 2381 dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor"); 2382 dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor"); 2383 dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor"); 2384 dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor"); 2385 dumpRawAbsoluteAxisInfo(dump, mRawAxes.orientation, "Orientation"); 2386 dumpRawAbsoluteAxisInfo(dump, mRawAxes.distance, "Distance"); 2387 dumpRawAbsoluteAxisInfo(dump, mRawAxes.trackingId, "TrackingId"); 2388 dumpRawAbsoluteAxisInfo(dump, mRawAxes.slot, "Slot"); 2389} 2390 2391bool TouchInputMapper::configureSurfaceLocked() { 2392 // Ensure we have valid X and Y axes. 2393 if (!mRawAxes.x.valid || !mRawAxes.y.valid) { 2394 LOGW(INDENT "Touch device '%s' did not report support for X or Y axis! " 2395 "The device will be inoperable.", getDeviceName().string()); 2396 return false; 2397 } 2398 2399 // Update orientation and dimensions if needed. 2400 int32_t orientation = DISPLAY_ORIENTATION_0; 2401 int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; 2402 int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; 2403 2404 if (mParameters.associatedDisplayId >= 0) { 2405 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 2406 if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 2407 mParameters.associatedDisplayIsExternal, 2408 &mLocked.associatedDisplayWidth, &mLocked.associatedDisplayHeight, 2409 &mLocked.associatedDisplayOrientation)) { 2410 return false; 2411 } 2412 2413 // A touch screen inherits the dimensions of the display. 2414 if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) { 2415 width = mLocked.associatedDisplayWidth; 2416 height = mLocked.associatedDisplayHeight; 2417 } 2418 2419 // The device inherits the orientation of the display if it is orientation aware. 2420 if (mParameters.orientationAware) { 2421 orientation = mLocked.associatedDisplayOrientation; 2422 } 2423 } 2424 2425 if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER 2426 && mPointerController == NULL) { 2427 mPointerController = getPolicy()->obtainPointerController(getDeviceId()); 2428 } 2429 2430 bool orientationChanged = mLocked.surfaceOrientation != orientation; 2431 if (orientationChanged) { 2432 mLocked.surfaceOrientation = orientation; 2433 } 2434 2435 bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height; 2436 if (sizeChanged) { 2437 LOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d", 2438 getDeviceId(), getDeviceName().string(), width, height); 2439 2440 mLocked.surfaceWidth = width; 2441 mLocked.surfaceHeight = height; 2442 2443 // Configure X and Y factors. 2444 mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1); 2445 mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1); 2446 mLocked.xPrecision = 1.0f / mLocked.xScale; 2447 mLocked.yPrecision = 1.0f / mLocked.yScale; 2448 2449 mLocked.orientedRanges.x.axis = AMOTION_EVENT_AXIS_X; 2450 mLocked.orientedRanges.x.source = mTouchSource; 2451 mLocked.orientedRanges.y.axis = AMOTION_EVENT_AXIS_Y; 2452 mLocked.orientedRanges.y.source = mTouchSource; 2453 2454 configureVirtualKeysLocked(); 2455 2456 // Scale factor for terms that are not oriented in a particular axis. 2457 // If the pixels are square then xScale == yScale otherwise we fake it 2458 // by choosing an average. 2459 mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale); 2460 2461 // Size of diagonal axis. 2462 float diagonalSize = hypotf(width, height); 2463 2464 // TouchMajor and TouchMinor factors. 2465 if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) { 2466 mLocked.orientedRanges.haveTouchSize = true; 2467 2468 mLocked.orientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR; 2469 mLocked.orientedRanges.touchMajor.source = mTouchSource; 2470 mLocked.orientedRanges.touchMajor.min = 0; 2471 mLocked.orientedRanges.touchMajor.max = diagonalSize; 2472 mLocked.orientedRanges.touchMajor.flat = 0; 2473 mLocked.orientedRanges.touchMajor.fuzz = 0; 2474 2475 mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor; 2476 mLocked.orientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR; 2477 } 2478 2479 // ToolMajor and ToolMinor factors. 2480 mLocked.toolSizeLinearScale = 0; 2481 mLocked.toolSizeLinearBias = 0; 2482 mLocked.toolSizeAreaScale = 0; 2483 mLocked.toolSizeAreaBias = 0; 2484 if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 2485 if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) { 2486 if (mCalibration.haveToolSizeLinearScale) { 2487 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 2488 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 2489 mLocked.toolSizeLinearScale = float(min(width, height)) 2490 / mRawAxes.toolMajor.maxValue; 2491 } 2492 2493 if (mCalibration.haveToolSizeLinearBias) { 2494 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 2495 } 2496 } else if (mCalibration.toolSizeCalibration == 2497 Calibration::TOOL_SIZE_CALIBRATION_AREA) { 2498 if (mCalibration.haveToolSizeLinearScale) { 2499 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 2500 } else { 2501 mLocked.toolSizeLinearScale = min(width, height); 2502 } 2503 2504 if (mCalibration.haveToolSizeLinearBias) { 2505 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 2506 } 2507 2508 if (mCalibration.haveToolSizeAreaScale) { 2509 mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale; 2510 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 2511 mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue; 2512 } 2513 2514 if (mCalibration.haveToolSizeAreaBias) { 2515 mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias; 2516 } 2517 } 2518 2519 mLocked.orientedRanges.haveToolSize = true; 2520 2521 mLocked.orientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR; 2522 mLocked.orientedRanges.toolMajor.source = mTouchSource; 2523 mLocked.orientedRanges.toolMajor.min = 0; 2524 mLocked.orientedRanges.toolMajor.max = diagonalSize; 2525 mLocked.orientedRanges.toolMajor.flat = 0; 2526 mLocked.orientedRanges.toolMajor.fuzz = 0; 2527 2528 mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor; 2529 mLocked.orientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR; 2530 } 2531 2532 // Pressure factors. 2533 mLocked.pressureScale = 0; 2534 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) { 2535 RawAbsoluteAxisInfo rawPressureAxis; 2536 switch (mCalibration.pressureSource) { 2537 case Calibration::PRESSURE_SOURCE_PRESSURE: 2538 rawPressureAxis = mRawAxes.pressure; 2539 break; 2540 case Calibration::PRESSURE_SOURCE_TOUCH: 2541 rawPressureAxis = mRawAxes.touchMajor; 2542 break; 2543 default: 2544 rawPressureAxis.clear(); 2545 } 2546 2547 if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL 2548 || mCalibration.pressureCalibration 2549 == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) { 2550 if (mCalibration.havePressureScale) { 2551 mLocked.pressureScale = mCalibration.pressureScale; 2552 } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) { 2553 mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue; 2554 } 2555 } 2556 2557 mLocked.orientedRanges.havePressure = true; 2558 2559 mLocked.orientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE; 2560 mLocked.orientedRanges.pressure.source = mTouchSource; 2561 mLocked.orientedRanges.pressure.min = 0; 2562 mLocked.orientedRanges.pressure.max = 1.0; 2563 mLocked.orientedRanges.pressure.flat = 0; 2564 mLocked.orientedRanges.pressure.fuzz = 0; 2565 } 2566 2567 // Size factors. 2568 mLocked.sizeScale = 0; 2569 if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) { 2570 if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) { 2571 if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 2572 mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue; 2573 } 2574 } 2575 2576 mLocked.orientedRanges.haveSize = true; 2577 2578 mLocked.orientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE; 2579 mLocked.orientedRanges.size.source = mTouchSource; 2580 mLocked.orientedRanges.size.min = 0; 2581 mLocked.orientedRanges.size.max = 1.0; 2582 mLocked.orientedRanges.size.flat = 0; 2583 mLocked.orientedRanges.size.fuzz = 0; 2584 } 2585 2586 // Orientation 2587 mLocked.orientationScale = 0; 2588 if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) { 2589 if (mCalibration.orientationCalibration 2590 == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) { 2591 if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) { 2592 mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue; 2593 } 2594 } 2595 2596 mLocked.orientedRanges.haveOrientation = true; 2597 2598 mLocked.orientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION; 2599 mLocked.orientedRanges.orientation.source = mTouchSource; 2600 mLocked.orientedRanges.orientation.min = - M_PI_2; 2601 mLocked.orientedRanges.orientation.max = M_PI_2; 2602 mLocked.orientedRanges.orientation.flat = 0; 2603 mLocked.orientedRanges.orientation.fuzz = 0; 2604 } 2605 2606 // Distance 2607 mLocked.distanceScale = 0; 2608 if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) { 2609 if (mCalibration.distanceCalibration 2610 == Calibration::DISTANCE_CALIBRATION_SCALED) { 2611 if (mCalibration.haveDistanceScale) { 2612 mLocked.distanceScale = mCalibration.distanceScale; 2613 } else { 2614 mLocked.distanceScale = 1.0f; 2615 } 2616 } 2617 2618 mLocked.orientedRanges.haveDistance = true; 2619 2620 mLocked.orientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE; 2621 mLocked.orientedRanges.distance.source = mTouchSource; 2622 mLocked.orientedRanges.distance.min = 2623 mRawAxes.distance.minValue * mLocked.distanceScale; 2624 mLocked.orientedRanges.distance.max = 2625 mRawAxes.distance.minValue * mLocked.distanceScale; 2626 mLocked.orientedRanges.distance.flat = 0; 2627 mLocked.orientedRanges.distance.fuzz = 2628 mRawAxes.distance.fuzz * mLocked.distanceScale; 2629 } 2630 } 2631 2632 if (orientationChanged || sizeChanged) { 2633 // Compute oriented surface dimensions, precision, scales and ranges. 2634 // Note that the maximum value reported is an inclusive maximum value so it is one 2635 // unit less than the total width or height of surface. 2636 switch (mLocked.surfaceOrientation) { 2637 case DISPLAY_ORIENTATION_90: 2638 case DISPLAY_ORIENTATION_270: 2639 mLocked.orientedSurfaceWidth = mLocked.surfaceHeight; 2640 mLocked.orientedSurfaceHeight = mLocked.surfaceWidth; 2641 2642 mLocked.orientedXPrecision = mLocked.yPrecision; 2643 mLocked.orientedYPrecision = mLocked.xPrecision; 2644 2645 mLocked.orientedRanges.x.min = 0; 2646 mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) 2647 * mLocked.yScale; 2648 mLocked.orientedRanges.x.flat = 0; 2649 mLocked.orientedRanges.x.fuzz = mLocked.yScale; 2650 2651 mLocked.orientedRanges.y.min = 0; 2652 mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) 2653 * mLocked.xScale; 2654 mLocked.orientedRanges.y.flat = 0; 2655 mLocked.orientedRanges.y.fuzz = mLocked.xScale; 2656 break; 2657 2658 default: 2659 mLocked.orientedSurfaceWidth = mLocked.surfaceWidth; 2660 mLocked.orientedSurfaceHeight = mLocked.surfaceHeight; 2661 2662 mLocked.orientedXPrecision = mLocked.xPrecision; 2663 mLocked.orientedYPrecision = mLocked.yPrecision; 2664 2665 mLocked.orientedRanges.x.min = 0; 2666 mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) 2667 * mLocked.xScale; 2668 mLocked.orientedRanges.x.flat = 0; 2669 mLocked.orientedRanges.x.fuzz = mLocked.xScale; 2670 2671 mLocked.orientedRanges.y.min = 0; 2672 mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) 2673 * mLocked.yScale; 2674 mLocked.orientedRanges.y.flat = 0; 2675 mLocked.orientedRanges.y.fuzz = mLocked.yScale; 2676 break; 2677 } 2678 2679 // Compute pointer gesture detection parameters. 2680 // TODO: These factors should not be hardcoded. 2681 if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) { 2682 int32_t rawWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; 2683 int32_t rawHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; 2684 float rawDiagonal = hypotf(rawWidth, rawHeight); 2685 float displayDiagonal = hypotf(mLocked.associatedDisplayWidth, 2686 mLocked.associatedDisplayHeight); 2687 2688 // Scale movements such that one whole swipe of the touch pad covers a 2689 // given area relative to the diagonal size of the display when no acceleration 2690 // is applied. 2691 // Assume that the touch pad has a square aspect ratio such that movements in 2692 // X and Y of the same number of raw units cover the same physical distance. 2693 mLocked.pointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio 2694 * displayDiagonal / rawDiagonal; 2695 mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale; 2696 2697 // Scale zooms to cover a smaller range of the display than movements do. 2698 // This value determines the area around the pointer that is affected by freeform 2699 // pointer gestures. 2700 mLocked.pointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio 2701 * displayDiagonal / rawDiagonal; 2702 mLocked.pointerGestureYZoomScale = mLocked.pointerGestureXZoomScale; 2703 2704 // Max width between pointers to detect a swipe gesture is more than some fraction 2705 // of the diagonal axis of the touch pad. Touches that are wider than this are 2706 // translated into freeform gestures. 2707 mLocked.pointerGestureMaxSwipeWidth = 2708 mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal; 2709 2710 // Reset the current pointer gesture. 2711 mPointerGesture.reset(); 2712 2713 // Remove any current spots. 2714 if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { 2715 mPointerController->clearSpots(); 2716 } 2717 } 2718 } 2719 2720 return true; 2721} 2722 2723void TouchInputMapper::dumpSurfaceLocked(String8& dump) { 2724 dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth); 2725 dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight); 2726 dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation); 2727} 2728 2729void TouchInputMapper::configureVirtualKeysLocked() { 2730 Vector<VirtualKeyDefinition> virtualKeyDefinitions; 2731 getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions); 2732 2733 mLocked.virtualKeys.clear(); 2734 2735 if (virtualKeyDefinitions.size() == 0) { 2736 return; 2737 } 2738 2739 mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size()); 2740 2741 int32_t touchScreenLeft = mRawAxes.x.minValue; 2742 int32_t touchScreenTop = mRawAxes.y.minValue; 2743 int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; 2744 int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; 2745 2746 for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) { 2747 const VirtualKeyDefinition& virtualKeyDefinition = 2748 virtualKeyDefinitions[i]; 2749 2750 mLocked.virtualKeys.add(); 2751 VirtualKey& virtualKey = mLocked.virtualKeys.editTop(); 2752 2753 virtualKey.scanCode = virtualKeyDefinition.scanCode; 2754 int32_t keyCode; 2755 uint32_t flags; 2756 if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 2757 & keyCode, & flags)) { 2758 LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", 2759 virtualKey.scanCode); 2760 mLocked.virtualKeys.pop(); // drop the key 2761 continue; 2762 } 2763 2764 virtualKey.keyCode = keyCode; 2765 virtualKey.flags = flags; 2766 2767 // convert the key definition's display coordinates into touch coordinates for a hit box 2768 int32_t halfWidth = virtualKeyDefinition.width / 2; 2769 int32_t halfHeight = virtualKeyDefinition.height / 2; 2770 2771 virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth) 2772 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 2773 virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth) 2774 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 2775 virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight) 2776 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 2777 virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) 2778 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 2779 } 2780} 2781 2782void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) { 2783 if (!mLocked.virtualKeys.isEmpty()) { 2784 dump.append(INDENT3 "Virtual Keys:\n"); 2785 2786 for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) { 2787 const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i); 2788 dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, " 2789 "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n", 2790 i, virtualKey.scanCode, virtualKey.keyCode, 2791 virtualKey.hitLeft, virtualKey.hitRight, 2792 virtualKey.hitTop, virtualKey.hitBottom); 2793 } 2794 } 2795} 2796 2797void TouchInputMapper::parseCalibration() { 2798 const PropertyMap& in = getDevice()->getConfiguration(); 2799 Calibration& out = mCalibration; 2800 2801 // Touch Size 2802 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT; 2803 String8 touchSizeCalibrationString; 2804 if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) { 2805 if (touchSizeCalibrationString == "none") { 2806 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 2807 } else if (touchSizeCalibrationString == "geometric") { 2808 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC; 2809 } else if (touchSizeCalibrationString == "pressure") { 2810 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 2811 } else if (touchSizeCalibrationString != "default") { 2812 LOGW("Invalid value for touch.touchSize.calibration: '%s'", 2813 touchSizeCalibrationString.string()); 2814 } 2815 } 2816 2817 // Tool Size 2818 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT; 2819 String8 toolSizeCalibrationString; 2820 if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) { 2821 if (toolSizeCalibrationString == "none") { 2822 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 2823 } else if (toolSizeCalibrationString == "geometric") { 2824 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC; 2825 } else if (toolSizeCalibrationString == "linear") { 2826 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 2827 } else if (toolSizeCalibrationString == "area") { 2828 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA; 2829 } else if (toolSizeCalibrationString != "default") { 2830 LOGW("Invalid value for touch.toolSize.calibration: '%s'", 2831 toolSizeCalibrationString.string()); 2832 } 2833 } 2834 2835 out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"), 2836 out.toolSizeLinearScale); 2837 out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"), 2838 out.toolSizeLinearBias); 2839 out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"), 2840 out.toolSizeAreaScale); 2841 out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"), 2842 out.toolSizeAreaBias); 2843 out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"), 2844 out.toolSizeIsSummed); 2845 2846 // Pressure 2847 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT; 2848 String8 pressureCalibrationString; 2849 if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) { 2850 if (pressureCalibrationString == "none") { 2851 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 2852 } else if (pressureCalibrationString == "physical") { 2853 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL; 2854 } else if (pressureCalibrationString == "amplitude") { 2855 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 2856 } else if (pressureCalibrationString != "default") { 2857 LOGW("Invalid value for touch.pressure.calibration: '%s'", 2858 pressureCalibrationString.string()); 2859 } 2860 } 2861 2862 out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT; 2863 String8 pressureSourceString; 2864 if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) { 2865 if (pressureSourceString == "pressure") { 2866 out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 2867 } else if (pressureSourceString == "touch") { 2868 out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 2869 } else if (pressureSourceString != "default") { 2870 LOGW("Invalid value for touch.pressure.source: '%s'", 2871 pressureSourceString.string()); 2872 } 2873 } 2874 2875 out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"), 2876 out.pressureScale); 2877 2878 // Size 2879 out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT; 2880 String8 sizeCalibrationString; 2881 if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) { 2882 if (sizeCalibrationString == "none") { 2883 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 2884 } else if (sizeCalibrationString == "normalized") { 2885 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 2886 } else if (sizeCalibrationString != "default") { 2887 LOGW("Invalid value for touch.size.calibration: '%s'", 2888 sizeCalibrationString.string()); 2889 } 2890 } 2891 2892 // Orientation 2893 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT; 2894 String8 orientationCalibrationString; 2895 if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) { 2896 if (orientationCalibrationString == "none") { 2897 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 2898 } else if (orientationCalibrationString == "interpolated") { 2899 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 2900 } else if (orientationCalibrationString == "vector") { 2901 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR; 2902 } else if (orientationCalibrationString != "default") { 2903 LOGW("Invalid value for touch.orientation.calibration: '%s'", 2904 orientationCalibrationString.string()); 2905 } 2906 } 2907 2908 // Distance 2909 out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT; 2910 String8 distanceCalibrationString; 2911 if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) { 2912 if (distanceCalibrationString == "none") { 2913 out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE; 2914 } else if (distanceCalibrationString == "scaled") { 2915 out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED; 2916 } else if (distanceCalibrationString != "default") { 2917 LOGW("Invalid value for touch.distance.calibration: '%s'", 2918 distanceCalibrationString.string()); 2919 } 2920 } 2921 2922 out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"), 2923 out.distanceScale); 2924} 2925 2926void TouchInputMapper::resolveCalibration() { 2927 // Pressure 2928 switch (mCalibration.pressureSource) { 2929 case Calibration::PRESSURE_SOURCE_DEFAULT: 2930 if (mRawAxes.pressure.valid) { 2931 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 2932 } else if (mRawAxes.touchMajor.valid) { 2933 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 2934 } 2935 break; 2936 2937 case Calibration::PRESSURE_SOURCE_PRESSURE: 2938 if (! mRawAxes.pressure.valid) { 2939 LOGW("Calibration property touch.pressure.source is 'pressure' but " 2940 "the pressure axis is not available."); 2941 } 2942 break; 2943 2944 case Calibration::PRESSURE_SOURCE_TOUCH: 2945 if (! mRawAxes.touchMajor.valid) { 2946 LOGW("Calibration property touch.pressure.source is 'touch' but " 2947 "the touchMajor axis is not available."); 2948 } 2949 break; 2950 2951 default: 2952 break; 2953 } 2954 2955 switch (mCalibration.pressureCalibration) { 2956 case Calibration::PRESSURE_CALIBRATION_DEFAULT: 2957 if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) { 2958 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 2959 } else { 2960 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 2961 } 2962 break; 2963 2964 default: 2965 break; 2966 } 2967 2968 // Tool Size 2969 switch (mCalibration.toolSizeCalibration) { 2970 case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT: 2971 if (mRawAxes.toolMajor.valid) { 2972 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 2973 } else { 2974 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 2975 } 2976 break; 2977 2978 default: 2979 break; 2980 } 2981 2982 // Touch Size 2983 switch (mCalibration.touchSizeCalibration) { 2984 case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT: 2985 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE 2986 && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 2987 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 2988 } else { 2989 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 2990 } 2991 break; 2992 2993 default: 2994 break; 2995 } 2996 2997 // Size 2998 switch (mCalibration.sizeCalibration) { 2999 case Calibration::SIZE_CALIBRATION_DEFAULT: 3000 if (mRawAxes.toolMajor.valid) { 3001 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 3002 } else { 3003 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 3004 } 3005 break; 3006 3007 default: 3008 break; 3009 } 3010 3011 // Orientation 3012 switch (mCalibration.orientationCalibration) { 3013 case Calibration::ORIENTATION_CALIBRATION_DEFAULT: 3014 if (mRawAxes.orientation.valid) { 3015 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 3016 } else { 3017 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 3018 } 3019 break; 3020 3021 default: 3022 break; 3023 } 3024 3025 // Distance 3026 switch (mCalibration.distanceCalibration) { 3027 case Calibration::DISTANCE_CALIBRATION_DEFAULT: 3028 if (mRawAxes.distance.valid) { 3029 mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED; 3030 } else { 3031 mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE; 3032 } 3033 break; 3034 3035 default: 3036 break; 3037 } 3038} 3039 3040void TouchInputMapper::dumpCalibration(String8& dump) { 3041 dump.append(INDENT3 "Calibration:\n"); 3042 3043 // Touch Size 3044 switch (mCalibration.touchSizeCalibration) { 3045 case Calibration::TOUCH_SIZE_CALIBRATION_NONE: 3046 dump.append(INDENT4 "touch.touchSize.calibration: none\n"); 3047 break; 3048 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 3049 dump.append(INDENT4 "touch.touchSize.calibration: geometric\n"); 3050 break; 3051 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 3052 dump.append(INDENT4 "touch.touchSize.calibration: pressure\n"); 3053 break; 3054 default: 3055 LOG_ASSERT(false); 3056 } 3057 3058 // Tool Size 3059 switch (mCalibration.toolSizeCalibration) { 3060 case Calibration::TOOL_SIZE_CALIBRATION_NONE: 3061 dump.append(INDENT4 "touch.toolSize.calibration: none\n"); 3062 break; 3063 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 3064 dump.append(INDENT4 "touch.toolSize.calibration: geometric\n"); 3065 break; 3066 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 3067 dump.append(INDENT4 "touch.toolSize.calibration: linear\n"); 3068 break; 3069 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 3070 dump.append(INDENT4 "touch.toolSize.calibration: area\n"); 3071 break; 3072 default: 3073 LOG_ASSERT(false); 3074 } 3075 3076 if (mCalibration.haveToolSizeLinearScale) { 3077 dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n", 3078 mCalibration.toolSizeLinearScale); 3079 } 3080 3081 if (mCalibration.haveToolSizeLinearBias) { 3082 dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n", 3083 mCalibration.toolSizeLinearBias); 3084 } 3085 3086 if (mCalibration.haveToolSizeAreaScale) { 3087 dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n", 3088 mCalibration.toolSizeAreaScale); 3089 } 3090 3091 if (mCalibration.haveToolSizeAreaBias) { 3092 dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n", 3093 mCalibration.toolSizeAreaBias); 3094 } 3095 3096 if (mCalibration.haveToolSizeIsSummed) { 3097 dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %s\n", 3098 toString(mCalibration.toolSizeIsSummed)); 3099 } 3100 3101 // Pressure 3102 switch (mCalibration.pressureCalibration) { 3103 case Calibration::PRESSURE_CALIBRATION_NONE: 3104 dump.append(INDENT4 "touch.pressure.calibration: none\n"); 3105 break; 3106 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 3107 dump.append(INDENT4 "touch.pressure.calibration: physical\n"); 3108 break; 3109 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 3110 dump.append(INDENT4 "touch.pressure.calibration: amplitude\n"); 3111 break; 3112 default: 3113 LOG_ASSERT(false); 3114 } 3115 3116 switch (mCalibration.pressureSource) { 3117 case Calibration::PRESSURE_SOURCE_PRESSURE: 3118 dump.append(INDENT4 "touch.pressure.source: pressure\n"); 3119 break; 3120 case Calibration::PRESSURE_SOURCE_TOUCH: 3121 dump.append(INDENT4 "touch.pressure.source: touch\n"); 3122 break; 3123 case Calibration::PRESSURE_SOURCE_DEFAULT: 3124 break; 3125 default: 3126 LOG_ASSERT(false); 3127 } 3128 3129 if (mCalibration.havePressureScale) { 3130 dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n", 3131 mCalibration.pressureScale); 3132 } 3133 3134 // Size 3135 switch (mCalibration.sizeCalibration) { 3136 case Calibration::SIZE_CALIBRATION_NONE: 3137 dump.append(INDENT4 "touch.size.calibration: none\n"); 3138 break; 3139 case Calibration::SIZE_CALIBRATION_NORMALIZED: 3140 dump.append(INDENT4 "touch.size.calibration: normalized\n"); 3141 break; 3142 default: 3143 LOG_ASSERT(false); 3144 } 3145 3146 // Orientation 3147 switch (mCalibration.orientationCalibration) { 3148 case Calibration::ORIENTATION_CALIBRATION_NONE: 3149 dump.append(INDENT4 "touch.orientation.calibration: none\n"); 3150 break; 3151 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 3152 dump.append(INDENT4 "touch.orientation.calibration: interpolated\n"); 3153 break; 3154 case Calibration::ORIENTATION_CALIBRATION_VECTOR: 3155 dump.append(INDENT4 "touch.orientation.calibration: vector\n"); 3156 break; 3157 default: 3158 LOG_ASSERT(false); 3159 } 3160 3161 // Distance 3162 switch (mCalibration.distanceCalibration) { 3163 case Calibration::DISTANCE_CALIBRATION_NONE: 3164 dump.append(INDENT4 "touch.distance.calibration: none\n"); 3165 break; 3166 case Calibration::DISTANCE_CALIBRATION_SCALED: 3167 dump.append(INDENT4 "touch.distance.calibration: scaled\n"); 3168 break; 3169 default: 3170 LOG_ASSERT(false); 3171 } 3172 3173 if (mCalibration.haveDistanceScale) { 3174 dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n", 3175 mCalibration.distanceScale); 3176 } 3177} 3178 3179void TouchInputMapper::reset() { 3180 // Synthesize touch up event if touch is currently down. 3181 // This will also take care of finishing virtual key processing if needed. 3182 if (mLastTouch.pointerCount != 0) { 3183 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 3184 mCurrentTouch.clear(); 3185 syncTouch(when, true); 3186 } 3187 3188 { // acquire lock 3189 AutoMutex _l(mLock); 3190 initializeLocked(); 3191 3192 if (mPointerController != NULL 3193 && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { 3194 mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); 3195 mPointerController->clearSpots(); 3196 } 3197 } // release lock 3198 3199 InputMapper::reset(); 3200} 3201 3202void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { 3203#if DEBUG_RAW_EVENTS 3204 if (!havePointerIds) { 3205 LOGD("syncTouch: pointerCount=%d, no pointer ids", mCurrentTouch.pointerCount); 3206 } else { 3207 LOGD("syncTouch: pointerCount=%d, up=0x%08x, down=0x%08x, move=0x%08x, " 3208 "last=0x%08x, current=0x%08x", mCurrentTouch.pointerCount, 3209 mLastTouch.idBits.value & ~mCurrentTouch.idBits.value, 3210 mCurrentTouch.idBits.value & ~mLastTouch.idBits.value, 3211 mLastTouch.idBits.value & mCurrentTouch.idBits.value, 3212 mLastTouch.idBits.value, mCurrentTouch.idBits.value); 3213 } 3214#endif 3215 3216 // Preprocess pointer data. 3217 if (!havePointerIds) { 3218 calculatePointerIds(); 3219 } 3220 3221 // Handle initial down events. 3222 uint32_t policyFlags = 0; 3223 if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) { 3224 if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) { 3225 // If this is a touch screen, hide the pointer on an initial down. 3226 getContext()->fadePointer(); 3227 } 3228 3229 // Initial downs on external touch devices should wake the device. 3230 // We don't do this for internal touch screens to prevent them from waking 3231 // up in your pocket. 3232 // TODO: Use the input device configuration to control this behavior more finely. 3233 if (getDevice()->isExternal()) { 3234 policyFlags |= POLICY_FLAG_WAKE_DROPPED; 3235 } 3236 } 3237 3238 // Synthesize key down from buttons if needed. 3239 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mTouchSource, 3240 policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState); 3241 3242 // Send motion events. 3243 TouchResult touchResult; 3244 if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount == 0 3245 && mLastTouch.buttonState == mCurrentTouch.buttonState) { 3246 // Drop spurious syncs. 3247 touchResult = DROP_STROKE; 3248 } else { 3249 // Process touches and virtual keys. 3250 touchResult = consumeOffScreenTouches(when, policyFlags); 3251 if (touchResult == DISPATCH_TOUCH) { 3252 suppressSwipeOntoVirtualKeys(when); 3253 if (mPointerController != NULL && mConfig.pointerGesturesEnabled) { 3254 dispatchPointerGestures(when, policyFlags, false /*isTimeout*/); 3255 } 3256 dispatchTouches(when, policyFlags); 3257 } 3258 } 3259 3260 // Synthesize key up from buttons if needed. 3261 synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mTouchSource, 3262 policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState); 3263 3264 // Copy current touch to last touch in preparation for the next cycle. 3265 // Keep the button state so we can track edge-triggered button state changes. 3266 if (touchResult == DROP_STROKE) { 3267 mLastTouch.clear(); 3268 mLastTouch.buttonState = mCurrentTouch.buttonState; 3269 } else { 3270 mLastTouch.copyFrom(mCurrentTouch); 3271 } 3272} 3273 3274void TouchInputMapper::timeoutExpired(nsecs_t when) { 3275 if (mPointerController != NULL) { 3276 dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/); 3277 } 3278} 3279 3280TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches( 3281 nsecs_t when, uint32_t policyFlags) { 3282 int32_t keyEventAction, keyEventFlags; 3283 int32_t keyCode, scanCode, downTime; 3284 TouchResult touchResult; 3285 3286 { // acquire lock 3287 AutoMutex _l(mLock); 3288 3289 // Update surface size and orientation, including virtual key positions. 3290 if (! configureSurfaceLocked()) { 3291 return DROP_STROKE; 3292 } 3293 3294 // Check for virtual key press. 3295 if (mLocked.currentVirtualKey.down) { 3296 if (mCurrentTouch.pointerCount == 0) { 3297 // Pointer went up while virtual key was down. 3298 mLocked.currentVirtualKey.down = false; 3299#if DEBUG_VIRTUAL_KEYS 3300 LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d", 3301 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 3302#endif 3303 keyEventAction = AKEY_EVENT_ACTION_UP; 3304 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 3305 touchResult = SKIP_TOUCH; 3306 goto DispatchVirtualKey; 3307 } 3308 3309 if (mCurrentTouch.pointerCount == 1) { 3310 int32_t x = mCurrentTouch.pointers[0].x; 3311 int32_t y = mCurrentTouch.pointers[0].y; 3312 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 3313 if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) { 3314 // Pointer is still within the space of the virtual key. 3315 return SKIP_TOUCH; 3316 } 3317 } 3318 3319 // Pointer left virtual key area or another pointer also went down. 3320 // Send key cancellation and drop the stroke so subsequent motions will be 3321 // considered fresh downs. This is useful when the user swipes away from the 3322 // virtual key area into the main display surface. 3323 mLocked.currentVirtualKey.down = false; 3324#if DEBUG_VIRTUAL_KEYS 3325 LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d", 3326 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 3327#endif 3328 keyEventAction = AKEY_EVENT_ACTION_UP; 3329 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY 3330 | AKEY_EVENT_FLAG_CANCELED; 3331 3332 // Check whether the pointer moved inside the display area where we should 3333 // start a new stroke. 3334 int32_t x = mCurrentTouch.pointers[0].x; 3335 int32_t y = mCurrentTouch.pointers[0].y; 3336 if (isPointInsideSurfaceLocked(x, y)) { 3337 mLastTouch.clear(); 3338 touchResult = DISPATCH_TOUCH; 3339 } else { 3340 touchResult = DROP_STROKE; 3341 } 3342 } else { 3343 if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) { 3344 // Pointer just went down. Handle off-screen touches, if needed. 3345 int32_t x = mCurrentTouch.pointers[0].x; 3346 int32_t y = mCurrentTouch.pointers[0].y; 3347 if (! isPointInsideSurfaceLocked(x, y)) { 3348 // If exactly one pointer went down, check for virtual key hit. 3349 // Otherwise we will drop the entire stroke. 3350 if (mCurrentTouch.pointerCount == 1) { 3351 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 3352 if (virtualKey) { 3353 if (mContext->shouldDropVirtualKey(when, getDevice(), 3354 virtualKey->keyCode, virtualKey->scanCode)) { 3355 return DROP_STROKE; 3356 } 3357 3358 mLocked.currentVirtualKey.down = true; 3359 mLocked.currentVirtualKey.downTime = when; 3360 mLocked.currentVirtualKey.keyCode = virtualKey->keyCode; 3361 mLocked.currentVirtualKey.scanCode = virtualKey->scanCode; 3362#if DEBUG_VIRTUAL_KEYS 3363 LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d", 3364 mLocked.currentVirtualKey.keyCode, 3365 mLocked.currentVirtualKey.scanCode); 3366#endif 3367 keyEventAction = AKEY_EVENT_ACTION_DOWN; 3368 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM 3369 | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 3370 touchResult = SKIP_TOUCH; 3371 goto DispatchVirtualKey; 3372 } 3373 } 3374 return DROP_STROKE; 3375 } 3376 } 3377 return DISPATCH_TOUCH; 3378 } 3379 3380 DispatchVirtualKey: 3381 // Collect remaining state needed to dispatch virtual key. 3382 keyCode = mLocked.currentVirtualKey.keyCode; 3383 scanCode = mLocked.currentVirtualKey.scanCode; 3384 downTime = mLocked.currentVirtualKey.downTime; 3385 } // release lock 3386 3387 // Dispatch virtual key. 3388 int32_t metaState = mContext->getGlobalMetaState(); 3389 policyFlags |= POLICY_FLAG_VIRTUAL; 3390 getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags, 3391 keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime); 3392 return touchResult; 3393} 3394 3395void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) { 3396 // Disable all virtual key touches that happen within a short time interval of the 3397 // most recent touch. The idea is to filter out stray virtual key presses when 3398 // interacting with the touch screen. 3399 // 3400 // Problems we're trying to solve: 3401 // 3402 // 1. While scrolling a list or dragging the window shade, the user swipes down into a 3403 // virtual key area that is implemented by a separate touch panel and accidentally 3404 // triggers a virtual key. 3405 // 3406 // 2. While typing in the on screen keyboard, the user taps slightly outside the screen 3407 // area and accidentally triggers a virtual key. This often happens when virtual keys 3408 // are layed out below the screen near to where the on screen keyboard's space bar 3409 // is displayed. 3410 if (mConfig.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) { 3411 mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime); 3412 } 3413} 3414 3415void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) { 3416 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 3417 uint32_t lastPointerCount = mLastTouch.pointerCount; 3418 if (currentPointerCount == 0 && lastPointerCount == 0) { 3419 return; // nothing to do! 3420 } 3421 3422 // Update current touch coordinates. 3423 float xPrecision, yPrecision; 3424 prepareTouches(&xPrecision, &yPrecision); 3425 3426 // Dispatch motions. 3427 BitSet32 currentIdBits = mCurrentTouch.idBits; 3428 BitSet32 lastIdBits = mLastTouch.idBits; 3429 int32_t metaState = getContext()->getGlobalMetaState(); 3430 int32_t buttonState = mCurrentTouch.buttonState; 3431 3432 if (currentIdBits == lastIdBits) { 3433 // No pointer id changes so this is a move event. 3434 // The dispatcher takes care of batching moves so we don't have to deal with that here. 3435 dispatchMotion(when, policyFlags, mTouchSource, 3436 AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 3437 AMOTION_EVENT_EDGE_FLAG_NONE, 3438 mCurrentTouchProperties, mCurrentTouchCoords, 3439 mCurrentTouch.idToIndex, currentIdBits, -1, 3440 xPrecision, yPrecision, mDownTime); 3441 } else { 3442 // There may be pointers going up and pointers going down and pointers moving 3443 // all at the same time. 3444 BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value); 3445 BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value); 3446 BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value); 3447 BitSet32 dispatchedIdBits(lastIdBits.value); 3448 3449 // Update last coordinates of pointers that have moved so that we observe the new 3450 // pointer positions at the same time as other pointers that have just gone up. 3451 bool moveNeeded = updateMovedPointers( 3452 mCurrentTouchProperties, mCurrentTouchCoords, mCurrentTouch.idToIndex, 3453 mLastTouchProperties, mLastTouchCoords, mLastTouch.idToIndex, 3454 moveIdBits); 3455 if (buttonState != mLastTouch.buttonState) { 3456 moveNeeded = true; 3457 } 3458 3459 // Dispatch pointer up events. 3460 while (!upIdBits.isEmpty()) { 3461 uint32_t upId = upIdBits.firstMarkedBit(); 3462 upIdBits.clearBit(upId); 3463 3464 dispatchMotion(when, policyFlags, mTouchSource, 3465 AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0, 3466 mLastTouchProperties, mLastTouchCoords, 3467 mLastTouch.idToIndex, dispatchedIdBits, upId, 3468 xPrecision, yPrecision, mDownTime); 3469 dispatchedIdBits.clearBit(upId); 3470 } 3471 3472 // Dispatch move events if any of the remaining pointers moved from their old locations. 3473 // Although applications receive new locations as part of individual pointer up 3474 // events, they do not generally handle them except when presented in a move event. 3475 if (moveNeeded) { 3476 LOG_ASSERT(moveIdBits.value == dispatchedIdBits.value); 3477 dispatchMotion(when, policyFlags, mTouchSource, 3478 AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0, 3479 mCurrentTouchProperties, mCurrentTouchCoords, 3480 mCurrentTouch.idToIndex, dispatchedIdBits, -1, 3481 xPrecision, yPrecision, mDownTime); 3482 } 3483 3484 // Dispatch pointer down events using the new pointer locations. 3485 while (!downIdBits.isEmpty()) { 3486 uint32_t downId = downIdBits.firstMarkedBit(); 3487 downIdBits.clearBit(downId); 3488 dispatchedIdBits.markBit(downId); 3489 3490 if (dispatchedIdBits.count() == 1) { 3491 // First pointer is going down. Set down time. 3492 mDownTime = when; 3493 } 3494 3495 dispatchMotion(when, policyFlags, mTouchSource, 3496 AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0, 3497 mCurrentTouchProperties, mCurrentTouchCoords, 3498 mCurrentTouch.idToIndex, dispatchedIdBits, downId, 3499 xPrecision, yPrecision, mDownTime); 3500 } 3501 } 3502 3503 // Update state for next time. 3504 for (uint32_t i = 0; i < currentPointerCount; i++) { 3505 mLastTouchProperties[i].copyFrom(mCurrentTouchProperties[i]); 3506 mLastTouchCoords[i].copyFrom(mCurrentTouchCoords[i]); 3507 } 3508} 3509 3510void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision) { 3511 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 3512 uint32_t lastPointerCount = mLastTouch.pointerCount; 3513 3514 AutoMutex _l(mLock); 3515 3516 // Walk through the the active pointers and map touch screen coordinates (TouchData) into 3517 // display or surface coordinates (PointerCoords) and adjust for display orientation. 3518 for (uint32_t i = 0; i < currentPointerCount; i++) { 3519 const PointerData& in = mCurrentTouch.pointers[i]; 3520 3521 // ToolMajor and ToolMinor 3522 float toolMajor, toolMinor; 3523 switch (mCalibration.toolSizeCalibration) { 3524 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 3525 toolMajor = in.toolMajor * mLocked.geometricScale; 3526 if (mRawAxes.toolMinor.valid) { 3527 toolMinor = in.toolMinor * mLocked.geometricScale; 3528 } else { 3529 toolMinor = toolMajor; 3530 } 3531 break; 3532 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 3533 toolMajor = in.toolMajor != 0 3534 ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias 3535 : 0; 3536 if (mRawAxes.toolMinor.valid) { 3537 toolMinor = in.toolMinor != 0 3538 ? in.toolMinor * mLocked.toolSizeLinearScale 3539 + mLocked.toolSizeLinearBias 3540 : 0; 3541 } else { 3542 toolMinor = toolMajor; 3543 } 3544 break; 3545 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 3546 if (in.toolMajor != 0) { 3547 float diameter = sqrtf(in.toolMajor 3548 * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias); 3549 toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias; 3550 } else { 3551 toolMajor = 0; 3552 } 3553 toolMinor = toolMajor; 3554 break; 3555 default: 3556 toolMajor = 0; 3557 toolMinor = 0; 3558 break; 3559 } 3560 3561 if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) { 3562 toolMajor /= currentPointerCount; 3563 toolMinor /= currentPointerCount; 3564 } 3565 3566 // Pressure 3567 float rawPressure; 3568 switch (mCalibration.pressureSource) { 3569 case Calibration::PRESSURE_SOURCE_PRESSURE: 3570 rawPressure = in.pressure; 3571 break; 3572 case Calibration::PRESSURE_SOURCE_TOUCH: 3573 rawPressure = in.touchMajor; 3574 break; 3575 default: 3576 rawPressure = 0; 3577 } 3578 3579 float pressure; 3580 switch (mCalibration.pressureCalibration) { 3581 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 3582 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 3583 pressure = rawPressure * mLocked.pressureScale; 3584 break; 3585 default: 3586 pressure = 1; 3587 break; 3588 } 3589 3590 // TouchMajor and TouchMinor 3591 float touchMajor, touchMinor; 3592 switch (mCalibration.touchSizeCalibration) { 3593 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 3594 touchMajor = in.touchMajor * mLocked.geometricScale; 3595 if (mRawAxes.touchMinor.valid) { 3596 touchMinor = in.touchMinor * mLocked.geometricScale; 3597 } else { 3598 touchMinor = touchMajor; 3599 } 3600 break; 3601 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 3602 touchMajor = toolMajor * pressure; 3603 touchMinor = toolMinor * pressure; 3604 break; 3605 default: 3606 touchMajor = 0; 3607 touchMinor = 0; 3608 break; 3609 } 3610 3611 if (touchMajor > toolMajor) { 3612 touchMajor = toolMajor; 3613 } 3614 if (touchMinor > toolMinor) { 3615 touchMinor = toolMinor; 3616 } 3617 3618 // Size 3619 float size; 3620 switch (mCalibration.sizeCalibration) { 3621 case Calibration::SIZE_CALIBRATION_NORMALIZED: { 3622 float rawSize = mRawAxes.toolMinor.valid 3623 ? avg(in.toolMajor, in.toolMinor) 3624 : in.toolMajor; 3625 size = rawSize * mLocked.sizeScale; 3626 break; 3627 } 3628 default: 3629 size = 0; 3630 break; 3631 } 3632 3633 // Orientation 3634 float orientation; 3635 switch (mCalibration.orientationCalibration) { 3636 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 3637 orientation = in.orientation * mLocked.orientationScale; 3638 break; 3639 case Calibration::ORIENTATION_CALIBRATION_VECTOR: { 3640 int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4); 3641 int32_t c2 = signExtendNybble(in.orientation & 0x0f); 3642 if (c1 != 0 || c2 != 0) { 3643 orientation = atan2f(c1, c2) * 0.5f; 3644 float scale = 1.0f + hypotf(c1, c2) / 16.0f; 3645 touchMajor *= scale; 3646 touchMinor /= scale; 3647 toolMajor *= scale; 3648 toolMinor /= scale; 3649 } else { 3650 orientation = 0; 3651 } 3652 break; 3653 } 3654 default: 3655 orientation = 0; 3656 } 3657 3658 // Distance 3659 float distance; 3660 switch (mCalibration.distanceCalibration) { 3661 case Calibration::DISTANCE_CALIBRATION_SCALED: 3662 distance = in.distance * mLocked.distanceScale; 3663 break; 3664 default: 3665 distance = 0; 3666 } 3667 3668 // X and Y 3669 // Adjust coords for surface orientation. 3670 float x, y; 3671 switch (mLocked.surfaceOrientation) { 3672 case DISPLAY_ORIENTATION_90: 3673 x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; 3674 y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; 3675 orientation -= M_PI_2; 3676 if (orientation < - M_PI_2) { 3677 orientation += M_PI; 3678 } 3679 break; 3680 case DISPLAY_ORIENTATION_180: 3681 x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; 3682 y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; 3683 break; 3684 case DISPLAY_ORIENTATION_270: 3685 x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; 3686 y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; 3687 orientation += M_PI_2; 3688 if (orientation > M_PI_2) { 3689 orientation -= M_PI; 3690 } 3691 break; 3692 default: 3693 x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; 3694 y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; 3695 break; 3696 } 3697 3698 // Write output coords. 3699 PointerCoords& out = mCurrentTouchCoords[i]; 3700 out.clear(); 3701 out.setAxisValue(AMOTION_EVENT_AXIS_X, x); 3702 out.setAxisValue(AMOTION_EVENT_AXIS_Y, y); 3703 out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure); 3704 out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size); 3705 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor); 3706 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor); 3707 out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor); 3708 out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor); 3709 out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation); 3710 if (distance != 0) { 3711 out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance); 3712 } 3713 3714 // Write output properties. 3715 PointerProperties& properties = mCurrentTouchProperties[i]; 3716 properties.clear(); 3717 properties.id = mCurrentTouch.pointers[i].id; 3718 properties.toolType = mCurrentTouch.pointers[i].toolType; 3719 } 3720 3721 *outXPrecision = mLocked.orientedXPrecision; 3722 *outYPrecision = mLocked.orientedYPrecision; 3723} 3724 3725void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, 3726 bool isTimeout) { 3727 // Update current gesture coordinates. 3728 bool cancelPreviousGesture, finishPreviousGesture; 3729 bool sendEvents = preparePointerGestures(when, 3730 &cancelPreviousGesture, &finishPreviousGesture, isTimeout); 3731 if (!sendEvents) { 3732 return; 3733 } 3734 if (finishPreviousGesture) { 3735 cancelPreviousGesture = false; 3736 } 3737 3738 // Update the pointer presentation and spots. 3739 if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { 3740 mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT); 3741 if (finishPreviousGesture || cancelPreviousGesture) { 3742 mPointerController->clearSpots(); 3743 } 3744 mPointerController->setSpots(mPointerGesture.currentGestureCoords, 3745 mPointerGesture.currentGestureIdToIndex, 3746 mPointerGesture.currentGestureIdBits); 3747 } else { 3748 mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); 3749 } 3750 3751 // Show or hide the pointer if needed. 3752 switch (mPointerGesture.currentGestureMode) { 3753 case PointerGesture::NEUTRAL: 3754 case PointerGesture::QUIET: 3755 if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS 3756 && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE 3757 || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) { 3758 // Remind the user of where the pointer is after finishing a gesture with spots. 3759 mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL); 3760 } 3761 break; 3762 case PointerGesture::TAP: 3763 case PointerGesture::TAP_DRAG: 3764 case PointerGesture::BUTTON_CLICK_OR_DRAG: 3765 case PointerGesture::HOVER: 3766 case PointerGesture::PRESS: 3767 // Unfade the pointer when the current gesture manipulates the 3768 // area directly under the pointer. 3769 mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); 3770 break; 3771 case PointerGesture::SWIPE: 3772 case PointerGesture::FREEFORM: 3773 // Fade the pointer when the current gesture manipulates a different 3774 // area and there are spots to guide the user experience. 3775 if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { 3776 mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); 3777 } else { 3778 mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); 3779 } 3780 break; 3781 } 3782 3783 // Send events! 3784 int32_t metaState = getContext()->getGlobalMetaState(); 3785 int32_t buttonState = mCurrentTouch.buttonState; 3786 3787 // Update last coordinates of pointers that have moved so that we observe the new 3788 // pointer positions at the same time as other pointers that have just gone up. 3789 bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP 3790 || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG 3791 || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG 3792 || mPointerGesture.currentGestureMode == PointerGesture::PRESS 3793 || mPointerGesture.currentGestureMode == PointerGesture::SWIPE 3794 || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM; 3795 bool moveNeeded = false; 3796 if (down && !cancelPreviousGesture && !finishPreviousGesture 3797 && !mPointerGesture.lastGestureIdBits.isEmpty() 3798 && !mPointerGesture.currentGestureIdBits.isEmpty()) { 3799 BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value 3800 & mPointerGesture.lastGestureIdBits.value); 3801 moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties, 3802 mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, 3803 mPointerGesture.lastGestureProperties, 3804 mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, 3805 movedGestureIdBits); 3806 if (buttonState != mLastTouch.buttonState) { 3807 moveNeeded = true; 3808 } 3809 } 3810 3811 // Send motion events for all pointers that went up or were canceled. 3812 BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits); 3813 if (!dispatchedGestureIdBits.isEmpty()) { 3814 if (cancelPreviousGesture) { 3815 dispatchMotion(when, policyFlags, mPointerSource, 3816 AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState, 3817 AMOTION_EVENT_EDGE_FLAG_NONE, 3818 mPointerGesture.lastGestureProperties, 3819 mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, 3820 dispatchedGestureIdBits, -1, 3821 0, 0, mPointerGesture.downTime); 3822 3823 dispatchedGestureIdBits.clear(); 3824 } else { 3825 BitSet32 upGestureIdBits; 3826 if (finishPreviousGesture) { 3827 upGestureIdBits = dispatchedGestureIdBits; 3828 } else { 3829 upGestureIdBits.value = dispatchedGestureIdBits.value 3830 & ~mPointerGesture.currentGestureIdBits.value; 3831 } 3832 while (!upGestureIdBits.isEmpty()) { 3833 uint32_t id = upGestureIdBits.firstMarkedBit(); 3834 upGestureIdBits.clearBit(id); 3835 3836 dispatchMotion(when, policyFlags, mPointerSource, 3837 AMOTION_EVENT_ACTION_POINTER_UP, 0, 3838 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, 3839 mPointerGesture.lastGestureProperties, 3840 mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex, 3841 dispatchedGestureIdBits, id, 3842 0, 0, mPointerGesture.downTime); 3843 3844 dispatchedGestureIdBits.clearBit(id); 3845 } 3846 } 3847 } 3848 3849 // Send motion events for all pointers that moved. 3850 if (moveNeeded) { 3851 dispatchMotion(when, policyFlags, mPointerSource, 3852 AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, 3853 mPointerGesture.currentGestureProperties, 3854 mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, 3855 dispatchedGestureIdBits, -1, 3856 0, 0, mPointerGesture.downTime); 3857 } 3858 3859 // Send motion events for all pointers that went down. 3860 if (down) { 3861 BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value 3862 & ~dispatchedGestureIdBits.value); 3863 while (!downGestureIdBits.isEmpty()) { 3864 uint32_t id = downGestureIdBits.firstMarkedBit(); 3865 downGestureIdBits.clearBit(id); 3866 dispatchedGestureIdBits.markBit(id); 3867 3868 if (dispatchedGestureIdBits.count() == 1) { 3869 mPointerGesture.downTime = when; 3870 } 3871 3872 dispatchMotion(when, policyFlags, mPointerSource, 3873 AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0, 3874 mPointerGesture.currentGestureProperties, 3875 mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, 3876 dispatchedGestureIdBits, id, 3877 0, 0, mPointerGesture.downTime); 3878 } 3879 } 3880 3881 // Send motion events for hover. 3882 if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) { 3883 dispatchMotion(when, policyFlags, mPointerSource, 3884 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 3885 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, 3886 mPointerGesture.currentGestureProperties, 3887 mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex, 3888 mPointerGesture.currentGestureIdBits, -1, 3889 0, 0, mPointerGesture.downTime); 3890 } else if (dispatchedGestureIdBits.isEmpty() 3891 && !mPointerGesture.lastGestureIdBits.isEmpty()) { 3892 // Synthesize a hover move event after all pointers go up to indicate that 3893 // the pointer is hovering again even if the user is not currently touching 3894 // the touch pad. This ensures that a view will receive a fresh hover enter 3895 // event after a tap. 3896 float x, y; 3897 mPointerController->getPosition(&x, &y); 3898 3899 PointerProperties pointerProperties; 3900 pointerProperties.clear(); 3901 pointerProperties.id = 0; 3902 pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER; 3903 3904 PointerCoords pointerCoords; 3905 pointerCoords.clear(); 3906 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); 3907 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); 3908 3909 getDispatcher()->notifyMotion(when, getDeviceId(), mPointerSource, policyFlags, 3910 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, 3911 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, 3912 1, &pointerProperties, &pointerCoords, 0, 0, mPointerGesture.downTime); 3913 } 3914 3915 // Update state. 3916 mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode; 3917 if (!down) { 3918 mPointerGesture.lastGestureIdBits.clear(); 3919 } else { 3920 mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits; 3921 for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) { 3922 uint32_t id = idBits.firstMarkedBit(); 3923 idBits.clearBit(id); 3924 uint32_t index = mPointerGesture.currentGestureIdToIndex[id]; 3925 mPointerGesture.lastGestureProperties[index].copyFrom( 3926 mPointerGesture.currentGestureProperties[index]); 3927 mPointerGesture.lastGestureCoords[index].copyFrom( 3928 mPointerGesture.currentGestureCoords[index]); 3929 mPointerGesture.lastGestureIdToIndex[id] = index; 3930 } 3931 } 3932} 3933 3934bool TouchInputMapper::preparePointerGestures(nsecs_t when, 3935 bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) { 3936 *outCancelPreviousGesture = false; 3937 *outFinishPreviousGesture = false; 3938 3939 AutoMutex _l(mLock); 3940 3941 // Handle TAP timeout. 3942 if (isTimeout) { 3943#if DEBUG_GESTURES 3944 LOGD("Gestures: Processing timeout"); 3945#endif 3946 3947 if (mPointerGesture.lastGestureMode == PointerGesture::TAP) { 3948 if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) { 3949 // The tap/drag timeout has not yet expired. 3950 getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime 3951 + mConfig.pointerGestureTapDragInterval); 3952 } else { 3953 // The tap is finished. 3954#if DEBUG_GESTURES 3955 LOGD("Gestures: TAP finished"); 3956#endif 3957 *outFinishPreviousGesture = true; 3958 3959 mPointerGesture.activeGestureId = -1; 3960 mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL; 3961 mPointerGesture.currentGestureIdBits.clear(); 3962 3963 mPointerGesture.pointerVelocityControl.reset(); 3964 return true; 3965 } 3966 } 3967 3968 // We did not handle this timeout. 3969 return false; 3970 } 3971 3972 // Update the velocity tracker. 3973 { 3974 VelocityTracker::Position positions[MAX_POINTERS]; 3975 uint32_t count = 0; 3976 for (BitSet32 idBits(mCurrentTouch.idBits); !idBits.isEmpty(); count++) { 3977 uint32_t id = idBits.firstMarkedBit(); 3978 idBits.clearBit(id); 3979 uint32_t index = mCurrentTouch.idToIndex[id]; 3980 positions[count].x = mCurrentTouch.pointers[index].x 3981 * mLocked.pointerGestureXMovementScale; 3982 positions[count].y = mCurrentTouch.pointers[index].y 3983 * mLocked.pointerGestureYMovementScale; 3984 } 3985 mPointerGesture.velocityTracker.addMovement(when, mCurrentTouch.idBits, positions); 3986 } 3987 3988 // Pick a new active touch id if needed. 3989 // Choose an arbitrary pointer that just went down, if there is one. 3990 // Otherwise choose an arbitrary remaining pointer. 3991 // This guarantees we always have an active touch id when there is at least one pointer. 3992 // We keep the same active touch id for as long as possible. 3993 bool activeTouchChanged = false; 3994 int32_t lastActiveTouchId = mPointerGesture.activeTouchId; 3995 int32_t activeTouchId = lastActiveTouchId; 3996 if (activeTouchId < 0) { 3997 if (!mCurrentTouch.idBits.isEmpty()) { 3998 activeTouchChanged = true; 3999 activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit(); 4000 mPointerGesture.firstTouchTime = when; 4001 } 4002 } else if (!mCurrentTouch.idBits.hasBit(activeTouchId)) { 4003 activeTouchChanged = true; 4004 if (!mCurrentTouch.idBits.isEmpty()) { 4005 activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit(); 4006 } else { 4007 activeTouchId = mPointerGesture.activeTouchId = -1; 4008 } 4009 } 4010 4011 // Determine whether we are in quiet time. 4012 bool isQuietTime = false; 4013 if (activeTouchId < 0) { 4014 mPointerGesture.resetQuietTime(); 4015 } else { 4016 isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval; 4017 if (!isQuietTime) { 4018 if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS 4019 || mPointerGesture.lastGestureMode == PointerGesture::SWIPE 4020 || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM) 4021 && mCurrentTouch.pointerCount < 2) { 4022 // Enter quiet time when exiting swipe or freeform state. 4023 // This is to prevent accidentally entering the hover state and flinging the 4024 // pointer when finishing a swipe and there is still one pointer left onscreen. 4025 isQuietTime = true; 4026 } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG 4027 && mCurrentTouch.pointerCount >= 2 4028 && !isPointerDown(mCurrentTouch.buttonState)) { 4029 // Enter quiet time when releasing the button and there are still two or more 4030 // fingers down. This may indicate that one finger was used to press the button 4031 // but it has not gone up yet. 4032 isQuietTime = true; 4033 } 4034 if (isQuietTime) { 4035 mPointerGesture.quietTime = when; 4036 } 4037 } 4038 } 4039 4040 // Switch states based on button and pointer state. 4041 if (isQuietTime) { 4042 // Case 1: Quiet time. (QUIET) 4043#if DEBUG_GESTURES 4044 LOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime 4045 + mConfig.pointerGestureQuietInterval - when) * 0.000001f); 4046#endif 4047 if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) { 4048 *outFinishPreviousGesture = true; 4049 } 4050 4051 mPointerGesture.activeGestureId = -1; 4052 mPointerGesture.currentGestureMode = PointerGesture::QUIET; 4053 mPointerGesture.currentGestureIdBits.clear(); 4054 4055 mPointerGesture.pointerVelocityControl.reset(); 4056 } else if (isPointerDown(mCurrentTouch.buttonState)) { 4057 // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG) 4058 // The pointer follows the active touch point. 4059 // Emit DOWN, MOVE, UP events at the pointer location. 4060 // 4061 // Only the active touch matters; other fingers are ignored. This policy helps 4062 // to handle the case where the user places a second finger on the touch pad 4063 // to apply the necessary force to depress an integrated button below the surface. 4064 // We don't want the second finger to be delivered to applications. 4065 // 4066 // For this to work well, we need to make sure to track the pointer that is really 4067 // active. If the user first puts one finger down to click then adds another 4068 // finger to drag then the active pointer should switch to the finger that is 4069 // being dragged. 4070#if DEBUG_GESTURES 4071 LOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, " 4072 "currentTouchPointerCount=%d", activeTouchId, mCurrentTouch.pointerCount); 4073#endif 4074 // Reset state when just starting. 4075 if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) { 4076 *outFinishPreviousGesture = true; 4077 mPointerGesture.activeGestureId = 0; 4078 } 4079 4080 // Switch pointers if needed. 4081 // Find the fastest pointer and follow it. 4082 if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) { 4083 int32_t bestId = -1; 4084 float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed; 4085 for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { 4086 uint32_t id = mCurrentTouch.pointers[i].id; 4087 float vx, vy; 4088 if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) { 4089 float speed = hypotf(vx, vy); 4090 if (speed > bestSpeed) { 4091 bestId = id; 4092 bestSpeed = speed; 4093 } 4094 } 4095 } 4096 if (bestId >= 0 && bestId != activeTouchId) { 4097 mPointerGesture.activeTouchId = activeTouchId = bestId; 4098 activeTouchChanged = true; 4099#if DEBUG_GESTURES 4100 LOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, " 4101 "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed); 4102#endif 4103 } 4104 } 4105 4106 if (activeTouchId >= 0 && mLastTouch.idBits.hasBit(activeTouchId)) { 4107 const PointerData& currentPointer = 4108 mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]]; 4109 const PointerData& lastPointer = 4110 mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]]; 4111 float deltaX = (currentPointer.x - lastPointer.x) 4112 * mLocked.pointerGestureXMovementScale; 4113 float deltaY = (currentPointer.y - lastPointer.y) 4114 * mLocked.pointerGestureYMovementScale; 4115 4116 rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY); 4117 mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY); 4118 4119 // Move the pointer using a relative motion. 4120 // When using spots, the click will occur at the position of the anchor 4121 // spot and all other spots will move there. 4122 mPointerController->move(deltaX, deltaY); 4123 } else { 4124 mPointerGesture.pointerVelocityControl.reset(); 4125 } 4126 4127 float x, y; 4128 mPointerController->getPosition(&x, &y); 4129 4130 mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG; 4131 mPointerGesture.currentGestureIdBits.clear(); 4132 mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId); 4133 mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0; 4134 mPointerGesture.currentGestureProperties[0].clear(); 4135 mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId; 4136 mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER; 4137 mPointerGesture.currentGestureCoords[0].clear(); 4138 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); 4139 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); 4140 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); 4141 } else if (mCurrentTouch.pointerCount == 0) { 4142 // Case 3. No fingers down and button is not pressed. (NEUTRAL) 4143 if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) { 4144 *outFinishPreviousGesture = true; 4145 } 4146 4147 // Watch for taps coming out of HOVER or TAP_DRAG mode. 4148 // Checking for taps after TAP_DRAG allows us to detect double-taps. 4149 bool tapped = false; 4150 if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER 4151 || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) 4152 && mLastTouch.pointerCount == 1) { 4153 if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) { 4154 float x, y; 4155 mPointerController->getPosition(&x, &y); 4156 if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop 4157 && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { 4158#if DEBUG_GESTURES 4159 LOGD("Gestures: TAP"); 4160#endif 4161 4162 mPointerGesture.tapUpTime = when; 4163 getContext()->requestTimeoutAtTime(when 4164 + mConfig.pointerGestureTapDragInterval); 4165 4166 mPointerGesture.activeGestureId = 0; 4167 mPointerGesture.currentGestureMode = PointerGesture::TAP; 4168 mPointerGesture.currentGestureIdBits.clear(); 4169 mPointerGesture.currentGestureIdBits.markBit( 4170 mPointerGesture.activeGestureId); 4171 mPointerGesture.currentGestureIdToIndex[ 4172 mPointerGesture.activeGestureId] = 0; 4173 mPointerGesture.currentGestureProperties[0].clear(); 4174 mPointerGesture.currentGestureProperties[0].id = 4175 mPointerGesture.activeGestureId; 4176 mPointerGesture.currentGestureProperties[0].toolType = 4177 AMOTION_EVENT_TOOL_TYPE_FINGER; 4178 mPointerGesture.currentGestureCoords[0].clear(); 4179 mPointerGesture.currentGestureCoords[0].setAxisValue( 4180 AMOTION_EVENT_AXIS_X, mPointerGesture.tapX); 4181 mPointerGesture.currentGestureCoords[0].setAxisValue( 4182 AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY); 4183 mPointerGesture.currentGestureCoords[0].setAxisValue( 4184 AMOTION_EVENT_AXIS_PRESSURE, 1.0f); 4185 4186 tapped = true; 4187 } else { 4188#if DEBUG_GESTURES 4189 LOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f", 4190 x - mPointerGesture.tapX, 4191 y - mPointerGesture.tapY); 4192#endif 4193 } 4194 } else { 4195#if DEBUG_GESTURES 4196 LOGD("Gestures: Not a TAP, %0.3fms since down", 4197 (when - mPointerGesture.tapDownTime) * 0.000001f); 4198#endif 4199 } 4200 } 4201 4202 mPointerGesture.pointerVelocityControl.reset(); 4203 4204 if (!tapped) { 4205#if DEBUG_GESTURES 4206 LOGD("Gestures: NEUTRAL"); 4207#endif 4208 mPointerGesture.activeGestureId = -1; 4209 mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL; 4210 mPointerGesture.currentGestureIdBits.clear(); 4211 } 4212 } else if (mCurrentTouch.pointerCount == 1) { 4213 // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG) 4214 // The pointer follows the active touch point. 4215 // When in HOVER, emit HOVER_MOVE events at the pointer location. 4216 // When in TAP_DRAG, emit MOVE events at the pointer location. 4217 LOG_ASSERT(activeTouchId >= 0); 4218 4219 mPointerGesture.currentGestureMode = PointerGesture::HOVER; 4220 if (mPointerGesture.lastGestureMode == PointerGesture::TAP) { 4221 if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) { 4222 float x, y; 4223 mPointerController->getPosition(&x, &y); 4224 if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop 4225 && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) { 4226 mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG; 4227 } else { 4228#if DEBUG_GESTURES 4229 LOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f", 4230 x - mPointerGesture.tapX, 4231 y - mPointerGesture.tapY); 4232#endif 4233 } 4234 } else { 4235#if DEBUG_GESTURES 4236 LOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up", 4237 (when - mPointerGesture.tapUpTime) * 0.000001f); 4238#endif 4239 } 4240 } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) { 4241 mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG; 4242 } 4243 4244 if (mLastTouch.idBits.hasBit(activeTouchId)) { 4245 const PointerData& currentPointer = 4246 mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]]; 4247 const PointerData& lastPointer = 4248 mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]]; 4249 float deltaX = (currentPointer.x - lastPointer.x) 4250 * mLocked.pointerGestureXMovementScale; 4251 float deltaY = (currentPointer.y - lastPointer.y) 4252 * mLocked.pointerGestureYMovementScale; 4253 4254 rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY); 4255 mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY); 4256 4257 // Move the pointer using a relative motion. 4258 // When using spots, the hover or drag will occur at the position of the anchor spot. 4259 mPointerController->move(deltaX, deltaY); 4260 } else { 4261 mPointerGesture.pointerVelocityControl.reset(); 4262 } 4263 4264 bool down; 4265 if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) { 4266#if DEBUG_GESTURES 4267 LOGD("Gestures: TAP_DRAG"); 4268#endif 4269 down = true; 4270 } else { 4271#if DEBUG_GESTURES 4272 LOGD("Gestures: HOVER"); 4273#endif 4274 if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) { 4275 *outFinishPreviousGesture = true; 4276 } 4277 mPointerGesture.activeGestureId = 0; 4278 down = false; 4279 } 4280 4281 float x, y; 4282 mPointerController->getPosition(&x, &y); 4283 4284 mPointerGesture.currentGestureIdBits.clear(); 4285 mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId); 4286 mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0; 4287 mPointerGesture.currentGestureProperties[0].clear(); 4288 mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId; 4289 mPointerGesture.currentGestureProperties[0].toolType = 4290 AMOTION_EVENT_TOOL_TYPE_FINGER; 4291 mPointerGesture.currentGestureCoords[0].clear(); 4292 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); 4293 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); 4294 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 4295 down ? 1.0f : 0.0f); 4296 4297 if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) { 4298 mPointerGesture.resetTap(); 4299 mPointerGesture.tapDownTime = when; 4300 mPointerGesture.tapX = x; 4301 mPointerGesture.tapY = y; 4302 } 4303 } else { 4304 // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM) 4305 // We need to provide feedback for each finger that goes down so we cannot wait 4306 // for the fingers to move before deciding what to do. 4307 // 4308 // The ambiguous case is deciding what to do when there are two fingers down but they 4309 // have not moved enough to determine whether they are part of a drag or part of a 4310 // freeform gesture, or just a press or long-press at the pointer location. 4311 // 4312 // When there are two fingers we start with the PRESS hypothesis and we generate a 4313 // down at the pointer location. 4314 // 4315 // When the two fingers move enough or when additional fingers are added, we make 4316 // a decision to transition into SWIPE or FREEFORM mode accordingly. 4317 LOG_ASSERT(activeTouchId >= 0); 4318 4319 bool settled = when >= mPointerGesture.firstTouchTime 4320 + mConfig.pointerGestureMultitouchSettleInterval; 4321 if (mPointerGesture.lastGestureMode != PointerGesture::PRESS 4322 && mPointerGesture.lastGestureMode != PointerGesture::SWIPE 4323 && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) { 4324 *outFinishPreviousGesture = true; 4325 } else if (!settled && mCurrentTouch.pointerCount > mLastTouch.pointerCount) { 4326 // Additional pointers have gone down but not yet settled. 4327 // Reset the gesture. 4328#if DEBUG_GESTURES 4329 LOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, " 4330 "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime 4331 + mConfig.pointerGestureMultitouchSettleInterval - when) 4332 * 0.000001f); 4333#endif 4334 *outCancelPreviousGesture = true; 4335 } else { 4336 // Continue previous gesture. 4337 mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode; 4338 } 4339 4340 if (*outFinishPreviousGesture || *outCancelPreviousGesture) { 4341 mPointerGesture.currentGestureMode = PointerGesture::PRESS; 4342 mPointerGesture.activeGestureId = 0; 4343 mPointerGesture.referenceIdBits.clear(); 4344 mPointerGesture.pointerVelocityControl.reset(); 4345 4346 // Use the centroid and pointer location as the reference points for the gesture. 4347#if DEBUG_GESTURES 4348 LOGD("Gestures: Using centroid as reference for MULTITOUCH, " 4349 "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime 4350 + mConfig.pointerGestureMultitouchSettleInterval - when) 4351 * 0.000001f); 4352#endif 4353 mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX, 4354 &mPointerGesture.referenceTouchY); 4355 mPointerController->getPosition(&mPointerGesture.referenceGestureX, 4356 &mPointerGesture.referenceGestureY); 4357 } 4358 4359 // Clear the reference deltas for fingers not yet included in the reference calculation. 4360 for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value); 4361 !idBits.isEmpty(); ) { 4362 uint32_t id = idBits.firstMarkedBit(); 4363 idBits.clearBit(id); 4364 4365 mPointerGesture.referenceDeltas[id].dx = 0; 4366 mPointerGesture.referenceDeltas[id].dy = 0; 4367 } 4368 mPointerGesture.referenceIdBits = mCurrentTouch.idBits; 4369 4370 // Add delta for all fingers and calculate a common movement delta. 4371 float commonDeltaX = 0, commonDeltaY = 0; 4372 BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value); 4373 for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) { 4374 bool first = (idBits == commonIdBits); 4375 uint32_t id = idBits.firstMarkedBit(); 4376 idBits.clearBit(id); 4377 4378 const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]]; 4379 const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]]; 4380 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; 4381 delta.dx += cpd.x - lpd.x; 4382 delta.dy += cpd.y - lpd.y; 4383 4384 if (first) { 4385 commonDeltaX = delta.dx; 4386 commonDeltaY = delta.dy; 4387 } else { 4388 commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx); 4389 commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy); 4390 } 4391 } 4392 4393 // Consider transitions from PRESS to SWIPE or MULTITOUCH. 4394 if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) { 4395 float dist[MAX_POINTER_ID + 1]; 4396 int32_t distOverThreshold = 0; 4397 for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) { 4398 uint32_t id = idBits.firstMarkedBit(); 4399 idBits.clearBit(id); 4400 4401 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; 4402 dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale, 4403 delta.dy * mLocked.pointerGestureYZoomScale); 4404 if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) { 4405 distOverThreshold += 1; 4406 } 4407 } 4408 4409 // Only transition when at least two pointers have moved further than 4410 // the minimum distance threshold. 4411 if (distOverThreshold >= 2) { 4412 float d; 4413 if (mCurrentTouch.pointerCount > 2) { 4414 // There are more than two pointers, switch to FREEFORM. 4415#if DEBUG_GESTURES 4416 LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2", 4417 mCurrentTouch.pointerCount); 4418#endif 4419 *outCancelPreviousGesture = true; 4420 mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; 4421 } else if (((d = distance( 4422 mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y, 4423 mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y)) 4424 > mLocked.pointerGestureMaxSwipeWidth)) { 4425 // There are two pointers but they are too far apart for a SWIPE, 4426 // switch to FREEFORM. 4427#if DEBUG_GESTURES 4428 LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f", 4429 d, mLocked.pointerGestureMaxSwipeWidth); 4430#endif 4431 *outCancelPreviousGesture = true; 4432 mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; 4433 } else { 4434 // There are two pointers. Wait for both pointers to start moving 4435 // before deciding whether this is a SWIPE or FREEFORM gesture. 4436 uint32_t id1 = mCurrentTouch.pointers[0].id; 4437 uint32_t id2 = mCurrentTouch.pointers[1].id; 4438 float dist1 = dist[id1]; 4439 float dist2 = dist[id2]; 4440 if (dist1 >= mConfig.pointerGestureMultitouchMinDistance 4441 && dist2 >= mConfig.pointerGestureMultitouchMinDistance) { 4442 // Calculate the dot product of the displacement vectors. 4443 // When the vectors are oriented in approximately the same direction, 4444 // the angle betweeen them is near zero and the cosine of the angle 4445 // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2). 4446 PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1]; 4447 PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2]; 4448 float dx1 = delta1.dx * mLocked.pointerGestureXZoomScale; 4449 float dy1 = delta1.dy * mLocked.pointerGestureYZoomScale; 4450 float dx2 = delta2.dx * mLocked.pointerGestureXZoomScale; 4451 float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale; 4452 float dot = dx1 * dx2 + dy1 * dy2; 4453 float cosine = dot / (dist1 * dist2); // denominator always > 0 4454 if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) { 4455 // Pointers are moving in the same direction. Switch to SWIPE. 4456#if DEBUG_GESTURES 4457 LOGD("Gestures: PRESS transitioned to SWIPE, " 4458 "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " 4459 "cosine %0.3f >= %0.3f", 4460 dist1, mConfig.pointerGestureMultitouchMinDistance, 4461 dist2, mConfig.pointerGestureMultitouchMinDistance, 4462 cosine, mConfig.pointerGestureSwipeTransitionAngleCosine); 4463#endif 4464 mPointerGesture.currentGestureMode = PointerGesture::SWIPE; 4465 } else { 4466 // Pointers are moving in different directions. Switch to FREEFORM. 4467#if DEBUG_GESTURES 4468 LOGD("Gestures: PRESS transitioned to FREEFORM, " 4469 "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " 4470 "cosine %0.3f < %0.3f", 4471 dist1, mConfig.pointerGestureMultitouchMinDistance, 4472 dist2, mConfig.pointerGestureMultitouchMinDistance, 4473 cosine, mConfig.pointerGestureSwipeTransitionAngleCosine); 4474#endif 4475 *outCancelPreviousGesture = true; 4476 mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; 4477 } 4478 } 4479 } 4480 } 4481 } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) { 4482 // Switch from SWIPE to FREEFORM if additional pointers go down. 4483 // Cancel previous gesture. 4484 if (mCurrentTouch.pointerCount > 2) { 4485#if DEBUG_GESTURES 4486 LOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2", 4487 mCurrentTouch.pointerCount); 4488#endif 4489 *outCancelPreviousGesture = true; 4490 mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; 4491 } 4492 } 4493 4494 // Move the reference points based on the overall group motion of the fingers 4495 // except in PRESS mode while waiting for a transition to occur. 4496 if (mPointerGesture.currentGestureMode != PointerGesture::PRESS 4497 && (commonDeltaX || commonDeltaY)) { 4498 for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) { 4499 uint32_t id = idBits.firstMarkedBit(); 4500 idBits.clearBit(id); 4501 4502 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; 4503 delta.dx = 0; 4504 delta.dy = 0; 4505 } 4506 4507 mPointerGesture.referenceTouchX += commonDeltaX; 4508 mPointerGesture.referenceTouchY += commonDeltaY; 4509 4510 commonDeltaX *= mLocked.pointerGestureXMovementScale; 4511 commonDeltaY *= mLocked.pointerGestureYMovementScale; 4512 4513 rotateDelta(mLocked.surfaceOrientation, &commonDeltaX, &commonDeltaY); 4514 mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY); 4515 4516 mPointerGesture.referenceGestureX += commonDeltaX; 4517 mPointerGesture.referenceGestureY += commonDeltaY; 4518 } 4519 4520 // Report gestures. 4521 if (mPointerGesture.currentGestureMode == PointerGesture::PRESS 4522 || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) { 4523 // PRESS or SWIPE mode. 4524#if DEBUG_GESTURES 4525 LOGD("Gestures: PRESS or SWIPE activeTouchId=%d," 4526 "activeGestureId=%d, currentTouchPointerCount=%d", 4527 activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount); 4528#endif 4529 LOG_ASSERT(mPointerGesture.activeGestureId >= 0); 4530 4531 mPointerGesture.currentGestureIdBits.clear(); 4532 mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId); 4533 mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0; 4534 mPointerGesture.currentGestureProperties[0].clear(); 4535 mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId; 4536 mPointerGesture.currentGestureProperties[0].toolType = 4537 AMOTION_EVENT_TOOL_TYPE_FINGER; 4538 mPointerGesture.currentGestureCoords[0].clear(); 4539 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, 4540 mPointerGesture.referenceGestureX); 4541 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, 4542 mPointerGesture.referenceGestureY); 4543 mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); 4544 } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) { 4545 // FREEFORM mode. 4546#if DEBUG_GESTURES 4547 LOGD("Gestures: FREEFORM activeTouchId=%d," 4548 "activeGestureId=%d, currentTouchPointerCount=%d", 4549 activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount); 4550#endif 4551 LOG_ASSERT(mPointerGesture.activeGestureId >= 0); 4552 4553 mPointerGesture.currentGestureIdBits.clear(); 4554 4555 BitSet32 mappedTouchIdBits; 4556 BitSet32 usedGestureIdBits; 4557 if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) { 4558 // Initially, assign the active gesture id to the active touch point 4559 // if there is one. No other touch id bits are mapped yet. 4560 if (!*outCancelPreviousGesture) { 4561 mappedTouchIdBits.markBit(activeTouchId); 4562 usedGestureIdBits.markBit(mPointerGesture.activeGestureId); 4563 mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] = 4564 mPointerGesture.activeGestureId; 4565 } else { 4566 mPointerGesture.activeGestureId = -1; 4567 } 4568 } else { 4569 // Otherwise, assume we mapped all touches from the previous frame. 4570 // Reuse all mappings that are still applicable. 4571 mappedTouchIdBits.value = mLastTouch.idBits.value & mCurrentTouch.idBits.value; 4572 usedGestureIdBits = mPointerGesture.lastGestureIdBits; 4573 4574 // Check whether we need to choose a new active gesture id because the 4575 // current went went up. 4576 for (BitSet32 upTouchIdBits(mLastTouch.idBits.value & ~mCurrentTouch.idBits.value); 4577 !upTouchIdBits.isEmpty(); ) { 4578 uint32_t upTouchId = upTouchIdBits.firstMarkedBit(); 4579 upTouchIdBits.clearBit(upTouchId); 4580 uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId]; 4581 if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) { 4582 mPointerGesture.activeGestureId = -1; 4583 break; 4584 } 4585 } 4586 } 4587 4588#if DEBUG_GESTURES 4589 LOGD("Gestures: FREEFORM follow up " 4590 "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, " 4591 "activeGestureId=%d", 4592 mappedTouchIdBits.value, usedGestureIdBits.value, 4593 mPointerGesture.activeGestureId); 4594#endif 4595 4596 for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { 4597 uint32_t touchId = mCurrentTouch.pointers[i].id; 4598 uint32_t gestureId; 4599 if (!mappedTouchIdBits.hasBit(touchId)) { 4600 gestureId = usedGestureIdBits.firstUnmarkedBit(); 4601 usedGestureIdBits.markBit(gestureId); 4602 mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId; 4603#if DEBUG_GESTURES 4604 LOGD("Gestures: FREEFORM " 4605 "new mapping for touch id %d -> gesture id %d", 4606 touchId, gestureId); 4607#endif 4608 } else { 4609 gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId]; 4610#if DEBUG_GESTURES 4611 LOGD("Gestures: FREEFORM " 4612 "existing mapping for touch id %d -> gesture id %d", 4613 touchId, gestureId); 4614#endif 4615 } 4616 mPointerGesture.currentGestureIdBits.markBit(gestureId); 4617 mPointerGesture.currentGestureIdToIndex[gestureId] = i; 4618 4619 float deltaX = (mCurrentTouch.pointers[i].x - mPointerGesture.referenceTouchX) 4620 * mLocked.pointerGestureXZoomScale; 4621 float deltaY = (mCurrentTouch.pointers[i].y - mPointerGesture.referenceTouchY) 4622 * mLocked.pointerGestureYZoomScale; 4623 rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY); 4624 4625 mPointerGesture.currentGestureProperties[i].clear(); 4626 mPointerGesture.currentGestureProperties[i].id = gestureId; 4627 mPointerGesture.currentGestureProperties[i].toolType = 4628 AMOTION_EVENT_TOOL_TYPE_FINGER; 4629 mPointerGesture.currentGestureCoords[i].clear(); 4630 mPointerGesture.currentGestureCoords[i].setAxisValue( 4631 AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX); 4632 mPointerGesture.currentGestureCoords[i].setAxisValue( 4633 AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY); 4634 mPointerGesture.currentGestureCoords[i].setAxisValue( 4635 AMOTION_EVENT_AXIS_PRESSURE, 1.0f); 4636 } 4637 4638 if (mPointerGesture.activeGestureId < 0) { 4639 mPointerGesture.activeGestureId = 4640 mPointerGesture.currentGestureIdBits.firstMarkedBit(); 4641#if DEBUG_GESTURES 4642 LOGD("Gestures: FREEFORM new " 4643 "activeGestureId=%d", mPointerGesture.activeGestureId); 4644#endif 4645 } 4646 } 4647 } 4648 4649 mPointerController->setButtonState(mCurrentTouch.buttonState); 4650 4651#if DEBUG_GESTURES 4652 LOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, " 4653 "currentGestureMode=%d, currentGestureIdBits=0x%08x, " 4654 "lastGestureMode=%d, lastGestureIdBits=0x%08x", 4655 toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture), 4656 mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value, 4657 mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value); 4658 for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) { 4659 uint32_t id = idBits.firstMarkedBit(); 4660 idBits.clearBit(id); 4661 uint32_t index = mPointerGesture.currentGestureIdToIndex[id]; 4662 const PointerProperties& properties = mPointerGesture.currentGestureProperties[index]; 4663 const PointerCoords& coords = mPointerGesture.currentGestureCoords[index]; 4664 LOGD(" currentGesture[%d]: index=%d, toolType=%d, " 4665 "x=%0.3f, y=%0.3f, pressure=%0.3f", 4666 id, index, properties.toolType, 4667 coords.getAxisValue(AMOTION_EVENT_AXIS_X), 4668 coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 4669 coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE)); 4670 } 4671 for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) { 4672 uint32_t id = idBits.firstMarkedBit(); 4673 idBits.clearBit(id); 4674 uint32_t index = mPointerGesture.lastGestureIdToIndex[id]; 4675 const PointerProperties& properties = mPointerGesture.lastGestureProperties[index]; 4676 const PointerCoords& coords = mPointerGesture.lastGestureCoords[index]; 4677 LOGD(" lastGesture[%d]: index=%d, toolType=%d, " 4678 "x=%0.3f, y=%0.3f, pressure=%0.3f", 4679 id, index, properties.toolType, 4680 coords.getAxisValue(AMOTION_EVENT_AXIS_X), 4681 coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 4682 coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE)); 4683 } 4684#endif 4685 return true; 4686} 4687 4688void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source, 4689 int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags, 4690 const PointerProperties* properties, const PointerCoords* coords, 4691 const uint32_t* idToIndex, BitSet32 idBits, 4692 int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) { 4693 PointerCoords pointerCoords[MAX_POINTERS]; 4694 PointerProperties pointerProperties[MAX_POINTERS]; 4695 uint32_t pointerCount = 0; 4696 while (!idBits.isEmpty()) { 4697 uint32_t id = idBits.firstMarkedBit(); 4698 idBits.clearBit(id); 4699 uint32_t index = idToIndex[id]; 4700 pointerProperties[pointerCount].copyFrom(properties[index]); 4701 pointerCoords[pointerCount].copyFrom(coords[index]); 4702 4703 if (changedId >= 0 && id == uint32_t(changedId)) { 4704 action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 4705 } 4706 4707 pointerCount += 1; 4708 } 4709 4710 LOG_ASSERT(pointerCount != 0); 4711 4712 if (changedId >= 0 && pointerCount == 1) { 4713 // Replace initial down and final up action. 4714 // We can compare the action without masking off the changed pointer index 4715 // because we know the index is 0. 4716 if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) { 4717 action = AMOTION_EVENT_ACTION_DOWN; 4718 } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) { 4719 action = AMOTION_EVENT_ACTION_UP; 4720 } else { 4721 // Can't happen. 4722 LOG_ASSERT(false); 4723 } 4724 } 4725 4726 getDispatcher()->notifyMotion(when, getDeviceId(), source, policyFlags, 4727 action, flags, metaState, buttonState, edgeFlags, 4728 pointerCount, pointerProperties, pointerCoords, xPrecision, yPrecision, downTime); 4729} 4730 4731bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties, 4732 const PointerCoords* inCoords, const uint32_t* inIdToIndex, 4733 PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex, 4734 BitSet32 idBits) const { 4735 bool changed = false; 4736 while (!idBits.isEmpty()) { 4737 uint32_t id = idBits.firstMarkedBit(); 4738 idBits.clearBit(id); 4739 4740 uint32_t inIndex = inIdToIndex[id]; 4741 uint32_t outIndex = outIdToIndex[id]; 4742 4743 const PointerProperties& curInProperties = inProperties[inIndex]; 4744 const PointerCoords& curInCoords = inCoords[inIndex]; 4745 PointerProperties& curOutProperties = outProperties[outIndex]; 4746 PointerCoords& curOutCoords = outCoords[outIndex]; 4747 4748 if (curInProperties != curOutProperties) { 4749 curOutProperties.copyFrom(curInProperties); 4750 changed = true; 4751 } 4752 4753 if (curInCoords != curOutCoords) { 4754 curOutCoords.copyFrom(curInCoords); 4755 changed = true; 4756 } 4757 } 4758 return changed; 4759} 4760 4761void TouchInputMapper::fadePointer() { 4762 { // acquire lock 4763 AutoMutex _l(mLock); 4764 if (mPointerController != NULL) { 4765 mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); 4766 } 4767 } // release lock 4768} 4769 4770bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) { 4771 return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue 4772 && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue; 4773} 4774 4775const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked( 4776 int32_t x, int32_t y) { 4777 size_t numVirtualKeys = mLocked.virtualKeys.size(); 4778 for (size_t i = 0; i < numVirtualKeys; i++) { 4779 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 4780 4781#if DEBUG_VIRTUAL_KEYS 4782 LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, " 4783 "left=%d, top=%d, right=%d, bottom=%d", 4784 x, y, 4785 virtualKey.keyCode, virtualKey.scanCode, 4786 virtualKey.hitLeft, virtualKey.hitTop, 4787 virtualKey.hitRight, virtualKey.hitBottom); 4788#endif 4789 4790 if (virtualKey.isHit(x, y)) { 4791 return & virtualKey; 4792 } 4793 } 4794 4795 return NULL; 4796} 4797 4798void TouchInputMapper::calculatePointerIds() { 4799 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 4800 uint32_t lastPointerCount = mLastTouch.pointerCount; 4801 4802 if (currentPointerCount == 0) { 4803 // No pointers to assign. 4804 mCurrentTouch.idBits.clear(); 4805 } else if (lastPointerCount == 0) { 4806 // All pointers are new. 4807 mCurrentTouch.idBits.clear(); 4808 for (uint32_t i = 0; i < currentPointerCount; i++) { 4809 mCurrentTouch.pointers[i].id = i; 4810 mCurrentTouch.idToIndex[i] = i; 4811 mCurrentTouch.idBits.markBit(i); 4812 } 4813 } else if (currentPointerCount == 1 && lastPointerCount == 1) { 4814 // Only one pointer and no change in count so it must have the same id as before. 4815 uint32_t id = mLastTouch.pointers[0].id; 4816 mCurrentTouch.pointers[0].id = id; 4817 mCurrentTouch.idToIndex[id] = 0; 4818 mCurrentTouch.idBits.value = BitSet32::valueForBit(id); 4819 } else { 4820 // General case. 4821 // We build a heap of squared euclidean distances between current and last pointers 4822 // associated with the current and last pointer indices. Then, we find the best 4823 // match (by distance) for each current pointer. 4824 PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS]; 4825 4826 uint32_t heapSize = 0; 4827 for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount; 4828 currentPointerIndex++) { 4829 for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount; 4830 lastPointerIndex++) { 4831 int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x 4832 - mLastTouch.pointers[lastPointerIndex].x; 4833 int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y 4834 - mLastTouch.pointers[lastPointerIndex].y; 4835 4836 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); 4837 4838 // Insert new element into the heap (sift up). 4839 heap[heapSize].currentPointerIndex = currentPointerIndex; 4840 heap[heapSize].lastPointerIndex = lastPointerIndex; 4841 heap[heapSize].distance = distance; 4842 heapSize += 1; 4843 } 4844 } 4845 4846 // Heapify 4847 for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) { 4848 startIndex -= 1; 4849 for (uint32_t parentIndex = startIndex; ;) { 4850 uint32_t childIndex = parentIndex * 2 + 1; 4851 if (childIndex >= heapSize) { 4852 break; 4853 } 4854 4855 if (childIndex + 1 < heapSize 4856 && heap[childIndex + 1].distance < heap[childIndex].distance) { 4857 childIndex += 1; 4858 } 4859 4860 if (heap[parentIndex].distance <= heap[childIndex].distance) { 4861 break; 4862 } 4863 4864 swap(heap[parentIndex], heap[childIndex]); 4865 parentIndex = childIndex; 4866 } 4867 } 4868 4869#if DEBUG_POINTER_ASSIGNMENT 4870 LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize); 4871 for (size_t i = 0; i < heapSize; i++) { 4872 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 4873 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 4874 heap[i].distance); 4875 } 4876#endif 4877 4878 // Pull matches out by increasing order of distance. 4879 // To avoid reassigning pointers that have already been matched, the loop keeps track 4880 // of which last and current pointers have been matched using the matchedXXXBits variables. 4881 // It also tracks the used pointer id bits. 4882 BitSet32 matchedLastBits(0); 4883 BitSet32 matchedCurrentBits(0); 4884 BitSet32 usedIdBits(0); 4885 bool first = true; 4886 for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) { 4887 for (;;) { 4888 if (first) { 4889 // The first time through the loop, we just consume the root element of 4890 // the heap (the one with smallest distance). 4891 first = false; 4892 } else { 4893 // Previous iterations consumed the root element of the heap. 4894 // Pop root element off of the heap (sift down). 4895 heapSize -= 1; 4896 LOG_ASSERT(heapSize > 0); 4897 4898 // Sift down. 4899 heap[0] = heap[heapSize]; 4900 for (uint32_t parentIndex = 0; ;) { 4901 uint32_t childIndex = parentIndex * 2 + 1; 4902 if (childIndex >= heapSize) { 4903 break; 4904 } 4905 4906 if (childIndex + 1 < heapSize 4907 && heap[childIndex + 1].distance < heap[childIndex].distance) { 4908 childIndex += 1; 4909 } 4910 4911 if (heap[parentIndex].distance <= heap[childIndex].distance) { 4912 break; 4913 } 4914 4915 swap(heap[parentIndex], heap[childIndex]); 4916 parentIndex = childIndex; 4917 } 4918 4919#if DEBUG_POINTER_ASSIGNMENT 4920 LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize); 4921 for (size_t i = 0; i < heapSize; i++) { 4922 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 4923 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 4924 heap[i].distance); 4925 } 4926#endif 4927 } 4928 4929 uint32_t currentPointerIndex = heap[0].currentPointerIndex; 4930 if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched 4931 4932 uint32_t lastPointerIndex = heap[0].lastPointerIndex; 4933 if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched 4934 4935 matchedCurrentBits.markBit(currentPointerIndex); 4936 matchedLastBits.markBit(lastPointerIndex); 4937 4938 uint32_t id = mLastTouch.pointers[lastPointerIndex].id; 4939 mCurrentTouch.pointers[currentPointerIndex].id = id; 4940 mCurrentTouch.idToIndex[id] = currentPointerIndex; 4941 usedIdBits.markBit(id); 4942 4943#if DEBUG_POINTER_ASSIGNMENT 4944 LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld", 4945 lastPointerIndex, currentPointerIndex, id, heap[0].distance); 4946#endif 4947 break; 4948 } 4949 } 4950 4951 // Assign fresh ids to new pointers. 4952 if (currentPointerCount > lastPointerCount) { 4953 for (uint32_t i = currentPointerCount - lastPointerCount; ;) { 4954 uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit(); 4955 uint32_t id = usedIdBits.firstUnmarkedBit(); 4956 4957 mCurrentTouch.pointers[currentPointerIndex].id = id; 4958 mCurrentTouch.idToIndex[id] = currentPointerIndex; 4959 usedIdBits.markBit(id); 4960 4961#if DEBUG_POINTER_ASSIGNMENT 4962 LOGD("calculatePointerIds - assigned: cur=%d, id=%d", 4963 currentPointerIndex, id); 4964#endif 4965 4966 if (--i == 0) break; // done 4967 matchedCurrentBits.markBit(currentPointerIndex); 4968 } 4969 } 4970 4971 // Fix id bits. 4972 mCurrentTouch.idBits = usedIdBits; 4973 } 4974} 4975 4976int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 4977 { // acquire lock 4978 AutoMutex _l(mLock); 4979 4980 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) { 4981 return AKEY_STATE_VIRTUAL; 4982 } 4983 4984 size_t numVirtualKeys = mLocked.virtualKeys.size(); 4985 for (size_t i = 0; i < numVirtualKeys; i++) { 4986 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 4987 if (virtualKey.keyCode == keyCode) { 4988 return AKEY_STATE_UP; 4989 } 4990 } 4991 } // release lock 4992 4993 return AKEY_STATE_UNKNOWN; 4994} 4995 4996int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 4997 { // acquire lock 4998 AutoMutex _l(mLock); 4999 5000 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) { 5001 return AKEY_STATE_VIRTUAL; 5002 } 5003 5004 size_t numVirtualKeys = mLocked.virtualKeys.size(); 5005 for (size_t i = 0; i < numVirtualKeys; i++) { 5006 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 5007 if (virtualKey.scanCode == scanCode) { 5008 return AKEY_STATE_UP; 5009 } 5010 } 5011 } // release lock 5012 5013 return AKEY_STATE_UNKNOWN; 5014} 5015 5016bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 5017 const int32_t* keyCodes, uint8_t* outFlags) { 5018 { // acquire lock 5019 AutoMutex _l(mLock); 5020 5021 size_t numVirtualKeys = mLocked.virtualKeys.size(); 5022 for (size_t i = 0; i < numVirtualKeys; i++) { 5023 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 5024 5025 for (size_t i = 0; i < numCodes; i++) { 5026 if (virtualKey.keyCode == keyCodes[i]) { 5027 outFlags[i] = 1; 5028 } 5029 } 5030 } 5031 } // release lock 5032 5033 return true; 5034} 5035 5036 5037// --- SingleTouchInputMapper --- 5038 5039SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) : 5040 TouchInputMapper(device) { 5041 clearState(); 5042} 5043 5044SingleTouchInputMapper::~SingleTouchInputMapper() { 5045} 5046 5047void SingleTouchInputMapper::clearState() { 5048 mCursorButtonAccumulator.clearButtons(); 5049 mTouchButtonAccumulator.clearButtons(); 5050 mSingleTouchMotionAccumulator.clearAbsoluteAxes(); 5051} 5052 5053void SingleTouchInputMapper::reset() { 5054 TouchInputMapper::reset(); 5055 5056 clearState(); 5057 } 5058 5059void SingleTouchInputMapper::process(const RawEvent* rawEvent) { 5060 mCursorButtonAccumulator.process(rawEvent); 5061 mTouchButtonAccumulator.process(rawEvent); 5062 mSingleTouchMotionAccumulator.process(rawEvent); 5063 5064 if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) { 5065 sync(rawEvent->when); 5066 } 5067} 5068 5069void SingleTouchInputMapper::sync(nsecs_t when) { 5070 mCurrentTouch.clear(); 5071 5072 if (mTouchButtonAccumulator.isActive()) { 5073 uint32_t buttonState = mTouchButtonAccumulator.getButtonState(); 5074 bool isHovering = mTouchButtonAccumulator.isHovering(); 5075 if (mSingleTouchMotionAccumulator.getAbsoluteDistance() > 0) { 5076 isHovering = true; 5077 } 5078 5079 mCurrentTouch.pointerCount = 1; 5080 mCurrentTouch.idToIndex[0] = 0; 5081 mCurrentTouch.idBits.markBit(0); 5082 mCurrentTouch.buttonState = buttonState; 5083 5084 PointerData& outPointer = mCurrentTouch.pointers[0]; 5085 outPointer.id = 0; 5086 outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX(); 5087 outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY(); 5088 outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure(); 5089 outPointer.touchMajor = 0; 5090 outPointer.touchMinor = 0; 5091 outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth(); 5092 outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth(); 5093 outPointer.orientation = 0; 5094 outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance(); 5095 outPointer.toolType = mTouchButtonAccumulator.getToolType(); 5096 if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) { 5097 outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER; 5098 } 5099 outPointer.isHovering = isHovering; 5100 } 5101 5102 syncTouch(when, true); 5103} 5104 5105void SingleTouchInputMapper::configureRawAxes() { 5106 TouchInputMapper::configureRawAxes(); 5107 5108 mTouchButtonAccumulator.configure(getDevice()); 5109 5110 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x); 5111 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y); 5112 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure); 5113 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor); 5114 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_DISTANCE, & mRawAxes.distance); 5115} 5116 5117 5118// --- MultiTouchInputMapper --- 5119 5120MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : 5121 TouchInputMapper(device) { 5122} 5123 5124MultiTouchInputMapper::~MultiTouchInputMapper() { 5125} 5126 5127void MultiTouchInputMapper::clearState() { 5128 mCursorButtonAccumulator.clearButtons(); 5129 mTouchButtonAccumulator.clearButtons(); 5130 mPointerIdBits.clear(); 5131 5132 if (mMultiTouchMotionAccumulator.isUsingSlotsProtocol()) { 5133 // Query the driver for the current slot index and use it as the initial slot 5134 // before we start reading events from the device. It is possible that the 5135 // current slot index will not be the same as it was when the first event was 5136 // written into the evdev buffer, which means the input mapper could start 5137 // out of sync with the initial state of the events in the evdev buffer. 5138 // In the extremely unlikely case that this happens, the data from 5139 // two slots will be confused until the next ABS_MT_SLOT event is received. 5140 // This can cause the touch point to "jump", but at least there will be 5141 // no stuck touches. 5142 int32_t initialSlot; 5143 status_t status = getEventHub()->getAbsoluteAxisValue(getDeviceId(), ABS_MT_SLOT, 5144 &initialSlot); 5145 if (status) { 5146 LOGW("Could not retrieve current multitouch slot index. status=%d", status); 5147 initialSlot = -1; 5148 } 5149 mMultiTouchMotionAccumulator.clearSlots(initialSlot); 5150 } else { 5151 mMultiTouchMotionAccumulator.clearSlots(-1); 5152 } 5153} 5154 5155void MultiTouchInputMapper::reset() { 5156 TouchInputMapper::reset(); 5157 5158 clearState(); 5159} 5160 5161void MultiTouchInputMapper::process(const RawEvent* rawEvent) { 5162 mCursorButtonAccumulator.process(rawEvent); 5163 mTouchButtonAccumulator.process(rawEvent); 5164 mMultiTouchMotionAccumulator.process(rawEvent); 5165 5166 if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) { 5167 sync(rawEvent->when); 5168 } 5169} 5170 5171void MultiTouchInputMapper::sync(nsecs_t when) { 5172 size_t inCount = mMultiTouchMotionAccumulator.getSlotCount(); 5173 size_t outCount = 0; 5174 bool havePointerIds = true; 5175 5176 mCurrentTouch.clear(); 5177 5178 for (size_t inIndex = 0; inIndex < inCount; inIndex++) { 5179 const MultiTouchMotionAccumulator::Slot* inSlot = 5180 mMultiTouchMotionAccumulator.getSlot(inIndex); 5181 if (!inSlot->isInUse()) { 5182 continue; 5183 } 5184 5185 if (outCount >= MAX_POINTERS) { 5186#if DEBUG_POINTERS 5187 LOGD("MultiTouch device %s emitted more than maximum of %d pointers; " 5188 "ignoring the rest.", 5189 getDeviceName().string(), MAX_POINTERS); 5190#endif 5191 break; // too many fingers! 5192 } 5193 5194 PointerData& outPointer = mCurrentTouch.pointers[outCount]; 5195 outPointer.x = inSlot->getX(); 5196 outPointer.y = inSlot->getY(); 5197 outPointer.pressure = inSlot->getPressure(); 5198 outPointer.touchMajor = inSlot->getTouchMajor(); 5199 outPointer.touchMinor = inSlot->getTouchMinor(); 5200 outPointer.toolMajor = inSlot->getToolMajor(); 5201 outPointer.toolMinor = inSlot->getToolMinor(); 5202 outPointer.orientation = inSlot->getOrientation(); 5203 outPointer.distance = inSlot->getDistance(); 5204 5205 outPointer.toolType = inSlot->getToolType(); 5206 if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) { 5207 outPointer.toolType = mTouchButtonAccumulator.getToolType(); 5208 if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) { 5209 outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER; 5210 } 5211 } 5212 5213 outPointer.isHovering = mTouchButtonAccumulator.isHovering() 5214 || inSlot->getDistance() > 0; 5215 5216 // Assign pointer id using tracking id if available. 5217 if (havePointerIds) { 5218 int32_t trackingId = inSlot->getTrackingId(); 5219 int32_t id = -1; 5220 if (trackingId >= 0) { 5221 for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) { 5222 uint32_t n = idBits.firstMarkedBit(); 5223 idBits.clearBit(n); 5224 5225 if (mPointerTrackingIdMap[n] == trackingId) { 5226 id = n; 5227 } 5228 } 5229 5230 if (id < 0 && !mPointerIdBits.isFull()) { 5231 id = mPointerIdBits.firstUnmarkedBit(); 5232 mPointerIdBits.markBit(id); 5233 mPointerTrackingIdMap[id] = trackingId; 5234 } 5235 } 5236 if (id < 0) { 5237 havePointerIds = false; 5238 mCurrentTouch.idBits.clear(); 5239 } else { 5240 outPointer.id = id; 5241 mCurrentTouch.idToIndex[id] = outCount; 5242 mCurrentTouch.idBits.markBit(id); 5243 } 5244 } 5245 5246 outCount += 1; 5247 } 5248 5249 mCurrentTouch.pointerCount = outCount; 5250 mCurrentTouch.buttonState = mTouchButtonAccumulator.getButtonState(); 5251 5252 mPointerIdBits = mCurrentTouch.idBits; 5253 5254 syncTouch(when, havePointerIds); 5255 5256 if (!mMultiTouchMotionAccumulator.isUsingSlotsProtocol()) { 5257 mMultiTouchMotionAccumulator.clearSlots(-1); 5258 } 5259} 5260 5261void MultiTouchInputMapper::configureRawAxes() { 5262 TouchInputMapper::configureRawAxes(); 5263 5264 mTouchButtonAccumulator.configure(getDevice()); 5265 5266 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, &mRawAxes.x); 5267 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, &mRawAxes.y); 5268 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, &mRawAxes.touchMajor); 5269 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, &mRawAxes.touchMinor); 5270 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, &mRawAxes.toolMajor); 5271 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, &mRawAxes.toolMinor); 5272 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, &mRawAxes.orientation); 5273 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, &mRawAxes.pressure); 5274 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_DISTANCE, &mRawAxes.distance); 5275 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TRACKING_ID, &mRawAxes.trackingId); 5276 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_SLOT, &mRawAxes.slot); 5277 5278 if (mRawAxes.trackingId.valid 5279 && mRawAxes.slot.valid && mRawAxes.slot.minValue == 0 && mRawAxes.slot.maxValue > 0) { 5280 size_t slotCount = mRawAxes.slot.maxValue + 1; 5281 if (slotCount > MAX_SLOTS) { 5282 LOGW("MultiTouch Device %s reported %d slots but the framework " 5283 "only supports a maximum of %d slots at this time.", 5284 getDeviceName().string(), slotCount, MAX_SLOTS); 5285 slotCount = MAX_SLOTS; 5286 } 5287 mMultiTouchMotionAccumulator.configure(slotCount, true /*usingSlotsProtocol*/); 5288 } else { 5289 mMultiTouchMotionAccumulator.configure(MAX_POINTERS, false /*usingSlotsProtocol*/); 5290 } 5291 5292 clearState(); 5293} 5294 5295 5296// --- JoystickInputMapper --- 5297 5298JoystickInputMapper::JoystickInputMapper(InputDevice* device) : 5299 InputMapper(device) { 5300} 5301 5302JoystickInputMapper::~JoystickInputMapper() { 5303} 5304 5305uint32_t JoystickInputMapper::getSources() { 5306 return AINPUT_SOURCE_JOYSTICK; 5307} 5308 5309void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 5310 InputMapper::populateDeviceInfo(info); 5311 5312 for (size_t i = 0; i < mAxes.size(); i++) { 5313 const Axis& axis = mAxes.valueAt(i); 5314 info->addMotionRange(axis.axisInfo.axis, AINPUT_SOURCE_JOYSTICK, 5315 axis.min, axis.max, axis.flat, axis.fuzz); 5316 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 5317 info->addMotionRange(axis.axisInfo.highAxis, AINPUT_SOURCE_JOYSTICK, 5318 axis.min, axis.max, axis.flat, axis.fuzz); 5319 } 5320 } 5321} 5322 5323void JoystickInputMapper::dump(String8& dump) { 5324 dump.append(INDENT2 "Joystick Input Mapper:\n"); 5325 5326 dump.append(INDENT3 "Axes:\n"); 5327 size_t numAxes = mAxes.size(); 5328 for (size_t i = 0; i < numAxes; i++) { 5329 const Axis& axis = mAxes.valueAt(i); 5330 const char* label = getAxisLabel(axis.axisInfo.axis); 5331 if (label) { 5332 dump.appendFormat(INDENT4 "%s", label); 5333 } else { 5334 dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis); 5335 } 5336 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 5337 label = getAxisLabel(axis.axisInfo.highAxis); 5338 if (label) { 5339 dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue); 5340 } else { 5341 dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis, 5342 axis.axisInfo.splitValue); 5343 } 5344 } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) { 5345 dump.append(" (invert)"); 5346 } 5347 5348 dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n", 5349 axis.min, axis.max, axis.flat, axis.fuzz); 5350 dump.appendFormat(INDENT4 " scale=%0.5f, offset=%0.5f, " 5351 "highScale=%0.5f, highOffset=%0.5f\n", 5352 axis.scale, axis.offset, axis.highScale, axis.highOffset); 5353 dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, " 5354 "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n", 5355 mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue, 5356 axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution); 5357 } 5358} 5359 5360void JoystickInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) { 5361 InputMapper::configure(config, changes); 5362 5363 if (!changes) { // first time only 5364 // Collect all axes. 5365 for (int32_t abs = 0; abs <= ABS_MAX; abs++) { 5366 RawAbsoluteAxisInfo rawAxisInfo; 5367 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo); 5368 if (rawAxisInfo.valid) { 5369 // Map axis. 5370 AxisInfo axisInfo; 5371 bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo); 5372 if (!explicitlyMapped) { 5373 // Axis is not explicitly mapped, will choose a generic axis later. 5374 axisInfo.mode = AxisInfo::MODE_NORMAL; 5375 axisInfo.axis = -1; 5376 } 5377 5378 // Apply flat override. 5379 int32_t rawFlat = axisInfo.flatOverride < 0 5380 ? rawAxisInfo.flat : axisInfo.flatOverride; 5381 5382 // Calculate scaling factors and limits. 5383 Axis axis; 5384 if (axisInfo.mode == AxisInfo::MODE_SPLIT) { 5385 float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue); 5386 float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue); 5387 axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped, 5388 scale, 0.0f, highScale, 0.0f, 5389 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale); 5390 } else if (isCenteredAxis(axisInfo.axis)) { 5391 float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue); 5392 float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale; 5393 axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped, 5394 scale, offset, scale, offset, 5395 -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale); 5396 } else { 5397 float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue); 5398 axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped, 5399 scale, 0.0f, scale, 0.0f, 5400 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale); 5401 } 5402 5403 // To eliminate noise while the joystick is at rest, filter out small variations 5404 // in axis values up front. 5405 axis.filter = axis.flat * 0.25f; 5406 5407 mAxes.add(abs, axis); 5408 } 5409 } 5410 5411 // If there are too many axes, start dropping them. 5412 // Prefer to keep explicitly mapped axes. 5413 if (mAxes.size() > PointerCoords::MAX_AXES) { 5414 LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.", 5415 getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES); 5416 pruneAxes(true); 5417 pruneAxes(false); 5418 } 5419 5420 // Assign generic axis ids to remaining axes. 5421 int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1; 5422 size_t numAxes = mAxes.size(); 5423 for (size_t i = 0; i < numAxes; i++) { 5424 Axis& axis = mAxes.editValueAt(i); 5425 if (axis.axisInfo.axis < 0) { 5426 while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16 5427 && haveAxis(nextGenericAxisId)) { 5428 nextGenericAxisId += 1; 5429 } 5430 5431 if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) { 5432 axis.axisInfo.axis = nextGenericAxisId; 5433 nextGenericAxisId += 1; 5434 } else { 5435 LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids " 5436 "have already been assigned to other axes.", 5437 getDeviceName().string(), mAxes.keyAt(i)); 5438 mAxes.removeItemsAt(i--); 5439 numAxes -= 1; 5440 } 5441 } 5442 } 5443 } 5444} 5445 5446bool JoystickInputMapper::haveAxis(int32_t axisId) { 5447 size_t numAxes = mAxes.size(); 5448 for (size_t i = 0; i < numAxes; i++) { 5449 const Axis& axis = mAxes.valueAt(i); 5450 if (axis.axisInfo.axis == axisId 5451 || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT 5452 && axis.axisInfo.highAxis == axisId)) { 5453 return true; 5454 } 5455 } 5456 return false; 5457} 5458 5459void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) { 5460 size_t i = mAxes.size(); 5461 while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) { 5462 if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) { 5463 continue; 5464 } 5465 LOGI("Discarding joystick '%s' axis %d because there are too many axes.", 5466 getDeviceName().string(), mAxes.keyAt(i)); 5467 mAxes.removeItemsAt(i); 5468 } 5469} 5470 5471bool JoystickInputMapper::isCenteredAxis(int32_t axis) { 5472 switch (axis) { 5473 case AMOTION_EVENT_AXIS_X: 5474 case AMOTION_EVENT_AXIS_Y: 5475 case AMOTION_EVENT_AXIS_Z: 5476 case AMOTION_EVENT_AXIS_RX: 5477 case AMOTION_EVENT_AXIS_RY: 5478 case AMOTION_EVENT_AXIS_RZ: 5479 case AMOTION_EVENT_AXIS_HAT_X: 5480 case AMOTION_EVENT_AXIS_HAT_Y: 5481 case AMOTION_EVENT_AXIS_ORIENTATION: 5482 case AMOTION_EVENT_AXIS_RUDDER: 5483 case AMOTION_EVENT_AXIS_WHEEL: 5484 return true; 5485 default: 5486 return false; 5487 } 5488} 5489 5490void JoystickInputMapper::reset() { 5491 // Recenter all axes. 5492 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 5493 5494 size_t numAxes = mAxes.size(); 5495 for (size_t i = 0; i < numAxes; i++) { 5496 Axis& axis = mAxes.editValueAt(i); 5497 axis.resetValue(); 5498 } 5499 5500 sync(when, true /*force*/); 5501 5502 InputMapper::reset(); 5503} 5504 5505void JoystickInputMapper::process(const RawEvent* rawEvent) { 5506 switch (rawEvent->type) { 5507 case EV_ABS: { 5508 ssize_t index = mAxes.indexOfKey(rawEvent->scanCode); 5509 if (index >= 0) { 5510 Axis& axis = mAxes.editValueAt(index); 5511 float newValue, highNewValue; 5512 switch (axis.axisInfo.mode) { 5513 case AxisInfo::MODE_INVERT: 5514 newValue = (axis.rawAxisInfo.maxValue - rawEvent->value) 5515 * axis.scale + axis.offset; 5516 highNewValue = 0.0f; 5517 break; 5518 case AxisInfo::MODE_SPLIT: 5519 if (rawEvent->value < axis.axisInfo.splitValue) { 5520 newValue = (axis.axisInfo.splitValue - rawEvent->value) 5521 * axis.scale + axis.offset; 5522 highNewValue = 0.0f; 5523 } else if (rawEvent->value > axis.axisInfo.splitValue) { 5524 newValue = 0.0f; 5525 highNewValue = (rawEvent->value - axis.axisInfo.splitValue) 5526 * axis.highScale + axis.highOffset; 5527 } else { 5528 newValue = 0.0f; 5529 highNewValue = 0.0f; 5530 } 5531 break; 5532 default: 5533 newValue = rawEvent->value * axis.scale + axis.offset; 5534 highNewValue = 0.0f; 5535 break; 5536 } 5537 axis.newValue = newValue; 5538 axis.highNewValue = highNewValue; 5539 } 5540 break; 5541 } 5542 5543 case EV_SYN: 5544 switch (rawEvent->scanCode) { 5545 case SYN_REPORT: 5546 sync(rawEvent->when, false /*force*/); 5547 break; 5548 } 5549 break; 5550 } 5551} 5552 5553void JoystickInputMapper::sync(nsecs_t when, bool force) { 5554 if (!filterAxes(force)) { 5555 return; 5556 } 5557 5558 int32_t metaState = mContext->getGlobalMetaState(); 5559 int32_t buttonState = 0; 5560 5561 PointerProperties pointerProperties; 5562 pointerProperties.clear(); 5563 pointerProperties.id = 0; 5564 pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN; 5565 5566 PointerCoords pointerCoords; 5567 pointerCoords.clear(); 5568 5569 size_t numAxes = mAxes.size(); 5570 for (size_t i = 0; i < numAxes; i++) { 5571 const Axis& axis = mAxes.valueAt(i); 5572 pointerCoords.setAxisValue(axis.axisInfo.axis, axis.currentValue); 5573 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 5574 pointerCoords.setAxisValue(axis.axisInfo.highAxis, axis.highCurrentValue); 5575 } 5576 } 5577 5578 // Moving a joystick axis should not wake the devide because joysticks can 5579 // be fairly noisy even when not in use. On the other hand, pushing a gamepad 5580 // button will likely wake the device. 5581 // TODO: Use the input device configuration to control this behavior more finely. 5582 uint32_t policyFlags = 0; 5583 5584 getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags, 5585 AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE, 5586 1, &pointerProperties, &pointerCoords, 0, 0, 0); 5587} 5588 5589bool JoystickInputMapper::filterAxes(bool force) { 5590 bool atLeastOneSignificantChange = force; 5591 size_t numAxes = mAxes.size(); 5592 for (size_t i = 0; i < numAxes; i++) { 5593 Axis& axis = mAxes.editValueAt(i); 5594 if (force || hasValueChangedSignificantly(axis.filter, 5595 axis.newValue, axis.currentValue, axis.min, axis.max)) { 5596 axis.currentValue = axis.newValue; 5597 atLeastOneSignificantChange = true; 5598 } 5599 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 5600 if (force || hasValueChangedSignificantly(axis.filter, 5601 axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) { 5602 axis.highCurrentValue = axis.highNewValue; 5603 atLeastOneSignificantChange = true; 5604 } 5605 } 5606 } 5607 return atLeastOneSignificantChange; 5608} 5609 5610bool JoystickInputMapper::hasValueChangedSignificantly( 5611 float filter, float newValue, float currentValue, float min, float max) { 5612 if (newValue != currentValue) { 5613 // Filter out small changes in value unless the value is converging on the axis 5614 // bounds or center point. This is intended to reduce the amount of information 5615 // sent to applications by particularly noisy joysticks (such as PS3). 5616 if (fabs(newValue - currentValue) > filter 5617 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min) 5618 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max) 5619 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) { 5620 return true; 5621 } 5622 } 5623 return false; 5624} 5625 5626bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange( 5627 float filter, float newValue, float currentValue, float thresholdValue) { 5628 float newDistance = fabs(newValue - thresholdValue); 5629 if (newDistance < filter) { 5630 float oldDistance = fabs(currentValue - thresholdValue); 5631 if (newDistance < oldDistance) { 5632 return true; 5633 } 5634 } 5635 return false; 5636} 5637 5638} // namespace android 5639