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