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