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