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