InputReader.cpp revision cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413
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_MOUSE: 1201 mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE; 1202 mAccumulator.btnMouse = rawEvent->value != 0; 1203 // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and 1204 // we need to ensure that we report the up/down promptly. 1205 sync(rawEvent->when); 1206 break; 1207 } 1208 break; 1209 1210 case EV_REL: 1211 switch (rawEvent->scanCode) { 1212 case REL_X: 1213 mAccumulator.fields |= Accumulator::FIELD_REL_X; 1214 mAccumulator.relX = rawEvent->value; 1215 break; 1216 case REL_Y: 1217 mAccumulator.fields |= Accumulator::FIELD_REL_Y; 1218 mAccumulator.relY = rawEvent->value; 1219 break; 1220 case REL_WHEEL: 1221 mAccumulator.fields |= Accumulator::FIELD_REL_WHEEL; 1222 mAccumulator.relWheel = rawEvent->value; 1223 break; 1224 case REL_HWHEEL: 1225 mAccumulator.fields |= Accumulator::FIELD_REL_HWHEEL; 1226 mAccumulator.relHWheel = rawEvent->value; 1227 break; 1228 } 1229 break; 1230 1231 case EV_SYN: 1232 switch (rawEvent->scanCode) { 1233 case SYN_REPORT: 1234 sync(rawEvent->when); 1235 break; 1236 } 1237 break; 1238 } 1239} 1240 1241void CursorInputMapper::sync(nsecs_t when) { 1242 uint32_t fields = mAccumulator.fields; 1243 if (fields == 0) { 1244 return; // no new state changes, so nothing to do 1245 } 1246 1247 int motionEventAction; 1248 PointerCoords pointerCoords; 1249 nsecs_t downTime; 1250 { // acquire lock 1251 AutoMutex _l(mLock); 1252 1253 bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE; 1254 1255 if (downChanged) { 1256 if (mAccumulator.btnMouse) { 1257 if (!mLocked.down) { 1258 mLocked.down = true; 1259 mLocked.downTime = when; 1260 } else { 1261 downChanged = false; 1262 } 1263 } else { 1264 if (mLocked.down) { 1265 mLocked.down = false; 1266 } else { 1267 downChanged = false; 1268 } 1269 } 1270 } 1271 1272 downTime = mLocked.downTime; 1273 float deltaX = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f; 1274 float deltaY = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f; 1275 1276 if (downChanged) { 1277 motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; 1278 } else if (mLocked.down || mPointerController == NULL) { 1279 motionEventAction = AMOTION_EVENT_ACTION_MOVE; 1280 } else { 1281 motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE; 1282 } 1283 1284 if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0 1285 && (deltaX != 0.0f || deltaY != 0.0f)) { 1286 // Rotate motion based on display orientation if needed. 1287 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1288 int32_t orientation; 1289 if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 1290 NULL, NULL, & orientation)) { 1291 orientation = DISPLAY_ORIENTATION_0; 1292 } 1293 1294 float temp; 1295 switch (orientation) { 1296 case DISPLAY_ORIENTATION_90: 1297 temp = deltaX; 1298 deltaX = deltaY; 1299 deltaY = -temp; 1300 break; 1301 1302 case DISPLAY_ORIENTATION_180: 1303 deltaX = -deltaX; 1304 deltaY = -deltaY; 1305 break; 1306 1307 case DISPLAY_ORIENTATION_270: 1308 temp = deltaX; 1309 deltaX = -deltaY; 1310 deltaY = temp; 1311 break; 1312 } 1313 } 1314 1315 pointerCoords.clear(); 1316 1317 if (mPointerController != NULL) { 1318 mPointerController->move(deltaX, deltaY); 1319 if (downChanged) { 1320 mPointerController->setButtonState(mLocked.down ? POINTER_BUTTON_1 : 0); 1321 } 1322 float x, y; 1323 mPointerController->getPosition(&x, &y); 1324 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x); 1325 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y); 1326 } else { 1327 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX); 1328 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY); 1329 } 1330 1331 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, mLocked.down ? 1.0f : 0.0f); 1332 1333 if (mHaveVWheel && (fields & Accumulator::FIELD_REL_WHEEL)) { 1334 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, mAccumulator.relWheel); 1335 } 1336 if (mHaveHWheel && (fields & Accumulator::FIELD_REL_HWHEEL)) { 1337 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, mAccumulator.relHWheel); 1338 } 1339 } // release lock 1340 1341 int32_t metaState = mContext->getGlobalMetaState(); 1342 int32_t pointerId = 0; 1343 getDispatcher()->notifyMotion(when, getDeviceId(), mSources, 0, 1344 motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, 1345 1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime); 1346 1347 mAccumulator.clear(); 1348} 1349 1350int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 1351 if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) { 1352 return getEventHub()->getScanCodeState(getDeviceId(), scanCode); 1353 } else { 1354 return AKEY_STATE_UNKNOWN; 1355 } 1356} 1357 1358 1359// --- TouchInputMapper --- 1360 1361TouchInputMapper::TouchInputMapper(InputDevice* device) : 1362 InputMapper(device) { 1363 mLocked.surfaceOrientation = -1; 1364 mLocked.surfaceWidth = -1; 1365 mLocked.surfaceHeight = -1; 1366 1367 initializeLocked(); 1368} 1369 1370TouchInputMapper::~TouchInputMapper() { 1371} 1372 1373uint32_t TouchInputMapper::getSources() { 1374 return mSources; 1375} 1376 1377void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 1378 InputMapper::populateDeviceInfo(info); 1379 1380 { // acquire lock 1381 AutoMutex _l(mLock); 1382 1383 // Ensure surface information is up to date so that orientation changes are 1384 // noticed immediately. 1385 configureSurfaceLocked(); 1386 1387 info->addMotionRange(AMOTION_EVENT_AXIS_X, mLocked.orientedRanges.x); 1388 info->addMotionRange(AMOTION_EVENT_AXIS_Y, mLocked.orientedRanges.y); 1389 1390 if (mLocked.orientedRanges.havePressure) { 1391 info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, 1392 mLocked.orientedRanges.pressure); 1393 } 1394 1395 if (mLocked.orientedRanges.haveSize) { 1396 info->addMotionRange(AMOTION_EVENT_AXIS_SIZE, 1397 mLocked.orientedRanges.size); 1398 } 1399 1400 if (mLocked.orientedRanges.haveTouchSize) { 1401 info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MAJOR, 1402 mLocked.orientedRanges.touchMajor); 1403 info->addMotionRange(AMOTION_EVENT_AXIS_TOUCH_MINOR, 1404 mLocked.orientedRanges.touchMinor); 1405 } 1406 1407 if (mLocked.orientedRanges.haveToolSize) { 1408 info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MAJOR, 1409 mLocked.orientedRanges.toolMajor); 1410 info->addMotionRange(AMOTION_EVENT_AXIS_TOOL_MINOR, 1411 mLocked.orientedRanges.toolMinor); 1412 } 1413 1414 if (mLocked.orientedRanges.haveOrientation) { 1415 info->addMotionRange(AMOTION_EVENT_AXIS_ORIENTATION, 1416 mLocked.orientedRanges.orientation); 1417 } 1418 } // release lock 1419} 1420 1421void TouchInputMapper::dump(String8& dump) { 1422 { // acquire lock 1423 AutoMutex _l(mLock); 1424 dump.append(INDENT2 "Touch Input Mapper:\n"); 1425 dumpParameters(dump); 1426 dumpVirtualKeysLocked(dump); 1427 dumpRawAxes(dump); 1428 dumpCalibration(dump); 1429 dumpSurfaceLocked(dump); 1430 dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n"); 1431 dump.appendFormat(INDENT4 "XOrigin: %d\n", mLocked.xOrigin); 1432 dump.appendFormat(INDENT4 "YOrigin: %d\n", mLocked.yOrigin); 1433 dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale); 1434 dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale); 1435 dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision); 1436 dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision); 1437 dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale); 1438 dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale); 1439 dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias); 1440 dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale); 1441 dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias); 1442 dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale); 1443 dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale); 1444 dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale); 1445 } // release lock 1446} 1447 1448void TouchInputMapper::initializeLocked() { 1449 mCurrentTouch.clear(); 1450 mLastTouch.clear(); 1451 mDownTime = 0; 1452 1453 for (uint32_t i = 0; i < MAX_POINTERS; i++) { 1454 mAveragingTouchFilter.historyStart[i] = 0; 1455 mAveragingTouchFilter.historyEnd[i] = 0; 1456 } 1457 1458 mJumpyTouchFilter.jumpyPointsDropped = 0; 1459 1460 mLocked.currentVirtualKey.down = false; 1461 1462 mLocked.orientedRanges.havePressure = false; 1463 mLocked.orientedRanges.haveSize = false; 1464 mLocked.orientedRanges.haveTouchSize = false; 1465 mLocked.orientedRanges.haveToolSize = false; 1466 mLocked.orientedRanges.haveOrientation = false; 1467} 1468 1469void TouchInputMapper::configure() { 1470 InputMapper::configure(); 1471 1472 // Configure basic parameters. 1473 configureParameters(); 1474 1475 // Configure sources. 1476 switch (mParameters.deviceType) { 1477 case Parameters::DEVICE_TYPE_TOUCH_SCREEN: 1478 mSources = AINPUT_SOURCE_TOUCHSCREEN; 1479 break; 1480 case Parameters::DEVICE_TYPE_TOUCH_PAD: 1481 mSources = AINPUT_SOURCE_TOUCHPAD; 1482 break; 1483 default: 1484 assert(false); 1485 } 1486 1487 // Configure absolute axis information. 1488 configureRawAxes(); 1489 1490 // Prepare input device calibration. 1491 parseCalibration(); 1492 resolveCalibration(); 1493 1494 { // acquire lock 1495 AutoMutex _l(mLock); 1496 1497 // Configure surface dimensions and orientation. 1498 configureSurfaceLocked(); 1499 } // release lock 1500} 1501 1502void TouchInputMapper::configureParameters() { 1503 mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents(); 1504 mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents(); 1505 mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents(); 1506 mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime(); 1507 1508 String8 deviceTypeString; 1509 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD; 1510 if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"), 1511 deviceTypeString)) { 1512 if (deviceTypeString == "touchScreen") { 1513 mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN; 1514 } else if (deviceTypeString != "touchPad") { 1515 LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string()); 1516 } 1517 } 1518 bool isTouchScreen = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; 1519 1520 mParameters.orientationAware = isTouchScreen; 1521 getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"), 1522 mParameters.orientationAware); 1523 1524 mParameters.associatedDisplayId = mParameters.orientationAware || isTouchScreen ? 0 : -1; 1525} 1526 1527void TouchInputMapper::dumpParameters(String8& dump) { 1528 dump.append(INDENT3 "Parameters:\n"); 1529 1530 switch (mParameters.deviceType) { 1531 case Parameters::DEVICE_TYPE_TOUCH_SCREEN: 1532 dump.append(INDENT4 "DeviceType: touchScreen\n"); 1533 break; 1534 case Parameters::DEVICE_TYPE_TOUCH_PAD: 1535 dump.append(INDENT4 "DeviceType: touchPad\n"); 1536 break; 1537 default: 1538 assert(false); 1539 } 1540 1541 dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n", 1542 mParameters.associatedDisplayId); 1543 dump.appendFormat(INDENT4 "OrientationAware: %s\n", 1544 toString(mParameters.orientationAware)); 1545 1546 dump.appendFormat(INDENT4 "UseBadTouchFilter: %s\n", 1547 toString(mParameters.useBadTouchFilter)); 1548 dump.appendFormat(INDENT4 "UseAveragingTouchFilter: %s\n", 1549 toString(mParameters.useAveragingTouchFilter)); 1550 dump.appendFormat(INDENT4 "UseJumpyTouchFilter: %s\n", 1551 toString(mParameters.useJumpyTouchFilter)); 1552} 1553 1554void TouchInputMapper::configureRawAxes() { 1555 mRawAxes.x.clear(); 1556 mRawAxes.y.clear(); 1557 mRawAxes.pressure.clear(); 1558 mRawAxes.touchMajor.clear(); 1559 mRawAxes.touchMinor.clear(); 1560 mRawAxes.toolMajor.clear(); 1561 mRawAxes.toolMinor.clear(); 1562 mRawAxes.orientation.clear(); 1563} 1564 1565void TouchInputMapper::dumpRawAxes(String8& dump) { 1566 dump.append(INDENT3 "Raw Axes:\n"); 1567 dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X"); 1568 dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y"); 1569 dumpRawAbsoluteAxisInfo(dump, mRawAxes.pressure, "Pressure"); 1570 dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor"); 1571 dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor"); 1572 dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor"); 1573 dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor"); 1574 dumpRawAbsoluteAxisInfo(dump, mRawAxes.orientation, "Orientation"); 1575} 1576 1577bool TouchInputMapper::configureSurfaceLocked() { 1578 // Update orientation and dimensions if needed. 1579 int32_t orientation = DISPLAY_ORIENTATION_0; 1580 int32_t width = mRawAxes.x.getRange(); 1581 int32_t height = mRawAxes.y.getRange(); 1582 1583 if (mParameters.associatedDisplayId >= 0) { 1584 bool wantSize = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN; 1585 bool wantOrientation = mParameters.orientationAware; 1586 1587 // Note: getDisplayInfo is non-reentrant so we can continue holding the lock. 1588 if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId, 1589 wantSize ? &width : NULL, wantSize ? &height : NULL, 1590 wantOrientation ? &orientation : NULL)) { 1591 return false; 1592 } 1593 } 1594 1595 bool orientationChanged = mLocked.surfaceOrientation != orientation; 1596 if (orientationChanged) { 1597 mLocked.surfaceOrientation = orientation; 1598 } 1599 1600 bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height; 1601 if (sizeChanged) { 1602 LOGI("Device reconfigured: id=%d, name='%s', display size is now %dx%d", 1603 getDeviceId(), getDeviceName().string(), width, height); 1604 1605 mLocked.surfaceWidth = width; 1606 mLocked.surfaceHeight = height; 1607 1608 // Configure X and Y factors. 1609 if (mRawAxes.x.valid && mRawAxes.y.valid) { 1610 mLocked.xOrigin = mCalibration.haveXOrigin 1611 ? mCalibration.xOrigin 1612 : mRawAxes.x.minValue; 1613 mLocked.yOrigin = mCalibration.haveYOrigin 1614 ? mCalibration.yOrigin 1615 : mRawAxes.y.minValue; 1616 mLocked.xScale = mCalibration.haveXScale 1617 ? mCalibration.xScale 1618 : float(width) / mRawAxes.x.getRange(); 1619 mLocked.yScale = mCalibration.haveYScale 1620 ? mCalibration.yScale 1621 : float(height) / mRawAxes.y.getRange(); 1622 mLocked.xPrecision = 1.0f / mLocked.xScale; 1623 mLocked.yPrecision = 1.0f / mLocked.yScale; 1624 1625 configureVirtualKeysLocked(); 1626 } else { 1627 LOGW(INDENT "Touch device did not report support for X or Y axis!"); 1628 mLocked.xOrigin = 0; 1629 mLocked.yOrigin = 0; 1630 mLocked.xScale = 1.0f; 1631 mLocked.yScale = 1.0f; 1632 mLocked.xPrecision = 1.0f; 1633 mLocked.yPrecision = 1.0f; 1634 } 1635 1636 // Scale factor for terms that are not oriented in a particular axis. 1637 // If the pixels are square then xScale == yScale otherwise we fake it 1638 // by choosing an average. 1639 mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale); 1640 1641 // Size of diagonal axis. 1642 float diagonalSize = pythag(width, height); 1643 1644 // TouchMajor and TouchMinor factors. 1645 if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) { 1646 mLocked.orientedRanges.haveTouchSize = true; 1647 mLocked.orientedRanges.touchMajor.min = 0; 1648 mLocked.orientedRanges.touchMajor.max = diagonalSize; 1649 mLocked.orientedRanges.touchMajor.flat = 0; 1650 mLocked.orientedRanges.touchMajor.fuzz = 0; 1651 mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor; 1652 } 1653 1654 // ToolMajor and ToolMinor factors. 1655 mLocked.toolSizeLinearScale = 0; 1656 mLocked.toolSizeLinearBias = 0; 1657 mLocked.toolSizeAreaScale = 0; 1658 mLocked.toolSizeAreaBias = 0; 1659 if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 1660 if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) { 1661 if (mCalibration.haveToolSizeLinearScale) { 1662 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 1663 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1664 mLocked.toolSizeLinearScale = float(min(width, height)) 1665 / mRawAxes.toolMajor.maxValue; 1666 } 1667 1668 if (mCalibration.haveToolSizeLinearBias) { 1669 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 1670 } 1671 } else if (mCalibration.toolSizeCalibration == 1672 Calibration::TOOL_SIZE_CALIBRATION_AREA) { 1673 if (mCalibration.haveToolSizeLinearScale) { 1674 mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale; 1675 } else { 1676 mLocked.toolSizeLinearScale = min(width, height); 1677 } 1678 1679 if (mCalibration.haveToolSizeLinearBias) { 1680 mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias; 1681 } 1682 1683 if (mCalibration.haveToolSizeAreaScale) { 1684 mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale; 1685 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1686 mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue; 1687 } 1688 1689 if (mCalibration.haveToolSizeAreaBias) { 1690 mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias; 1691 } 1692 } 1693 1694 mLocked.orientedRanges.haveToolSize = true; 1695 mLocked.orientedRanges.toolMajor.min = 0; 1696 mLocked.orientedRanges.toolMajor.max = diagonalSize; 1697 mLocked.orientedRanges.toolMajor.flat = 0; 1698 mLocked.orientedRanges.toolMajor.fuzz = 0; 1699 mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor; 1700 } 1701 1702 // Pressure factors. 1703 mLocked.pressureScale = 0; 1704 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) { 1705 RawAbsoluteAxisInfo rawPressureAxis; 1706 switch (mCalibration.pressureSource) { 1707 case Calibration::PRESSURE_SOURCE_PRESSURE: 1708 rawPressureAxis = mRawAxes.pressure; 1709 break; 1710 case Calibration::PRESSURE_SOURCE_TOUCH: 1711 rawPressureAxis = mRawAxes.touchMajor; 1712 break; 1713 default: 1714 rawPressureAxis.clear(); 1715 } 1716 1717 if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL 1718 || mCalibration.pressureCalibration 1719 == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) { 1720 if (mCalibration.havePressureScale) { 1721 mLocked.pressureScale = mCalibration.pressureScale; 1722 } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) { 1723 mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue; 1724 } 1725 } 1726 1727 mLocked.orientedRanges.havePressure = true; 1728 mLocked.orientedRanges.pressure.min = 0; 1729 mLocked.orientedRanges.pressure.max = 1.0; 1730 mLocked.orientedRanges.pressure.flat = 0; 1731 mLocked.orientedRanges.pressure.fuzz = 0; 1732 } 1733 1734 // Size factors. 1735 mLocked.sizeScale = 0; 1736 if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) { 1737 if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) { 1738 if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) { 1739 mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue; 1740 } 1741 } 1742 1743 mLocked.orientedRanges.haveSize = true; 1744 mLocked.orientedRanges.size.min = 0; 1745 mLocked.orientedRanges.size.max = 1.0; 1746 mLocked.orientedRanges.size.flat = 0; 1747 mLocked.orientedRanges.size.fuzz = 0; 1748 } 1749 1750 // Orientation 1751 mLocked.orientationScale = 0; 1752 if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) { 1753 if (mCalibration.orientationCalibration 1754 == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) { 1755 if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) { 1756 mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue; 1757 } 1758 } 1759 1760 mLocked.orientedRanges.orientation.min = - M_PI_2; 1761 mLocked.orientedRanges.orientation.max = M_PI_2; 1762 mLocked.orientedRanges.orientation.flat = 0; 1763 mLocked.orientedRanges.orientation.fuzz = 0; 1764 } 1765 } 1766 1767 if (orientationChanged || sizeChanged) { 1768 // Compute oriented surface dimensions, precision, and scales. 1769 float orientedXScale, orientedYScale; 1770 switch (mLocked.surfaceOrientation) { 1771 case DISPLAY_ORIENTATION_90: 1772 case DISPLAY_ORIENTATION_270: 1773 mLocked.orientedSurfaceWidth = mLocked.surfaceHeight; 1774 mLocked.orientedSurfaceHeight = mLocked.surfaceWidth; 1775 mLocked.orientedXPrecision = mLocked.yPrecision; 1776 mLocked.orientedYPrecision = mLocked.xPrecision; 1777 orientedXScale = mLocked.yScale; 1778 orientedYScale = mLocked.xScale; 1779 break; 1780 default: 1781 mLocked.orientedSurfaceWidth = mLocked.surfaceWidth; 1782 mLocked.orientedSurfaceHeight = mLocked.surfaceHeight; 1783 mLocked.orientedXPrecision = mLocked.xPrecision; 1784 mLocked.orientedYPrecision = mLocked.yPrecision; 1785 orientedXScale = mLocked.xScale; 1786 orientedYScale = mLocked.yScale; 1787 break; 1788 } 1789 1790 // Configure position ranges. 1791 mLocked.orientedRanges.x.min = 0; 1792 mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth; 1793 mLocked.orientedRanges.x.flat = 0; 1794 mLocked.orientedRanges.x.fuzz = orientedXScale; 1795 1796 mLocked.orientedRanges.y.min = 0; 1797 mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight; 1798 mLocked.orientedRanges.y.flat = 0; 1799 mLocked.orientedRanges.y.fuzz = orientedYScale; 1800 } 1801 1802 return true; 1803} 1804 1805void TouchInputMapper::dumpSurfaceLocked(String8& dump) { 1806 dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth); 1807 dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight); 1808 dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation); 1809} 1810 1811void TouchInputMapper::configureVirtualKeysLocked() { 1812 assert(mRawAxes.x.valid && mRawAxes.y.valid); 1813 1814 Vector<VirtualKeyDefinition> virtualKeyDefinitions; 1815 getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions); 1816 1817 mLocked.virtualKeys.clear(); 1818 1819 if (virtualKeyDefinitions.size() == 0) { 1820 return; 1821 } 1822 1823 mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size()); 1824 1825 int32_t touchScreenLeft = mRawAxes.x.minValue; 1826 int32_t touchScreenTop = mRawAxes.y.minValue; 1827 int32_t touchScreenWidth = mRawAxes.x.getRange(); 1828 int32_t touchScreenHeight = mRawAxes.y.getRange(); 1829 1830 for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) { 1831 const VirtualKeyDefinition& virtualKeyDefinition = 1832 virtualKeyDefinitions[i]; 1833 1834 mLocked.virtualKeys.add(); 1835 VirtualKey& virtualKey = mLocked.virtualKeys.editTop(); 1836 1837 virtualKey.scanCode = virtualKeyDefinition.scanCode; 1838 int32_t keyCode; 1839 uint32_t flags; 1840 if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 1841 & keyCode, & flags)) { 1842 LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", 1843 virtualKey.scanCode); 1844 mLocked.virtualKeys.pop(); // drop the key 1845 continue; 1846 } 1847 1848 virtualKey.keyCode = keyCode; 1849 virtualKey.flags = flags; 1850 1851 // convert the key definition's display coordinates into touch coordinates for a hit box 1852 int32_t halfWidth = virtualKeyDefinition.width / 2; 1853 int32_t halfHeight = virtualKeyDefinition.height / 2; 1854 1855 virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth) 1856 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 1857 virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth) 1858 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft; 1859 virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight) 1860 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 1861 virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) 1862 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop; 1863 1864 } 1865} 1866 1867void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) { 1868 if (!mLocked.virtualKeys.isEmpty()) { 1869 dump.append(INDENT3 "Virtual Keys:\n"); 1870 1871 for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) { 1872 const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i); 1873 dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, " 1874 "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n", 1875 i, virtualKey.scanCode, virtualKey.keyCode, 1876 virtualKey.hitLeft, virtualKey.hitRight, 1877 virtualKey.hitTop, virtualKey.hitBottom); 1878 } 1879 } 1880} 1881 1882void TouchInputMapper::parseCalibration() { 1883 const PropertyMap& in = getDevice()->getConfiguration(); 1884 Calibration& out = mCalibration; 1885 1886 // Position 1887 out.haveXOrigin = in.tryGetProperty(String8("touch.position.xOrigin"), out.xOrigin); 1888 out.haveYOrigin = in.tryGetProperty(String8("touch.position.yOrigin"), out.yOrigin); 1889 out.haveXScale = in.tryGetProperty(String8("touch.position.xScale"), out.xScale); 1890 out.haveYScale = in.tryGetProperty(String8("touch.position.yScale"), out.yScale); 1891 1892 // Touch Size 1893 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT; 1894 String8 touchSizeCalibrationString; 1895 if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) { 1896 if (touchSizeCalibrationString == "none") { 1897 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 1898 } else if (touchSizeCalibrationString == "geometric") { 1899 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC; 1900 } else if (touchSizeCalibrationString == "pressure") { 1901 out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 1902 } else if (touchSizeCalibrationString != "default") { 1903 LOGW("Invalid value for touch.touchSize.calibration: '%s'", 1904 touchSizeCalibrationString.string()); 1905 } 1906 } 1907 1908 // Tool Size 1909 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT; 1910 String8 toolSizeCalibrationString; 1911 if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) { 1912 if (toolSizeCalibrationString == "none") { 1913 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 1914 } else if (toolSizeCalibrationString == "geometric") { 1915 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC; 1916 } else if (toolSizeCalibrationString == "linear") { 1917 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 1918 } else if (toolSizeCalibrationString == "area") { 1919 out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA; 1920 } else if (toolSizeCalibrationString != "default") { 1921 LOGW("Invalid value for touch.toolSize.calibration: '%s'", 1922 toolSizeCalibrationString.string()); 1923 } 1924 } 1925 1926 out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"), 1927 out.toolSizeLinearScale); 1928 out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"), 1929 out.toolSizeLinearBias); 1930 out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"), 1931 out.toolSizeAreaScale); 1932 out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"), 1933 out.toolSizeAreaBias); 1934 out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"), 1935 out.toolSizeIsSummed); 1936 1937 // Pressure 1938 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT; 1939 String8 pressureCalibrationString; 1940 if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) { 1941 if (pressureCalibrationString == "none") { 1942 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 1943 } else if (pressureCalibrationString == "physical") { 1944 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL; 1945 } else if (pressureCalibrationString == "amplitude") { 1946 out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 1947 } else if (pressureCalibrationString != "default") { 1948 LOGW("Invalid value for touch.pressure.calibration: '%s'", 1949 pressureCalibrationString.string()); 1950 } 1951 } 1952 1953 out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT; 1954 String8 pressureSourceString; 1955 if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) { 1956 if (pressureSourceString == "pressure") { 1957 out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 1958 } else if (pressureSourceString == "touch") { 1959 out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 1960 } else if (pressureSourceString != "default") { 1961 LOGW("Invalid value for touch.pressure.source: '%s'", 1962 pressureSourceString.string()); 1963 } 1964 } 1965 1966 out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"), 1967 out.pressureScale); 1968 1969 // Size 1970 out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT; 1971 String8 sizeCalibrationString; 1972 if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) { 1973 if (sizeCalibrationString == "none") { 1974 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 1975 } else if (sizeCalibrationString == "normalized") { 1976 out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 1977 } else if (sizeCalibrationString != "default") { 1978 LOGW("Invalid value for touch.size.calibration: '%s'", 1979 sizeCalibrationString.string()); 1980 } 1981 } 1982 1983 // Orientation 1984 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT; 1985 String8 orientationCalibrationString; 1986 if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) { 1987 if (orientationCalibrationString == "none") { 1988 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 1989 } else if (orientationCalibrationString == "interpolated") { 1990 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 1991 } else if (orientationCalibrationString == "vector") { 1992 out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR; 1993 } else if (orientationCalibrationString != "default") { 1994 LOGW("Invalid value for touch.orientation.calibration: '%s'", 1995 orientationCalibrationString.string()); 1996 } 1997 } 1998} 1999 2000void TouchInputMapper::resolveCalibration() { 2001 // Pressure 2002 switch (mCalibration.pressureSource) { 2003 case Calibration::PRESSURE_SOURCE_DEFAULT: 2004 if (mRawAxes.pressure.valid) { 2005 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; 2006 } else if (mRawAxes.touchMajor.valid) { 2007 mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; 2008 } 2009 break; 2010 2011 case Calibration::PRESSURE_SOURCE_PRESSURE: 2012 if (! mRawAxes.pressure.valid) { 2013 LOGW("Calibration property touch.pressure.source is 'pressure' but " 2014 "the pressure axis is not available."); 2015 } 2016 break; 2017 2018 case Calibration::PRESSURE_SOURCE_TOUCH: 2019 if (! mRawAxes.touchMajor.valid) { 2020 LOGW("Calibration property touch.pressure.source is 'touch' but " 2021 "the touchMajor axis is not available."); 2022 } 2023 break; 2024 2025 default: 2026 break; 2027 } 2028 2029 switch (mCalibration.pressureCalibration) { 2030 case Calibration::PRESSURE_CALIBRATION_DEFAULT: 2031 if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) { 2032 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; 2033 } else { 2034 mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; 2035 } 2036 break; 2037 2038 default: 2039 break; 2040 } 2041 2042 // Tool Size 2043 switch (mCalibration.toolSizeCalibration) { 2044 case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT: 2045 if (mRawAxes.toolMajor.valid) { 2046 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; 2047 } else { 2048 mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; 2049 } 2050 break; 2051 2052 default: 2053 break; 2054 } 2055 2056 // Touch Size 2057 switch (mCalibration.touchSizeCalibration) { 2058 case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT: 2059 if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE 2060 && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { 2061 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; 2062 } else { 2063 mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; 2064 } 2065 break; 2066 2067 default: 2068 break; 2069 } 2070 2071 // Size 2072 switch (mCalibration.sizeCalibration) { 2073 case Calibration::SIZE_CALIBRATION_DEFAULT: 2074 if (mRawAxes.toolMajor.valid) { 2075 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; 2076 } else { 2077 mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; 2078 } 2079 break; 2080 2081 default: 2082 break; 2083 } 2084 2085 // Orientation 2086 switch (mCalibration.orientationCalibration) { 2087 case Calibration::ORIENTATION_CALIBRATION_DEFAULT: 2088 if (mRawAxes.orientation.valid) { 2089 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; 2090 } else { 2091 mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; 2092 } 2093 break; 2094 2095 default: 2096 break; 2097 } 2098} 2099 2100void TouchInputMapper::dumpCalibration(String8& dump) { 2101 dump.append(INDENT3 "Calibration:\n"); 2102 2103 // Position 2104 if (mCalibration.haveXOrigin) { 2105 dump.appendFormat(INDENT4 "touch.position.xOrigin: %d\n", mCalibration.xOrigin); 2106 } 2107 if (mCalibration.haveYOrigin) { 2108 dump.appendFormat(INDENT4 "touch.position.yOrigin: %d\n", mCalibration.yOrigin); 2109 } 2110 if (mCalibration.haveXScale) { 2111 dump.appendFormat(INDENT4 "touch.position.xScale: %0.3f\n", mCalibration.xScale); 2112 } 2113 if (mCalibration.haveYScale) { 2114 dump.appendFormat(INDENT4 "touch.position.yScale: %0.3f\n", mCalibration.yScale); 2115 } 2116 2117 // Touch Size 2118 switch (mCalibration.touchSizeCalibration) { 2119 case Calibration::TOUCH_SIZE_CALIBRATION_NONE: 2120 dump.append(INDENT4 "touch.touchSize.calibration: none\n"); 2121 break; 2122 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 2123 dump.append(INDENT4 "touch.touchSize.calibration: geometric\n"); 2124 break; 2125 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 2126 dump.append(INDENT4 "touch.touchSize.calibration: pressure\n"); 2127 break; 2128 default: 2129 assert(false); 2130 } 2131 2132 // Tool Size 2133 switch (mCalibration.toolSizeCalibration) { 2134 case Calibration::TOOL_SIZE_CALIBRATION_NONE: 2135 dump.append(INDENT4 "touch.toolSize.calibration: none\n"); 2136 break; 2137 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 2138 dump.append(INDENT4 "touch.toolSize.calibration: geometric\n"); 2139 break; 2140 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 2141 dump.append(INDENT4 "touch.toolSize.calibration: linear\n"); 2142 break; 2143 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 2144 dump.append(INDENT4 "touch.toolSize.calibration: area\n"); 2145 break; 2146 default: 2147 assert(false); 2148 } 2149 2150 if (mCalibration.haveToolSizeLinearScale) { 2151 dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n", 2152 mCalibration.toolSizeLinearScale); 2153 } 2154 2155 if (mCalibration.haveToolSizeLinearBias) { 2156 dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n", 2157 mCalibration.toolSizeLinearBias); 2158 } 2159 2160 if (mCalibration.haveToolSizeAreaScale) { 2161 dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n", 2162 mCalibration.toolSizeAreaScale); 2163 } 2164 2165 if (mCalibration.haveToolSizeAreaBias) { 2166 dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n", 2167 mCalibration.toolSizeAreaBias); 2168 } 2169 2170 if (mCalibration.haveToolSizeIsSummed) { 2171 dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %s\n", 2172 toString(mCalibration.toolSizeIsSummed)); 2173 } 2174 2175 // Pressure 2176 switch (mCalibration.pressureCalibration) { 2177 case Calibration::PRESSURE_CALIBRATION_NONE: 2178 dump.append(INDENT4 "touch.pressure.calibration: none\n"); 2179 break; 2180 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 2181 dump.append(INDENT4 "touch.pressure.calibration: physical\n"); 2182 break; 2183 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 2184 dump.append(INDENT4 "touch.pressure.calibration: amplitude\n"); 2185 break; 2186 default: 2187 assert(false); 2188 } 2189 2190 switch (mCalibration.pressureSource) { 2191 case Calibration::PRESSURE_SOURCE_PRESSURE: 2192 dump.append(INDENT4 "touch.pressure.source: pressure\n"); 2193 break; 2194 case Calibration::PRESSURE_SOURCE_TOUCH: 2195 dump.append(INDENT4 "touch.pressure.source: touch\n"); 2196 break; 2197 case Calibration::PRESSURE_SOURCE_DEFAULT: 2198 break; 2199 default: 2200 assert(false); 2201 } 2202 2203 if (mCalibration.havePressureScale) { 2204 dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n", 2205 mCalibration.pressureScale); 2206 } 2207 2208 // Size 2209 switch (mCalibration.sizeCalibration) { 2210 case Calibration::SIZE_CALIBRATION_NONE: 2211 dump.append(INDENT4 "touch.size.calibration: none\n"); 2212 break; 2213 case Calibration::SIZE_CALIBRATION_NORMALIZED: 2214 dump.append(INDENT4 "touch.size.calibration: normalized\n"); 2215 break; 2216 default: 2217 assert(false); 2218 } 2219 2220 // Orientation 2221 switch (mCalibration.orientationCalibration) { 2222 case Calibration::ORIENTATION_CALIBRATION_NONE: 2223 dump.append(INDENT4 "touch.orientation.calibration: none\n"); 2224 break; 2225 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 2226 dump.append(INDENT4 "touch.orientation.calibration: interpolated\n"); 2227 break; 2228 case Calibration::ORIENTATION_CALIBRATION_VECTOR: 2229 dump.append(INDENT4 "touch.orientation.calibration: vector\n"); 2230 break; 2231 default: 2232 assert(false); 2233 } 2234} 2235 2236void TouchInputMapper::reset() { 2237 // Synthesize touch up event if touch is currently down. 2238 // This will also take care of finishing virtual key processing if needed. 2239 if (mLastTouch.pointerCount != 0) { 2240 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 2241 mCurrentTouch.clear(); 2242 syncTouch(when, true); 2243 } 2244 2245 { // acquire lock 2246 AutoMutex _l(mLock); 2247 initializeLocked(); 2248 } // release lock 2249 2250 InputMapper::reset(); 2251} 2252 2253void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) { 2254 uint32_t policyFlags = 0; 2255 2256 // Preprocess pointer data. 2257 2258 if (mParameters.useBadTouchFilter) { 2259 if (applyBadTouchFilter()) { 2260 havePointerIds = false; 2261 } 2262 } 2263 2264 if (mParameters.useJumpyTouchFilter) { 2265 if (applyJumpyTouchFilter()) { 2266 havePointerIds = false; 2267 } 2268 } 2269 2270 if (! havePointerIds) { 2271 calculatePointerIds(); 2272 } 2273 2274 TouchData temp; 2275 TouchData* savedTouch; 2276 if (mParameters.useAveragingTouchFilter) { 2277 temp.copyFrom(mCurrentTouch); 2278 savedTouch = & temp; 2279 2280 applyAveragingTouchFilter(); 2281 } else { 2282 savedTouch = & mCurrentTouch; 2283 } 2284 2285 // Process touches and virtual keys. 2286 2287 TouchResult touchResult = consumeOffScreenTouches(when, policyFlags); 2288 if (touchResult == DISPATCH_TOUCH) { 2289 detectGestures(when); 2290 dispatchTouches(when, policyFlags); 2291 } 2292 2293 // Copy current touch to last touch in preparation for the next cycle. 2294 2295 if (touchResult == DROP_STROKE) { 2296 mLastTouch.clear(); 2297 } else { 2298 mLastTouch.copyFrom(*savedTouch); 2299 } 2300} 2301 2302TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches( 2303 nsecs_t when, uint32_t policyFlags) { 2304 int32_t keyEventAction, keyEventFlags; 2305 int32_t keyCode, scanCode, downTime; 2306 TouchResult touchResult; 2307 2308 { // acquire lock 2309 AutoMutex _l(mLock); 2310 2311 // Update surface size and orientation, including virtual key positions. 2312 if (! configureSurfaceLocked()) { 2313 return DROP_STROKE; 2314 } 2315 2316 // Check for virtual key press. 2317 if (mLocked.currentVirtualKey.down) { 2318 if (mCurrentTouch.pointerCount == 0) { 2319 // Pointer went up while virtual key was down. 2320 mLocked.currentVirtualKey.down = false; 2321#if DEBUG_VIRTUAL_KEYS 2322 LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d", 2323 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 2324#endif 2325 keyEventAction = AKEY_EVENT_ACTION_UP; 2326 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 2327 touchResult = SKIP_TOUCH; 2328 goto DispatchVirtualKey; 2329 } 2330 2331 if (mCurrentTouch.pointerCount == 1) { 2332 int32_t x = mCurrentTouch.pointers[0].x; 2333 int32_t y = mCurrentTouch.pointers[0].y; 2334 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 2335 if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) { 2336 // Pointer is still within the space of the virtual key. 2337 return SKIP_TOUCH; 2338 } 2339 } 2340 2341 // Pointer left virtual key area or another pointer also went down. 2342 // Send key cancellation and drop the stroke so subsequent motions will be 2343 // considered fresh downs. This is useful when the user swipes away from the 2344 // virtual key area into the main display surface. 2345 mLocked.currentVirtualKey.down = false; 2346#if DEBUG_VIRTUAL_KEYS 2347 LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d", 2348 mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode); 2349#endif 2350 keyEventAction = AKEY_EVENT_ACTION_UP; 2351 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY 2352 | AKEY_EVENT_FLAG_CANCELED; 2353 2354 // Check whether the pointer moved inside the display area where we should 2355 // start a new stroke. 2356 int32_t x = mCurrentTouch.pointers[0].x; 2357 int32_t y = mCurrentTouch.pointers[0].y; 2358 if (isPointInsideSurfaceLocked(x, y)) { 2359 mLastTouch.clear(); 2360 touchResult = DISPATCH_TOUCH; 2361 } else { 2362 touchResult = DROP_STROKE; 2363 } 2364 } else { 2365 if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) { 2366 // Pointer just went down. Handle off-screen touches, if needed. 2367 int32_t x = mCurrentTouch.pointers[0].x; 2368 int32_t y = mCurrentTouch.pointers[0].y; 2369 if (! isPointInsideSurfaceLocked(x, y)) { 2370 // If exactly one pointer went down, check for virtual key hit. 2371 // Otherwise we will drop the entire stroke. 2372 if (mCurrentTouch.pointerCount == 1) { 2373 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y); 2374 if (virtualKey) { 2375 if (mContext->shouldDropVirtualKey(when, getDevice(), 2376 virtualKey->keyCode, virtualKey->scanCode)) { 2377 return DROP_STROKE; 2378 } 2379 2380 mLocked.currentVirtualKey.down = true; 2381 mLocked.currentVirtualKey.downTime = when; 2382 mLocked.currentVirtualKey.keyCode = virtualKey->keyCode; 2383 mLocked.currentVirtualKey.scanCode = virtualKey->scanCode; 2384#if DEBUG_VIRTUAL_KEYS 2385 LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d", 2386 mLocked.currentVirtualKey.keyCode, 2387 mLocked.currentVirtualKey.scanCode); 2388#endif 2389 keyEventAction = AKEY_EVENT_ACTION_DOWN; 2390 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM 2391 | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 2392 touchResult = SKIP_TOUCH; 2393 goto DispatchVirtualKey; 2394 } 2395 } 2396 return DROP_STROKE; 2397 } 2398 } 2399 return DISPATCH_TOUCH; 2400 } 2401 2402 DispatchVirtualKey: 2403 // Collect remaining state needed to dispatch virtual key. 2404 keyCode = mLocked.currentVirtualKey.keyCode; 2405 scanCode = mLocked.currentVirtualKey.scanCode; 2406 downTime = mLocked.currentVirtualKey.downTime; 2407 } // release lock 2408 2409 // Dispatch virtual key. 2410 int32_t metaState = mContext->getGlobalMetaState(); 2411 policyFlags |= POLICY_FLAG_VIRTUAL; 2412 getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags, 2413 keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime); 2414 return touchResult; 2415} 2416 2417void TouchInputMapper::detectGestures(nsecs_t when) { 2418 // Disable all virtual key touches that happen within a short time interval of the 2419 // most recent touch. The idea is to filter out stray virtual key presses when 2420 // interacting with the touch screen. 2421 // 2422 // Problems we're trying to solve: 2423 // 2424 // 1. While scrolling a list or dragging the window shade, the user swipes down into a 2425 // virtual key area that is implemented by a separate touch panel and accidentally 2426 // triggers a virtual key. 2427 // 2428 // 2. While typing in the on screen keyboard, the user taps slightly outside the screen 2429 // area and accidentally triggers a virtual key. This often happens when virtual keys 2430 // are layed out below the screen near to where the on screen keyboard's space bar 2431 // is displayed. 2432 if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) { 2433 mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime); 2434 } 2435} 2436 2437void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) { 2438 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 2439 uint32_t lastPointerCount = mLastTouch.pointerCount; 2440 if (currentPointerCount == 0 && lastPointerCount == 0) { 2441 return; // nothing to do! 2442 } 2443 2444 BitSet32 currentIdBits = mCurrentTouch.idBits; 2445 BitSet32 lastIdBits = mLastTouch.idBits; 2446 2447 if (currentIdBits == lastIdBits) { 2448 // No pointer id changes so this is a move event. 2449 // The dispatcher takes care of batching moves so we don't have to deal with that here. 2450 int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE; 2451 dispatchTouch(when, policyFlags, & mCurrentTouch, 2452 currentIdBits, -1, currentPointerCount, motionEventAction); 2453 } else { 2454 // There may be pointers going up and pointers going down and pointers moving 2455 // all at the same time. 2456 BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value); 2457 BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value); 2458 BitSet32 activeIdBits(lastIdBits.value); 2459 uint32_t pointerCount = lastPointerCount; 2460 2461 // Produce an intermediate representation of the touch data that consists of the 2462 // old location of pointers that have just gone up and the new location of pointers that 2463 // have just moved but omits the location of pointers that have just gone down. 2464 TouchData interimTouch; 2465 interimTouch.copyFrom(mLastTouch); 2466 2467 BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value); 2468 bool moveNeeded = false; 2469 while (!moveIdBits.isEmpty()) { 2470 uint32_t moveId = moveIdBits.firstMarkedBit(); 2471 moveIdBits.clearBit(moveId); 2472 2473 int32_t oldIndex = mLastTouch.idToIndex[moveId]; 2474 int32_t newIndex = mCurrentTouch.idToIndex[moveId]; 2475 if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) { 2476 interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex]; 2477 moveNeeded = true; 2478 } 2479 } 2480 2481 // Dispatch pointer up events using the interim pointer locations. 2482 while (!upIdBits.isEmpty()) { 2483 uint32_t upId = upIdBits.firstMarkedBit(); 2484 upIdBits.clearBit(upId); 2485 BitSet32 oldActiveIdBits = activeIdBits; 2486 activeIdBits.clearBit(upId); 2487 2488 int32_t motionEventAction; 2489 if (activeIdBits.isEmpty()) { 2490 motionEventAction = AMOTION_EVENT_ACTION_UP; 2491 } else { 2492 motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP; 2493 } 2494 2495 dispatchTouch(when, policyFlags, &interimTouch, 2496 oldActiveIdBits, upId, pointerCount, motionEventAction); 2497 pointerCount -= 1; 2498 } 2499 2500 // Dispatch move events if any of the remaining pointers moved from their old locations. 2501 // Although applications receive new locations as part of individual pointer up 2502 // events, they do not generally handle them except when presented in a move event. 2503 if (moveNeeded) { 2504 dispatchTouch(when, policyFlags, &mCurrentTouch, 2505 activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE); 2506 } 2507 2508 // Dispatch pointer down events using the new pointer locations. 2509 while (!downIdBits.isEmpty()) { 2510 uint32_t downId = downIdBits.firstMarkedBit(); 2511 downIdBits.clearBit(downId); 2512 BitSet32 oldActiveIdBits = activeIdBits; 2513 activeIdBits.markBit(downId); 2514 2515 int32_t motionEventAction; 2516 if (oldActiveIdBits.isEmpty()) { 2517 motionEventAction = AMOTION_EVENT_ACTION_DOWN; 2518 mDownTime = when; 2519 } else { 2520 motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN; 2521 } 2522 2523 pointerCount += 1; 2524 dispatchTouch(when, policyFlags, &mCurrentTouch, 2525 activeIdBits, downId, pointerCount, motionEventAction); 2526 } 2527 } 2528} 2529 2530void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, 2531 TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount, 2532 int32_t motionEventAction) { 2533 int32_t pointerIds[MAX_POINTERS]; 2534 PointerCoords pointerCoords[MAX_POINTERS]; 2535 int32_t motionEventEdgeFlags = 0; 2536 float xPrecision, yPrecision; 2537 2538 { // acquire lock 2539 AutoMutex _l(mLock); 2540 2541 // Walk through the the active pointers and map touch screen coordinates (TouchData) into 2542 // display coordinates (PointerCoords) and adjust for display orientation. 2543 for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) { 2544 uint32_t id = idBits.firstMarkedBit(); 2545 idBits.clearBit(id); 2546 uint32_t inIndex = touch->idToIndex[id]; 2547 2548 const PointerData& in = touch->pointers[inIndex]; 2549 2550 // X and Y 2551 float x = float(in.x - mLocked.xOrigin) * mLocked.xScale; 2552 float y = float(in.y - mLocked.yOrigin) * mLocked.yScale; 2553 2554 // ToolMajor and ToolMinor 2555 float toolMajor, toolMinor; 2556 switch (mCalibration.toolSizeCalibration) { 2557 case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: 2558 toolMajor = in.toolMajor * mLocked.geometricScale; 2559 if (mRawAxes.toolMinor.valid) { 2560 toolMinor = in.toolMinor * mLocked.geometricScale; 2561 } else { 2562 toolMinor = toolMajor; 2563 } 2564 break; 2565 case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: 2566 toolMajor = in.toolMajor != 0 2567 ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias 2568 : 0; 2569 if (mRawAxes.toolMinor.valid) { 2570 toolMinor = in.toolMinor != 0 2571 ? in.toolMinor * mLocked.toolSizeLinearScale 2572 + mLocked.toolSizeLinearBias 2573 : 0; 2574 } else { 2575 toolMinor = toolMajor; 2576 } 2577 break; 2578 case Calibration::TOOL_SIZE_CALIBRATION_AREA: 2579 if (in.toolMajor != 0) { 2580 float diameter = sqrtf(in.toolMajor 2581 * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias); 2582 toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias; 2583 } else { 2584 toolMajor = 0; 2585 } 2586 toolMinor = toolMajor; 2587 break; 2588 default: 2589 toolMajor = 0; 2590 toolMinor = 0; 2591 break; 2592 } 2593 2594 if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) { 2595 toolMajor /= pointerCount; 2596 toolMinor /= pointerCount; 2597 } 2598 2599 // Pressure 2600 float rawPressure; 2601 switch (mCalibration.pressureSource) { 2602 case Calibration::PRESSURE_SOURCE_PRESSURE: 2603 rawPressure = in.pressure; 2604 break; 2605 case Calibration::PRESSURE_SOURCE_TOUCH: 2606 rawPressure = in.touchMajor; 2607 break; 2608 default: 2609 rawPressure = 0; 2610 } 2611 2612 float pressure; 2613 switch (mCalibration.pressureCalibration) { 2614 case Calibration::PRESSURE_CALIBRATION_PHYSICAL: 2615 case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: 2616 pressure = rawPressure * mLocked.pressureScale; 2617 break; 2618 default: 2619 pressure = 1; 2620 break; 2621 } 2622 2623 // TouchMajor and TouchMinor 2624 float touchMajor, touchMinor; 2625 switch (mCalibration.touchSizeCalibration) { 2626 case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: 2627 touchMajor = in.touchMajor * mLocked.geometricScale; 2628 if (mRawAxes.touchMinor.valid) { 2629 touchMinor = in.touchMinor * mLocked.geometricScale; 2630 } else { 2631 touchMinor = touchMajor; 2632 } 2633 break; 2634 case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: 2635 touchMajor = toolMajor * pressure; 2636 touchMinor = toolMinor * pressure; 2637 break; 2638 default: 2639 touchMajor = 0; 2640 touchMinor = 0; 2641 break; 2642 } 2643 2644 if (touchMajor > toolMajor) { 2645 touchMajor = toolMajor; 2646 } 2647 if (touchMinor > toolMinor) { 2648 touchMinor = toolMinor; 2649 } 2650 2651 // Size 2652 float size; 2653 switch (mCalibration.sizeCalibration) { 2654 case Calibration::SIZE_CALIBRATION_NORMALIZED: { 2655 float rawSize = mRawAxes.toolMinor.valid 2656 ? avg(in.toolMajor, in.toolMinor) 2657 : in.toolMajor; 2658 size = rawSize * mLocked.sizeScale; 2659 break; 2660 } 2661 default: 2662 size = 0; 2663 break; 2664 } 2665 2666 // Orientation 2667 float orientation; 2668 switch (mCalibration.orientationCalibration) { 2669 case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED: 2670 orientation = in.orientation * mLocked.orientationScale; 2671 break; 2672 case Calibration::ORIENTATION_CALIBRATION_VECTOR: { 2673 int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4); 2674 int32_t c2 = signExtendNybble(in.orientation & 0x0f); 2675 if (c1 != 0 || c2 != 0) { 2676 orientation = atan2f(c1, c2) * 0.5f; 2677 float scale = 1.0f + pythag(c1, c2) / 16.0f; 2678 touchMajor *= scale; 2679 touchMinor /= scale; 2680 toolMajor *= scale; 2681 toolMinor /= scale; 2682 } else { 2683 orientation = 0; 2684 } 2685 break; 2686 } 2687 default: 2688 orientation = 0; 2689 } 2690 2691 // Adjust coords for orientation. 2692 switch (mLocked.surfaceOrientation) { 2693 case DISPLAY_ORIENTATION_90: { 2694 float xTemp = x; 2695 x = y; 2696 y = mLocked.surfaceWidth - xTemp; 2697 orientation -= M_PI_2; 2698 if (orientation < - M_PI_2) { 2699 orientation += M_PI; 2700 } 2701 break; 2702 } 2703 case DISPLAY_ORIENTATION_180: { 2704 x = mLocked.surfaceWidth - x; 2705 y = mLocked.surfaceHeight - y; 2706 break; 2707 } 2708 case DISPLAY_ORIENTATION_270: { 2709 float xTemp = x; 2710 x = mLocked.surfaceHeight - y; 2711 y = xTemp; 2712 orientation += M_PI_2; 2713 if (orientation > M_PI_2) { 2714 orientation -= M_PI; 2715 } 2716 break; 2717 } 2718 } 2719 2720 // Write output coords. 2721 PointerCoords& out = pointerCoords[outIndex]; 2722 out.clear(); 2723 out.setAxisValue(AMOTION_EVENT_AXIS_X, x); 2724 out.setAxisValue(AMOTION_EVENT_AXIS_Y, y); 2725 out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure); 2726 out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size); 2727 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor); 2728 out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor); 2729 out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor); 2730 out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor); 2731 out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation); 2732 2733 pointerIds[outIndex] = int32_t(id); 2734 2735 if (id == changedId) { 2736 motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 2737 } 2738 } 2739 2740 // Check edge flags by looking only at the first pointer since the flags are 2741 // global to the event. 2742 if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) { 2743 float x = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X); 2744 float y = pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y); 2745 2746 if (x <= 0) { 2747 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT; 2748 } else if (x >= mLocked.orientedSurfaceWidth) { 2749 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT; 2750 } 2751 if (y <= 0) { 2752 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP; 2753 } else if (y >= mLocked.orientedSurfaceHeight) { 2754 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM; 2755 } 2756 } 2757 2758 xPrecision = mLocked.orientedXPrecision; 2759 yPrecision = mLocked.orientedYPrecision; 2760 } // release lock 2761 2762 getDispatcher()->notifyMotion(when, getDeviceId(), mSources, policyFlags, 2763 motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags, 2764 pointerCount, pointerIds, pointerCoords, 2765 xPrecision, yPrecision, mDownTime); 2766} 2767 2768bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) { 2769 if (mRawAxes.x.valid && mRawAxes.y.valid) { 2770 return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue 2771 && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue; 2772 } 2773 return true; 2774} 2775 2776const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked( 2777 int32_t x, int32_t y) { 2778 size_t numVirtualKeys = mLocked.virtualKeys.size(); 2779 for (size_t i = 0; i < numVirtualKeys; i++) { 2780 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 2781 2782#if DEBUG_VIRTUAL_KEYS 2783 LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, " 2784 "left=%d, top=%d, right=%d, bottom=%d", 2785 x, y, 2786 virtualKey.keyCode, virtualKey.scanCode, 2787 virtualKey.hitLeft, virtualKey.hitTop, 2788 virtualKey.hitRight, virtualKey.hitBottom); 2789#endif 2790 2791 if (virtualKey.isHit(x, y)) { 2792 return & virtualKey; 2793 } 2794 } 2795 2796 return NULL; 2797} 2798 2799void TouchInputMapper::calculatePointerIds() { 2800 uint32_t currentPointerCount = mCurrentTouch.pointerCount; 2801 uint32_t lastPointerCount = mLastTouch.pointerCount; 2802 2803 if (currentPointerCount == 0) { 2804 // No pointers to assign. 2805 mCurrentTouch.idBits.clear(); 2806 } else if (lastPointerCount == 0) { 2807 // All pointers are new. 2808 mCurrentTouch.idBits.clear(); 2809 for (uint32_t i = 0; i < currentPointerCount; i++) { 2810 mCurrentTouch.pointers[i].id = i; 2811 mCurrentTouch.idToIndex[i] = i; 2812 mCurrentTouch.idBits.markBit(i); 2813 } 2814 } else if (currentPointerCount == 1 && lastPointerCount == 1) { 2815 // Only one pointer and no change in count so it must have the same id as before. 2816 uint32_t id = mLastTouch.pointers[0].id; 2817 mCurrentTouch.pointers[0].id = id; 2818 mCurrentTouch.idToIndex[id] = 0; 2819 mCurrentTouch.idBits.value = BitSet32::valueForBit(id); 2820 } else { 2821 // General case. 2822 // We build a heap of squared euclidean distances between current and last pointers 2823 // associated with the current and last pointer indices. Then, we find the best 2824 // match (by distance) for each current pointer. 2825 PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS]; 2826 2827 uint32_t heapSize = 0; 2828 for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount; 2829 currentPointerIndex++) { 2830 for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount; 2831 lastPointerIndex++) { 2832 int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x 2833 - mLastTouch.pointers[lastPointerIndex].x; 2834 int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y 2835 - mLastTouch.pointers[lastPointerIndex].y; 2836 2837 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); 2838 2839 // Insert new element into the heap (sift up). 2840 heap[heapSize].currentPointerIndex = currentPointerIndex; 2841 heap[heapSize].lastPointerIndex = lastPointerIndex; 2842 heap[heapSize].distance = distance; 2843 heapSize += 1; 2844 } 2845 } 2846 2847 // Heapify 2848 for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) { 2849 startIndex -= 1; 2850 for (uint32_t parentIndex = startIndex; ;) { 2851 uint32_t childIndex = parentIndex * 2 + 1; 2852 if (childIndex >= heapSize) { 2853 break; 2854 } 2855 2856 if (childIndex + 1 < heapSize 2857 && heap[childIndex + 1].distance < heap[childIndex].distance) { 2858 childIndex += 1; 2859 } 2860 2861 if (heap[parentIndex].distance <= heap[childIndex].distance) { 2862 break; 2863 } 2864 2865 swap(heap[parentIndex], heap[childIndex]); 2866 parentIndex = childIndex; 2867 } 2868 } 2869 2870#if DEBUG_POINTER_ASSIGNMENT 2871 LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize); 2872 for (size_t i = 0; i < heapSize; i++) { 2873 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 2874 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 2875 heap[i].distance); 2876 } 2877#endif 2878 2879 // Pull matches out by increasing order of distance. 2880 // To avoid reassigning pointers that have already been matched, the loop keeps track 2881 // of which last and current pointers have been matched using the matchedXXXBits variables. 2882 // It also tracks the used pointer id bits. 2883 BitSet32 matchedLastBits(0); 2884 BitSet32 matchedCurrentBits(0); 2885 BitSet32 usedIdBits(0); 2886 bool first = true; 2887 for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) { 2888 for (;;) { 2889 if (first) { 2890 // The first time through the loop, we just consume the root element of 2891 // the heap (the one with smallest distance). 2892 first = false; 2893 } else { 2894 // Previous iterations consumed the root element of the heap. 2895 // Pop root element off of the heap (sift down). 2896 heapSize -= 1; 2897 assert(heapSize > 0); 2898 2899 // Sift down. 2900 heap[0] = heap[heapSize]; 2901 for (uint32_t parentIndex = 0; ;) { 2902 uint32_t childIndex = parentIndex * 2 + 1; 2903 if (childIndex >= heapSize) { 2904 break; 2905 } 2906 2907 if (childIndex + 1 < heapSize 2908 && heap[childIndex + 1].distance < heap[childIndex].distance) { 2909 childIndex += 1; 2910 } 2911 2912 if (heap[parentIndex].distance <= heap[childIndex].distance) { 2913 break; 2914 } 2915 2916 swap(heap[parentIndex], heap[childIndex]); 2917 parentIndex = childIndex; 2918 } 2919 2920#if DEBUG_POINTER_ASSIGNMENT 2921 LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize); 2922 for (size_t i = 0; i < heapSize; i++) { 2923 LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld", 2924 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex, 2925 heap[i].distance); 2926 } 2927#endif 2928 } 2929 2930 uint32_t currentPointerIndex = heap[0].currentPointerIndex; 2931 if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched 2932 2933 uint32_t lastPointerIndex = heap[0].lastPointerIndex; 2934 if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched 2935 2936 matchedCurrentBits.markBit(currentPointerIndex); 2937 matchedLastBits.markBit(lastPointerIndex); 2938 2939 uint32_t id = mLastTouch.pointers[lastPointerIndex].id; 2940 mCurrentTouch.pointers[currentPointerIndex].id = id; 2941 mCurrentTouch.idToIndex[id] = currentPointerIndex; 2942 usedIdBits.markBit(id); 2943 2944#if DEBUG_POINTER_ASSIGNMENT 2945 LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld", 2946 lastPointerIndex, currentPointerIndex, id, heap[0].distance); 2947#endif 2948 break; 2949 } 2950 } 2951 2952 // Assign fresh ids to new pointers. 2953 if (currentPointerCount > lastPointerCount) { 2954 for (uint32_t i = currentPointerCount - lastPointerCount; ;) { 2955 uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit(); 2956 uint32_t id = usedIdBits.firstUnmarkedBit(); 2957 2958 mCurrentTouch.pointers[currentPointerIndex].id = id; 2959 mCurrentTouch.idToIndex[id] = currentPointerIndex; 2960 usedIdBits.markBit(id); 2961 2962#if DEBUG_POINTER_ASSIGNMENT 2963 LOGD("calculatePointerIds - assigned: cur=%d, id=%d", 2964 currentPointerIndex, id); 2965#endif 2966 2967 if (--i == 0) break; // done 2968 matchedCurrentBits.markBit(currentPointerIndex); 2969 } 2970 } 2971 2972 // Fix id bits. 2973 mCurrentTouch.idBits = usedIdBits; 2974 } 2975} 2976 2977/* Special hack for devices that have bad screen data: if one of the 2978 * points has moved more than a screen height from the last position, 2979 * then drop it. */ 2980bool TouchInputMapper::applyBadTouchFilter() { 2981 // This hack requires valid axis parameters. 2982 if (! mRawAxes.y.valid) { 2983 return false; 2984 } 2985 2986 uint32_t pointerCount = mCurrentTouch.pointerCount; 2987 2988 // Nothing to do if there are no points. 2989 if (pointerCount == 0) { 2990 return false; 2991 } 2992 2993 // Don't do anything if a finger is going down or up. We run 2994 // here before assigning pointer IDs, so there isn't a good 2995 // way to do per-finger matching. 2996 if (pointerCount != mLastTouch.pointerCount) { 2997 return false; 2998 } 2999 3000 // We consider a single movement across more than a 7/16 of 3001 // the long size of the screen to be bad. This was a magic value 3002 // determined by looking at the maximum distance it is feasible 3003 // to actually move in one sample. 3004 int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16; 3005 3006 // XXX The original code in InputDevice.java included commented out 3007 // code for testing the X axis. Note that when we drop a point 3008 // we don't actually restore the old X either. Strange. 3009 // The old code also tries to track when bad points were previously 3010 // detected but it turns out that due to the placement of a "break" 3011 // at the end of the loop, we never set mDroppedBadPoint to true 3012 // so it is effectively dead code. 3013 // Need to figure out if the old code is busted or just overcomplicated 3014 // but working as intended. 3015 3016 // Look through all new points and see if any are farther than 3017 // acceptable from all previous points. 3018 for (uint32_t i = pointerCount; i-- > 0; ) { 3019 int32_t y = mCurrentTouch.pointers[i].y; 3020 int32_t closestY = INT_MAX; 3021 int32_t closestDeltaY = 0; 3022 3023#if DEBUG_HACKS 3024 LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y); 3025#endif 3026 3027 for (uint32_t j = pointerCount; j-- > 0; ) { 3028 int32_t lastY = mLastTouch.pointers[j].y; 3029 int32_t deltaY = abs(y - lastY); 3030 3031#if DEBUG_HACKS 3032 LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d", 3033 j, lastY, deltaY); 3034#endif 3035 3036 if (deltaY < maxDeltaY) { 3037 goto SkipSufficientlyClosePoint; 3038 } 3039 if (deltaY < closestDeltaY) { 3040 closestDeltaY = deltaY; 3041 closestY = lastY; 3042 } 3043 } 3044 3045 // Must not have found a close enough match. 3046#if DEBUG_HACKS 3047 LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d", 3048 i, y, closestY, closestDeltaY, maxDeltaY); 3049#endif 3050 3051 mCurrentTouch.pointers[i].y = closestY; 3052 return true; // XXX original code only corrects one point 3053 3054 SkipSufficientlyClosePoint: ; 3055 } 3056 3057 // No change. 3058 return false; 3059} 3060 3061/* Special hack for devices that have bad screen data: drop points where 3062 * the coordinate value for one axis has jumped to the other pointer's location. 3063 */ 3064bool TouchInputMapper::applyJumpyTouchFilter() { 3065 // This hack requires valid axis parameters. 3066 if (! mRawAxes.y.valid) { 3067 return false; 3068 } 3069 3070 uint32_t pointerCount = mCurrentTouch.pointerCount; 3071 if (mLastTouch.pointerCount != pointerCount) { 3072#if DEBUG_HACKS 3073 LOGD("JumpyTouchFilter: Different pointer count %d -> %d", 3074 mLastTouch.pointerCount, pointerCount); 3075 for (uint32_t i = 0; i < pointerCount; i++) { 3076 LOGD(" Pointer %d (%d, %d)", i, 3077 mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); 3078 } 3079#endif 3080 3081 if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) { 3082 if (mLastTouch.pointerCount == 1 && pointerCount == 2) { 3083 // Just drop the first few events going from 1 to 2 pointers. 3084 // They're bad often enough that they're not worth considering. 3085 mCurrentTouch.pointerCount = 1; 3086 mJumpyTouchFilter.jumpyPointsDropped += 1; 3087 3088#if DEBUG_HACKS 3089 LOGD("JumpyTouchFilter: Pointer 2 dropped"); 3090#endif 3091 return true; 3092 } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) { 3093 // The event when we go from 2 -> 1 tends to be messed up too 3094 mCurrentTouch.pointerCount = 2; 3095 mCurrentTouch.pointers[0] = mLastTouch.pointers[0]; 3096 mCurrentTouch.pointers[1] = mLastTouch.pointers[1]; 3097 mJumpyTouchFilter.jumpyPointsDropped += 1; 3098 3099#if DEBUG_HACKS 3100 for (int32_t i = 0; i < 2; i++) { 3101 LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i, 3102 mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y); 3103 } 3104#endif 3105 return true; 3106 } 3107 } 3108 // Reset jumpy points dropped on other transitions or if limit exceeded. 3109 mJumpyTouchFilter.jumpyPointsDropped = 0; 3110 3111#if DEBUG_HACKS 3112 LOGD("JumpyTouchFilter: Transition - drop limit reset"); 3113#endif 3114 return false; 3115 } 3116 3117 // We have the same number of pointers as last time. 3118 // A 'jumpy' point is one where the coordinate value for one axis 3119 // has jumped to the other pointer's location. No need to do anything 3120 // else if we only have one pointer. 3121 if (pointerCount < 2) { 3122 return false; 3123 } 3124 3125 if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) { 3126 int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR; 3127 3128 // We only replace the single worst jumpy point as characterized by pointer distance 3129 // in a single axis. 3130 int32_t badPointerIndex = -1; 3131 int32_t badPointerReplacementIndex = -1; 3132 int32_t badPointerDistance = INT_MIN; // distance to be corrected 3133 3134 for (uint32_t i = pointerCount; i-- > 0; ) { 3135 int32_t x = mCurrentTouch.pointers[i].x; 3136 int32_t y = mCurrentTouch.pointers[i].y; 3137 3138#if DEBUG_HACKS 3139 LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y); 3140#endif 3141 3142 // Check if a touch point is too close to another's coordinates 3143 bool dropX = false, dropY = false; 3144 for (uint32_t j = 0; j < pointerCount; j++) { 3145 if (i == j) { 3146 continue; 3147 } 3148 3149 if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) { 3150 dropX = true; 3151 break; 3152 } 3153 3154 if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) { 3155 dropY = true; 3156 break; 3157 } 3158 } 3159 if (! dropX && ! dropY) { 3160 continue; // not jumpy 3161 } 3162 3163 // Find a replacement candidate by comparing with older points on the 3164 // complementary (non-jumpy) axis. 3165 int32_t distance = INT_MIN; // distance to be corrected 3166 int32_t replacementIndex = -1; 3167 3168 if (dropX) { 3169 // X looks too close. Find an older replacement point with a close Y. 3170 int32_t smallestDeltaY = INT_MAX; 3171 for (uint32_t j = 0; j < pointerCount; j++) { 3172 int32_t deltaY = abs(y - mLastTouch.pointers[j].y); 3173 if (deltaY < smallestDeltaY) { 3174 smallestDeltaY = deltaY; 3175 replacementIndex = j; 3176 } 3177 } 3178 distance = abs(x - mLastTouch.pointers[replacementIndex].x); 3179 } else { 3180 // Y looks too close. Find an older replacement point with a close X. 3181 int32_t smallestDeltaX = INT_MAX; 3182 for (uint32_t j = 0; j < pointerCount; j++) { 3183 int32_t deltaX = abs(x - mLastTouch.pointers[j].x); 3184 if (deltaX < smallestDeltaX) { 3185 smallestDeltaX = deltaX; 3186 replacementIndex = j; 3187 } 3188 } 3189 distance = abs(y - mLastTouch.pointers[replacementIndex].y); 3190 } 3191 3192 // If replacing this pointer would correct a worse error than the previous ones 3193 // considered, then use this replacement instead. 3194 if (distance > badPointerDistance) { 3195 badPointerIndex = i; 3196 badPointerReplacementIndex = replacementIndex; 3197 badPointerDistance = distance; 3198 } 3199 } 3200 3201 // Correct the jumpy pointer if one was found. 3202 if (badPointerIndex >= 0) { 3203#if DEBUG_HACKS 3204 LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)", 3205 badPointerIndex, 3206 mLastTouch.pointers[badPointerReplacementIndex].x, 3207 mLastTouch.pointers[badPointerReplacementIndex].y); 3208#endif 3209 3210 mCurrentTouch.pointers[badPointerIndex].x = 3211 mLastTouch.pointers[badPointerReplacementIndex].x; 3212 mCurrentTouch.pointers[badPointerIndex].y = 3213 mLastTouch.pointers[badPointerReplacementIndex].y; 3214 mJumpyTouchFilter.jumpyPointsDropped += 1; 3215 return true; 3216 } 3217 } 3218 3219 mJumpyTouchFilter.jumpyPointsDropped = 0; 3220 return false; 3221} 3222 3223/* Special hack for devices that have bad screen data: aggregate and 3224 * compute averages of the coordinate data, to reduce the amount of 3225 * jitter seen by applications. */ 3226void TouchInputMapper::applyAveragingTouchFilter() { 3227 for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) { 3228 uint32_t id = mCurrentTouch.pointers[currentIndex].id; 3229 int32_t x = mCurrentTouch.pointers[currentIndex].x; 3230 int32_t y = mCurrentTouch.pointers[currentIndex].y; 3231 int32_t pressure; 3232 switch (mCalibration.pressureSource) { 3233 case Calibration::PRESSURE_SOURCE_PRESSURE: 3234 pressure = mCurrentTouch.pointers[currentIndex].pressure; 3235 break; 3236 case Calibration::PRESSURE_SOURCE_TOUCH: 3237 pressure = mCurrentTouch.pointers[currentIndex].touchMajor; 3238 break; 3239 default: 3240 pressure = 1; 3241 break; 3242 } 3243 3244 if (mLastTouch.idBits.hasBit(id)) { 3245 // Pointer was down before and is still down now. 3246 // Compute average over history trace. 3247 uint32_t start = mAveragingTouchFilter.historyStart[id]; 3248 uint32_t end = mAveragingTouchFilter.historyEnd[id]; 3249 3250 int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x; 3251 int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y; 3252 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY); 3253 3254#if DEBUG_HACKS 3255 LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld", 3256 id, distance); 3257#endif 3258 3259 if (distance < AVERAGING_DISTANCE_LIMIT) { 3260 // Increment end index in preparation for recording new historical data. 3261 end += 1; 3262 if (end > AVERAGING_HISTORY_SIZE) { 3263 end = 0; 3264 } 3265 3266 // If the end index has looped back to the start index then we have filled 3267 // the historical trace up to the desired size so we drop the historical 3268 // data at the start of the trace. 3269 if (end == start) { 3270 start += 1; 3271 if (start > AVERAGING_HISTORY_SIZE) { 3272 start = 0; 3273 } 3274 } 3275 3276 // Add the raw data to the historical trace. 3277 mAveragingTouchFilter.historyStart[id] = start; 3278 mAveragingTouchFilter.historyEnd[id] = end; 3279 mAveragingTouchFilter.historyData[end].pointers[id].x = x; 3280 mAveragingTouchFilter.historyData[end].pointers[id].y = y; 3281 mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure; 3282 3283 // Average over all historical positions in the trace by total pressure. 3284 int32_t averagedX = 0; 3285 int32_t averagedY = 0; 3286 int32_t totalPressure = 0; 3287 for (;;) { 3288 int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x; 3289 int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y; 3290 int32_t historicalPressure = mAveragingTouchFilter.historyData[start] 3291 .pointers[id].pressure; 3292 3293 averagedX += historicalX * historicalPressure; 3294 averagedY += historicalY * historicalPressure; 3295 totalPressure += historicalPressure; 3296 3297 if (start == end) { 3298 break; 3299 } 3300 3301 start += 1; 3302 if (start > AVERAGING_HISTORY_SIZE) { 3303 start = 0; 3304 } 3305 } 3306 3307 if (totalPressure != 0) { 3308 averagedX /= totalPressure; 3309 averagedY /= totalPressure; 3310 3311#if DEBUG_HACKS 3312 LOGD("AveragingTouchFilter: Pointer id %d - " 3313 "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure, 3314 averagedX, averagedY); 3315#endif 3316 3317 mCurrentTouch.pointers[currentIndex].x = averagedX; 3318 mCurrentTouch.pointers[currentIndex].y = averagedY; 3319 } 3320 } else { 3321#if DEBUG_HACKS 3322 LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id); 3323#endif 3324 } 3325 } else { 3326#if DEBUG_HACKS 3327 LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id); 3328#endif 3329 } 3330 3331 // Reset pointer history. 3332 mAveragingTouchFilter.historyStart[id] = 0; 3333 mAveragingTouchFilter.historyEnd[id] = 0; 3334 mAveragingTouchFilter.historyData[0].pointers[id].x = x; 3335 mAveragingTouchFilter.historyData[0].pointers[id].y = y; 3336 mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure; 3337 } 3338} 3339 3340int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) { 3341 { // acquire lock 3342 AutoMutex _l(mLock); 3343 3344 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) { 3345 return AKEY_STATE_VIRTUAL; 3346 } 3347 3348 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3349 for (size_t i = 0; i < numVirtualKeys; i++) { 3350 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3351 if (virtualKey.keyCode == keyCode) { 3352 return AKEY_STATE_UP; 3353 } 3354 } 3355 } // release lock 3356 3357 return AKEY_STATE_UNKNOWN; 3358} 3359 3360int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) { 3361 { // acquire lock 3362 AutoMutex _l(mLock); 3363 3364 if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) { 3365 return AKEY_STATE_VIRTUAL; 3366 } 3367 3368 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3369 for (size_t i = 0; i < numVirtualKeys; i++) { 3370 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3371 if (virtualKey.scanCode == scanCode) { 3372 return AKEY_STATE_UP; 3373 } 3374 } 3375 } // release lock 3376 3377 return AKEY_STATE_UNKNOWN; 3378} 3379 3380bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, 3381 const int32_t* keyCodes, uint8_t* outFlags) { 3382 { // acquire lock 3383 AutoMutex _l(mLock); 3384 3385 size_t numVirtualKeys = mLocked.virtualKeys.size(); 3386 for (size_t i = 0; i < numVirtualKeys; i++) { 3387 const VirtualKey& virtualKey = mLocked.virtualKeys[i]; 3388 3389 for (size_t i = 0; i < numCodes; i++) { 3390 if (virtualKey.keyCode == keyCodes[i]) { 3391 outFlags[i] = 1; 3392 } 3393 } 3394 } 3395 } // release lock 3396 3397 return true; 3398} 3399 3400 3401// --- SingleTouchInputMapper --- 3402 3403SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) : 3404 TouchInputMapper(device) { 3405 initialize(); 3406} 3407 3408SingleTouchInputMapper::~SingleTouchInputMapper() { 3409} 3410 3411void SingleTouchInputMapper::initialize() { 3412 mAccumulator.clear(); 3413 3414 mDown = false; 3415 mX = 0; 3416 mY = 0; 3417 mPressure = 0; // default to 0 for devices that don't report pressure 3418 mToolWidth = 0; // default to 0 for devices that don't report tool width 3419} 3420 3421void SingleTouchInputMapper::reset() { 3422 TouchInputMapper::reset(); 3423 3424 initialize(); 3425 } 3426 3427void SingleTouchInputMapper::process(const RawEvent* rawEvent) { 3428 switch (rawEvent->type) { 3429 case EV_KEY: 3430 switch (rawEvent->scanCode) { 3431 case BTN_TOUCH: 3432 mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH; 3433 mAccumulator.btnTouch = rawEvent->value != 0; 3434 // Don't sync immediately. Wait until the next SYN_REPORT since we might 3435 // not have received valid position information yet. This logic assumes that 3436 // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet. 3437 break; 3438 } 3439 break; 3440 3441 case EV_ABS: 3442 switch (rawEvent->scanCode) { 3443 case ABS_X: 3444 mAccumulator.fields |= Accumulator::FIELD_ABS_X; 3445 mAccumulator.absX = rawEvent->value; 3446 break; 3447 case ABS_Y: 3448 mAccumulator.fields |= Accumulator::FIELD_ABS_Y; 3449 mAccumulator.absY = rawEvent->value; 3450 break; 3451 case ABS_PRESSURE: 3452 mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE; 3453 mAccumulator.absPressure = rawEvent->value; 3454 break; 3455 case ABS_TOOL_WIDTH: 3456 mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH; 3457 mAccumulator.absToolWidth = rawEvent->value; 3458 break; 3459 } 3460 break; 3461 3462 case EV_SYN: 3463 switch (rawEvent->scanCode) { 3464 case SYN_REPORT: 3465 sync(rawEvent->when); 3466 break; 3467 } 3468 break; 3469 } 3470} 3471 3472void SingleTouchInputMapper::sync(nsecs_t when) { 3473 uint32_t fields = mAccumulator.fields; 3474 if (fields == 0) { 3475 return; // no new state changes, so nothing to do 3476 } 3477 3478 if (fields & Accumulator::FIELD_BTN_TOUCH) { 3479 mDown = mAccumulator.btnTouch; 3480 } 3481 3482 if (fields & Accumulator::FIELD_ABS_X) { 3483 mX = mAccumulator.absX; 3484 } 3485 3486 if (fields & Accumulator::FIELD_ABS_Y) { 3487 mY = mAccumulator.absY; 3488 } 3489 3490 if (fields & Accumulator::FIELD_ABS_PRESSURE) { 3491 mPressure = mAccumulator.absPressure; 3492 } 3493 3494 if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) { 3495 mToolWidth = mAccumulator.absToolWidth; 3496 } 3497 3498 mCurrentTouch.clear(); 3499 3500 if (mDown) { 3501 mCurrentTouch.pointerCount = 1; 3502 mCurrentTouch.pointers[0].id = 0; 3503 mCurrentTouch.pointers[0].x = mX; 3504 mCurrentTouch.pointers[0].y = mY; 3505 mCurrentTouch.pointers[0].pressure = mPressure; 3506 mCurrentTouch.pointers[0].touchMajor = 0; 3507 mCurrentTouch.pointers[0].touchMinor = 0; 3508 mCurrentTouch.pointers[0].toolMajor = mToolWidth; 3509 mCurrentTouch.pointers[0].toolMinor = mToolWidth; 3510 mCurrentTouch.pointers[0].orientation = 0; 3511 mCurrentTouch.idToIndex[0] = 0; 3512 mCurrentTouch.idBits.markBit(0); 3513 } 3514 3515 syncTouch(when, true); 3516 3517 mAccumulator.clear(); 3518} 3519 3520void SingleTouchInputMapper::configureRawAxes() { 3521 TouchInputMapper::configureRawAxes(); 3522 3523 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x); 3524 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y); 3525 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure); 3526 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor); 3527} 3528 3529 3530// --- MultiTouchInputMapper --- 3531 3532MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : 3533 TouchInputMapper(device) { 3534 initialize(); 3535} 3536 3537MultiTouchInputMapper::~MultiTouchInputMapper() { 3538} 3539 3540void MultiTouchInputMapper::initialize() { 3541 mAccumulator.clear(); 3542} 3543 3544void MultiTouchInputMapper::reset() { 3545 TouchInputMapper::reset(); 3546 3547 initialize(); 3548} 3549 3550void MultiTouchInputMapper::process(const RawEvent* rawEvent) { 3551 switch (rawEvent->type) { 3552 case EV_ABS: { 3553 uint32_t pointerIndex = mAccumulator.pointerCount; 3554 Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex]; 3555 3556 switch (rawEvent->scanCode) { 3557 case ABS_MT_POSITION_X: 3558 pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X; 3559 pointer->absMTPositionX = rawEvent->value; 3560 break; 3561 case ABS_MT_POSITION_Y: 3562 pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y; 3563 pointer->absMTPositionY = rawEvent->value; 3564 break; 3565 case ABS_MT_TOUCH_MAJOR: 3566 pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR; 3567 pointer->absMTTouchMajor = rawEvent->value; 3568 break; 3569 case ABS_MT_TOUCH_MINOR: 3570 pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR; 3571 pointer->absMTTouchMinor = rawEvent->value; 3572 break; 3573 case ABS_MT_WIDTH_MAJOR: 3574 pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR; 3575 pointer->absMTWidthMajor = rawEvent->value; 3576 break; 3577 case ABS_MT_WIDTH_MINOR: 3578 pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR; 3579 pointer->absMTWidthMinor = rawEvent->value; 3580 break; 3581 case ABS_MT_ORIENTATION: 3582 pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION; 3583 pointer->absMTOrientation = rawEvent->value; 3584 break; 3585 case ABS_MT_TRACKING_ID: 3586 pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID; 3587 pointer->absMTTrackingId = rawEvent->value; 3588 break; 3589 case ABS_MT_PRESSURE: 3590 pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE; 3591 pointer->absMTPressure = rawEvent->value; 3592 break; 3593 } 3594 break; 3595 } 3596 3597 case EV_SYN: 3598 switch (rawEvent->scanCode) { 3599 case SYN_MT_REPORT: { 3600 // MultiTouch Sync: The driver has returned all data for *one* of the pointers. 3601 uint32_t pointerIndex = mAccumulator.pointerCount; 3602 3603 if (mAccumulator.pointers[pointerIndex].fields) { 3604 if (pointerIndex == MAX_POINTERS) { 3605 LOGW("MultiTouch device driver returned more than maximum of %d pointers.", 3606 MAX_POINTERS); 3607 } else { 3608 pointerIndex += 1; 3609 mAccumulator.pointerCount = pointerIndex; 3610 } 3611 } 3612 3613 mAccumulator.pointers[pointerIndex].clear(); 3614 break; 3615 } 3616 3617 case SYN_REPORT: 3618 sync(rawEvent->when); 3619 break; 3620 } 3621 break; 3622 } 3623} 3624 3625void MultiTouchInputMapper::sync(nsecs_t when) { 3626 static const uint32_t REQUIRED_FIELDS = 3627 Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y; 3628 3629 uint32_t inCount = mAccumulator.pointerCount; 3630 uint32_t outCount = 0; 3631 bool havePointerIds = true; 3632 3633 mCurrentTouch.clear(); 3634 3635 for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) { 3636 const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex]; 3637 uint32_t fields = inPointer.fields; 3638 3639 if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) { 3640 // Some drivers send empty MT sync packets without X / Y to indicate a pointer up. 3641 // Drop this finger. 3642 continue; 3643 } 3644 3645 PointerData& outPointer = mCurrentTouch.pointers[outCount]; 3646 outPointer.x = inPointer.absMTPositionX; 3647 outPointer.y = inPointer.absMTPositionY; 3648 3649 if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) { 3650 if (inPointer.absMTPressure <= 0) { 3651 // Some devices send sync packets with X / Y but with a 0 pressure to indicate 3652 // a pointer going up. Drop this finger. 3653 continue; 3654 } 3655 outPointer.pressure = inPointer.absMTPressure; 3656 } else { 3657 // Default pressure to 0 if absent. 3658 outPointer.pressure = 0; 3659 } 3660 3661 if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) { 3662 if (inPointer.absMTTouchMajor <= 0) { 3663 // Some devices send sync packets with X / Y but with a 0 touch major to indicate 3664 // a pointer going up. Drop this finger. 3665 continue; 3666 } 3667 outPointer.touchMajor = inPointer.absMTTouchMajor; 3668 } else { 3669 // Default touch area to 0 if absent. 3670 outPointer.touchMajor = 0; 3671 } 3672 3673 if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) { 3674 outPointer.touchMinor = inPointer.absMTTouchMinor; 3675 } else { 3676 // Assume touch area is circular. 3677 outPointer.touchMinor = outPointer.touchMajor; 3678 } 3679 3680 if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) { 3681 outPointer.toolMajor = inPointer.absMTWidthMajor; 3682 } else { 3683 // Default tool area to 0 if absent. 3684 outPointer.toolMajor = 0; 3685 } 3686 3687 if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) { 3688 outPointer.toolMinor = inPointer.absMTWidthMinor; 3689 } else { 3690 // Assume tool area is circular. 3691 outPointer.toolMinor = outPointer.toolMajor; 3692 } 3693 3694 if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) { 3695 outPointer.orientation = inPointer.absMTOrientation; 3696 } else { 3697 // Default orientation to vertical if absent. 3698 outPointer.orientation = 0; 3699 } 3700 3701 // Assign pointer id using tracking id if available. 3702 if (havePointerIds) { 3703 if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) { 3704 uint32_t id = uint32_t(inPointer.absMTTrackingId); 3705 3706 if (id > MAX_POINTER_ID) { 3707#if DEBUG_POINTERS 3708 LOGD("Pointers: Ignoring driver provided pointer id %d because " 3709 "it is larger than max supported id %d", 3710 id, MAX_POINTER_ID); 3711#endif 3712 havePointerIds = false; 3713 } 3714 else { 3715 outPointer.id = id; 3716 mCurrentTouch.idToIndex[id] = outCount; 3717 mCurrentTouch.idBits.markBit(id); 3718 } 3719 } else { 3720 havePointerIds = false; 3721 } 3722 } 3723 3724 outCount += 1; 3725 } 3726 3727 mCurrentTouch.pointerCount = outCount; 3728 3729 syncTouch(when, havePointerIds); 3730 3731 mAccumulator.clear(); 3732} 3733 3734void MultiTouchInputMapper::configureRawAxes() { 3735 TouchInputMapper::configureRawAxes(); 3736 3737 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x); 3738 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y); 3739 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor); 3740 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor); 3741 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor); 3742 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor); 3743 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation); 3744 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure); 3745} 3746 3747 3748// --- JoystickInputMapper --- 3749 3750JoystickInputMapper::JoystickInputMapper(InputDevice* device) : 3751 InputMapper(device) { 3752} 3753 3754JoystickInputMapper::~JoystickInputMapper() { 3755} 3756 3757uint32_t JoystickInputMapper::getSources() { 3758 return AINPUT_SOURCE_JOYSTICK; 3759} 3760 3761void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) { 3762 InputMapper::populateDeviceInfo(info); 3763 3764 for (size_t i = 0; i < mAxes.size(); i++) { 3765 const Axis& axis = mAxes.valueAt(i); 3766 info->addMotionRange(axis.axis, axis.min, axis.max, axis.flat, axis.fuzz); 3767 } 3768} 3769 3770void JoystickInputMapper::dump(String8& dump) { 3771 dump.append(INDENT2 "Joystick Input Mapper:\n"); 3772 3773 dump.append(INDENT3 "Axes:\n"); 3774 size_t numAxes = mAxes.size(); 3775 for (size_t i = 0; i < numAxes; i++) { 3776 const Axis& axis = mAxes.valueAt(i); 3777 const char* label = getAxisLabel(axis.axis); 3778 char name[32]; 3779 if (label) { 3780 strncpy(name, label, sizeof(name)); 3781 name[sizeof(name) - 1] = '\0'; 3782 } else { 3783 snprintf(name, sizeof(name), "%d", axis.axis); 3784 } 3785 dump.appendFormat(INDENT4 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, " 3786 "scale=%0.3f, offset=%0.3f\n", 3787 name, axis.min, axis.max, axis.flat, axis.fuzz, 3788 axis.scale, axis.offset); 3789 dump.appendFormat(INDENT4 " rawAxis=%d, rawMin=%d, rawMax=%d, rawFlat=%d, rawFuzz=%d\n", 3790 mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue, 3791 axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz); 3792 } 3793} 3794 3795void JoystickInputMapper::configure() { 3796 InputMapper::configure(); 3797 3798 // Collect all axes. 3799 for (int32_t abs = 0; abs <= ABS_MAX; abs++) { 3800 RawAbsoluteAxisInfo rawAxisInfo; 3801 getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo); 3802 if (rawAxisInfo.valid) { 3803 int32_t axisId; 3804 bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisId); 3805 if (!explicitlyMapped) { 3806 // Axis is not explicitly mapped, will choose a generic axis later. 3807 axisId = -1; 3808 } 3809 3810 Axis axis; 3811 if (isCenteredAxis(axisId)) { 3812 float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue); 3813 float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale; 3814 axis.initialize(rawAxisInfo, axisId, explicitlyMapped, 3815 scale, offset, -1.0f, 1.0f, 3816 rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale); 3817 } else { 3818 float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue); 3819 axis.initialize(rawAxisInfo, axisId, explicitlyMapped, 3820 scale, 0.0f, 0.0f, 1.0f, 3821 rawAxisInfo.flat * scale, rawAxisInfo.fuzz * scale); 3822 } 3823 3824 // To eliminate noise while the joystick is at rest, filter out small variations 3825 // in axis values up front. 3826 axis.filter = axis.flat * 0.25f; 3827 3828 mAxes.add(abs, axis); 3829 } 3830 } 3831 3832 // If there are too many axes, start dropping them. 3833 // Prefer to keep explicitly mapped axes. 3834 if (mAxes.size() > PointerCoords::MAX_AXES) { 3835 LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.", 3836 getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES); 3837 pruneAxes(true); 3838 pruneAxes(false); 3839 } 3840 3841 // Assign generic axis ids to remaining axes. 3842 int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1; 3843 size_t numAxes = mAxes.size(); 3844 for (size_t i = 0; i < numAxes; i++) { 3845 Axis& axis = mAxes.editValueAt(i); 3846 if (axis.axis < 0) { 3847 while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16 3848 && haveAxis(nextGenericAxisId)) { 3849 nextGenericAxisId += 1; 3850 } 3851 3852 if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) { 3853 axis.axis = nextGenericAxisId; 3854 nextGenericAxisId += 1; 3855 } else { 3856 LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids " 3857 "have already been assigned to other axes.", 3858 getDeviceName().string(), mAxes.keyAt(i)); 3859 mAxes.removeItemsAt(i--); 3860 numAxes -= 1; 3861 } 3862 } 3863 } 3864} 3865 3866bool JoystickInputMapper::haveAxis(int32_t axis) { 3867 size_t numAxes = mAxes.size(); 3868 for (size_t i = 0; i < numAxes; i++) { 3869 if (mAxes.valueAt(i).axis == axis) { 3870 return true; 3871 } 3872 } 3873 return false; 3874} 3875 3876void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) { 3877 size_t i = mAxes.size(); 3878 while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) { 3879 if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) { 3880 continue; 3881 } 3882 LOGI("Discarding joystick '%s' axis %d because there are too many axes.", 3883 getDeviceName().string(), mAxes.keyAt(i)); 3884 mAxes.removeItemsAt(i); 3885 } 3886} 3887 3888bool JoystickInputMapper::isCenteredAxis(int32_t axis) { 3889 switch (axis) { 3890 case AMOTION_EVENT_AXIS_X: 3891 case AMOTION_EVENT_AXIS_Y: 3892 case AMOTION_EVENT_AXIS_Z: 3893 case AMOTION_EVENT_AXIS_RX: 3894 case AMOTION_EVENT_AXIS_RY: 3895 case AMOTION_EVENT_AXIS_RZ: 3896 case AMOTION_EVENT_AXIS_HAT_X: 3897 case AMOTION_EVENT_AXIS_HAT_Y: 3898 case AMOTION_EVENT_AXIS_ORIENTATION: 3899 return true; 3900 default: 3901 return false; 3902 } 3903} 3904 3905void JoystickInputMapper::reset() { 3906 // Recenter all axes. 3907 nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); 3908 3909 size_t numAxes = mAxes.size(); 3910 for (size_t i = 0; i < numAxes; i++) { 3911 Axis& axis = mAxes.editValueAt(i); 3912 axis.newValue = 0; 3913 } 3914 3915 sync(when, true /*force*/); 3916 3917 InputMapper::reset(); 3918} 3919 3920void JoystickInputMapper::process(const RawEvent* rawEvent) { 3921 switch (rawEvent->type) { 3922 case EV_ABS: { 3923 ssize_t index = mAxes.indexOfKey(rawEvent->scanCode); 3924 if (index >= 0) { 3925 Axis& axis = mAxes.editValueAt(index); 3926 float newValue = rawEvent->value * axis.scale + axis.offset; 3927 if (newValue != axis.newValue) { 3928 axis.newValue = newValue; 3929 } 3930 } 3931 break; 3932 } 3933 3934 case EV_SYN: 3935 switch (rawEvent->scanCode) { 3936 case SYN_REPORT: 3937 sync(rawEvent->when, false /*force*/); 3938 break; 3939 } 3940 break; 3941 } 3942} 3943 3944void JoystickInputMapper::sync(nsecs_t when, bool force) { 3945 if (!force && !haveAxesChangedSignificantly()) { 3946 return; 3947 } 3948 3949 int32_t metaState = mContext->getGlobalMetaState(); 3950 3951 PointerCoords pointerCoords; 3952 pointerCoords.clear(); 3953 3954 size_t numAxes = mAxes.size(); 3955 for (size_t i = 0; i < numAxes; i++) { 3956 Axis& axis = mAxes.editValueAt(i); 3957 pointerCoords.setAxisValue(axis.axis, axis.newValue); 3958 axis.oldValue = axis.newValue; 3959 } 3960 3961 int32_t pointerId = 0; 3962 getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, 0, 3963 AMOTION_EVENT_ACTION_MOVE, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, 3964 1, &pointerId, &pointerCoords, 0, 0, 0); 3965} 3966 3967bool JoystickInputMapper::haveAxesChangedSignificantly() { 3968 size_t numAxes = mAxes.size(); 3969 for (size_t i = 0; i < numAxes; i++) { 3970 const Axis& axis = mAxes.valueAt(i); 3971 if (axis.newValue != axis.oldValue 3972 && fabs(axis.newValue - axis.oldValue) > axis.filter) { 3973 return true; 3974 } 3975 } 3976 return false; 3977} 3978 3979} // namespace android 3980