InputReader.cpp revision efd3266b719eed5f1b217021c0a9e76e4b274b06
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 37#include "InputReader.h" 38 39#include <cutils/log.h> 40#include <ui/Keyboard.h> 41#include <ui/VirtualKeyMap.h> 42 43#include <stddef.h> 44#include <stdlib.h> 45#include <unistd.h> 46#include <errno.h> 47#include <limits.h> 48#include <math.h> 49 50#define INDENT " " 51#define INDENT2 " " 52#define INDENT3 " " 53#define INDENT4 " " 54 55namespace android { 56 57// --- Static Functions --- 58 59template<typename T> 60inline static T abs(const T& value) { 61 return value < 0 ? - value : value; 62} 63 64template<typename T> 65inline static T min(const T& a, const T& b) { 66 return a < b ? a : b; 67} 68 69template<typename T> 70inline static void swap(T& a, T& b) { 71 T temp = a; 72 a = b; 73 b = temp; 74} 75 76inline static float avg(float x, float y) { 77 return (x + y) / 2; 78} 79 80inline static float pythag(float x, float y) { 81 return sqrtf(x * x + y * y); 82} 83 84inline static int32_t signExtendNybble(int32_t value) { 85 return value >= 8 ? value - 16 : value; 86} 87 88static inline const char* toString(bool value) { 89 return value ? "true" : "false"; 90} 91 92static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation, 93 const int32_t map[][4], size_t mapSize) { 94 if (orientation != DISPLAY_ORIENTATION_0) { 95 for (size_t i = 0; i < mapSize; i++) { 96 if (value == map[i][0]) { 97 return map[i][orientation]; 98 } 99 } 100 } 101 return value; 102} 103 104static const int32_t keyCodeRotationMap[][4] = { 105 // key codes enumerated counter-clockwise with the original (unrotated) key first 106 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation 107 { AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT }, 108 { AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN }, 109 { AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT }, 110 { AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP }, 111}; 112static const size_t keyCodeRotationMapSize = 113 sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]); 114 115int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) { 116 return rotateValueUsingRotationMap(keyCode, orientation, 117 keyCodeRotationMap, keyCodeRotationMapSize); 118} 119 120static const int32_t edgeFlagRotationMap[][4] = { 121 // edge flags enumerated counter-clockwise with the original (unrotated) edge flag first 122 // no rotation, 90 degree rotation, 180 degree rotation, 270 degree rotation 123 { AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT, 124 AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT }, 125 { AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP, 126 AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM }, 127 { AMOTION_EVENT_EDGE_FLAG_TOP, AMOTION_EVENT_EDGE_FLAG_LEFT, 128 AMOTION_EVENT_EDGE_FLAG_BOTTOM, AMOTION_EVENT_EDGE_FLAG_RIGHT }, 129 { AMOTION_EVENT_EDGE_FLAG_LEFT, AMOTION_EVENT_EDGE_FLAG_BOTTOM, 130 AMOTION_EVENT_EDGE_FLAG_RIGHT, AMOTION_EVENT_EDGE_FLAG_TOP }, 131}; 132static const size_t edgeFlagRotationMapSize = 133 sizeof(edgeFlagRotationMap) / sizeof(edgeFlagRotationMap[0]); 134 135static int32_t rotateEdgeFlag(int32_t edgeFlag, int32_t orientation) { 136 return rotateValueUsingRotationMap(edgeFlag, orientation, 137 edgeFlagRotationMap, edgeFlagRotationMapSize); 138} 139 140static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) { 141 return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0; 142} 143 144static uint32_t getButtonStateForScanCode(int32_t scanCode) { 145 // Currently all buttons are mapped to the primary button. 146 switch (scanCode) { 147 case BTN_LEFT: 148 case BTN_RIGHT: 149 case BTN_MIDDLE: 150 case BTN_SIDE: 151 case BTN_EXTRA: 152 case BTN_FORWARD: 153 case BTN_BACK: 154 case BTN_TASK: 155 return BUTTON_STATE_PRIMARY; 156 default: 157 return 0; 158 } 159} 160 161// Returns true if the pointer should be reported as being down given the specified 162// button states. 163static bool isPointerDown(uint32_t buttonState) { 164 return buttonState & BUTTON_STATE_PRIMARY; 165} 166 167static int32_t calculateEdgeFlagsUsingPointerBounds( 168 const sp<PointerControllerInterface>& pointerController, float x, float y) { 169 int32_t edgeFlags = 0; 170 float minX, minY, maxX, maxY; 171 if (pointerController->getBounds(&minX, &minY, &maxX, &maxY)) { 172 if (x <= minX) { 173 edgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; 174 } else if (x >= maxX) { 175 edgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; 176 } 177 if (y <= minY) { 178 edgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; 179 } else if (y >= maxY) { 180 edgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; 181 } 182 } 183 return edgeFlags; 184} 185 186 187// --- InputReader --- 188 189InputReader::InputReader(const sp<EventHubInterface>& eventHub, 190 const sp<InputReaderPolicyInterface>& policy, 191 const sp<InputDispatcherInterface>& dispatcher) : 192 mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher), 193 mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) { 194 configureExcludedDevices(); 195 updateGlobalMetaState(); 196 updateInputConfiguration(); 197} 198 199InputReader::~InputReader() { 200 for (size_t i = 0; i < mDevices.size(); i++) { 201 delete mDevices.valueAt(i); 202 } 203} 204 205void InputReader::loopOnce() { 206 RawEvent rawEvent; 207 mEventHub->getEvent(& rawEvent); 208 209#if DEBUG_RAW_EVENTS 210 LOGD("Input event: device=%d type=0x%x scancode=%d keycode=%d value=%d", 211 rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode, 212 rawEvent.value); 213#endif 214 215 process(& rawEvent); 216} 217 218void InputReader::process(const RawEvent* rawEvent) { 219 switch (rawEvent->type) { 220 case EventHubInterface::DEVICE_ADDED: 221 addDevice(rawEvent->deviceId); 222 break; 223 224 case EventHubInterface::DEVICE_REMOVED: 225 removeDevice(rawEvent->deviceId); 226 break; 227 228 case EventHubInterface::FINISHED_DEVICE_SCAN: 229 handleConfigurationChanged(rawEvent->when); 230 break; 231 232 default: 233 consumeEvent(rawEvent); 234 break; 235 } 236} 237 238void InputReader::addDevice(int32_t deviceId) { 239 String8 name = mEventHub->getDeviceName(deviceId); 240 uint32_t classes = mEventHub->getDeviceClasses(deviceId); 241 242 InputDevice* device = createDevice(deviceId, name, classes); 243 device->configure(); 244 245 if (device->isIgnored()) { 246 LOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, name.string()); 247 } else { 248 LOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, name.string(), 249 device->getSources()); 250 } 251 252 bool added = false; 253 { // acquire device registry writer lock 254 RWLock::AutoWLock _wl(mDeviceRegistryLock); 255 256 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 257 if (deviceIndex < 0) { 258 mDevices.add(deviceId, device); 259 added = true; 260 } 261 } // release device registry writer lock 262 263 if (! added) { 264 LOGW("Ignoring spurious device added event for deviceId %d.", deviceId); 265 delete device; 266 return; 267 } 268} 269 270void InputReader::removeDevice(int32_t deviceId) { 271 bool removed = false; 272 InputDevice* device = NULL; 273 { // acquire device registry writer lock 274 RWLock::AutoWLock _wl(mDeviceRegistryLock); 275 276 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 277 if (deviceIndex >= 0) { 278 device = mDevices.valueAt(deviceIndex); 279 mDevices.removeItemsAt(deviceIndex, 1); 280 removed = true; 281 } 282 } // release device registry writer lock 283 284 if (! removed) { 285 LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId); 286 return; 287 } 288 289 if (device->isIgnored()) { 290 LOGI("Device removed: id=%d, name='%s' (ignored non-input device)", 291 device->getId(), device->getName().string()); 292 } else { 293 LOGI("Device removed: id=%d, name='%s', sources=0x%08x", 294 device->getId(), device->getName().string(), device->getSources()); 295 } 296 297 device->reset(); 298 299 delete device; 300} 301 302InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) { 303 InputDevice* device = new InputDevice(this, deviceId, name); 304 305 // External devices. 306 if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { 307 device->setExternal(true); 308 } 309 310 // Switch-like devices. 311 if (classes & INPUT_DEVICE_CLASS_SWITCH) { 312 device->addMapper(new SwitchInputMapper(device)); 313 } 314 315 // Keyboard-like devices. 316 uint32_t keyboardSource = 0; 317 int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC; 318 if (classes & INPUT_DEVICE_CLASS_KEYBOARD) { 319 keyboardSource |= AINPUT_SOURCE_KEYBOARD; 320 } 321 if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) { 322 keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC; 323 } 324 if (classes & INPUT_DEVICE_CLASS_DPAD) { 325 keyboardSource |= AINPUT_SOURCE_DPAD; 326 } 327 if (classes & INPUT_DEVICE_CLASS_GAMEPAD) { 328 keyboardSource |= AINPUT_SOURCE_GAMEPAD; 329 } 330 331 if (keyboardSource != 0) { 332 device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType)); 333 } 334 335 // Cursor-like devices. 336 if (classes & INPUT_DEVICE_CLASS_CURSOR) { 337 device->addMapper(new CursorInputMapper(device)); 338 } 339 340 // Touchscreens and touchpad devices. 341 if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) { 342 device->addMapper(new MultiTouchInputMapper(device)); 343 } else if (classes & INPUT_DEVICE_CLASS_TOUCH) { 344 device->addMapper(new SingleTouchInputMapper(device)); 345 } 346 347 // Joystick-like devices. 348 if (classes & INPUT_DEVICE_CLASS_JOYSTICK) { 349 device->addMapper(new JoystickInputMapper(device)); 350 } 351 352 return device; 353} 354 355void InputReader::consumeEvent(const RawEvent* rawEvent) { 356 int32_t deviceId = rawEvent->deviceId; 357 358 { // acquire device registry reader lock 359 RWLock::AutoRLock _rl(mDeviceRegistryLock); 360 361 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 362 if (deviceIndex < 0) { 363 LOGW("Discarding event for unknown deviceId %d.", deviceId); 364 return; 365 } 366 367 InputDevice* device = mDevices.valueAt(deviceIndex); 368 if (device->isIgnored()) { 369 //LOGD("Discarding event for ignored deviceId %d.", deviceId); 370 return; 371 } 372 373 device->process(rawEvent); 374 } // release device registry reader lock 375} 376 377void InputReader::handleConfigurationChanged(nsecs_t when) { 378 // Reset global meta state because it depends on the list of all configured devices. 379 updateGlobalMetaState(); 380 381 // Update input configuration. 382 updateInputConfiguration(); 383 384 // Enqueue configuration changed. 385 mDispatcher->notifyConfigurationChanged(when); 386} 387 388void InputReader::configureExcludedDevices() { 389 Vector<String8> excludedDeviceNames; 390 mPolicy->getExcludedDeviceNames(excludedDeviceNames); 391 392 for (size_t i = 0; i < excludedDeviceNames.size(); i++) { 393 mEventHub->addExcludedDevice(excludedDeviceNames[i]); 394 } 395} 396 397void InputReader::updateGlobalMetaState() { 398 { // acquire state lock 399 AutoMutex _l(mStateLock); 400 401 mGlobalMetaState = 0; 402 403 { // acquire device registry reader lock 404 RWLock::AutoRLock _rl(mDeviceRegistryLock); 405 406 for (size_t i = 0; i < mDevices.size(); i++) { 407 InputDevice* device = mDevices.valueAt(i); 408 mGlobalMetaState |= device->getMetaState(); 409 } 410 } // release device registry reader lock 411 } // release state lock 412} 413 414int32_t InputReader::getGlobalMetaState() { 415 { // acquire state lock 416 AutoMutex _l(mStateLock); 417 418 return mGlobalMetaState; 419 } // release state lock 420} 421 422void InputReader::updateInputConfiguration() { 423 { // acquire state lock 424 AutoMutex _l(mStateLock); 425 426 int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH; 427 int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS; 428 int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV; 429 { // acquire device registry reader lock 430 RWLock::AutoRLock _rl(mDeviceRegistryLock); 431 432 InputDeviceInfo deviceInfo; 433 for (size_t i = 0; i < mDevices.size(); i++) { 434 InputDevice* device = mDevices.valueAt(i); 435 device->getDeviceInfo(& deviceInfo); 436 uint32_t sources = deviceInfo.getSources(); 437 438 if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) { 439 touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER; 440 } 441 if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) { 442 navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL; 443 } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) { 444 navigationConfig = InputConfiguration::NAVIGATION_DPAD; 445 } 446 if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) { 447 keyboardConfig = InputConfiguration::KEYBOARD_QWERTY; 448 } 449 } 450 } // release device registry reader lock 451 452 mInputConfiguration.touchScreen = touchScreenConfig; 453 mInputConfiguration.keyboard = keyboardConfig; 454 mInputConfiguration.navigation = navigationConfig; 455 } // release state lock 456} 457 458void InputReader::disableVirtualKeysUntil(nsecs_t time) { 459 mDisableVirtualKeysTimeout = time; 460} 461 462bool InputReader::shouldDropVirtualKey(nsecs_t now, 463 InputDevice* device, int32_t keyCode, int32_t scanCode) { 464 if (now < mDisableVirtualKeysTimeout) { 465 LOGI("Dropping virtual key from device %s because virtual keys are " 466 "temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d", 467 device->getName().string(), 468 (mDisableVirtualKeysTimeout - now) * 0.000001, 469 keyCode, scanCode); 470 return true; 471 } else { 472 return false; 473 } 474} 475 476void InputReader::fadePointer() { 477 { // acquire device registry reader lock 478 RWLock::AutoRLock _rl(mDeviceRegistryLock); 479 480 for (size_t i = 0; i < mDevices.size(); i++) { 481 InputDevice* device = mDevices.valueAt(i); 482 device->fadePointer(); 483 } 484 } // release device registry reader lock 485} 486 487void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) { 488 { // acquire state lock 489 AutoMutex _l(mStateLock); 490 491 *outConfiguration = mInputConfiguration; 492 } // release state lock 493} 494 495status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) { 496 { // acquire device registry reader lock 497 RWLock::AutoRLock _rl(mDeviceRegistryLock); 498 499 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 500 if (deviceIndex < 0) { 501 return NAME_NOT_FOUND; 502 } 503 504 InputDevice* device = mDevices.valueAt(deviceIndex); 505 if (device->isIgnored()) { 506 return NAME_NOT_FOUND; 507 } 508 509 device->getDeviceInfo(outDeviceInfo); 510 return OK; 511 } // release device registy reader lock 512} 513 514void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) { 515 outDeviceIds.clear(); 516 517 { // acquire device registry reader lock 518 RWLock::AutoRLock _rl(mDeviceRegistryLock); 519 520 size_t numDevices = mDevices.size(); 521 for (size_t i = 0; i < numDevices; i++) { 522 InputDevice* device = mDevices.valueAt(i); 523 if (! device->isIgnored()) { 524 outDeviceIds.add(device->getId()); 525 } 526 } 527 } // release device registy reader lock 528} 529 530int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, 531 int32_t keyCode) { 532 return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState); 533} 534 535int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask, 536 int32_t scanCode) { 537 return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState); 538} 539 540int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) { 541 return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState); 542} 543 544int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code, 545 GetStateFunc getStateFunc) { 546 { // acquire device registry reader lock 547 RWLock::AutoRLock _rl(mDeviceRegistryLock); 548 549 int32_t result = AKEY_STATE_UNKNOWN; 550 if (deviceId >= 0) { 551 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 552 if (deviceIndex >= 0) { 553 InputDevice* device = mDevices.valueAt(deviceIndex); 554 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 555 result = (device->*getStateFunc)(sourceMask, code); 556 } 557 } 558 } else { 559 size_t numDevices = mDevices.size(); 560 for (size_t i = 0; i < numDevices; i++) { 561 InputDevice* device = mDevices.valueAt(i); 562 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 563 result = (device->*getStateFunc)(sourceMask, code); 564 if (result >= AKEY_STATE_DOWN) { 565 return result; 566 } 567 } 568 } 569 } 570 return result; 571 } // release device registy reader lock 572} 573 574bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask, 575 size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) { 576 memset(outFlags, 0, numCodes); 577 return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags); 578} 579 580bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes, 581 const int32_t* keyCodes, uint8_t* outFlags) { 582 { // acquire device registry reader lock 583 RWLock::AutoRLock _rl(mDeviceRegistryLock); 584 bool result = false; 585 if (deviceId >= 0) { 586 ssize_t deviceIndex = mDevices.indexOfKey(deviceId); 587 if (deviceIndex >= 0) { 588 InputDevice* device = mDevices.valueAt(deviceIndex); 589 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 590 result = device->markSupportedKeyCodes(sourceMask, 591 numCodes, keyCodes, outFlags); 592 } 593 } 594 } else { 595 size_t numDevices = mDevices.size(); 596 for (size_t i = 0; i < numDevices; i++) { 597 InputDevice* device = mDevices.valueAt(i); 598 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) { 599 result |= device->markSupportedKeyCodes(sourceMask, 600 numCodes, keyCodes, outFlags); 601 } 602 } 603 } 604 return result; 605 } // release device registy reader lock 606} 607 608void InputReader::dump(String8& dump) { 609 mEventHub->dump(dump); 610 dump.append("\n"); 611 612 dump.append("Input Reader State:\n"); 613 614 { // acquire device registry reader lock 615 RWLock::AutoRLock _rl(mDeviceRegistryLock); 616 617 for (size_t i = 0; i < mDevices.size(); i++) { 618 mDevices.valueAt(i)->dump(dump); 619 } 620 } // release device registy reader lock 621} 622 623 624// --- InputReaderThread --- 625 626InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) : 627 Thread(/*canCallJava*/ true), mReader(reader) { 628} 629 630InputReaderThread::~InputReaderThread() { 631} 632 633bool InputReaderThread::threadLoop() { 634 mReader->loopOnce(); 635 return true; 636} 637 638 639// --- InputDevice --- 640 641InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) : 642 mContext(context), mId(id), mName(name), mSources(0), mIsExternal(false) { 643} 644 645InputDevice::~InputDevice() { 646 size_t numMappers = mMappers.size(); 647 for (size_t i = 0; i < numMappers; i++) { 648 delete mMappers[i]; 649 } 650 mMappers.clear(); 651} 652 653void InputDevice::dump(String8& dump) { 654 InputDeviceInfo deviceInfo; 655 getDeviceInfo(& deviceInfo); 656 657 dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(), 658 deviceInfo.getName().string()); 659 dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); 660 dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); 661 dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType()); 662 663 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges(); 664 if (!ranges.isEmpty()) { 665 dump.append(INDENT2 "Motion Ranges:\n"); 666 for (size_t i = 0; i < ranges.size(); i++) { 667 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i); 668 const char* label = getAxisLabel(range.axis); 669 char name[32]; 670 if (label) { 671 strncpy(name, label, sizeof(name)); 672 name[sizeof(name) - 1] = '\0'; 673 } else { 674 snprintf(name, sizeof(name), "%d", range.axis); 675 } 676 dump.appendFormat(INDENT3 "%s: source=0x%08x, " 677 "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n", 678 name, range.source, range.min, range.max, range.flat, range.fuzz); 679 } 680 } 681 682 size_t numMappers = mMappers.size(); 683 for (size_t i = 0; i < numMappers; i++) { 684 InputMapper* mapper = mMappers[i]; 685 mapper->dump(dump); 686 } 687} 688 689void InputDevice::addMapper(InputMapper* mapper) { 690 mMappers.add(mapper); 691} 692 693void InputDevice::configure() { 694 if (! isIgnored()) { 695 mContext->getEventHub()->getConfiguration(mId, &mConfiguration); 696 } 697 698 mSources = 0; 699 700 size_t numMappers = mMappers.size(); 701 for (size_t i = 0; i < numMappers; i++) { 702 InputMapper* mapper = mMappers[i]; 703 mapper->configure(); 704 mSources |= mapper->getSources(); 705 } 706} 707 708void InputDevice::reset() { 709 size_t numMappers = mMappers.size(); 710 for (size_t i = 0; i < numMappers; i++) { 711 InputMapper* mapper = mMappers[i]; 712 mapper->reset(); 713 } 714} 715 716void InputDevice::process(const RawEvent* rawEvent) { 717 size_t numMappers = mMappers.size(); 718 for (size_t i = 0; i < numMappers; i++) { 719 InputMapper* mapper = mMappers[i]; 720 mapper->process(rawEvent); 721 } 722} 723 724void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { 725 outDeviceInfo->initialize(mId, mName); 726 727 size_t numMappers = mMappers.size(); 728 for (size_t i = 0; i < numMappers; i++) { 729 InputMapper* mapper = mMappers[i]; 730 mapper->populateDeviceInfo(outDeviceInfo); 731 } 732} 733 734int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 735 return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState); 736} 737 738int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 739 return getState(sourceMask, scanCode, & InputMapper::getScanCodeState); 740} 741 742int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 743 return getState(sourceMask, switchCode, & InputMapper::getSwitchState); 744} 745 746int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) { 747 int32_t result = AKEY_STATE_UNKNOWN; 748 size_t numMappers = mMappers.size(); 749 for (size_t i = 0; i < numMappers; i++) { 750 InputMapper* mapper = mMappers[i]; 751 if (sourcesMatchMask(mapper->getSources(), sourceMask)) { 752 result = (mapper->*getStateFunc)(sourceMask, code); 753 if (result >= AKEY_STATE_DOWN) { 754 return result; 755 } 756 } 757 } 758 return result; 759} 760 761bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 762 const int32_t* keyCodes, uint8_t* outFlags) { 763 bool result = false; 764 size_t numMappers = mMappers.size(); 765 for (size_t i = 0; i < numMappers; i++) { 766 InputMapper* mapper = mMappers[i]; 767 if (sourcesMatchMask(mapper->getSources(), sourceMask)) { 768 result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags); 769 } 770 } 771 return result; 772} 773 774int32_t InputDevice::getMetaState() { 775 int32_t result = 0; 776 size_t numMappers = mMappers.size(); 777 for (size_t i = 0; i < numMappers; i++) { 778 InputMapper* mapper = mMappers[i]; 779 result |= mapper->getMetaState(); 780 } 781 return result; 782} 783 784void InputDevice::fadePointer() { 785 size_t numMappers = mMappers.size(); 786 for (size_t i = 0; i < numMappers; i++) { 787 InputMapper* mapper = mMappers[i]; 788 mapper->fadePointer(); 789 } 790} 791 792 793// --- InputMapper --- 794 795InputMapper::InputMapper(InputDevice* device) : 796 mDevice(device), mContext(device->getContext()) { 797} 798 799InputMapper::~InputMapper() { 800} 801 802void InputMapper::populateDeviceInfo(InputDeviceInfo* info) { 803 info->addSource(getSources()); 804} 805 806void InputMapper::dump(String8& dump) { 807} 808 809void InputMapper::configure() { 810} 811 812void InputMapper::reset() { 813} 814 815int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 816 return AKEY_STATE_UNKNOWN; 817} 818 819int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 820 return AKEY_STATE_UNKNOWN; 821} 822 823int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 824 return AKEY_STATE_UNKNOWN; 825} 826 827bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 828 const int32_t* keyCodes, uint8_t* outFlags) { 829 return false; 830} 831 832int32_t InputMapper::getMetaState() { 833 return 0; 834} 835 836void InputMapper::fadePointer() { 837} 838 839void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump, 840 const RawAbsoluteAxisInfo& axis, const char* name) { 841 if (axis.valid) { 842 dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d\n", 843 name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz); 844 } else { 845 dump.appendFormat(INDENT4 "%s: unknown range\n", name); 846 } 847} 848 849 850// --- SwitchInputMapper --- 851 852SwitchInputMapper::SwitchInputMapper(InputDevice* device) : 853 InputMapper(device) { 854} 855 856SwitchInputMapper::~SwitchInputMapper() { 857} 858 859uint32_t SwitchInputMapper::getSources() { 860 return AINPUT_SOURCE_SWITCH; 861} 862 863void SwitchInputMapper::process(const RawEvent* rawEvent) { 864 switch (rawEvent->type) { 865 case EV_SW: 866 processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value); 867 break; 868 } 869} 870 871void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) { 872 getDispatcher()->notifySwitch(when, switchCode, switchValue, 0); 873} 874 875int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) { 876 return getEventHub()->getSwitchState(getDeviceId(), switchCode); 877} 878 879 880// --- KeyboardInputMapper --- 881 882KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, 883 uint32_t source, int32_t keyboardType) : 884 InputMapper(device), mSource(source), 885 mKeyboardType(keyboardType) { 886 initializeLocked(); 887} 888 889KeyboardInputMapper::~KeyboardInputMapper() { 890} 891 892void KeyboardInputMapper::initializeLocked() { 893 mLocked.metaState = AMETA_NONE; 894 mLocked.downTime = 0; 895} 896 897uint32_t KeyboardInputMapper::getSources() { 898 return mSource; 899} 900 901void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 902 InputMapper::populateDeviceInfo(info); 903 904 info->setKeyboardType(mKeyboardType); 905} 906 907void KeyboardInputMapper::dump(String8& dump) { 908 { // acquire lock 909 AutoMutex _l(mLock); 910 dump.append(INDENT2 "Keyboard Input Mapper:\n"); 911 dumpParameters(dump); 912 dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType); 913 dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size()); 914 dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState); 915 dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); 916 } // release lock 917} 918 919 920void KeyboardInputMapper::configure() { 921 InputMapper::configure(); 922 923 // Configure basic parameters. 924 configureParameters(); 925 926 // Reset LEDs. 927 { 928 AutoMutex _l(mLock); 929 resetLedStateLocked(); 930 } 931} 932 933void KeyboardInputMapper::configureParameters() { 934 mParameters.orientationAware = false; 935 getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"), 936 mParameters.orientationAware); 937 938 mParameters.associatedDisplayId = mParameters.orientationAware ? 0 : -1; 939} 940 941void KeyboardInputMapper::dumpParameters(String8& dump) { 942 dump.append(INDENT3 "Parameters:\n"); 943 dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", 944 mParameters.associatedDisplayId); 945 dump.appendFormat(INDENT4 "OrientationAware: %s\n", 946 toString(mParameters.orientationAware)); 947} 948 949void KeyboardInputMapper::reset() { 950 for (;;) { 951 int32_t keyCode, scanCode; 952 { // acquire lock 953 AutoMutex _l(mLock); 954 955 // Synthesize key up event on reset if keys are currently down. 956 if (mLocked.keyDowns.isEmpty()) { 957 initializeLocked(); 958 resetLedStateLocked(); 959 break; // done 960 } 961 962 const KeyDown& keyDown = mLocked.keyDowns.top(); 963 keyCode = keyDown.keyCode; 964 scanCode = keyDown.scanCode; 965 } // release lock 966 967 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 968 processKey(when, false, keyCode, scanCode, 0); 969 } 970 971 InputMapper::reset(); 972 getContext()->updateGlobalMetaState(); 973} 974 975void KeyboardInputMapper::process(const RawEvent* rawEvent) { 976 switch (rawEvent->type) { 977 case EV_KEY: { 978 int32_t scanCode = rawEvent->scanCode; 979 if (isKeyboardOrGamepadKey(scanCode)) { 980 processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode, 981 rawEvent->flags); 982 } 983 break; 984 } 985 } 986} 987 988bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) { 989 return scanCode < BTN_MOUSE 990 || scanCode >= KEY_OK 991 || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE) 992 || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI); 993} 994 995void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, 996 int32_t scanCode, uint32_t policyFlags) { 997 int32_t newMetaState; 998 nsecs_t downTime; 999 bool metaStateChanged = false; 1000 1001 { // acquire lock 1002 AutoMutex _l(mLock); 1003 1004 if (down) { 1005 // Rotate key codes according to orientation if needed. 1006 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1007 if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) { 1008 int32_t orientation; 1009 if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 1010 NULL, NULL, & orientation)) { 1011 orientation = DISPLAY_ORIENTATION_0; 1012 } 1013 1014 keyCode = rotateKeyCode(keyCode, orientation); 1015 } 1016 1017 // Add key down. 1018 ssize_t keyDownIndex = findKeyDownLocked(scanCode); 1019 if (keyDownIndex >= 0) { 1020 // key repeat, be sure to use same keycode as before in case of rotation 1021 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode; 1022 } else { 1023 // key down 1024 if ((policyFlags & POLICY_FLAG_VIRTUAL) 1025 && mContext->shouldDropVirtualKey(when, 1026 getDevice(), keyCode, scanCode)) { 1027 return; 1028 } 1029 1030 mLocked.keyDowns.push(); 1031 KeyDown& keyDown = mLocked.keyDowns.editTop(); 1032 keyDown.keyCode = keyCode; 1033 keyDown.scanCode = scanCode; 1034 } 1035 1036 mLocked.downTime = when; 1037 } else { 1038 // Remove key down. 1039 ssize_t keyDownIndex = findKeyDownLocked(scanCode); 1040 if (keyDownIndex >= 0) { 1041 // key up, be sure to use same keycode as before in case of rotation 1042 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode; 1043 mLocked.keyDowns.removeAt(size_t(keyDownIndex)); 1044 } else { 1045 // key was not actually down 1046 LOGI("Dropping key up from device %s because the key was not down. " 1047 "keyCode=%d, scanCode=%d", 1048 getDeviceName().string(), keyCode, scanCode); 1049 return; 1050 } 1051 } 1052 1053 int32_t oldMetaState = mLocked.metaState; 1054 newMetaState = updateMetaState(keyCode, down, oldMetaState); 1055 if (oldMetaState != newMetaState) { 1056 mLocked.metaState = newMetaState; 1057 metaStateChanged = true; 1058 updateLedStateLocked(false); 1059 } 1060 1061 downTime = mLocked.downTime; 1062 } // release lock 1063 1064 // Key down on external an keyboard should wake the device. 1065 // We don't do this for internal keyboards to prevent them from waking up in your pocket. 1066 // For internal keyboards, the key layout file should specify the policy flags for 1067 // each wake key individually. 1068 // TODO: Use the input device configuration to control this behavior more finely. 1069 if (down && getDevice()->isExternal() 1070 && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) { 1071 policyFlags |= POLICY_FLAG_WAKE_DROPPED; 1072 } 1073 1074 if (metaStateChanged) { 1075 getContext()->updateGlobalMetaState(); 1076 } 1077 1078 if (down && !isMetaKey(keyCode)) { 1079 getContext()->fadePointer(); 1080 } 1081 1082 getDispatcher()->notifyKey(when, getDeviceId(), mSource, policyFlags, 1083 down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, 1084 AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime); 1085} 1086 1087ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) { 1088 size_t n = mLocked.keyDowns.size(); 1089 for (size_t i = 0; i < n; i++) { 1090 if (mLocked.keyDowns[i].scanCode == scanCode) { 1091 return i; 1092 } 1093 } 1094 return -1; 1095} 1096 1097int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 1098 return getEventHub()->getKeyCodeState(getDeviceId(), keyCode); 1099} 1100 1101int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 1102 return getEventHub()->getScanCodeState(getDeviceId(), scanCode); 1103} 1104 1105bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 1106 const int32_t* keyCodes, uint8_t* outFlags) { 1107 return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags); 1108} 1109 1110int32_t KeyboardInputMapper::getMetaState() { 1111 { // acquire lock 1112 AutoMutex _l(mLock); 1113 return mLocked.metaState; 1114 } // release lock 1115} 1116 1117void KeyboardInputMapper::resetLedStateLocked() { 1118 initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL); 1119 initializeLedStateLocked(mLocked.numLockLedState, LED_NUML); 1120 initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL); 1121 1122 updateLedStateLocked(true); 1123} 1124 1125void KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) { 1126 ledState.avail = getEventHub()->hasLed(getDeviceId(), led); 1127 ledState.on = false; 1128} 1129 1130void KeyboardInputMapper::updateLedStateLocked(bool reset) { 1131 updateLedStateForModifierLocked(mLocked.capsLockLedState, LED_CAPSL, 1132 AMETA_CAPS_LOCK_ON, reset); 1133 updateLedStateForModifierLocked(mLocked.numLockLedState, LED_NUML, 1134 AMETA_NUM_LOCK_ON, reset); 1135 updateLedStateForModifierLocked(mLocked.scrollLockLedState, LED_SCROLLL, 1136 AMETA_SCROLL_LOCK_ON, reset); 1137} 1138 1139void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState& ledState, 1140 int32_t led, int32_t modifier, bool reset) { 1141 if (ledState.avail) { 1142 bool desiredState = (mLocked.metaState & modifier) != 0; 1143 if (reset || ledState.on != desiredState) { 1144 getEventHub()->setLedState(getDeviceId(), led, desiredState); 1145 ledState.on = desiredState; 1146 } 1147 } 1148} 1149 1150 1151// --- CursorInputMapper --- 1152 1153CursorInputMapper::CursorInputMapper(InputDevice* device) : 1154 InputMapper(device) { 1155 initializeLocked(); 1156} 1157 1158CursorInputMapper::~CursorInputMapper() { 1159} 1160 1161uint32_t CursorInputMapper::getSources() { 1162 return mSource; 1163} 1164 1165void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1166 InputMapper::populateDeviceInfo(info); 1167 1168 if (mParameters.mode == Parameters::MODE_POINTER) { 1169 float minX, minY, maxX, maxY; 1170 if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) { 1171 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f); 1172 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f); 1173 } 1174 } else { 1175 info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale); 1176 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale); 1177 } 1178 info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f); 1179 1180 if (mHaveVWheel) { 1181 info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f); 1182 } 1183 if (mHaveHWheel) { 1184 info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f); 1185 } 1186} 1187 1188void CursorInputMapper::dump(String8& dump) { 1189 { // acquire lock 1190 AutoMutex _l(mLock); 1191 dump.append(INDENT2 "Cursor Input Mapper:\n"); 1192 dumpParameters(dump); 1193 dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale); 1194 dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale); 1195 dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision); 1196 dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision); 1197 dump.appendFormat(INDENT3 "HaveVWheel: %s\n", toString(mHaveVWheel)); 1198 dump.appendFormat(INDENT3 "HaveHWheel: %s\n", toString(mHaveHWheel)); 1199 dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale); 1200 dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale); 1201 dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mLocked.buttonState); 1202 dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mLocked.buttonState))); 1203 dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime); 1204 } // release lock 1205} 1206 1207void CursorInputMapper::configure() { 1208 InputMapper::configure(); 1209 1210 // Configure basic parameters. 1211 configureParameters(); 1212 1213 // Configure device mode. 1214 switch (mParameters.mode) { 1215 case Parameters::MODE_POINTER: 1216 mSource = AINPUT_SOURCE_MOUSE; 1217 mXPrecision = 1.0f; 1218 mYPrecision = 1.0f; 1219 mXScale = 1.0f; 1220 mYScale = 1.0f; 1221 mPointerController = getPolicy()->obtainPointerController(getDeviceId()); 1222 break; 1223 case Parameters::MODE_NAVIGATION: 1224 mSource = AINPUT_SOURCE_TRACKBALL; 1225 mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD; 1226 mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD; 1227 mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD; 1228 mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD; 1229 break; 1230 } 1231 1232 mVWheelScale = 1.0f; 1233 mHWheelScale = 1.0f; 1234 1235 mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL); 1236 mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL); 1237} 1238 1239void CursorInputMapper::configureParameters() { 1240 mParameters.mode = Parameters::MODE_POINTER; 1241 String8 cursorModeString; 1242 if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) { 1243 if (cursorModeString == "navigation") { 1244 mParameters.mode = Parameters::MODE_NAVIGATION; 1245 } else if (cursorModeString != "pointer" && cursorModeString != "default") { 1246 LOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string()); 1247 } 1248 } 1249 1250 mParameters.orientationAware = false; 1251 getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"), 1252 mParameters.orientationAware); 1253 1254 mParameters.associatedDisplayId = mParameters.mode == Parameters::MODE_POINTER 1255 || mParameters.orientationAware ? 0 : -1; 1256} 1257 1258void CursorInputMapper::dumpParameters(String8& dump) { 1259 dump.append(INDENT3 "Parameters:\n"); 1260 dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", 1261 mParameters.associatedDisplayId); 1262 1263 switch (mParameters.mode) { 1264 case Parameters::MODE_POINTER: 1265 dump.append(INDENT4 "Mode: pointer\n"); 1266 break; 1267 case Parameters::MODE_NAVIGATION: 1268 dump.append(INDENT4 "Mode: navigation\n"); 1269 break; 1270 default: 1271 assert(false); 1272 } 1273 1274 dump.appendFormat(INDENT4 "OrientationAware: %s\n", 1275 toString(mParameters.orientationAware)); 1276} 1277 1278void CursorInputMapper::initializeLocked() { 1279 mAccumulator.clear(); 1280 1281 mLocked.buttonState = 0; 1282 mLocked.downTime = 0; 1283} 1284 1285void CursorInputMapper::reset() { 1286 for (;;) { 1287 uint32_t buttonState; 1288 { // acquire lock 1289 AutoMutex _l(mLock); 1290 1291 buttonState = mLocked.buttonState; 1292 if (!buttonState) { 1293 initializeLocked(); 1294 break; // done 1295 } 1296 } // release lock 1297 1298 // Synthesize button up event on reset. 1299 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 1300 mAccumulator.clear(); 1301 mAccumulator.buttonDown = 0; 1302 mAccumulator.buttonUp = buttonState; 1303 mAccumulator.fields = Accumulator::FIELD_BUTTONS; 1304 sync(when); 1305 } 1306 1307 InputMapper::reset(); 1308} 1309 1310void CursorInputMapper::process(const RawEvent* rawEvent) { 1311 switch (rawEvent->type) { 1312 case EV_KEY: { 1313 uint32_t buttonState = getButtonStateForScanCode(rawEvent->scanCode); 1314 if (buttonState) { 1315 if (rawEvent->value) { 1316 mAccumulator.buttonDown = buttonState; 1317 mAccumulator.buttonUp = 0; 1318 } else { 1319 mAccumulator.buttonDown = 0; 1320 mAccumulator.buttonUp = buttonState; 1321 } 1322 mAccumulator.fields |= Accumulator::FIELD_BUTTONS; 1323 1324 // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and 1325 // we need to ensure that we report the up/down promptly. 1326 sync(rawEvent->when); 1327 break; 1328 } 1329 break; 1330 } 1331 1332 case EV_REL: 1333 switch (rawEvent->scanCode) { 1334 case REL_X: 1335 mAccumulator.fields |= Accumulator::FIELD_REL_X; 1336 mAccumulator.relX = rawEvent->value; 1337 break; 1338 case REL_Y: 1339 mAccumulator.fields |= Accumulator::FIELD_REL_Y; 1340 mAccumulator.relY = rawEvent->value; 1341 break; 1342 case REL_WHEEL: 1343 mAccumulator.fields |= Accumulator::FIELD_REL_WHEEL; 1344 mAccumulator.relWheel = rawEvent->value; 1345 break; 1346 case REL_HWHEEL: 1347 mAccumulator.fields |= Accumulator::FIELD_REL_HWHEEL; 1348 mAccumulator.relHWheel = rawEvent->value; 1349 break; 1350 } 1351 break; 1352 1353 case EV_SYN: 1354 switch (rawEvent->scanCode) { 1355 case SYN_REPORT: 1356 sync(rawEvent->when); 1357 break; 1358 } 1359 break; 1360 } 1361} 1362 1363void CursorInputMapper::sync(nsecs_t when) { 1364 uint32_t fields = mAccumulator.fields; 1365 if (fields == 0) { 1366 return; // no new state changes, so nothing to do 1367 } 1368 1369 int32_t motionEventAction; 1370 int32_t motionEventEdgeFlags; 1371 PointerCoords pointerCoords; 1372 nsecs_t downTime; 1373 float vscroll, hscroll; 1374 { // acquire lock 1375 AutoMutex _l(mLock); 1376 1377 bool down, downChanged; 1378 bool wasDown = isPointerDown(mLocked.buttonState); 1379 bool buttonsChanged = fields & Accumulator::FIELD_BUTTONS; 1380 if (buttonsChanged) { 1381 mLocked.buttonState = (mLocked.buttonState | mAccumulator.buttonDown) 1382 & ~mAccumulator.buttonUp; 1383 1384 down = isPointerDown(mLocked.buttonState); 1385 1386 if (!wasDown && down) { 1387 mLocked.downTime = when; 1388 downChanged = true; 1389 } else if (wasDown && !down) { 1390 downChanged = true; 1391 } else { 1392 downChanged = false; 1393 } 1394 } else { 1395 down = wasDown; 1396 downChanged = false; 1397 } 1398 1399 downTime = mLocked.downTime; 1400 float deltaX = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f; 1401 float deltaY = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f; 1402 1403 if (downChanged) { 1404 motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; 1405 } else if (down || mPointerController == NULL) { 1406 motionEventAction = AMOTION_EVENT_ACTION_MOVE; 1407 } else { 1408 motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE; 1409 } 1410 1411 if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0 1412 && (deltaX != 0.0f || deltaY != 0.0f)) { 1413 // Rotate motion based on display orientation if needed. 1414 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1415 int32_t orientation; 1416 if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 1417 NULL, NULL, & orientation)) { 1418 orientation = DISPLAY_ORIENTATION_0; 1419 } 1420 1421 float temp; 1422 switch (orientation) { 1423 case DISPLAY_ORIENTATION_90: 1424 temp = deltaX; 1425 deltaX = deltaY; 1426 deltaY = -temp; 1427 break; 1428 1429 case DISPLAY_ORIENTATION_180: 1430 deltaX = -deltaX; 1431 deltaY = -deltaY; 1432 break; 1433 1434 case DISPLAY_ORIENTATION_270: 1435 temp = deltaX; 1436 deltaX = -deltaY; 1437 deltaY = temp; 1438 break; 1439 } 1440 } 1441 1442 pointerCoords.clear(); 1443 1444 motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE; 1445 1446 if (mPointerController != NULL) { 1447 mPointerController->move(deltaX, deltaY); 1448 if (buttonsChanged) { 1449 mPointerController->setButtonState(mLocked.buttonState); 1450 } 1451 1452 float x, y; 1453 mPointerController->getPosition(&x, &y); 1454 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); 1455 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); 1456 1457 if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { 1458 motionEventEdgeFlags = calculateEdgeFlagsUsingPointerBounds( 1459 mPointerController, x, y); 1460 } 1461 } else { 1462 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); 1463 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY); 1464 } 1465 1466 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f); 1467 1468 if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) { 1469 vscroll = mAccumulator.relWheel; 1470 } else { 1471 vscroll = 0; 1472 } 1473 if (mHaveHWheel && (fields & Accumulator::FIELD_REL_HWHEEL)) { 1474 hscroll = mAccumulator.relHWheel; 1475 } else { 1476 hscroll = 0; 1477 } 1478 if (hscroll != 0 || vscroll != 0) { 1479 mPointerController->unfade(); 1480 } 1481 } // release lock 1482 1483 // Moving an external trackball or mouse should wake the device. 1484 // We don't do this for internal cursor devices to prevent them from waking up 1485 // the device in your pocket. 1486 // TODO: Use the input device configuration to control this behavior more finely. 1487 uint32_t policyFlags = 0; 1488 if (getDevice()->isExternal()) { 1489 policyFlags |= POLICY_FLAG_WAKE_DROPPED; 1490 } 1491 1492 int32_t metaState = mContext->getGlobalMetaState(); 1493 int32_t pointerId = 0; 1494 getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags, 1495 motionEventAction, 0, metaState, motionEventEdgeFlags, 1496 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime); 1497 1498 mAccumulator.clear(); 1499 1500 if (vscroll != 0 || hscroll != 0) { 1501 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll); 1502 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll); 1503 1504 getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags, 1505 AMOTION_EVENT_ACTION_SCROLL, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, 1506 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime); 1507 } 1508} 1509 1510int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 1511 if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) { 1512 return getEventHub()->getScanCodeState(getDeviceId(), scanCode); 1513 } else { 1514 return AKEY_STATE_UNKNOWN; 1515 } 1516} 1517 1518void CursorInputMapper::fadePointer() { 1519 { // acquire lock 1520 AutoMutex _l(mLock); 1521 if (mPointerController != NULL) { 1522 mPointerController->fade(); 1523 } 1524 } // release lock 1525} 1526 1527 1528// --- TouchInputMapper --- 1529 1530TouchInputMapper::TouchInputMapper(InputDevice* device) : 1531 InputMapper(device) { 1532 mLocked.surfaceOrientation = -1; 1533 mLocked.surfaceWidth = -1; 1534 mLocked.surfaceHeight = -1; 1535 1536 initializeLocked(); 1537} 1538 1539TouchInputMapper::~TouchInputMapper() { 1540} 1541 1542uint32_t TouchInputMapper::getSources() { 1543 return mTouchSource; 1544} 1545 1546void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1547 InputMapper::populateDeviceInfo(info); 1548 1549 { // acquire lock 1550 AutoMutex _l(mLock); 1551 1552 // Ensure surface information is up to date so that orientation changes are 1553 // noticed immediately. 1554 if (!configureSurfaceLocked()) { 1555 return; 1556 } 1557 1558 info->addMotionRange(mLocked.orientedRanges.x); 1559 info->addMotionRange(mLocked.orientedRanges.y); 1560 1561 if (mLocked.orientedRanges.havePressure) { 1562 info->addMotionRange(mLocked.orientedRanges.pressure); 1563 } 1564 1565 if (mLocked.orientedRanges.haveSize) { 1566 info->addMotionRange(mLocked.orientedRanges.size); 1567 } 1568 1569 if (mLocked.orientedRanges.haveTouchSize) { 1570 info->addMotionRange(mLocked.orientedRanges.touchMajor); 1571 info->addMotionRange(mLocked.orientedRanges.touchMinor); 1572 } 1573 1574 if (mLocked.orientedRanges.haveToolSize) { 1575 info->addMotionRange(mLocked.orientedRanges.toolMajor); 1576 info->addMotionRange(mLocked.orientedRanges.toolMinor); 1577 } 1578 1579 if (mLocked.orientedRanges.haveOrientation) { 1580 info->addMotionRange(mLocked.orientedRanges.orientation); 1581 } 1582 } // release lock 1583} 1584 1585void TouchInputMapper::dump(String8& dump) { 1586 { // acquire lock 1587 AutoMutex _l(mLock); 1588 dump.append(INDENT2 "Touch Input Mapper:\n"); 1589 dumpParameters(dump); 1590 dumpVirtualKeysLocked(dump); 1591 dumpRawAxes(dump); 1592 dumpCalibration(dump); 1593 dumpSurfaceLocked(dump); 1594 1595 dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n"); 1596 dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale); 1597 dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale); 1598 dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision); 1599 dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision); 1600 dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale); 1601 dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale); 1602 dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias); 1603 dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale); 1604 dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias); 1605 dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale); 1606 dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale); 1607 dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mLocked.orientationScale); 1608 1609 dump.appendFormat(INDENT3 "Last Touch:\n"); 1610 dump.appendFormat(INDENT4 "Pointer Count: %d\n", mLastTouch.pointerCount); 1611 } // release lock 1612} 1613 1614void TouchInputMapper::initializeLocked() { 1615 mCurrentTouch.clear(); 1616 mLastTouch.clear(); 1617 mDownTime = 0; 1618 1619 for (uint32_t i = 0; i < MAX_POINTERS; i++) { 1620 mAveragingTouchFilter.historyStart[i] = 0; 1621 mAveragingTouchFilter.historyEnd[i] = 0; 1622 } 1623 1624 mJumpyTouchFilter.jumpyPointsDropped = 0; 1625 1626 mLocked.currentVirtualKey.down = false; 1627 1628 mLocked.orientedRanges.havePressure = false; 1629 mLocked.orientedRanges.haveSize = false; 1630 mLocked.orientedRanges.haveTouchSize = false; 1631 mLocked.orientedRanges.haveToolSize = false; 1632 mLocked.orientedRanges.haveOrientation = false; 1633} 1634 1635void TouchInputMapper::configure() { 1636 InputMapper::configure(); 1637 1638 // Configure basic parameters. 1639 configureParameters(); 1640 1641 // Configure sources. 1642 switch (mParameters.deviceType) { 1643 case Parameters::DEVICE_TYPE_TOUCH_SCREEN: 1644 mTouchSource = AINPUT_SOURCE_TOUCHSCREEN; 1645 break; 1646 case Parameters::DEVICE_TYPE_TOUCH_PAD: 1647 mTouchSource = AINPUT_SOURCE_TOUCHPAD; 1648 break; 1649 default: 1650 assert(false); 1651 } 1652 1653 // Configure absolute axis information. 1654 configureRawAxes(); 1655 1656 // Prepare input device calibration. 1657 parseCalibration(); 1658 resolveCalibration(); 1659 1660 { // acquire lock 1661 AutoMutex _l(mLock); 1662 1663 // Configure surface dimensions and orientation. 1664 configureSurfaceLocked(); 1665 } // release lock 1666} 1667 1668void TouchInputMapper::configureParameters() { 1669 mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents(); 1670 mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents(); 1671 mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents(); 1672 mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime(); 1673 1674 String8 deviceTypeString; 1675 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD; 1676 if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"), 1677 deviceTypeString)) { 1678 if (deviceTypeString == "touchScreen") { 1679 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN; 1680 } else if (deviceTypeString == "touchPad") { 1681 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD; 1682 } else { 1683 LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string()); 1684 } 1685 } 1686 1687 mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; 1688 getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"), 1689 mParameters.orientationAware); 1690 1691 mParameters.associatedDisplayId = mParameters.orientationAware 1692 || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN 1693 ? 0 : -1; 1694} 1695 1696void TouchInputMapper::dumpParameters(String8& dump) { 1697 dump.append(INDENT3 "Parameters:\n"); 1698 1699 switch (mParameters.deviceType) { 1700 case Parameters::DEVICE_TYPE_TOUCH_SCREEN: 1701 dump.append(INDENT4 "DeviceType: touchScreen\n"); 1702 break; 1703 case Parameters::DEVICE_TYPE_TOUCH_PAD: 1704 dump.append(INDENT4 "DeviceType: touchPad\n"); 1705 break; 1706 default: 1707 assert(false); 1708 } 1709 1710 dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", 1711 mParameters.associatedDisplayId); 1712 dump.appendFormat(INDENT4 "OrientationAware: %s\n", 1713 toString(mParameters.orientationAware)); 1714 1715 dump.appendFormat(INDENT4 "UseBadTouchFilter: %s\n", 1716 toString(mParameters.useBadTouchFilter)); 1717 dump.appendFormat(INDENT4 "UseAveragingTouchFilter: %s\n", 1718 toString(mParameters.useAveragingTouchFilter)); 1719 dump.appendFormat(INDENT4 "UseJumpyTouchFilter: %s\n", 1720 toString(mParameters.useJumpyTouchFilter)); 1721} 1722 1723void TouchInputMapper::configureRawAxes() { 1724 mRawAxes.x.clear(); 1725 mRawAxes.y.clear(); 1726 mRawAxes.pressure.clear(); 1727 mRawAxes.touchMajor.clear(); 1728 mRawAxes.touchMinor.clear(); 1729 mRawAxes.toolMajor.clear(); 1730 mRawAxes.toolMinor.clear(); 1731 mRawAxes.orientation.clear(); 1732} 1733 1734void TouchInputMapper::dumpRawAxes(String8& dump) { 1735 dump.append(INDENT3 "Raw Axes:\n"); 1736 dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X"); 1737 dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y"); 1738 dumpRawAbsoluteAxisInfo(dump, mRawAxes.pressure, "Pressure"); 1739 dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor"); 1740 dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor"); 1741 dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor"); 1742 dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor"); 1743 dumpRawAbsoluteAxisInfo(dump, mRawAxes.orientation, "Orientation"); 1744} 1745 1746bool TouchInputMapper::configureSurfaceLocked() { 1747 // Ensure we have valid X and Y axes. 1748 if (!mRawAxes.x.valid || !mRawAxes.y.valid) { 1749 LOGW(INDENT "Touch device '%s' did not report support for X or Y axis! " 1750 "The device will be inoperable.", getDeviceName().string()); 1751 return false; 1752 } 1753 1754 // Update orientation and dimensions if needed. 1755 int32_t orientation = DISPLAY_ORIENTATION_0; 1756 int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; 1757 int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; 1758 1759 if (mParameters.associatedDisplayId >= 0) { 1760 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1761 if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 1762 &mLocked.associatedDisplayWidth, &mLocked.associatedDisplayHeight, 1763 &mLocked.associatedDisplayOrientation)) { 1764 return false; 1765 } 1766 1767 // A touch screen inherits the dimensions of the display. 1768 if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) { 1769 width = mLocked.associatedDisplayWidth; 1770 height = mLocked.associatedDisplayHeight; 1771 } 1772 1773 // The device inherits the orientation of the display if it is orientation aware. 1774 if (mParameters.orientationAware) { 1775 orientation = mLocked.associatedDisplayOrientation; 1776 } 1777 } 1778 1779 bool orientationChanged = mLocked.surfaceOrientation != orientation; 1780 if (orientationChanged) { 1781 mLocked.surfaceOrientation = orientation; 1782 } 1783 1784 bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height; 1785 if (sizeChanged) { 1786 LOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d", 1787 getDeviceId(), getDeviceName().string(), width, height); 1788 1789 mLocked.surfaceWidth = width; 1790 mLocked.surfaceHeight = height; 1791 1792 // Configure X and Y factors. 1793 mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1); 1794 mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1); 1795 mLocked.xPrecision = 1.0f / mLocked.xScale; 1796 mLocked.yPrecision = 1.0f / mLocked.yScale; 1797 1798 mLocked.orientedRanges.x.axis = AMOTION_EVENT_AXIS_X; 1799 mLocked.orientedRanges.x.source = mTouchSource; 1800 mLocked.orientedRanges.y.axis = AMOTION_EVENT_AXIS_Y; 1801 mLocked.orientedRanges.y.source = mTouchSource; 1802 1803 configureVirtualKeysLocked(); 1804 1805 // Scale factor for terms that are not oriented in a particular axis. 1806 // If the pixels are square then xScale == yScale otherwise we fake it 1807 // by choosing an average. 1808 mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale); 1809 1810 // Size of diagonal axis. 1811 float diagonalSize = pythag(width, height); 1812 1813 // TouchMajor and TouchMinor factors. 1814 if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) { 1815 mLocked.orientedRanges.haveTouchSize = true; 1816 1817 mLocked.orientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR; 1818 mLocked.orientedRanges.touchMajor.source = mTouchSource; 1819 mLocked.orientedRanges.touchMajor.min = 0; 1820 mLocked.orientedRanges.touchMajor.max = diagonalSize; 1821 mLocked.orientedRanges.touchMajor.flat = 0; 1822 mLocked.orientedRanges.touchMajor.fuzz = 0; 1823 1824 mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor; 1825 mLocked.orientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR; 1826 } 1827 1828 // ToolMajor and ToolMinor factors. 1829 mLocked.toolSizeLinearScale = 0; 1830 mLocked.toolSizeLinearBias = 0; 1831 mLocked.toolSizeAreaScale = 0; 1832 mLocked.toolSizeAreaBias = 0; 1833 if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 1834 if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) { 1835 if (mCalibration.haveToolSizeLinearScale) { 1836 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 1837 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1838 mLocked.toolSizeLinearScale = float(min(width, height)) 1839 / mRawAxes.toolMajor.maxValue; 1840 } 1841 1842 if (mCalibration.haveToolSizeLinearBias) { 1843 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 1844 } 1845 } else if (mCalibration.toolSizeCalibration == 1846 Calibration::TOOL_SIZE_CALIBRATION_AREA) { 1847 if (mCalibration.haveToolSizeLinearScale) { 1848 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 1849 } else { 1850 mLocked.toolSizeLinearScale = min(width, height); 1851 } 1852 1853 if (mCalibration.haveToolSizeLinearBias) { 1854 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 1855 } 1856 1857 if (mCalibration.haveToolSizeAreaScale) { 1858 mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale; 1859 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1860 mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue; 1861 } 1862 1863 if (mCalibration.haveToolSizeAreaBias) { 1864 mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias; 1865 } 1866 } 1867 1868 mLocked.orientedRanges.haveToolSize = true; 1869 1870 mLocked.orientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR; 1871 mLocked.orientedRanges.toolMajor.source = mTouchSource; 1872 mLocked.orientedRanges.toolMajor.min = 0; 1873 mLocked.orientedRanges.toolMajor.max = diagonalSize; 1874 mLocked.orientedRanges.toolMajor.flat = 0; 1875 mLocked.orientedRanges.toolMajor.fuzz = 0; 1876 1877 mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor; 1878 mLocked.orientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR; 1879 } 1880 1881 // Pressure factors. 1882 mLocked.pressureScale = 0; 1883 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) { 1884 RawAbsoluteAxisInfo rawPressureAxis; 1885 switch (mCalibration.pressureSource) { 1886 case Calibration::PRESSURE_SOURCE_PRESSURE: 1887 rawPressureAxis = mRawAxes.pressure; 1888 break; 1889 case Calibration::PRESSURE_SOURCE_TOUCH: 1890 rawPressureAxis = mRawAxes.touchMajor; 1891 break; 1892 default: 1893 rawPressureAxis.clear(); 1894 } 1895 1896 if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL 1897 || mCalibration.pressureCalibration 1898 == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) { 1899 if (mCalibration.havePressureScale) { 1900 mLocked.pressureScale = mCalibration.pressureScale; 1901 } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) { 1902 mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue; 1903 } 1904 } 1905 1906 mLocked.orientedRanges.havePressure = true; 1907 1908 mLocked.orientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE; 1909 mLocked.orientedRanges.pressure.source = mTouchSource; 1910 mLocked.orientedRanges.pressure.min = 0; 1911 mLocked.orientedRanges.pressure.max = 1.0; 1912 mLocked.orientedRanges.pressure.flat = 0; 1913 mLocked.orientedRanges.pressure.fuzz = 0; 1914 } 1915 1916 // Size factors. 1917 mLocked.sizeScale = 0; 1918 if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) { 1919 if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) { 1920 if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1921 mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue; 1922 } 1923 } 1924 1925 mLocked.orientedRanges.haveSize = true; 1926 1927 mLocked.orientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE; 1928 mLocked.orientedRanges.size.source = mTouchSource; 1929 mLocked.orientedRanges.size.min = 0; 1930 mLocked.orientedRanges.size.max = 1.0; 1931 mLocked.orientedRanges.size.flat = 0; 1932 mLocked.orientedRanges.size.fuzz = 0; 1933 } 1934 1935 // Orientation 1936 mLocked.orientationScale = 0; 1937 if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) { 1938 if (mCalibration.orientationCalibration 1939 == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) { 1940 if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) { 1941 mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue; 1942 } 1943 } 1944 1945 mLocked.orientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION; 1946 mLocked.orientedRanges.orientation.source = mTouchSource; 1947 mLocked.orientedRanges.orientation.min = - M_PI_2; 1948 mLocked.orientedRanges.orientation.max = M_PI_2; 1949 mLocked.orientedRanges.orientation.flat = 0; 1950 mLocked.orientedRanges.orientation.fuzz = 0; 1951 } 1952 } 1953 1954 if (orientationChanged || sizeChanged) { 1955 // Compute oriented surface dimensions, precision, scales and ranges. 1956 // Note that the maximum value reported is an inclusive maximum value so it is one 1957 // unit less than the total width or height of surface. 1958 switch (mLocked.surfaceOrientation) { 1959 case DISPLAY_ORIENTATION_90: 1960 case DISPLAY_ORIENTATION_270: 1961 mLocked.orientedSurfaceWidth = mLocked.surfaceHeight; 1962 mLocked.orientedSurfaceHeight = mLocked.surfaceWidth; 1963 1964 mLocked.orientedXPrecision = mLocked.yPrecision; 1965 mLocked.orientedYPrecision = mLocked.xPrecision; 1966 1967 mLocked.orientedRanges.x.min = 0; 1968 mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) 1969 * mLocked.yScale; 1970 mLocked.orientedRanges.x.flat = 0; 1971 mLocked.orientedRanges.x.fuzz = mLocked.yScale; 1972 1973 mLocked.orientedRanges.y.min = 0; 1974 mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) 1975 * mLocked.xScale; 1976 mLocked.orientedRanges.y.flat = 0; 1977 mLocked.orientedRanges.y.fuzz = mLocked.xScale; 1978 break; 1979 1980 default: 1981 mLocked.orientedSurfaceWidth = mLocked.surfaceWidth; 1982 mLocked.orientedSurfaceHeight = mLocked.surfaceHeight; 1983 1984 mLocked.orientedXPrecision = mLocked.xPrecision; 1985 mLocked.orientedYPrecision = mLocked.yPrecision; 1986 1987 mLocked.orientedRanges.x.min = 0; 1988 mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue) 1989 * mLocked.xScale; 1990 mLocked.orientedRanges.x.flat = 0; 1991 mLocked.orientedRanges.x.fuzz = mLocked.xScale; 1992 1993 mLocked.orientedRanges.y.min = 0; 1994 mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue) 1995 * mLocked.yScale; 1996 mLocked.orientedRanges.y.flat = 0; 1997 mLocked.orientedRanges.y.fuzz = mLocked.yScale; 1998 break; 1999 } 2000 } 2001 2002 return true; 2003} 2004 2005void TouchInputMapper::dumpSurfaceLocked(String8& dump) { 2006 dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth); 2007 dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight); 2008 dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation); 2009} 2010 2011void TouchInputMapper::configureVirtualKeysLocked() { 2012 Vector<VirtualKeyDefinition> virtualKeyDefinitions; 2013 getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions); 2014 2015 mLocked.virtualKeys.clear(); 2016 2017 if (virtualKeyDefinitions.size() == 0) { 2018 return; 2019 } 2020 2021 mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size()); 2022 2023 int32_t touchScreenLeft = mRawAxes.x.minValue; 2024 int32_t touchScreenTop = mRawAxes.y.minValue; 2025 int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1; 2026 int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1; 2027 2028 for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) { 2029 const VirtualKeyDefinition& virtualKeyDefinition = 2030 virtualKeyDefinitions[i]; 2031 2032 mLocked.virtualKeys.add(); 2033 VirtualKey& virtualKey = mLocked.virtualKeys.editTop(); 2034 2035 virtualKey.scanCode = virtualKeyDefinition.scanCode; 2036 int32_t keyCode; 2037 uint32_t flags; 2038 if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 2039 & keyCode, & flags)) { 2040 LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", 2041 virtualKey.scanCode); 2042 mLocked.virtualKeys.pop(); // drop the key 2043 continue; 2044 } 2045 2046 virtualKey.keyCode = keyCode; 2047 virtualKey.flags = flags; 2048 2049 // convert the key definition's display coordinates into touch coordinates for a hit box 2050 int32_t halfWidth = virtualKeyDefinition.width / 2; 2051 int32_t halfHeight = virtualKeyDefinition.height / 2; 2052 2053 virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth) 2054 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 2055 virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth) 2056 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 2057 virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight) 2058 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 2059 virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) 2060 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 2061 } 2062} 2063 2064void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) { 2065 if (!mLocked.virtualKeys.isEmpty()) { 2066 dump.append(INDENT3 "Virtual Keys:\n"); 2067 2068 for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) { 2069 const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i); 2070 dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, " 2071 "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n", 2072 i, virtualKey.scanCode, virtualKey.keyCode, 2073 virtualKey.hitLeft, virtualKey.hitRight, 2074 virtualKey.hitTop, virtualKey.hitBottom); 2075 } 2076 } 2077} 2078 2079void TouchInputMapper::parseCalibration() { 2080 const PropertyMap& in = getDevice()->getConfiguration(); 2081 Calibration& out = mCalibration; 2082 2083 // Touch Size 2084 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT; 2085 String8 touchSizeCalibrationString; 2086 if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) { 2087 if (touchSizeCalibrationString == "none") { 2088 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 2089 } else if (touchSizeCalibrationString == "geometric") { 2090 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC; 2091 } else if (touchSizeCalibrationString == "pressure") { 2092 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 2093 } else if (touchSizeCalibrationString != "default") { 2094 LOGW("Invalid value for touch.touchSize.calibration: '%s'", 2095 touchSizeCalibrationString.string()); 2096 } 2097 } 2098 2099 // Tool Size 2100 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT; 2101 String8 toolSizeCalibrationString; 2102 if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) { 2103 if (toolSizeCalibrationString == "none") { 2104 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 2105 } else if (toolSizeCalibrationString == "geometric") { 2106 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC; 2107 } else if (toolSizeCalibrationString == "linear") { 2108 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 2109 } else if (toolSizeCalibrationString == "area") { 2110 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA; 2111 } else if (toolSizeCalibrationString != "default") { 2112 LOGW("Invalid value for touch.toolSize.calibration: '%s'", 2113 toolSizeCalibrationString.string()); 2114 } 2115 } 2116 2117 out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"), 2118 out.toolSizeLinearScale); 2119 out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"), 2120 out.toolSizeLinearBias); 2121 out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"), 2122 out.toolSizeAreaScale); 2123 out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"), 2124 out.toolSizeAreaBias); 2125 out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"), 2126 out.toolSizeIsSummed); 2127 2128 // Pressure 2129 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT; 2130 String8 pressureCalibrationString; 2131 if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) { 2132 if (pressureCalibrationString == "none") { 2133 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 2134 } else if (pressureCalibrationString == "physical") { 2135 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL; 2136 } else if (pressureCalibrationString == "amplitude") { 2137 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 2138 } else if (pressureCalibrationString != "default") { 2139 LOGW("Invalid value for touch.pressure.calibration: '%s'", 2140 pressureCalibrationString.string()); 2141 } 2142 } 2143 2144 out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT; 2145 String8 pressureSourceString; 2146 if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) { 2147 if (pressureSourceString == "pressure") { 2148 out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 2149 } else if (pressureSourceString == "touch") { 2150 out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 2151 } else if (pressureSourceString != "default") { 2152 LOGW("Invalid value for touch.pressure.source: '%s'", 2153 pressureSourceString.string()); 2154 } 2155 } 2156 2157 out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"), 2158 out.pressureScale); 2159 2160 // Size 2161 out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT; 2162 String8 sizeCalibrationString; 2163 if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) { 2164 if (sizeCalibrationString == "none") { 2165 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 2166 } else if (sizeCalibrationString == "normalized") { 2167 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 2168 } else if (sizeCalibrationString != "default") { 2169 LOGW("Invalid value for touch.size.calibration: '%s'", 2170 sizeCalibrationString.string()); 2171 } 2172 } 2173 2174 // Orientation 2175 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT; 2176 String8 orientationCalibrationString; 2177 if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) { 2178 if (orientationCalibrationString == "none") { 2179 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 2180 } else if (orientationCalibrationString == "interpolated") { 2181 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 2182 } else if (orientationCalibrationString == "vector") { 2183 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR; 2184 } else if (orientationCalibrationString != "default") { 2185 LOGW("Invalid value for touch.orientation.calibration: '%s'", 2186 orientationCalibrationString.string()); 2187 } 2188 } 2189} 2190 2191void TouchInputMapper::resolveCalibration() { 2192 // Pressure 2193 switch (mCalibration.pressureSource) { 2194 case Calibration::PRESSURE_SOURCE_DEFAULT: 2195 if (mRawAxes.pressure.valid) { 2196 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 2197 } else if (mRawAxes.touchMajor.valid) { 2198 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 2199 } 2200 break; 2201 2202 case Calibration::PRESSURE_SOURCE_PRESSURE: 2203 if (! mRawAxes.pressure.valid) { 2204 LOGW("Calibration property touch.pressure.source is 'pressure' but " 2205 "the pressure axis is not available."); 2206 } 2207 break; 2208 2209 case Calibration::PRESSURE_SOURCE_TOUCH: 2210 if (! mRawAxes.touchMajor.valid) { 2211 LOGW("Calibration property touch.pressure.source is 'touch' but " 2212 "the touchMajor axis is not available."); 2213 } 2214 break; 2215 2216 default: 2217 break; 2218 } 2219 2220 switch (mCalibration.pressureCalibration) { 2221 case Calibration::PRESSURE_CALIBRATION_DEFAULT: 2222 if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) { 2223 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 2224 } else { 2225 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 2226 } 2227 break; 2228 2229 default: 2230 break; 2231 } 2232 2233 // Tool Size 2234 switch (mCalibration.toolSizeCalibration) { 2235 case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT: 2236 if (mRawAxes.toolMajor.valid) { 2237 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 2238 } else { 2239 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 2240 } 2241 break; 2242 2243 default: 2244 break; 2245 } 2246 2247 // Touch Size 2248 switch (mCalibration.touchSizeCalibration) { 2249 case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT: 2250 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE 2251 && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 2252 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 2253 } else { 2254 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 2255 } 2256 break; 2257 2258 default: 2259 break; 2260 } 2261 2262 // Size 2263 switch (mCalibration.sizeCalibration) { 2264 case Calibration::SIZE_CALIBRATION_DEFAULT: 2265 if (mRawAxes.toolMajor.valid) { 2266 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 2267 } else { 2268 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 2269 } 2270 break; 2271 2272 default: 2273 break; 2274 } 2275 2276 // Orientation 2277 switch (mCalibration.orientationCalibration) { 2278 case Calibration::ORIENTATION_CALIBRATION_DEFAULT: 2279 if (mRawAxes.orientation.valid) { 2280 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 2281 } else { 2282 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 2283 } 2284 break; 2285 2286 default: 2287 break; 2288 } 2289} 2290 2291void TouchInputMapper::dumpCalibration(String8& dump) { 2292 dump.append(INDENT3 "Calibration:\n"); 2293 2294 // Touch Size 2295 switch (mCalibration.touchSizeCalibration) { 2296 case Calibration::TOUCH_SIZE_CALIBRATION_NONE: 2297 dump.append(INDENT4 "touch.touchSize.calibration: none\n"); 2298 break; 2299 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 2300 dump.append(INDENT4 "touch.touchSize.calibration: geometric\n"); 2301 break; 2302 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 2303 dump.append(INDENT4 "touch.touchSize.calibration: pressure\n"); 2304 break; 2305 default: 2306 assert(false); 2307 } 2308 2309 // Tool Size 2310 switch (mCalibration.toolSizeCalibration) { 2311 case Calibration::TOOL_SIZE_CALIBRATION_NONE: 2312 dump.append(INDENT4 "touch.toolSize.calibration: none\n"); 2313 break; 2314 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 2315 dump.append(INDENT4 "touch.toolSize.calibration: geometric\n"); 2316 break; 2317 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 2318 dump.append(INDENT4 "touch.toolSize.calibration: linear\n"); 2319 break; 2320 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 2321 dump.append(INDENT4 "touch.toolSize.calibration: area\n"); 2322 break; 2323 default: 2324 assert(false); 2325 } 2326 2327 if (mCalibration.haveToolSizeLinearScale) { 2328 dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n", 2329 mCalibration.toolSizeLinearScale); 2330 } 2331 2332 if (mCalibration.haveToolSizeLinearBias) { 2333 dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n", 2334 mCalibration.toolSizeLinearBias); 2335 } 2336 2337 if (mCalibration.haveToolSizeAreaScale) { 2338 dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n", 2339 mCalibration.toolSizeAreaScale); 2340 } 2341 2342 if (mCalibration.haveToolSizeAreaBias) { 2343 dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n", 2344 mCalibration.toolSizeAreaBias); 2345 } 2346 2347 if (mCalibration.haveToolSizeIsSummed) { 2348 dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %s\n", 2349 toString(mCalibration.toolSizeIsSummed)); 2350 } 2351 2352 // Pressure 2353 switch (mCalibration.pressureCalibration) { 2354 case Calibration::PRESSURE_CALIBRATION_NONE: 2355 dump.append(INDENT4 "touch.pressure.calibration: none\n"); 2356 break; 2357 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 2358 dump.append(INDENT4 "touch.pressure.calibration: physical\n"); 2359 break; 2360 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 2361 dump.append(INDENT4 "touch.pressure.calibration: amplitude\n"); 2362 break; 2363 default: 2364 assert(false); 2365 } 2366 2367 switch (mCalibration.pressureSource) { 2368 case Calibration::PRESSURE_SOURCE_PRESSURE: 2369 dump.append(INDENT4 "touch.pressure.source: pressure\n"); 2370 break; 2371 case Calibration::PRESSURE_SOURCE_TOUCH: 2372 dump.append(INDENT4 "touch.pressure.source: touch\n"); 2373 break; 2374 case Calibration::PRESSURE_SOURCE_DEFAULT: 2375 break; 2376 default: 2377 assert(false); 2378 } 2379 2380 if (mCalibration.havePressureScale) { 2381 dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n", 2382 mCalibration.pressureScale); 2383 } 2384 2385 // Size 2386 switch (mCalibration.sizeCalibration) { 2387 case Calibration::SIZE_CALIBRATION_NONE: 2388 dump.append(INDENT4 "touch.size.calibration: none\n"); 2389 break; 2390 case Calibration::SIZE_CALIBRATION_NORMALIZED: 2391 dump.append(INDENT4 "touch.size.calibration: normalized\n"); 2392 break; 2393 default: 2394 assert(false); 2395 } 2396 2397 // Orientation 2398 switch (mCalibration.orientationCalibration) { 2399 case Calibration::ORIENTATION_CALIBRATION_NONE: 2400 dump.append(INDENT4 "touch.orientation.calibration: none\n"); 2401 break; 2402 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 2403 dump.append(INDENT4 "touch.orientation.calibration: interpolated\n"); 2404 break; 2405 case Calibration::ORIENTATION_CALIBRATION_VECTOR: 2406 dump.append(INDENT4 "touch.orientation.calibration: vector\n"); 2407 break; 2408 default: 2409 assert(false); 2410 } 2411} 2412 2413void TouchInputMapper::reset() { 2414 // Synthesize touch up event if touch is currently down. 2415 // This will also take care of finishing virtual key processing if needed. 2416 if (mLastTouch.pointerCount != 0) { 2417 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 2418 mCurrentTouch.clear(); 2419 syncTouch(when, true); 2420 } 2421 2422 { // acquire lock 2423 AutoMutex _l(mLock); 2424 initializeLocked(); 2425 } // release lock 2426 2427 InputMapper::reset(); 2428} 2429 2430void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { 2431 // Preprocess pointer data. 2432 if (mParameters.useBadTouchFilter) { 2433 if (applyBadTouchFilter()) { 2434 havePointerIds = false; 2435 } 2436 } 2437 2438 if (mParameters.useJumpyTouchFilter) { 2439 if (applyJumpyTouchFilter()) { 2440 havePointerIds = false; 2441 } 2442 } 2443 2444 if (! havePointerIds) { 2445 calculatePointerIds(); 2446 } 2447 2448 TouchData temp; 2449 TouchData* savedTouch; 2450 if (mParameters.useAveragingTouchFilter) { 2451 temp.copyFrom(mCurrentTouch); 2452 savedTouch = & temp; 2453 2454 applyAveragingTouchFilter(); 2455 } else { 2456 savedTouch = & mCurrentTouch; 2457 } 2458 2459 uint32_t policyFlags = 0; 2460 if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) { 2461 if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) { 2462 // If this is a touch screen, hide the pointer on an initial down. 2463 getContext()->fadePointer(); 2464 } 2465 2466 // Initial downs on external touch devices should wake the device. 2467 // We don't do this for internal touch screens to prevent them from waking 2468 // up in your pocket. 2469 // TODO: Use the input device configuration to control this behavior more finely. 2470 if (getDevice()->isExternal()) { 2471 policyFlags |= POLICY_FLAG_WAKE_DROPPED; 2472 } 2473 } 2474 2475 // Process touches and virtual keys. 2476 TouchResult touchResult = consumeOffScreenTouches(when, policyFlags); 2477 if (touchResult == DISPATCH_TOUCH) { 2478 suppressSwipeOntoVirtualKeys(when); 2479 dispatchTouches(when, policyFlags); 2480 } 2481 2482 // Copy current touch to last touch in preparation for the next cycle. 2483 if (touchResult == DROP_STROKE) { 2484 mLastTouch.clear(); 2485 } else { 2486 mLastTouch.copyFrom(*savedTouch); 2487 } 2488} 2489 2490TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches( 2491 nsecs_t when, uint32_t policyFlags) { 2492 int32_t keyEventAction, keyEventFlags; 2493 int32_t keyCode, scanCode, downTime; 2494 TouchResult touchResult; 2495 2496 { // acquire lock 2497 AutoMutex _l(mLock); 2498 2499 // Update surface size and orientation, including virtual key positions. 2500 if (! configureSurfaceLocked()) { 2501 return DROP_STROKE; 2502 } 2503 2504 // Check for virtual key press. 2505 if (mLocked.currentVirtualKey.down) { 2506 if (mCurrentTouch.pointerCount == 0) { 2507 // Pointer went up while virtual key was down. 2508 mLocked.currentVirtualKey.down = false; 2509#if DEBUG_VIRTUAL_KEYS 2510 LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d", 2511 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 2512#endif 2513 keyEventAction = AKEY_EVENT_ACTION_UP; 2514 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 2515 touchResult = SKIP_TOUCH; 2516 goto DispatchVirtualKey; 2517 } 2518 2519 if (mCurrentTouch.pointerCount == 1) { 2520 int32_t x = mCurrentTouch.pointers[0].x; 2521 int32_t y = mCurrentTouch.pointers[0].y; 2522 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 2523 if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) { 2524 // Pointer is still within the space of the virtual key. 2525 return SKIP_TOUCH; 2526 } 2527 } 2528 2529 // Pointer left virtual key area or another pointer also went down. 2530 // Send key cancellation and drop the stroke so subsequent motions will be 2531 // considered fresh downs. This is useful when the user swipes away from the 2532 // virtual key area into the main display surface. 2533 mLocked.currentVirtualKey.down = false; 2534#if DEBUG_VIRTUAL_KEYS 2535 LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d", 2536 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 2537#endif 2538 keyEventAction = AKEY_EVENT_ACTION_UP; 2539 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY 2540 | AKEY_EVENT_FLAG_CANCELED; 2541 2542 // Check whether the pointer moved inside the display area where we should 2543 // start a new stroke. 2544 int32_t x = mCurrentTouch.pointers[0].x; 2545 int32_t y = mCurrentTouch.pointers[0].y; 2546 if (isPointInsideSurfaceLocked(x, y)) { 2547 mLastTouch.clear(); 2548 touchResult = DISPATCH_TOUCH; 2549 } else { 2550 touchResult = DROP_STROKE; 2551 } 2552 } else { 2553 if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) { 2554 // Pointer just went down. Handle off-screen touches, if needed. 2555 int32_t x = mCurrentTouch.pointers[0].x; 2556 int32_t y = mCurrentTouch.pointers[0].y; 2557 if (! isPointInsideSurfaceLocked(x, y)) { 2558 // If exactly one pointer went down, check for virtual key hit. 2559 // Otherwise we will drop the entire stroke. 2560 if (mCurrentTouch.pointerCount == 1) { 2561 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 2562 if (virtualKey) { 2563 if (mContext->shouldDropVirtualKey(when, getDevice(), 2564 virtualKey->keyCode, virtualKey->scanCode)) { 2565 return DROP_STROKE; 2566 } 2567 2568 mLocked.currentVirtualKey.down = true; 2569 mLocked.currentVirtualKey.downTime = when; 2570 mLocked.currentVirtualKey.keyCode = virtualKey->keyCode; 2571 mLocked.currentVirtualKey.scanCode = virtualKey->scanCode; 2572#if DEBUG_VIRTUAL_KEYS 2573 LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d", 2574 mLocked.currentVirtualKey.keyCode, 2575 mLocked.currentVirtualKey.scanCode); 2576#endif 2577 keyEventAction = AKEY_EVENT_ACTION_DOWN; 2578 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM 2579 | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 2580 touchResult = SKIP_TOUCH; 2581 goto DispatchVirtualKey; 2582 } 2583 } 2584 return DROP_STROKE; 2585 } 2586 } 2587 return DISPATCH_TOUCH; 2588 } 2589 2590 DispatchVirtualKey: 2591 // Collect remaining state needed to dispatch virtual key. 2592 keyCode = mLocked.currentVirtualKey.keyCode; 2593 scanCode = mLocked.currentVirtualKey.scanCode; 2594 downTime = mLocked.currentVirtualKey.downTime; 2595 } // release lock 2596 2597 // Dispatch virtual key. 2598 int32_t metaState = mContext->getGlobalMetaState(); 2599 policyFlags |= POLICY_FLAG_VIRTUAL; 2600 getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags, 2601 keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime); 2602 return touchResult; 2603} 2604 2605void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) { 2606 // Disable all virtual key touches that happen within a short time interval of the 2607 // most recent touch. The idea is to filter out stray virtual key presses when 2608 // interacting with the touch screen. 2609 // 2610 // Problems we're trying to solve: 2611 // 2612 // 1. While scrolling a list or dragging the window shade, the user swipes down into a 2613 // virtual key area that is implemented by a separate touch panel and accidentally 2614 // triggers a virtual key. 2615 // 2616 // 2. While typing in the on screen keyboard, the user taps slightly outside the screen 2617 // area and accidentally triggers a virtual key. This often happens when virtual keys 2618 // are layed out below the screen near to where the on screen keyboard's space bar 2619 // is displayed. 2620 if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) { 2621 mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime); 2622 } 2623} 2624 2625void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) { 2626 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 2627 uint32_t lastPointerCount = mLastTouch.pointerCount; 2628 if (currentPointerCount == 0 && lastPointerCount == 0) { 2629 return; // nothing to do! 2630 } 2631 2632 BitSet32 currentIdBits = mCurrentTouch.idBits; 2633 BitSet32 lastIdBits = mLastTouch.idBits; 2634 2635 if (currentIdBits == lastIdBits) { 2636 // No pointer id changes so this is a move event. 2637 // The dispatcher takes care of batching moves so we don't have to deal with that here. 2638 int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE; 2639 dispatchTouch(when, policyFlags, & mCurrentTouch, 2640 currentIdBits, -1, currentPointerCount, motionEventAction); 2641 } else { 2642 // There may be pointers going up and pointers going down and pointers moving 2643 // all at the same time. 2644 BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value); 2645 BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value); 2646 BitSet32 activeIdBits(lastIdBits.value); 2647 uint32_t pointerCount = lastPointerCount; 2648 2649 // Produce an intermediate representation of the touch data that consists of the 2650 // old location of pointers that have just gone up and the new location of pointers that 2651 // have just moved but omits the location of pointers that have just gone down. 2652 TouchData interimTouch; 2653 interimTouch.copyFrom(mLastTouch); 2654 2655 BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value); 2656 bool moveNeeded = false; 2657 while (!moveIdBits.isEmpty()) { 2658 uint32_t moveId = moveIdBits.firstMarkedBit(); 2659 moveIdBits.clearBit(moveId); 2660 2661 int32_t oldIndex = mLastTouch.idToIndex[moveId]; 2662 int32_t newIndex = mCurrentTouch.idToIndex[moveId]; 2663 if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) { 2664 interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex]; 2665 moveNeeded = true; 2666 } 2667 } 2668 2669 // Dispatch pointer up events using the interim pointer locations. 2670 while (!upIdBits.isEmpty()) { 2671 uint32_t upId = upIdBits.firstMarkedBit(); 2672 upIdBits.clearBit(upId); 2673 BitSet32 oldActiveIdBits = activeIdBits; 2674 activeIdBits.clearBit(upId); 2675 2676 int32_t motionEventAction; 2677 if (activeIdBits.isEmpty()) { 2678 motionEventAction = AMOTION_EVENT_ACTION_UP; 2679 } else { 2680 motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP; 2681 } 2682 2683 dispatchTouch(when, policyFlags, &interimTouch, 2684 oldActiveIdBits, upId, pointerCount, motionEventAction); 2685 pointerCount -= 1; 2686 } 2687 2688 // Dispatch move events if any of the remaining pointers moved from their old locations. 2689 // Although applications receive new locations as part of individual pointer up 2690 // events, they do not generally handle them except when presented in a move event. 2691 if (moveNeeded) { 2692 dispatchTouch(when, policyFlags, &mCurrentTouch, 2693 activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE); 2694 } 2695 2696 // Dispatch pointer down events using the new pointer locations. 2697 while (!downIdBits.isEmpty()) { 2698 uint32_t downId = downIdBits.firstMarkedBit(); 2699 downIdBits.clearBit(downId); 2700 BitSet32 oldActiveIdBits = activeIdBits; 2701 activeIdBits.markBit(downId); 2702 2703 int32_t motionEventAction; 2704 if (oldActiveIdBits.isEmpty()) { 2705 motionEventAction = AMOTION_EVENT_ACTION_DOWN; 2706 mDownTime = when; 2707 } else { 2708 motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN; 2709 } 2710 2711 pointerCount += 1; 2712 dispatchTouch(when, policyFlags, &mCurrentTouch, 2713 activeIdBits, downId, pointerCount, motionEventAction); 2714 } 2715 } 2716} 2717 2718void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, 2719 TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount, 2720 int32_t motionEventAction) { 2721 int32_t pointerIds[MAX_POINTERS]; 2722 PointerCoords pointerCoords[MAX_POINTERS]; 2723 int32_t motionEventEdgeFlags = AMOTION_EVENT_EDGE_FLAG_NONE; 2724 float xPrecision, yPrecision; 2725 2726 { // acquire lock 2727 AutoMutex _l(mLock); 2728 2729 // Walk through the the active pointers and map touch screen coordinates (TouchData) into 2730 // display or surface coordinates (PointerCoords) and adjust for display orientation. 2731 for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) { 2732 uint32_t id = idBits.firstMarkedBit(); 2733 idBits.clearBit(id); 2734 uint32_t inIndex = touch->idToIndex[id]; 2735 2736 const PointerData& in = touch->pointers[inIndex]; 2737 2738 // ToolMajor and ToolMinor 2739 float toolMajor, toolMinor; 2740 switch (mCalibration.toolSizeCalibration) { 2741 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 2742 toolMajor = in.toolMajor * mLocked.geometricScale; 2743 if (mRawAxes.toolMinor.valid) { 2744 toolMinor = in.toolMinor * mLocked.geometricScale; 2745 } else { 2746 toolMinor = toolMajor; 2747 } 2748 break; 2749 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 2750 toolMajor = in.toolMajor != 0 2751 ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias 2752 : 0; 2753 if (mRawAxes.toolMinor.valid) { 2754 toolMinor = in.toolMinor != 0 2755 ? in.toolMinor * mLocked.toolSizeLinearScale 2756 + mLocked.toolSizeLinearBias 2757 : 0; 2758 } else { 2759 toolMinor = toolMajor; 2760 } 2761 break; 2762 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 2763 if (in.toolMajor != 0) { 2764 float diameter = sqrtf(in.toolMajor 2765 * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias); 2766 toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias; 2767 } else { 2768 toolMajor = 0; 2769 } 2770 toolMinor = toolMajor; 2771 break; 2772 default: 2773 toolMajor = 0; 2774 toolMinor = 0; 2775 break; 2776 } 2777 2778 if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) { 2779 toolMajor /= pointerCount; 2780 toolMinor /= pointerCount; 2781 } 2782 2783 // Pressure 2784 float rawPressure; 2785 switch (mCalibration.pressureSource) { 2786 case Calibration::PRESSURE_SOURCE_PRESSURE: 2787 rawPressure = in.pressure; 2788 break; 2789 case Calibration::PRESSURE_SOURCE_TOUCH: 2790 rawPressure = in.touchMajor; 2791 break; 2792 default: 2793 rawPressure = 0; 2794 } 2795 2796 float pressure; 2797 switch (mCalibration.pressureCalibration) { 2798 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 2799 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 2800 pressure = rawPressure * mLocked.pressureScale; 2801 break; 2802 default: 2803 pressure = 1; 2804 break; 2805 } 2806 2807 // TouchMajor and TouchMinor 2808 float touchMajor, touchMinor; 2809 switch (mCalibration.touchSizeCalibration) { 2810 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 2811 touchMajor = in.touchMajor * mLocked.geometricScale; 2812 if (mRawAxes.touchMinor.valid) { 2813 touchMinor = in.touchMinor * mLocked.geometricScale; 2814 } else { 2815 touchMinor = touchMajor; 2816 } 2817 break; 2818 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 2819 touchMajor = toolMajor * pressure; 2820 touchMinor = toolMinor * pressure; 2821 break; 2822 default: 2823 touchMajor = 0; 2824 touchMinor = 0; 2825 break; 2826 } 2827 2828 if (touchMajor > toolMajor) { 2829 touchMajor = toolMajor; 2830 } 2831 if (touchMinor > toolMinor) { 2832 touchMinor = toolMinor; 2833 } 2834 2835 // Size 2836 float size; 2837 switch (mCalibration.sizeCalibration) { 2838 case Calibration::SIZE_CALIBRATION_NORMALIZED: { 2839 float rawSize = mRawAxes.toolMinor.valid 2840 ? avg(in.toolMajor, in.toolMinor) 2841 : in.toolMajor; 2842 size = rawSize * mLocked.sizeScale; 2843 break; 2844 } 2845 default: 2846 size = 0; 2847 break; 2848 } 2849 2850 // Orientation 2851 float orientation; 2852 switch (mCalibration.orientationCalibration) { 2853 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 2854 orientation = in.orientation * mLocked.orientationScale; 2855 break; 2856 case Calibration::ORIENTATION_CALIBRATION_VECTOR: { 2857 int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4); 2858 int32_t c2 = signExtendNybble(in.orientation & 0x0f); 2859 if (c1 != 0 || c2 != 0) { 2860 orientation = atan2f(c1, c2) * 0.5f; 2861 float scale = 1.0f + pythag(c1, c2) / 16.0f; 2862 touchMajor *= scale; 2863 touchMinor /= scale; 2864 toolMajor *= scale; 2865 toolMinor /= scale; 2866 } else { 2867 orientation = 0; 2868 } 2869 break; 2870 } 2871 default: 2872 orientation = 0; 2873 } 2874 2875 // X and Y 2876 // Adjust coords for surface orientation. 2877 float x, y; 2878 switch (mLocked.surfaceOrientation) { 2879 case DISPLAY_ORIENTATION_90: 2880 x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; 2881 y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; 2882 orientation -= M_PI_2; 2883 if (orientation < - M_PI_2) { 2884 orientation += M_PI; 2885 } 2886 break; 2887 case DISPLAY_ORIENTATION_180: 2888 x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale; 2889 y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; 2890 break; 2891 case DISPLAY_ORIENTATION_270: 2892 x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale; 2893 y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; 2894 orientation += M_PI_2; 2895 if (orientation > M_PI_2) { 2896 orientation -= M_PI; 2897 } 2898 break; 2899 default: 2900 x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale; 2901 y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale; 2902 break; 2903 } 2904 2905 // Write output coords. 2906 PointerCoords& out = pointerCoords[outIndex]; 2907 out.clear(); 2908 out.setAxisValue(AMOTION_EVENT_AXIS_X, x); 2909 out.setAxisValue(AMOTION_EVENT_AXIS_Y, y); 2910 out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure); 2911 out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size); 2912 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor); 2913 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor); 2914 out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor); 2915 out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor); 2916 out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation); 2917 2918 pointerIds[outIndex] = int32_t(id); 2919 2920 if (id == changedId) { 2921 motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 2922 } 2923 } 2924 2925 // Check edge flags by looking only at the first pointer since the flags are 2926 // global to the event. 2927 if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { 2928 uint32_t inIndex = touch->idToIndex[pointerIds[0]]; 2929 const PointerData& in = touch->pointers[inIndex]; 2930 2931 if (in.x <= mRawAxes.x.minValue) { 2932 motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_LEFT, 2933 mLocked.surfaceOrientation); 2934 } else if (in.x >= mRawAxes.x.maxValue) { 2935 motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_RIGHT, 2936 mLocked.surfaceOrientation); 2937 } 2938 if (in.y <= mRawAxes.y.minValue) { 2939 motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_TOP, 2940 mLocked.surfaceOrientation); 2941 } else if (in.y >= mRawAxes.y.maxValue) { 2942 motionEventEdgeFlags |= rotateEdgeFlag(AMOTION_EVENT_EDGE_FLAG_BOTTOM, 2943 mLocked.surfaceOrientation); 2944 } 2945 } 2946 2947 xPrecision = mLocked.orientedXPrecision; 2948 yPrecision = mLocked.orientedYPrecision; 2949 } // release lock 2950 2951 getDispatcher()->notifyMotion(when, getDeviceId(), mTouchSource, policyFlags, 2952 motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags, 2953 pointerCount, pointerIds, pointerCoords, 2954 xPrecision, yPrecision, mDownTime); 2955} 2956 2957bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) { 2958 return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue 2959 && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue; 2960} 2961 2962const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked( 2963 int32_t x, int32_t y) { 2964 size_t numVirtualKeys = mLocked.virtualKeys.size(); 2965 for (size_t i = 0; i < numVirtualKeys; i++) { 2966 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 2967 2968#if DEBUG_VIRTUAL_KEYS 2969 LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, " 2970 "left=%d, top=%d, right=%d, bottom=%d", 2971 x, y, 2972 virtualKey.keyCode, virtualKey.scanCode, 2973 virtualKey.hitLeft, virtualKey.hitTop, 2974 virtualKey.hitRight, virtualKey.hitBottom); 2975#endif 2976 2977 if (virtualKey.isHit(x, y)) { 2978 return & virtualKey; 2979 } 2980 } 2981 2982 return NULL; 2983} 2984 2985void TouchInputMapper::calculatePointerIds() { 2986 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 2987 uint32_t lastPointerCount = mLastTouch.pointerCount; 2988 2989 if (currentPointerCount == 0) { 2990 // No pointers to assign. 2991 mCurrentTouch.idBits.clear(); 2992 } else if (lastPointerCount == 0) { 2993 // All pointers are new. 2994 mCurrentTouch.idBits.clear(); 2995 for (uint32_t i = 0; i < currentPointerCount; i++) { 2996 mCurrentTouch.pointers[i].id = i; 2997 mCurrentTouch.idToIndex[i] = i; 2998 mCurrentTouch.idBits.markBit(i); 2999 } 3000 } else if (currentPointerCount == 1 && lastPointerCount == 1) { 3001 // Only one pointer and no change in count so it must have the same id as before. 3002 uint32_t id = mLastTouch.pointers[0].id; 3003 mCurrentTouch.pointers[0].id = id; 3004 mCurrentTouch.idToIndex[id] = 0; 3005 mCurrentTouch.idBits.value = BitSet32::valueForBit(id); 3006 } else { 3007 // General case. 3008 // We build a heap of squared euclidean distances between current and last pointers 3009 // associated with the current and last pointer indices. Then, we find the best 3010 // match (by distance) for each current pointer. 3011 PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS]; 3012 3013 uint32_t heapSize = 0; 3014 for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount; 3015 currentPointerIndex++) { 3016 for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount; 3017 lastPointerIndex++) { 3018 int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x 3019 - mLastTouch.pointers[lastPointerIndex].x; 3020 int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y 3021 - mLastTouch.pointers[lastPointerIndex].y; 3022 3023 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); 3024 3025 // Insert new element into the heap (sift up). 3026 heap[heapSize].currentPointerIndex = currentPointerIndex; 3027 heap[heapSize].lastPointerIndex = lastPointerIndex; 3028 heap[heapSize].distance = distance; 3029 heapSize += 1; 3030 } 3031 } 3032 3033 // Heapify 3034 for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) { 3035 startIndex -= 1; 3036 for (uint32_t parentIndex = startIndex; ;) { 3037 uint32_t childIndex = parentIndex * 2 + 1; 3038 if (childIndex >= heapSize) { 3039 break; 3040 } 3041 3042 if (childIndex + 1 < heapSize 3043 && heap[childIndex + 1].distance < heap[childIndex].distance) { 3044 childIndex += 1; 3045 } 3046 3047 if (heap[parentIndex].distance <= heap[childIndex].distance) { 3048 break; 3049 } 3050 3051 swap(heap[parentIndex], heap[childIndex]); 3052 parentIndex = childIndex; 3053 } 3054 } 3055 3056#if DEBUG_POINTER_ASSIGNMENT 3057 LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize); 3058 for (size_t i = 0; i < heapSize; i++) { 3059 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 3060 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 3061 heap[i].distance); 3062 } 3063#endif 3064 3065 // Pull matches out by increasing order of distance. 3066 // To avoid reassigning pointers that have already been matched, the loop keeps track 3067 // of which last and current pointers have been matched using the matchedXXXBits variables. 3068 // It also tracks the used pointer id bits. 3069 BitSet32 matchedLastBits(0); 3070 BitSet32 matchedCurrentBits(0); 3071 BitSet32 usedIdBits(0); 3072 bool first = true; 3073 for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) { 3074 for (;;) { 3075 if (first) { 3076 // The first time through the loop, we just consume the root element of 3077 // the heap (the one with smallest distance). 3078 first = false; 3079 } else { 3080 // Previous iterations consumed the root element of the heap. 3081 // Pop root element off of the heap (sift down). 3082 heapSize -= 1; 3083 assert(heapSize > 0); 3084 3085 // Sift down. 3086 heap[0] = heap[heapSize]; 3087 for (uint32_t parentIndex = 0; ;) { 3088 uint32_t childIndex = parentIndex * 2 + 1; 3089 if (childIndex >= heapSize) { 3090 break; 3091 } 3092 3093 if (childIndex + 1 < heapSize 3094 && heap[childIndex + 1].distance < heap[childIndex].distance) { 3095 childIndex += 1; 3096 } 3097 3098 if (heap[parentIndex].distance <= heap[childIndex].distance) { 3099 break; 3100 } 3101 3102 swap(heap[parentIndex], heap[childIndex]); 3103 parentIndex = childIndex; 3104 } 3105 3106#if DEBUG_POINTER_ASSIGNMENT 3107 LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize); 3108 for (size_t i = 0; i < heapSize; i++) { 3109 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 3110 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 3111 heap[i].distance); 3112 } 3113#endif 3114 } 3115 3116 uint32_t currentPointerIndex = heap[0].currentPointerIndex; 3117 if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched 3118 3119 uint32_t lastPointerIndex = heap[0].lastPointerIndex; 3120 if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched 3121 3122 matchedCurrentBits.markBit(currentPointerIndex); 3123 matchedLastBits.markBit(lastPointerIndex); 3124 3125 uint32_t id = mLastTouch.pointers[lastPointerIndex].id; 3126 mCurrentTouch.pointers[currentPointerIndex].id = id; 3127 mCurrentTouch.idToIndex[id] = currentPointerIndex; 3128 usedIdBits.markBit(id); 3129 3130#if DEBUG_POINTER_ASSIGNMENT 3131 LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld", 3132 lastPointerIndex, currentPointerIndex, id, heap[0].distance); 3133#endif 3134 break; 3135 } 3136 } 3137 3138 // Assign fresh ids to new pointers. 3139 if (currentPointerCount > lastPointerCount) { 3140 for (uint32_t i = currentPointerCount - lastPointerCount; ;) { 3141 uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit(); 3142 uint32_t id = usedIdBits.firstUnmarkedBit(); 3143 3144 mCurrentTouch.pointers[currentPointerIndex].id = id; 3145 mCurrentTouch.idToIndex[id] = currentPointerIndex; 3146 usedIdBits.markBit(id); 3147 3148#if DEBUG_POINTER_ASSIGNMENT 3149 LOGD("calculatePointerIds - assigned: cur=%d, id=%d", 3150 currentPointerIndex, id); 3151#endif 3152 3153 if (--i == 0) break; // done 3154 matchedCurrentBits.markBit(currentPointerIndex); 3155 } 3156 } 3157 3158 // Fix id bits. 3159 mCurrentTouch.idBits = usedIdBits; 3160 } 3161} 3162 3163/* Special hack for devices that have bad screen data: if one of the 3164 * points has moved more than a screen height from the last position, 3165 * then drop it. */ 3166bool TouchInputMapper::applyBadTouchFilter() { 3167 uint32_t pointerCount = mCurrentTouch.pointerCount; 3168 3169 // Nothing to do if there are no points. 3170 if (pointerCount == 0) { 3171 return false; 3172 } 3173 3174 // Don't do anything if a finger is going down or up. We run 3175 // here before assigning pointer IDs, so there isn't a good 3176 // way to do per-finger matching. 3177 if (pointerCount != mLastTouch.pointerCount) { 3178 return false; 3179 } 3180 3181 // We consider a single movement across more than a 7/16 of 3182 // the long size of the screen to be bad. This was a magic value 3183 // determined by looking at the maximum distance it is feasible 3184 // to actually move in one sample. 3185 int32_t maxDeltaY = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) * 7 / 16; 3186 3187 // XXX The original code in InputDevice.java included commented out 3188 // code for testing the X axis. Note that when we drop a point 3189 // we don't actually restore the old X either. Strange. 3190 // The old code also tries to track when bad points were previously 3191 // detected but it turns out that due to the placement of a "break" 3192 // at the end of the loop, we never set mDroppedBadPoint to true 3193 // so it is effectively dead code. 3194 // Need to figure out if the old code is busted or just overcomplicated 3195 // but working as intended. 3196 3197 // Look through all new points and see if any are farther than 3198 // acceptable from all previous points. 3199 for (uint32_t i = pointerCount; i-- > 0; ) { 3200 int32_t y = mCurrentTouch.pointers[i].y; 3201 int32_t closestY = INT_MAX; 3202 int32_t closestDeltaY = 0; 3203 3204#if DEBUG_HACKS 3205 LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y); 3206#endif 3207 3208 for (uint32_t j = pointerCount; j-- > 0; ) { 3209 int32_t lastY = mLastTouch.pointers[j].y; 3210 int32_t deltaY = abs(y - lastY); 3211 3212#if DEBUG_HACKS 3213 LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d", 3214 j, lastY, deltaY); 3215#endif 3216 3217 if (deltaY < maxDeltaY) { 3218 goto SkipSufficientlyClosePoint; 3219 } 3220 if (deltaY < closestDeltaY) { 3221 closestDeltaY = deltaY; 3222 closestY = lastY; 3223 } 3224 } 3225 3226 // Must not have found a close enough match. 3227#if DEBUG_HACKS 3228 LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d", 3229 i, y, closestY, closestDeltaY, maxDeltaY); 3230#endif 3231 3232 mCurrentTouch.pointers[i].y = closestY; 3233 return true; // XXX original code only corrects one point 3234 3235 SkipSufficientlyClosePoint: ; 3236 } 3237 3238 // No change. 3239 return false; 3240} 3241 3242/* Special hack for devices that have bad screen data: drop points where 3243 * the coordinate value for one axis has jumped to the other pointer's location. 3244 */ 3245bool TouchInputMapper::applyJumpyTouchFilter() { 3246 uint32_t pointerCount = mCurrentTouch.pointerCount; 3247 if (mLastTouch.pointerCount != pointerCount) { 3248#if DEBUG_HACKS 3249 LOGD("JumpyTouchFilter: Different pointer count %d -> %d", 3250 mLastTouch.pointerCount, pointerCount); 3251 for (uint32_t i = 0; i < pointerCount; i++) { 3252 LOGD(" Pointer %d (%d, %d)", i, 3253 mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); 3254 } 3255#endif 3256 3257 if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) { 3258 if (mLastTouch.pointerCount == 1 && pointerCount == 2) { 3259 // Just drop the first few events going from 1 to 2 pointers. 3260 // They're bad often enough that they're not worth considering. 3261 mCurrentTouch.pointerCount = 1; 3262 mJumpyTouchFilter.jumpyPointsDropped += 1; 3263 3264#if DEBUG_HACKS 3265 LOGD("JumpyTouchFilter: Pointer 2 dropped"); 3266#endif 3267 return true; 3268 } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) { 3269 // The event when we go from 2 -> 1 tends to be messed up too 3270 mCurrentTouch.pointerCount = 2; 3271 mCurrentTouch.pointers[0] = mLastTouch.pointers[0]; 3272 mCurrentTouch.pointers[1] = mLastTouch.pointers[1]; 3273 mJumpyTouchFilter.jumpyPointsDropped += 1; 3274 3275#if DEBUG_HACKS 3276 for (int32_t i = 0; i < 2; i++) { 3277 LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i, 3278 mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); 3279 } 3280#endif 3281 return true; 3282 } 3283 } 3284 // Reset jumpy points dropped on other transitions or if limit exceeded. 3285 mJumpyTouchFilter.jumpyPointsDropped = 0; 3286 3287#if DEBUG_HACKS 3288 LOGD("JumpyTouchFilter: Transition - drop limit reset"); 3289#endif 3290 return false; 3291 } 3292 3293 // We have the same number of pointers as last time. 3294 // A 'jumpy' point is one where the coordinate value for one axis 3295 // has jumped to the other pointer's location. No need to do anything 3296 // else if we only have one pointer. 3297 if (pointerCount < 2) { 3298 return false; 3299 } 3300 3301 if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) { 3302 int jumpyEpsilon = (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1) / JUMPY_EPSILON_DIVISOR; 3303 3304 // We only replace the single worst jumpy point as characterized by pointer distance 3305 // in a single axis. 3306 int32_t badPointerIndex = -1; 3307 int32_t badPointerReplacementIndex = -1; 3308 int32_t badPointerDistance = INT_MIN; // distance to be corrected 3309 3310 for (uint32_t i = pointerCount; i-- > 0; ) { 3311 int32_t x = mCurrentTouch.pointers[i].x; 3312 int32_t y = mCurrentTouch.pointers[i].y; 3313 3314#if DEBUG_HACKS 3315 LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y); 3316#endif 3317 3318 // Check if a touch point is too close to another's coordinates 3319 bool dropX = false, dropY = false; 3320 for (uint32_t j = 0; j < pointerCount; j++) { 3321 if (i == j) { 3322 continue; 3323 } 3324 3325 if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) { 3326 dropX = true; 3327 break; 3328 } 3329 3330 if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) { 3331 dropY = true; 3332 break; 3333 } 3334 } 3335 if (! dropX && ! dropY) { 3336 continue; // not jumpy 3337 } 3338 3339 // Find a replacement candidate by comparing with older points on the 3340 // complementary (non-jumpy) axis. 3341 int32_t distance = INT_MIN; // distance to be corrected 3342 int32_t replacementIndex = -1; 3343 3344 if (dropX) { 3345 // X looks too close. Find an older replacement point with a close Y. 3346 int32_t smallestDeltaY = INT_MAX; 3347 for (uint32_t j = 0; j < pointerCount; j++) { 3348 int32_t deltaY = abs(y - mLastTouch.pointers[j].y); 3349 if (deltaY < smallestDeltaY) { 3350 smallestDeltaY = deltaY; 3351 replacementIndex = j; 3352 } 3353 } 3354 distance = abs(x - mLastTouch.pointers[replacementIndex].x); 3355 } else { 3356 // Y looks too close. Find an older replacement point with a close X. 3357 int32_t smallestDeltaX = INT_MAX; 3358 for (uint32_t j = 0; j < pointerCount; j++) { 3359 int32_t deltaX = abs(x - mLastTouch.pointers[j].x); 3360 if (deltaX < smallestDeltaX) { 3361 smallestDeltaX = deltaX; 3362 replacementIndex = j; 3363 } 3364 } 3365 distance = abs(y - mLastTouch.pointers[replacementIndex].y); 3366 } 3367 3368 // If replacing this pointer would correct a worse error than the previous ones 3369 // considered, then use this replacement instead. 3370 if (distance > badPointerDistance) { 3371 badPointerIndex = i; 3372 badPointerReplacementIndex = replacementIndex; 3373 badPointerDistance = distance; 3374 } 3375 } 3376 3377 // Correct the jumpy pointer if one was found. 3378 if (badPointerIndex >= 0) { 3379#if DEBUG_HACKS 3380 LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)", 3381 badPointerIndex, 3382 mLastTouch.pointers[badPointerReplacementIndex].x, 3383 mLastTouch.pointers[badPointerReplacementIndex].y); 3384#endif 3385 3386 mCurrentTouch.pointers[badPointerIndex].x = 3387 mLastTouch.pointers[badPointerReplacementIndex].x; 3388 mCurrentTouch.pointers[badPointerIndex].y = 3389 mLastTouch.pointers[badPointerReplacementIndex].y; 3390 mJumpyTouchFilter.jumpyPointsDropped += 1; 3391 return true; 3392 } 3393 } 3394 3395 mJumpyTouchFilter.jumpyPointsDropped = 0; 3396 return false; 3397} 3398 3399/* Special hack for devices that have bad screen data: aggregate and 3400 * compute averages of the coordinate data, to reduce the amount of 3401 * jitter seen by applications. */ 3402void TouchInputMapper::applyAveragingTouchFilter() { 3403 for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) { 3404 uint32_t id = mCurrentTouch.pointers[currentIndex].id; 3405 int32_t x = mCurrentTouch.pointers[currentIndex].x; 3406 int32_t y = mCurrentTouch.pointers[currentIndex].y; 3407 int32_t pressure; 3408 switch (mCalibration.pressureSource) { 3409 case Calibration::PRESSURE_SOURCE_PRESSURE: 3410 pressure = mCurrentTouch.pointers[currentIndex].pressure; 3411 break; 3412 case Calibration::PRESSURE_SOURCE_TOUCH: 3413 pressure = mCurrentTouch.pointers[currentIndex].touchMajor; 3414 break; 3415 default: 3416 pressure = 1; 3417 break; 3418 } 3419 3420 if (mLastTouch.idBits.hasBit(id)) { 3421 // Pointer was down before and is still down now. 3422 // Compute average over history trace. 3423 uint32_t start = mAveragingTouchFilter.historyStart[id]; 3424 uint32_t end = mAveragingTouchFilter.historyEnd[id]; 3425 3426 int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x; 3427 int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y; 3428 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); 3429 3430#if DEBUG_HACKS 3431 LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld", 3432 id, distance); 3433#endif 3434 3435 if (distance < AVERAGING_DISTANCE_LIMIT) { 3436 // Increment end index in preparation for recording new historical data. 3437 end += 1; 3438 if (end > AVERAGING_HISTORY_SIZE) { 3439 end = 0; 3440 } 3441 3442 // If the end index has looped back to the start index then we have filled 3443 // the historical trace up to the desired size so we drop the historical 3444 // data at the start of the trace. 3445 if (end == start) { 3446 start += 1; 3447 if (start > AVERAGING_HISTORY_SIZE) { 3448 start = 0; 3449 } 3450 } 3451 3452 // Add the raw data to the historical trace. 3453 mAveragingTouchFilter.historyStart[id] = start; 3454 mAveragingTouchFilter.historyEnd[id] = end; 3455 mAveragingTouchFilter.historyData[end].pointers[id].x = x; 3456 mAveragingTouchFilter.historyData[end].pointers[id].y = y; 3457 mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure; 3458 3459 // Average over all historical positions in the trace by total pressure. 3460 int32_t averagedX = 0; 3461 int32_t averagedY = 0; 3462 int32_t totalPressure = 0; 3463 for (;;) { 3464 int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x; 3465 int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y; 3466 int32_t historicalPressure = mAveragingTouchFilter.historyData[start] 3467 .pointers[id].pressure; 3468 3469 averagedX += historicalX * historicalPressure; 3470 averagedY += historicalY * historicalPressure; 3471 totalPressure += historicalPressure; 3472 3473 if (start == end) { 3474 break; 3475 } 3476 3477 start += 1; 3478 if (start > AVERAGING_HISTORY_SIZE) { 3479 start = 0; 3480 } 3481 } 3482 3483 if (totalPressure != 0) { 3484 averagedX /= totalPressure; 3485 averagedY /= totalPressure; 3486 3487#if DEBUG_HACKS 3488 LOGD("AveragingTouchFilter: Pointer id %d - " 3489 "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure, 3490 averagedX, averagedY); 3491#endif 3492 3493 mCurrentTouch.pointers[currentIndex].x = averagedX; 3494 mCurrentTouch.pointers[currentIndex].y = averagedY; 3495 } 3496 } else { 3497#if DEBUG_HACKS 3498 LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id); 3499#endif 3500 } 3501 } else { 3502#if DEBUG_HACKS 3503 LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id); 3504#endif 3505 } 3506 3507 // Reset pointer history. 3508 mAveragingTouchFilter.historyStart[id] = 0; 3509 mAveragingTouchFilter.historyEnd[id] = 0; 3510 mAveragingTouchFilter.historyData[0].pointers[id].x = x; 3511 mAveragingTouchFilter.historyData[0].pointers[id].y = y; 3512 mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure; 3513 } 3514} 3515 3516int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 3517 { // acquire lock 3518 AutoMutex _l(mLock); 3519 3520 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) { 3521 return AKEY_STATE_VIRTUAL; 3522 } 3523 3524 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3525 for (size_t i = 0; i < numVirtualKeys; i++) { 3526 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3527 if (virtualKey.keyCode == keyCode) { 3528 return AKEY_STATE_UP; 3529 } 3530 } 3531 } // release lock 3532 3533 return AKEY_STATE_UNKNOWN; 3534} 3535 3536int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 3537 { // acquire lock 3538 AutoMutex _l(mLock); 3539 3540 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) { 3541 return AKEY_STATE_VIRTUAL; 3542 } 3543 3544 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3545 for (size_t i = 0; i < numVirtualKeys; i++) { 3546 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3547 if (virtualKey.scanCode == scanCode) { 3548 return AKEY_STATE_UP; 3549 } 3550 } 3551 } // release lock 3552 3553 return AKEY_STATE_UNKNOWN; 3554} 3555 3556bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 3557 const int32_t* keyCodes, uint8_t* outFlags) { 3558 { // acquire lock 3559 AutoMutex _l(mLock); 3560 3561 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3562 for (size_t i = 0; i < numVirtualKeys; i++) { 3563 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3564 3565 for (size_t i = 0; i < numCodes; i++) { 3566 if (virtualKey.keyCode == keyCodes[i]) { 3567 outFlags[i] = 1; 3568 } 3569 } 3570 } 3571 } // release lock 3572 3573 return true; 3574} 3575 3576 3577// --- SingleTouchInputMapper --- 3578 3579SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) : 3580 TouchInputMapper(device) { 3581 initialize(); 3582} 3583 3584SingleTouchInputMapper::~SingleTouchInputMapper() { 3585} 3586 3587void SingleTouchInputMapper::initialize() { 3588 mAccumulator.clear(); 3589 3590 mDown = false; 3591 mX = 0; 3592 mY = 0; 3593 mPressure = 0; // default to 0 for devices that don't report pressure 3594 mToolWidth = 0; // default to 0 for devices that don't report tool width 3595} 3596 3597void SingleTouchInputMapper::reset() { 3598 TouchInputMapper::reset(); 3599 3600 initialize(); 3601 } 3602 3603void SingleTouchInputMapper::process(const RawEvent* rawEvent) { 3604 switch (rawEvent->type) { 3605 case EV_KEY: 3606 switch (rawEvent->scanCode) { 3607 case BTN_TOUCH: 3608 mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH; 3609 mAccumulator.btnTouch = rawEvent->value != 0; 3610 // Don't sync immediately. Wait until the next SYN_REPORT since we might 3611 // not have received valid position information yet. This logic assumes that 3612 // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet. 3613 break; 3614 } 3615 break; 3616 3617 case EV_ABS: 3618 switch (rawEvent->scanCode) { 3619 case ABS_X: 3620 mAccumulator.fields |= Accumulator::FIELD_ABS_X; 3621 mAccumulator.absX = rawEvent->value; 3622 break; 3623 case ABS_Y: 3624 mAccumulator.fields |= Accumulator::FIELD_ABS_Y; 3625 mAccumulator.absY = rawEvent->value; 3626 break; 3627 case ABS_PRESSURE: 3628 mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE; 3629 mAccumulator.absPressure = rawEvent->value; 3630 break; 3631 case ABS_TOOL_WIDTH: 3632 mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH; 3633 mAccumulator.absToolWidth = rawEvent->value; 3634 break; 3635 } 3636 break; 3637 3638 case EV_SYN: 3639 switch (rawEvent->scanCode) { 3640 case SYN_REPORT: 3641 sync(rawEvent->when); 3642 break; 3643 } 3644 break; 3645 } 3646} 3647 3648void SingleTouchInputMapper::sync(nsecs_t when) { 3649 uint32_t fields = mAccumulator.fields; 3650 if (fields == 0) { 3651 return; // no new state changes, so nothing to do 3652 } 3653 3654 if (fields & Accumulator::FIELD_BTN_TOUCH) { 3655 mDown = mAccumulator.btnTouch; 3656 } 3657 3658 if (fields & Accumulator::FIELD_ABS_X) { 3659 mX = mAccumulator.absX; 3660 } 3661 3662 if (fields & Accumulator::FIELD_ABS_Y) { 3663 mY = mAccumulator.absY; 3664 } 3665 3666 if (fields & Accumulator::FIELD_ABS_PRESSURE) { 3667 mPressure = mAccumulator.absPressure; 3668 } 3669 3670 if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) { 3671 mToolWidth = mAccumulator.absToolWidth; 3672 } 3673 3674 mCurrentTouch.clear(); 3675 3676 if (mDown) { 3677 mCurrentTouch.pointerCount = 1; 3678 mCurrentTouch.pointers[0].id = 0; 3679 mCurrentTouch.pointers[0].x = mX; 3680 mCurrentTouch.pointers[0].y = mY; 3681 mCurrentTouch.pointers[0].pressure = mPressure; 3682 mCurrentTouch.pointers[0].touchMajor = 0; 3683 mCurrentTouch.pointers[0].touchMinor = 0; 3684 mCurrentTouch.pointers[0].toolMajor = mToolWidth; 3685 mCurrentTouch.pointers[0].toolMinor = mToolWidth; 3686 mCurrentTouch.pointers[0].orientation = 0; 3687 mCurrentTouch.idToIndex[0] = 0; 3688 mCurrentTouch.idBits.markBit(0); 3689 } 3690 3691 syncTouch(when, true); 3692 3693 mAccumulator.clear(); 3694} 3695 3696void SingleTouchInputMapper::configureRawAxes() { 3697 TouchInputMapper::configureRawAxes(); 3698 3699 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x); 3700 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y); 3701 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure); 3702 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor); 3703} 3704 3705 3706// --- MultiTouchInputMapper --- 3707 3708MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : 3709 TouchInputMapper(device) { 3710 initialize(); 3711} 3712 3713MultiTouchInputMapper::~MultiTouchInputMapper() { 3714} 3715 3716void MultiTouchInputMapper::initialize() { 3717 mAccumulator.clear(); 3718} 3719 3720void MultiTouchInputMapper::reset() { 3721 TouchInputMapper::reset(); 3722 3723 initialize(); 3724} 3725 3726void MultiTouchInputMapper::process(const RawEvent* rawEvent) { 3727 switch (rawEvent->type) { 3728 case EV_ABS: { 3729 uint32_t pointerIndex = mAccumulator.pointerCount; 3730 Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex]; 3731 3732 switch (rawEvent->scanCode) { 3733 case ABS_MT_POSITION_X: 3734 pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X; 3735 pointer->absMTPositionX = rawEvent->value; 3736 break; 3737 case ABS_MT_POSITION_Y: 3738 pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y; 3739 pointer->absMTPositionY = rawEvent->value; 3740 break; 3741 case ABS_MT_TOUCH_MAJOR: 3742 pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR; 3743 pointer->absMTTouchMajor = rawEvent->value; 3744 break; 3745 case ABS_MT_TOUCH_MINOR: 3746 pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR; 3747 pointer->absMTTouchMinor = rawEvent->value; 3748 break; 3749 case ABS_MT_WIDTH_MAJOR: 3750 pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR; 3751 pointer->absMTWidthMajor = rawEvent->value; 3752 break; 3753 case ABS_MT_WIDTH_MINOR: 3754 pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR; 3755 pointer->absMTWidthMinor = rawEvent->value; 3756 break; 3757 case ABS_MT_ORIENTATION: 3758 pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION; 3759 pointer->absMTOrientation = rawEvent->value; 3760 break; 3761 case ABS_MT_TRACKING_ID: 3762 pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID; 3763 pointer->absMTTrackingId = rawEvent->value; 3764 break; 3765 case ABS_MT_PRESSURE: 3766 pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE; 3767 pointer->absMTPressure = rawEvent->value; 3768 break; 3769 } 3770 break; 3771 } 3772 3773 case EV_SYN: 3774 switch (rawEvent->scanCode) { 3775 case SYN_MT_REPORT: { 3776 // MultiTouch Sync: The driver has returned all data for *one* of the pointers. 3777 uint32_t pointerIndex = mAccumulator.pointerCount; 3778 3779 if (mAccumulator.pointers[pointerIndex].fields) { 3780 if (pointerIndex == MAX_POINTERS) { 3781 LOGW("MultiTouch device driver returned more than maximum of %d pointers.", 3782 MAX_POINTERS); 3783 } else { 3784 pointerIndex += 1; 3785 mAccumulator.pointerCount = pointerIndex; 3786 } 3787 } 3788 3789 mAccumulator.pointers[pointerIndex].clear(); 3790 break; 3791 } 3792 3793 case SYN_REPORT: 3794 sync(rawEvent->when); 3795 break; 3796 } 3797 break; 3798 } 3799} 3800 3801void MultiTouchInputMapper::sync(nsecs_t when) { 3802 static const uint32_t REQUIRED_FIELDS = 3803 Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y; 3804 3805 uint32_t inCount = mAccumulator.pointerCount; 3806 uint32_t outCount = 0; 3807 bool havePointerIds = true; 3808 3809 mCurrentTouch.clear(); 3810 3811 for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) { 3812 const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex]; 3813 uint32_t fields = inPointer.fields; 3814 3815 if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) { 3816 // Some drivers send empty MT sync packets without X / Y to indicate a pointer up. 3817 // Drop this finger. 3818 continue; 3819 } 3820 3821 PointerData& outPointer = mCurrentTouch.pointers[outCount]; 3822 outPointer.x = inPointer.absMTPositionX; 3823 outPointer.y = inPointer.absMTPositionY; 3824 3825 if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) { 3826 if (inPointer.absMTPressure <= 0) { 3827 // Some devices send sync packets with X / Y but with a 0 pressure to indicate 3828 // a pointer going up. Drop this finger. 3829 continue; 3830 } 3831 outPointer.pressure = inPointer.absMTPressure; 3832 } else { 3833 // Default pressure to 0 if absent. 3834 outPointer.pressure = 0; 3835 } 3836 3837 if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) { 3838 if (inPointer.absMTTouchMajor <= 0) { 3839 // Some devices send sync packets with X / Y but with a 0 touch major to indicate 3840 // a pointer going up. Drop this finger. 3841 continue; 3842 } 3843 outPointer.touchMajor = inPointer.absMTTouchMajor; 3844 } else { 3845 // Default touch area to 0 if absent. 3846 outPointer.touchMajor = 0; 3847 } 3848 3849 if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) { 3850 outPointer.touchMinor = inPointer.absMTTouchMinor; 3851 } else { 3852 // Assume touch area is circular. 3853 outPointer.touchMinor = outPointer.touchMajor; 3854 } 3855 3856 if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) { 3857 outPointer.toolMajor = inPointer.absMTWidthMajor; 3858 } else { 3859 // Default tool area to 0 if absent. 3860 outPointer.toolMajor = 0; 3861 } 3862 3863 if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) { 3864 outPointer.toolMinor = inPointer.absMTWidthMinor; 3865 } else { 3866 // Assume tool area is circular. 3867 outPointer.toolMinor = outPointer.toolMajor; 3868 } 3869 3870 if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) { 3871 outPointer.orientation = inPointer.absMTOrientation; 3872 } else { 3873 // Default orientation to vertical if absent. 3874 outPointer.orientation = 0; 3875 } 3876 3877 // Assign pointer id using tracking id if available. 3878 if (havePointerIds) { 3879 if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) { 3880 uint32_t id = uint32_t(inPointer.absMTTrackingId); 3881 3882 if (id > MAX_POINTER_ID) { 3883#if DEBUG_POINTERS 3884 LOGD("Pointers: Ignoring driver provided pointer id %d because " 3885 "it is larger than max supported id %d", 3886 id, MAX_POINTER_ID); 3887#endif 3888 havePointerIds = false; 3889 } 3890 else { 3891 outPointer.id = id; 3892 mCurrentTouch.idToIndex[id] = outCount; 3893 mCurrentTouch.idBits.markBit(id); 3894 } 3895 } else { 3896 havePointerIds = false; 3897 } 3898 } 3899 3900 outCount += 1; 3901 } 3902 3903 mCurrentTouch.pointerCount = outCount; 3904 3905 syncTouch(when, havePointerIds); 3906 3907 mAccumulator.clear(); 3908} 3909 3910void MultiTouchInputMapper::configureRawAxes() { 3911 TouchInputMapper::configureRawAxes(); 3912 3913 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x); 3914 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y); 3915 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor); 3916 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor); 3917 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor); 3918 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor); 3919 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation); 3920 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure); 3921} 3922 3923 3924// --- JoystickInputMapper --- 3925 3926JoystickInputMapper::JoystickInputMapper(InputDevice* device) : 3927 InputMapper(device) { 3928} 3929 3930JoystickInputMapper::~JoystickInputMapper() { 3931} 3932 3933uint32_t JoystickInputMapper::getSources() { 3934 return AINPUT_SOURCE_JOYSTICK; 3935} 3936 3937void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 3938 InputMapper::populateDeviceInfo(info); 3939 3940 for (size_t i = 0; i < mAxes.size(); i++) { 3941 const Axis& axis = mAxes.valueAt(i); 3942 info->addMotionRange(axis.axisInfo.axis, AINPUT_SOURCE_JOYSTICK, 3943 axis.min, axis.max, axis.flat, axis.fuzz); 3944 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 3945 info->addMotionRange(axis.axisInfo.highAxis, AINPUT_SOURCE_JOYSTICK, 3946 axis.min, axis.max, axis.flat, axis.fuzz); 3947 } 3948 } 3949} 3950 3951void JoystickInputMapper::dump(String8& dump) { 3952 dump.append(INDENT2 "Joystick Input Mapper:\n"); 3953 3954 dump.append(INDENT3 "Axes:\n"); 3955 size_t numAxes = mAxes.size(); 3956 for (size_t i = 0; i < numAxes; i++) { 3957 const Axis& axis = mAxes.valueAt(i); 3958 const char* label = getAxisLabel(axis.axisInfo.axis); 3959 if (label) { 3960 dump.appendFormat(INDENT4 "%s", label); 3961 } else { 3962 dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis); 3963 } 3964 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 3965 label = getAxisLabel(axis.axisInfo.highAxis); 3966 if (label) { 3967 dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue); 3968 } else { 3969 dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis, 3970 axis.axisInfo.splitValue); 3971 } 3972 } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) { 3973 dump.append(" (invert)"); 3974 } 3975 3976 dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n", 3977 axis.min, axis.max, axis.flat, axis.fuzz); 3978 dump.appendFormat(INDENT4 " scale=%0.5f, offset=%0.5f, " 3979 "highScale=%0.5f, highOffset=%0.5f\n", 3980 axis.scale, axis.offset, axis.highScale, axis.highOffset); 3981 dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n", 3982 mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue, 3983 axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz); 3984 } 3985} 3986 3987void JoystickInputMapper::configure() { 3988 InputMapper::configure(); 3989 3990 // Collect all axes. 3991 for (int32_t abs = 0; abs <= ABS_MAX; abs++) { 3992 RawAbsoluteAxisInfo rawAxisInfo; 3993 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo); 3994 if (rawAxisInfo.valid) { 3995 // Map axis. 3996 AxisInfo axisInfo; 3997 bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo); 3998 if (!explicitlyMapped) { 3999 // Axis is not explicitly mapped, will choose a generic axis later. 4000 axisInfo.mode = AxisInfo::MODE_NORMAL; 4001 axisInfo.axis = -1; 4002 } 4003 4004 // Apply flat override. 4005 int32_t rawFlat = axisInfo.flatOverride < 0 4006 ? rawAxisInfo.flat : axisInfo.flatOverride; 4007 4008 // Calculate scaling factors and limits. 4009 Axis axis; 4010 if (axisInfo.mode == AxisInfo::MODE_SPLIT) { 4011 float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue); 4012 float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue); 4013 axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped, 4014 scale, 0.0f, highScale, 0.0f, 4015 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale); 4016 } else if (isCenteredAxis(axisInfo.axis)) { 4017 float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue); 4018 float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale; 4019 axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped, 4020 scale, offset, scale, offset, 4021 -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale); 4022 } else { 4023 float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue); 4024 axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped, 4025 scale, 0.0f, scale, 0.0f, 4026 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale); 4027 } 4028 4029 // To eliminate noise while the joystick is at rest, filter out small variations 4030 // in axis values up front. 4031 axis.filter = axis.flat * 0.25f; 4032 4033 mAxes.add(abs, axis); 4034 } 4035 } 4036 4037 // If there are too many axes, start dropping them. 4038 // Prefer to keep explicitly mapped axes. 4039 if (mAxes.size() > PointerCoords::MAX_AXES) { 4040 LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.", 4041 getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES); 4042 pruneAxes(true); 4043 pruneAxes(false); 4044 } 4045 4046 // Assign generic axis ids to remaining axes. 4047 int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1; 4048 size_t numAxes = mAxes.size(); 4049 for (size_t i = 0; i < numAxes; i++) { 4050 Axis& axis = mAxes.editValueAt(i); 4051 if (axis.axisInfo.axis < 0) { 4052 while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16 4053 && haveAxis(nextGenericAxisId)) { 4054 nextGenericAxisId += 1; 4055 } 4056 4057 if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) { 4058 axis.axisInfo.axis = nextGenericAxisId; 4059 nextGenericAxisId += 1; 4060 } else { 4061 LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids " 4062 "have already been assigned to other axes.", 4063 getDeviceName().string(), mAxes.keyAt(i)); 4064 mAxes.removeItemsAt(i--); 4065 numAxes -= 1; 4066 } 4067 } 4068 } 4069} 4070 4071bool JoystickInputMapper::haveAxis(int32_t axisId) { 4072 size_t numAxes = mAxes.size(); 4073 for (size_t i = 0; i < numAxes; i++) { 4074 const Axis& axis = mAxes.valueAt(i); 4075 if (axis.axisInfo.axis == axisId 4076 || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT 4077 && axis.axisInfo.highAxis == axisId)) { 4078 return true; 4079 } 4080 } 4081 return false; 4082} 4083 4084void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) { 4085 size_t i = mAxes.size(); 4086 while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) { 4087 if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) { 4088 continue; 4089 } 4090 LOGI("Discarding joystick '%s' axis %d because there are too many axes.", 4091 getDeviceName().string(), mAxes.keyAt(i)); 4092 mAxes.removeItemsAt(i); 4093 } 4094} 4095 4096bool JoystickInputMapper::isCenteredAxis(int32_t axis) { 4097 switch (axis) { 4098 case AMOTION_EVENT_AXIS_X: 4099 case AMOTION_EVENT_AXIS_Y: 4100 case AMOTION_EVENT_AXIS_Z: 4101 case AMOTION_EVENT_AXIS_RX: 4102 case AMOTION_EVENT_AXIS_RY: 4103 case AMOTION_EVENT_AXIS_RZ: 4104 case AMOTION_EVENT_AXIS_HAT_X: 4105 case AMOTION_EVENT_AXIS_HAT_Y: 4106 case AMOTION_EVENT_AXIS_ORIENTATION: 4107 case AMOTION_EVENT_AXIS_RUDDER: 4108 case AMOTION_EVENT_AXIS_WHEEL: 4109 return true; 4110 default: 4111 return false; 4112 } 4113} 4114 4115void JoystickInputMapper::reset() { 4116 // Recenter all axes. 4117 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 4118 4119 size_t numAxes = mAxes.size(); 4120 for (size_t i = 0; i < numAxes; i++) { 4121 Axis& axis = mAxes.editValueAt(i); 4122 axis.resetValue(); 4123 } 4124 4125 sync(when, true /*force*/); 4126 4127 InputMapper::reset(); 4128} 4129 4130void JoystickInputMapper::process(const RawEvent* rawEvent) { 4131 switch (rawEvent->type) { 4132 case EV_ABS: { 4133 ssize_t index = mAxes.indexOfKey(rawEvent->scanCode); 4134 if (index >= 0) { 4135 Axis& axis = mAxes.editValueAt(index); 4136 float newValue, highNewValue; 4137 switch (axis.axisInfo.mode) { 4138 case AxisInfo::MODE_INVERT: 4139 newValue = (axis.rawAxisInfo.maxValue - rawEvent->value) 4140 * axis.scale + axis.offset; 4141 highNewValue = 0.0f; 4142 break; 4143 case AxisInfo::MODE_SPLIT: 4144 if (rawEvent->value < axis.axisInfo.splitValue) { 4145 newValue = (axis.axisInfo.splitValue - rawEvent->value) 4146 * axis.scale + axis.offset; 4147 highNewValue = 0.0f; 4148 } else if (rawEvent->value > axis.axisInfo.splitValue) { 4149 newValue = 0.0f; 4150 highNewValue = (rawEvent->value - axis.axisInfo.splitValue) 4151 * axis.highScale + axis.highOffset; 4152 } else { 4153 newValue = 0.0f; 4154 highNewValue = 0.0f; 4155 } 4156 break; 4157 default: 4158 newValue = rawEvent->value * axis.scale + axis.offset; 4159 highNewValue = 0.0f; 4160 break; 4161 } 4162 axis.newValue = newValue; 4163 axis.highNewValue = highNewValue; 4164 } 4165 break; 4166 } 4167 4168 case EV_SYN: 4169 switch (rawEvent->scanCode) { 4170 case SYN_REPORT: 4171 sync(rawEvent->when, false /*force*/); 4172 break; 4173 } 4174 break; 4175 } 4176} 4177 4178void JoystickInputMapper::sync(nsecs_t when, bool force) { 4179 if (!filterAxes(force)) { 4180 return; 4181 } 4182 4183 int32_t metaState = mContext->getGlobalMetaState(); 4184 4185 PointerCoords pointerCoords; 4186 pointerCoords.clear(); 4187 4188 size_t numAxes = mAxes.size(); 4189 for (size_t i = 0; i < numAxes; i++) { 4190 const Axis& axis = mAxes.valueAt(i); 4191 pointerCoords.setAxisValue(axis.axisInfo.axis, axis.currentValue); 4192 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 4193 pointerCoords.setAxisValue(axis.axisInfo.highAxis, axis.highCurrentValue); 4194 } 4195 } 4196 4197 // Moving a joystick axis should not wake the devide because joysticks can 4198 // be fairly noisy even when not in use. On the other hand, pushing a gamepad 4199 // button will likely wake the device. 4200 // TODO: Use the input device configuration to control this behavior more finely. 4201 uint32_t policyFlags = 0; 4202 4203 int32_t pointerId = 0; 4204 getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags, 4205 AMOTION_EVENT_ACTION_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, 4206 1, &pointerId, &pointerCoords, 0, 0, 0); 4207} 4208 4209bool JoystickInputMapper::filterAxes(bool force) { 4210 bool atLeastOneSignificantChange = force; 4211 size_t numAxes = mAxes.size(); 4212 for (size_t i = 0; i < numAxes; i++) { 4213 Axis& axis = mAxes.editValueAt(i); 4214 if (force || hasValueChangedSignificantly(axis.filter, 4215 axis.newValue, axis.currentValue, axis.min, axis.max)) { 4216 axis.currentValue = axis.newValue; 4217 atLeastOneSignificantChange = true; 4218 } 4219 if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) { 4220 if (force || hasValueChangedSignificantly(axis.filter, 4221 axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) { 4222 axis.highCurrentValue = axis.highNewValue; 4223 atLeastOneSignificantChange = true; 4224 } 4225 } 4226 } 4227 return atLeastOneSignificantChange; 4228} 4229 4230bool JoystickInputMapper::hasValueChangedSignificantly( 4231 float filter, float newValue, float currentValue, float min, float max) { 4232 if (newValue != currentValue) { 4233 // Filter out small changes in value unless the value is converging on the axis 4234 // bounds or center point. This is intended to reduce the amount of information 4235 // sent to applications by particularly noisy joysticks (such as PS3). 4236 if (fabs(newValue - currentValue) > filter 4237 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min) 4238 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max) 4239 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) { 4240 return true; 4241 } 4242 } 4243 return false; 4244} 4245 4246bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange( 4247 float filter, float newValue, float currentValue, float thresholdValue) { 4248 float newDistance = fabs(newValue - thresholdValue); 4249 if (newDistance < filter) { 4250 float oldDistance = fabs(currentValue - thresholdValue); 4251 if (newDistance < oldDistance) { 4252 return true; 4253 } 4254 } 4255 return false; 4256} 4257 4258} // namespace android 4259