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