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