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