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