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