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