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