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