Home | History | Annotate | Download | only in input
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "InputReader"
     18 
     19 //#define LOG_NDEBUG 0
     20 
     21 // Log debug messages for each raw event received from the EventHub.
     22 #define DEBUG_RAW_EVENTS 0
     23 
     24 // Log debug messages about touch screen filtering hacks.
     25 #define DEBUG_HACKS 0
     26 
     27 // Log debug messages about virtual key processing.
     28 #define DEBUG_VIRTUAL_KEYS 0
     29 
     30 // Log debug messages about pointers.
     31 #define DEBUG_POINTERS 0
     32 
     33 // Log debug messages about pointer assignment calculations.
     34 #define DEBUG_POINTER_ASSIGNMENT 0
     35 
     36 // Log debug messages about gesture detection.
     37 #define DEBUG_GESTURES 0
     38 
     39 // Log debug messages about the vibrator.
     40 #define DEBUG_VIBRATOR 0
     41 
     42 #include "InputReader.h"
     43 
     44 #include <cutils/log.h>
     45 #include <androidfw/Keyboard.h>
     46 #include <androidfw/VirtualKeyMap.h>
     47 
     48 #include <stddef.h>
     49 #include <stdlib.h>
     50 #include <unistd.h>
     51 #include <errno.h>
     52 #include <limits.h>
     53 #include <math.h>
     54 
     55 #define INDENT "  "
     56 #define INDENT2 "    "
     57 #define INDENT3 "      "
     58 #define INDENT4 "        "
     59 #define INDENT5 "          "
     60 
     61 namespace android {
     62 
     63 // --- Constants ---
     64 
     65 // Maximum number of slots supported when using the slot-based Multitouch Protocol B.
     66 static const size_t MAX_SLOTS = 32;
     67 
     68 // --- Static Functions ---
     69 
     70 template<typename T>
     71 inline static T abs(const T& value) {
     72     return value < 0 ? - value : value;
     73 }
     74 
     75 template<typename T>
     76 inline static T min(const T& a, const T& b) {
     77     return a < b ? a : b;
     78 }
     79 
     80 template<typename T>
     81 inline static void swap(T& a, T& b) {
     82     T temp = a;
     83     a = b;
     84     b = temp;
     85 }
     86 
     87 inline static float avg(float x, float y) {
     88     return (x + y) / 2;
     89 }
     90 
     91 inline static float distance(float x1, float y1, float x2, float y2) {
     92     return hypotf(x1 - x2, y1 - y2);
     93 }
     94 
     95 inline static int32_t signExtendNybble(int32_t value) {
     96     return value >= 8 ? value - 16 : value;
     97 }
     98 
     99 static inline const char* toString(bool value) {
    100     return value ? "true" : "false";
    101 }
    102 
    103 static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
    104         const int32_t map[][4], size_t mapSize) {
    105     if (orientation != DISPLAY_ORIENTATION_0) {
    106         for (size_t i = 0; i < mapSize; i++) {
    107             if (value == map[i][0]) {
    108                 return map[i][orientation];
    109             }
    110         }
    111     }
    112     return value;
    113 }
    114 
    115 static const int32_t keyCodeRotationMap[][4] = {
    116         // key codes enumerated counter-clockwise with the original (unrotated) key first
    117         // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
    118         { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
    119         { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
    120         { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
    121         { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
    122 };
    123 static const size_t keyCodeRotationMapSize =
    124         sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
    125 
    126 static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
    127     return rotateValueUsingRotationMap(keyCode, orientation,
    128             keyCodeRotationMap, keyCodeRotationMapSize);
    129 }
    130 
    131 static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
    132     float temp;
    133     switch (orientation) {
    134     case DISPLAY_ORIENTATION_90:
    135         temp = *deltaX;
    136         *deltaX = *deltaY;
    137         *deltaY = -temp;
    138         break;
    139 
    140     case DISPLAY_ORIENTATION_180:
    141         *deltaX = -*deltaX;
    142         *deltaY = -*deltaY;
    143         break;
    144 
    145     case DISPLAY_ORIENTATION_270:
    146         temp = *deltaX;
    147         *deltaX = -*deltaY;
    148         *deltaY = temp;
    149         break;
    150     }
    151 }
    152 
    153 static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
    154     return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
    155 }
    156 
    157 // Returns true if the pointer should be reported as being down given the specified
    158 // button states.  This determines whether the event is reported as a touch event.
    159 static bool isPointerDown(int32_t buttonState) {
    160     return buttonState &
    161             (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
    162                     | AMOTION_EVENT_BUTTON_TERTIARY);
    163 }
    164 
    165 static float calculateCommonVector(float a, float b) {
    166     if (a > 0 && b > 0) {
    167         return a < b ? a : b;
    168     } else if (a < 0 && b < 0) {
    169         return a > b ? a : b;
    170     } else {
    171         return 0;
    172     }
    173 }
    174 
    175 static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
    176         nsecs_t when, int32_t deviceId, uint32_t source,
    177         uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
    178         int32_t buttonState, int32_t keyCode) {
    179     if (
    180             (action == AKEY_EVENT_ACTION_DOWN
    181                     && !(lastButtonState & buttonState)
    182                     && (currentButtonState & buttonState))
    183             || (action == AKEY_EVENT_ACTION_UP
    184                     && (lastButtonState & buttonState)
    185                     && !(currentButtonState & buttonState))) {
    186         NotifyKeyArgs args(when, deviceId, source, policyFlags,
    187                 action, 0, keyCode, 0, context->getGlobalMetaState(), when);
    188         context->getListener()->notifyKey(&args);
    189     }
    190 }
    191 
    192 static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
    193         nsecs_t when, int32_t deviceId, uint32_t source,
    194         uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
    195     synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
    196             lastButtonState, currentButtonState,
    197             AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
    198     synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
    199             lastButtonState, currentButtonState,
    200             AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
    201 }
    202 
    203 
    204 // --- InputReaderConfiguration ---
    205 
    206 bool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
    207     const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
    208     if (viewport.displayId >= 0) {
    209         *outViewport = viewport;
    210         return true;
    211     }
    212     return false;
    213 }
    214 
    215 void InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
    216     DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
    217     v = viewport;
    218 }
    219 
    220 
    221 // --- InputReader ---
    222 
    223 InputReader::InputReader(const sp<EventHubInterface>& eventHub,
    224         const sp<InputReaderPolicyInterface>& policy,
    225         const sp<InputListenerInterface>& listener) :
    226         mContext(this), mEventHub(eventHub), mPolicy(policy),
    227         mGlobalMetaState(0), mGeneration(1),
    228         mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
    229         mConfigurationChangesToRefresh(0) {
    230     mQueuedListener = new QueuedInputListener(listener);
    231 
    232     { // acquire lock
    233         AutoMutex _l(mLock);
    234 
    235         refreshConfigurationLocked(0);
    236         updateGlobalMetaStateLocked();
    237     } // release lock
    238 }
    239 
    240 InputReader::~InputReader() {
    241     for (size_t i = 0; i < mDevices.size(); i++) {
    242         delete mDevices.valueAt(i);
    243     }
    244 }
    245 
    246 void InputReader::loopOnce() {
    247     int32_t oldGeneration;
    248     int32_t timeoutMillis;
    249     bool inputDevicesChanged = false;
    250     Vector<InputDeviceInfo> inputDevices;
    251     { // acquire lock
    252         AutoMutex _l(mLock);
    253 
    254         oldGeneration = mGeneration;
    255         timeoutMillis = -1;
    256 
    257         uint32_t changes = mConfigurationChangesToRefresh;
    258         if (changes) {
    259             mConfigurationChangesToRefresh = 0;
    260             timeoutMillis = 0;
    261             refreshConfigurationLocked(changes);
    262         } else if (mNextTimeout != LLONG_MAX) {
    263             nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    264             timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
    265         }
    266     } // release lock
    267 
    268     size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
    269 
    270     { // acquire lock
    271         AutoMutex _l(mLock);
    272         mReaderIsAliveCondition.broadcast();
    273 
    274         if (count) {
    275             processEventsLocked(mEventBuffer, count);
    276         }
    277 
    278         if (mNextTimeout != LLONG_MAX) {
    279             nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    280             if (now >= mNextTimeout) {
    281 #if DEBUG_RAW_EVENTS
    282                 ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
    283 #endif
    284                 mNextTimeout = LLONG_MAX;
    285                 timeoutExpiredLocked(now);
    286             }
    287         }
    288 
    289         if (oldGeneration != mGeneration) {
    290             inputDevicesChanged = true;
    291             getInputDevicesLocked(inputDevices);
    292         }
    293     } // release lock
    294 
    295     // Send out a message that the describes the changed input devices.
    296     if (inputDevicesChanged) {
    297         mPolicy->notifyInputDevicesChanged(inputDevices);
    298     }
    299 
    300     // Flush queued events out to the listener.
    301     // This must happen outside of the lock because the listener could potentially call
    302     // back into the InputReader's methods, such as getScanCodeState, or become blocked
    303     // on another thread similarly waiting to acquire the InputReader lock thereby
    304     // resulting in a deadlock.  This situation is actually quite plausible because the
    305     // listener is actually the input dispatcher, which calls into the window manager,
    306     // which occasionally calls into the input reader.
    307     mQueuedListener->flush();
    308 }
    309 
    310 void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    311     for (const RawEvent* rawEvent = rawEvents; count;) {
    312         int32_t type = rawEvent->type;
    313         size_t batchSize = 1;
    314         if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
    315             int32_t deviceId = rawEvent->deviceId;
    316             while (batchSize < count) {
    317                 if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
    318                         || rawEvent[batchSize].deviceId != deviceId) {
    319                     break;
    320                 }
    321                 batchSize += 1;
    322             }
    323 #if DEBUG_RAW_EVENTS
    324             ALOGD("BatchSize: %d Count: %d", batchSize, count);
    325 #endif
    326             processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
    327         } else {
    328             switch (rawEvent->type) {
    329             case EventHubInterface::DEVICE_ADDED:
    330                 addDeviceLocked(rawEvent->when, rawEvent->deviceId);
    331                 break;
    332             case EventHubInterface::DEVICE_REMOVED:
    333                 removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
    334                 break;
    335             case EventHubInterface::FINISHED_DEVICE_SCAN:
    336                 handleConfigurationChangedLocked(rawEvent->when);
    337                 break;
    338             default:
    339                 ALOG_ASSERT(false); // can't happen
    340                 break;
    341             }
    342         }
    343         count -= batchSize;
    344         rawEvent += batchSize;
    345     }
    346 }
    347 
    348 void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
    349     ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    350     if (deviceIndex >= 0) {
    351         ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
    352         return;
    353     }
    354 
    355     InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
    356     uint32_t classes = mEventHub->getDeviceClasses(deviceId);
    357 
    358     InputDevice* device = createDeviceLocked(deviceId, identifier, classes);
    359     device->configure(when, &mConfig, 0);
    360     device->reset(when);
    361 
    362     if (device->isIgnored()) {
    363         ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
    364                 identifier.name.string());
    365     } else {
    366         ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
    367                 identifier.name.string(), device->getSources());
    368     }
    369 
    370     mDevices.add(deviceId, device);
    371     bumpGenerationLocked();
    372 }
    373 
    374 void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
    375     InputDevice* device = NULL;
    376     ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    377     if (deviceIndex < 0) {
    378         ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
    379         return;
    380     }
    381 
    382     device = mDevices.valueAt(deviceIndex);
    383     mDevices.removeItemsAt(deviceIndex, 1);
    384     bumpGenerationLocked();
    385 
    386     if (device->isIgnored()) {
    387         ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
    388                 device->getId(), device->getName().string());
    389     } else {
    390         ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
    391                 device->getId(), device->getName().string(), device->getSources());
    392     }
    393 
    394     device->reset(when);
    395     delete device;
    396 }
    397 
    398 InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
    399         const InputDeviceIdentifier& identifier, uint32_t classes) {
    400     InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
    401             identifier, classes);
    402 
    403     // External devices.
    404     if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
    405         device->setExternal(true);
    406     }
    407 
    408     // Switch-like devices.
    409     if (classes & INPUT_DEVICE_CLASS_SWITCH) {
    410         device->addMapper(new SwitchInputMapper(device));
    411     }
    412 
    413     // Vibrator-like devices.
    414     if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
    415         device->addMapper(new VibratorInputMapper(device));
    416     }
    417 
    418     // Keyboard-like devices.
    419     uint32_t keyboardSource = 0;
    420     int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
    421     if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
    422         keyboardSource |= AINPUT_SOURCE_KEYBOARD;
    423     }
    424     if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
    425         keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
    426     }
    427     if (classes & INPUT_DEVICE_CLASS_DPAD) {
    428         keyboardSource |= AINPUT_SOURCE_DPAD;
    429     }
    430     if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
    431         keyboardSource |= AINPUT_SOURCE_GAMEPAD;
    432     }
    433 
    434     if (keyboardSource != 0) {
    435         device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
    436     }
    437 
    438     // Cursor-like devices.
    439     if (classes & INPUT_DEVICE_CLASS_CURSOR) {
    440         device->addMapper(new CursorInputMapper(device));
    441     }
    442 
    443     // Touchscreens and touchpad devices.
    444     if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
    445         device->addMapper(new MultiTouchInputMapper(device));
    446     } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
    447         device->addMapper(new SingleTouchInputMapper(device));
    448     }
    449 
    450     // Joystick-like devices.
    451     if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
    452         device->addMapper(new JoystickInputMapper(device));
    453     }
    454 
    455     return device;
    456 }
    457 
    458 void InputReader::processEventsForDeviceLocked(int32_t deviceId,
    459         const RawEvent* rawEvents, size_t count) {
    460     ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    461     if (deviceIndex < 0) {
    462         ALOGW("Discarding event for unknown deviceId %d.", deviceId);
    463         return;
    464     }
    465 
    466     InputDevice* device = mDevices.valueAt(deviceIndex);
    467     if (device->isIgnored()) {
    468         //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
    469         return;
    470     }
    471 
    472     device->process(rawEvents, count);
    473 }
    474 
    475 void InputReader::timeoutExpiredLocked(nsecs_t when) {
    476     for (size_t i = 0; i < mDevices.size(); i++) {
    477         InputDevice* device = mDevices.valueAt(i);
    478         if (!device->isIgnored()) {
    479             device->timeoutExpired(when);
    480         }
    481     }
    482 }
    483 
    484 void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
    485     // Reset global meta state because it depends on the list of all configured devices.
    486     updateGlobalMetaStateLocked();
    487 
    488     // Enqueue configuration changed.
    489     NotifyConfigurationChangedArgs args(when);
    490     mQueuedListener->notifyConfigurationChanged(&args);
    491 }
    492 
    493 void InputReader::refreshConfigurationLocked(uint32_t changes) {
    494     mPolicy->getReaderConfiguration(&mConfig);
    495     mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
    496 
    497     if (changes) {
    498         ALOGI("Reconfiguring input devices.  changes=0x%08x", changes);
    499         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    500 
    501         if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
    502             mEventHub->requestReopenDevices();
    503         } else {
    504             for (size_t i = 0; i < mDevices.size(); i++) {
    505                 InputDevice* device = mDevices.valueAt(i);
    506                 device->configure(now, &mConfig, changes);
    507             }
    508         }
    509     }
    510 }
    511 
    512 void InputReader::updateGlobalMetaStateLocked() {
    513     mGlobalMetaState = 0;
    514 
    515     for (size_t i = 0; i < mDevices.size(); i++) {
    516         InputDevice* device = mDevices.valueAt(i);
    517         mGlobalMetaState |= device->getMetaState();
    518     }
    519 }
    520 
    521 int32_t InputReader::getGlobalMetaStateLocked() {
    522     return mGlobalMetaState;
    523 }
    524 
    525 void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
    526     mDisableVirtualKeysTimeout = time;
    527 }
    528 
    529 bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
    530         InputDevice* device, int32_t keyCode, int32_t scanCode) {
    531     if (now < mDisableVirtualKeysTimeout) {
    532         ALOGI("Dropping virtual key from device %s because virtual keys are "
    533                 "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
    534                 device->getName().string(),
    535                 (mDisableVirtualKeysTimeout - now) * 0.000001,
    536                 keyCode, scanCode);
    537         return true;
    538     } else {
    539         return false;
    540     }
    541 }
    542 
    543 void InputReader::fadePointerLocked() {
    544     for (size_t i = 0; i < mDevices.size(); i++) {
    545         InputDevice* device = mDevices.valueAt(i);
    546         device->fadePointer();
    547     }
    548 }
    549 
    550 void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
    551     if (when < mNextTimeout) {
    552         mNextTimeout = when;
    553         mEventHub->wake();
    554     }
    555 }
    556 
    557 int32_t InputReader::bumpGenerationLocked() {
    558     return ++mGeneration;
    559 }
    560 
    561 void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
    562     AutoMutex _l(mLock);
    563     getInputDevicesLocked(outInputDevices);
    564 }
    565 
    566 void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
    567     outInputDevices.clear();
    568 
    569     size_t numDevices = mDevices.size();
    570     for (size_t i = 0; i < numDevices; i++) {
    571         InputDevice* device = mDevices.valueAt(i);
    572         if (!device->isIgnored()) {
    573             outInputDevices.push();
    574             device->getDeviceInfo(&outInputDevices.editTop());
    575         }
    576     }
    577 }
    578 
    579 int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
    580         int32_t keyCode) {
    581     AutoMutex _l(mLock);
    582 
    583     return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
    584 }
    585 
    586 int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
    587         int32_t scanCode) {
    588     AutoMutex _l(mLock);
    589 
    590     return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
    591 }
    592 
    593 int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
    594     AutoMutex _l(mLock);
    595 
    596     return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
    597 }
    598 
    599 int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
    600         GetStateFunc getStateFunc) {
    601     int32_t result = AKEY_STATE_UNKNOWN;
    602     if (deviceId >= 0) {
    603         ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    604         if (deviceIndex >= 0) {
    605             InputDevice* device = mDevices.valueAt(deviceIndex);
    606             if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
    607                 result = (device->*getStateFunc)(sourceMask, code);
    608             }
    609         }
    610     } else {
    611         size_t numDevices = mDevices.size();
    612         for (size_t i = 0; i < numDevices; i++) {
    613             InputDevice* device = mDevices.valueAt(i);
    614             if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
    615                 // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
    616                 // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
    617                 int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
    618                 if (currentResult >= AKEY_STATE_DOWN) {
    619                     return currentResult;
    620                 } else if (currentResult == AKEY_STATE_UP) {
    621                     result = currentResult;
    622                 }
    623             }
    624         }
    625     }
    626     return result;
    627 }
    628 
    629 bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
    630         size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
    631     AutoMutex _l(mLock);
    632 
    633     memset(outFlags, 0, numCodes);
    634     return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
    635 }
    636 
    637 bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
    638         size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
    639     bool result = false;
    640     if (deviceId >= 0) {
    641         ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    642         if (deviceIndex >= 0) {
    643             InputDevice* device = mDevices.valueAt(deviceIndex);
    644             if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
    645                 result = device->markSupportedKeyCodes(sourceMask,
    646                         numCodes, keyCodes, outFlags);
    647             }
    648         }
    649     } else {
    650         size_t numDevices = mDevices.size();
    651         for (size_t i = 0; i < numDevices; i++) {
    652             InputDevice* device = mDevices.valueAt(i);
    653             if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
    654                 result |= device->markSupportedKeyCodes(sourceMask,
    655                         numCodes, keyCodes, outFlags);
    656             }
    657         }
    658     }
    659     return result;
    660 }
    661 
    662 void InputReader::requestRefreshConfiguration(uint32_t changes) {
    663     AutoMutex _l(mLock);
    664 
    665     if (changes) {
    666         bool needWake = !mConfigurationChangesToRefresh;
    667         mConfigurationChangesToRefresh |= changes;
    668 
    669         if (needWake) {
    670             mEventHub->wake();
    671         }
    672     }
    673 }
    674 
    675 void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
    676         ssize_t repeat, int32_t token) {
    677     AutoMutex _l(mLock);
    678 
    679     ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    680     if (deviceIndex >= 0) {
    681         InputDevice* device = mDevices.valueAt(deviceIndex);
    682         device->vibrate(pattern, patternSize, repeat, token);
    683     }
    684 }
    685 
    686 void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
    687     AutoMutex _l(mLock);
    688 
    689     ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    690     if (deviceIndex >= 0) {
    691         InputDevice* device = mDevices.valueAt(deviceIndex);
    692         device->cancelVibrate(token);
    693     }
    694 }
    695 
    696 void InputReader::dump(String8& dump) {
    697     AutoMutex _l(mLock);
    698 
    699     mEventHub->dump(dump);
    700     dump.append("\n");
    701 
    702     dump.append("Input Reader State:\n");
    703 
    704     for (size_t i = 0; i < mDevices.size(); i++) {
    705         mDevices.valueAt(i)->dump(dump);
    706     }
    707 
    708     dump.append(INDENT "Configuration:\n");
    709     dump.append(INDENT2 "ExcludedDeviceNames: [");
    710     for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
    711         if (i != 0) {
    712             dump.append(", ");
    713         }
    714         dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
    715     }
    716     dump.append("]\n");
    717     dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
    718             mConfig.virtualKeyQuietTime * 0.000001f);
    719 
    720     dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
    721             "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
    722             mConfig.pointerVelocityControlParameters.scale,
    723             mConfig.pointerVelocityControlParameters.lowThreshold,
    724             mConfig.pointerVelocityControlParameters.highThreshold,
    725             mConfig.pointerVelocityControlParameters.acceleration);
    726 
    727     dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
    728             "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
    729             mConfig.wheelVelocityControlParameters.scale,
    730             mConfig.wheelVelocityControlParameters.lowThreshold,
    731             mConfig.wheelVelocityControlParameters.highThreshold,
    732             mConfig.wheelVelocityControlParameters.acceleration);
    733 
    734     dump.appendFormat(INDENT2 "PointerGesture:\n");
    735     dump.appendFormat(INDENT3 "Enabled: %s\n",
    736             toString(mConfig.pointerGesturesEnabled));
    737     dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
    738             mConfig.pointerGestureQuietInterval * 0.000001f);
    739     dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
    740             mConfig.pointerGestureDragMinSwitchSpeed);
    741     dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
    742             mConfig.pointerGestureTapInterval * 0.000001f);
    743     dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
    744             mConfig.pointerGestureTapDragInterval * 0.000001f);
    745     dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
    746             mConfig.pointerGestureTapSlop);
    747     dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
    748             mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
    749     dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
    750             mConfig.pointerGestureMultitouchMinDistance);
    751     dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
    752             mConfig.pointerGestureSwipeTransitionAngleCosine);
    753     dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
    754             mConfig.pointerGestureSwipeMaxWidthRatio);
    755     dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
    756             mConfig.pointerGestureMovementSpeedRatio);
    757     dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
    758             mConfig.pointerGestureZoomSpeedRatio);
    759 }
    760 
    761 void InputReader::monitor() {
    762     // Acquire and release the lock to ensure that the reader has not deadlocked.
    763     mLock.lock();
    764     mEventHub->wake();
    765     mReaderIsAliveCondition.wait(mLock);
    766     mLock.unlock();
    767 
    768     // Check the EventHub
    769     mEventHub->monitor();
    770 }
    771 
    772 
    773 // --- InputReader::ContextImpl ---
    774 
    775 InputReader::ContextImpl::ContextImpl(InputReader* reader) :
    776         mReader(reader) {
    777 }
    778 
    779 void InputReader::ContextImpl::updateGlobalMetaState() {
    780     // lock is already held by the input loop
    781     mReader->updateGlobalMetaStateLocked();
    782 }
    783 
    784 int32_t InputReader::ContextImpl::getGlobalMetaState() {
    785     // lock is already held by the input loop
    786     return mReader->getGlobalMetaStateLocked();
    787 }
    788 
    789 void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
    790     // lock is already held by the input loop
    791     mReader->disableVirtualKeysUntilLocked(time);
    792 }
    793 
    794 bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
    795         InputDevice* device, int32_t keyCode, int32_t scanCode) {
    796     // lock is already held by the input loop
    797     return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
    798 }
    799 
    800 void InputReader::ContextImpl::fadePointer() {
    801     // lock is already held by the input loop
    802     mReader->fadePointerLocked();
    803 }
    804 
    805 void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
    806     // lock is already held by the input loop
    807     mReader->requestTimeoutAtTimeLocked(when);
    808 }
    809 
    810 int32_t InputReader::ContextImpl::bumpGeneration() {
    811     // lock is already held by the input loop
    812     return mReader->bumpGenerationLocked();
    813 }
    814 
    815 InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
    816     return mReader->mPolicy.get();
    817 }
    818 
    819 InputListenerInterface* InputReader::ContextImpl::getListener() {
    820     return mReader->mQueuedListener.get();
    821 }
    822 
    823 EventHubInterface* InputReader::ContextImpl::getEventHub() {
    824     return mReader->mEventHub.get();
    825 }
    826 
    827 
    828 // --- InputReaderThread ---
    829 
    830 InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
    831         Thread(/*canCallJava*/ true), mReader(reader) {
    832 }
    833 
    834 InputReaderThread::~InputReaderThread() {
    835 }
    836 
    837 bool InputReaderThread::threadLoop() {
    838     mReader->loopOnce();
    839     return true;
    840 }
    841 
    842 
    843 // --- InputDevice ---
    844 
    845 InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
    846         const InputDeviceIdentifier& identifier, uint32_t classes) :
    847         mContext(context), mId(id), mGeneration(generation),
    848         mIdentifier(identifier), mClasses(classes),
    849         mSources(0), mIsExternal(false), mDropUntilNextSync(false) {
    850 }
    851 
    852 InputDevice::~InputDevice() {
    853     size_t numMappers = mMappers.size();
    854     for (size_t i = 0; i < numMappers; i++) {
    855         delete mMappers[i];
    856     }
    857     mMappers.clear();
    858 }
    859 
    860 void InputDevice::dump(String8& dump) {
    861     InputDeviceInfo deviceInfo;
    862     getDeviceInfo(& deviceInfo);
    863 
    864     dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
    865             deviceInfo.getDisplayName().string());
    866     dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
    867     dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
    868     dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
    869     dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
    870 
    871     const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
    872     if (!ranges.isEmpty()) {
    873         dump.append(INDENT2 "Motion Ranges:\n");
    874         for (size_t i = 0; i < ranges.size(); i++) {
    875             const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
    876             const char* label = getAxisLabel(range.axis);
    877             char name[32];
    878             if (label) {
    879                 strncpy(name, label, sizeof(name));
    880                 name[sizeof(name) - 1] = '\0';
    881             } else {
    882                 snprintf(name, sizeof(name), "%d", range.axis);
    883             }
    884             dump.appendFormat(INDENT3 "%s: source=0x%08x, "
    885                     "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
    886                     name, range.source, range.min, range.max, range.flat, range.fuzz);
    887         }
    888     }
    889 
    890     size_t numMappers = mMappers.size();
    891     for (size_t i = 0; i < numMappers; i++) {
    892         InputMapper* mapper = mMappers[i];
    893         mapper->dump(dump);
    894     }
    895 }
    896 
    897 void InputDevice::addMapper(InputMapper* mapper) {
    898     mMappers.add(mapper);
    899 }
    900 
    901 void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
    902     mSources = 0;
    903 
    904     if (!isIgnored()) {
    905         if (!changes) { // first time only
    906             mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
    907         }
    908 
    909         if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
    910             if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
    911                 sp<KeyCharacterMap> keyboardLayout =
    912                         mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier.descriptor);
    913                 if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
    914                     bumpGeneration();
    915                 }
    916             }
    917         }
    918 
    919         if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
    920             if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
    921                 String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
    922                 if (mAlias != alias) {
    923                     mAlias = alias;
    924                     bumpGeneration();
    925                 }
    926             }
    927         }
    928 
    929         size_t numMappers = mMappers.size();
    930         for (size_t i = 0; i < numMappers; i++) {
    931             InputMapper* mapper = mMappers[i];
    932             mapper->configure(when, config, changes);
    933             mSources |= mapper->getSources();
    934         }
    935     }
    936 }
    937 
    938 void InputDevice::reset(nsecs_t when) {
    939     size_t numMappers = mMappers.size();
    940     for (size_t i = 0; i < numMappers; i++) {
    941         InputMapper* mapper = mMappers[i];
    942         mapper->reset(when);
    943     }
    944 
    945     mContext->updateGlobalMetaState();
    946 
    947     notifyReset(when);
    948 }
    949 
    950 void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    951     // Process all of the events in order for each mapper.
    952     // We cannot simply ask each mapper to process them in bulk because mappers may
    953     // have side-effects that must be interleaved.  For example, joystick movement events and
    954     // gamepad button presses are handled by different mappers but they should be dispatched
    955     // in the order received.
    956     size_t numMappers = mMappers.size();
    957     for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
    958 #if DEBUG_RAW_EVENTS
    959         ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
    960                 rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
    961                 rawEvent->when);
    962 #endif
    963 
    964         if (mDropUntilNextSync) {
    965             if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
    966                 mDropUntilNextSync = false;
    967 #if DEBUG_RAW_EVENTS
    968                 ALOGD("Recovered from input event buffer overrun.");
    969 #endif
    970             } else {
    971 #if DEBUG_RAW_EVENTS
    972                 ALOGD("Dropped input event while waiting for next input sync.");
    973 #endif
    974             }
    975         } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
    976             ALOGI("Detected input event buffer overrun for device %s.", getName().string());
    977             mDropUntilNextSync = true;
    978             reset(rawEvent->when);
    979         } else {
    980             for (size_t i = 0; i < numMappers; i++) {
    981                 InputMapper* mapper = mMappers[i];
    982                 mapper->process(rawEvent);
    983             }
    984         }
    985     }
    986 }
    987 
    988 void InputDevice::timeoutExpired(nsecs_t when) {
    989     size_t numMappers = mMappers.size();
    990     for (size_t i = 0; i < numMappers; i++) {
    991         InputMapper* mapper = mMappers[i];
    992         mapper->timeoutExpired(when);
    993     }
    994 }
    995 
    996 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
    997     outDeviceInfo->initialize(mId, mGeneration, mIdentifier, mAlias, mIsExternal);
    998 
    999     size_t numMappers = mMappers.size();
   1000     for (size_t i = 0; i < numMappers; i++) {
   1001         InputMapper* mapper = mMappers[i];
   1002         mapper->populateDeviceInfo(outDeviceInfo);
   1003     }
   1004 }
   1005 
   1006 int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
   1007     return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
   1008 }
   1009 
   1010 int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
   1011     return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
   1012 }
   1013 
   1014 int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
   1015     return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
   1016 }
   1017 
   1018 int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
   1019     int32_t result = AKEY_STATE_UNKNOWN;
   1020     size_t numMappers = mMappers.size();
   1021     for (size_t i = 0; i < numMappers; i++) {
   1022         InputMapper* mapper = mMappers[i];
   1023         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
   1024             // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
   1025             // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
   1026             int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
   1027             if (currentResult >= AKEY_STATE_DOWN) {
   1028                 return currentResult;
   1029             } else if (currentResult == AKEY_STATE_UP) {
   1030                 result = currentResult;
   1031             }
   1032         }
   1033     }
   1034     return result;
   1035 }
   1036 
   1037 bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
   1038         const int32_t* keyCodes, uint8_t* outFlags) {
   1039     bool result = false;
   1040     size_t numMappers = mMappers.size();
   1041     for (size_t i = 0; i < numMappers; i++) {
   1042         InputMapper* mapper = mMappers[i];
   1043         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
   1044             result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
   1045         }
   1046     }
   1047     return result;
   1048 }
   1049 
   1050 void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
   1051         int32_t token) {
   1052     size_t numMappers = mMappers.size();
   1053     for (size_t i = 0; i < numMappers; i++) {
   1054         InputMapper* mapper = mMappers[i];
   1055         mapper->vibrate(pattern, patternSize, repeat, token);
   1056     }
   1057 }
   1058 
   1059 void InputDevice::cancelVibrate(int32_t token) {
   1060     size_t numMappers = mMappers.size();
   1061     for (size_t i = 0; i < numMappers; i++) {
   1062         InputMapper* mapper = mMappers[i];
   1063         mapper->cancelVibrate(token);
   1064     }
   1065 }
   1066 
   1067 int32_t InputDevice::getMetaState() {
   1068     int32_t result = 0;
   1069     size_t numMappers = mMappers.size();
   1070     for (size_t i = 0; i < numMappers; i++) {
   1071         InputMapper* mapper = mMappers[i];
   1072         result |= mapper->getMetaState();
   1073     }
   1074     return result;
   1075 }
   1076 
   1077 void InputDevice::fadePointer() {
   1078     size_t numMappers = mMappers.size();
   1079     for (size_t i = 0; i < numMappers; i++) {
   1080         InputMapper* mapper = mMappers[i];
   1081         mapper->fadePointer();
   1082     }
   1083 }
   1084 
   1085 void InputDevice::bumpGeneration() {
   1086     mGeneration = mContext->bumpGeneration();
   1087 }
   1088 
   1089 void InputDevice::notifyReset(nsecs_t when) {
   1090     NotifyDeviceResetArgs args(when, mId);
   1091     mContext->getListener()->notifyDeviceReset(&args);
   1092 }
   1093 
   1094 
   1095 // --- CursorButtonAccumulator ---
   1096 
   1097 CursorButtonAccumulator::CursorButtonAccumulator() {
   1098     clearButtons();
   1099 }
   1100 
   1101 void CursorButtonAccumulator::reset(InputDevice* device) {
   1102     mBtnLeft = device->isKeyPressed(BTN_LEFT);
   1103     mBtnRight = device->isKeyPressed(BTN_RIGHT);
   1104     mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
   1105     mBtnBack = device->isKeyPressed(BTN_BACK);
   1106     mBtnSide = device->isKeyPressed(BTN_SIDE);
   1107     mBtnForward = device->isKeyPressed(BTN_FORWARD);
   1108     mBtnExtra = device->isKeyPressed(BTN_EXTRA);
   1109     mBtnTask = device->isKeyPressed(BTN_TASK);
   1110 }
   1111 
   1112 void CursorButtonAccumulator::clearButtons() {
   1113     mBtnLeft = 0;
   1114     mBtnRight = 0;
   1115     mBtnMiddle = 0;
   1116     mBtnBack = 0;
   1117     mBtnSide = 0;
   1118     mBtnForward = 0;
   1119     mBtnExtra = 0;
   1120     mBtnTask = 0;
   1121 }
   1122 
   1123 void CursorButtonAccumulator::process(const RawEvent* rawEvent) {
   1124     if (rawEvent->type == EV_KEY) {
   1125         switch (rawEvent->code) {
   1126         case BTN_LEFT:
   1127             mBtnLeft = rawEvent->value;
   1128             break;
   1129         case BTN_RIGHT:
   1130             mBtnRight = rawEvent->value;
   1131             break;
   1132         case BTN_MIDDLE:
   1133             mBtnMiddle = rawEvent->value;
   1134             break;
   1135         case BTN_BACK:
   1136             mBtnBack = rawEvent->value;
   1137             break;
   1138         case BTN_SIDE:
   1139             mBtnSide = rawEvent->value;
   1140             break;
   1141         case BTN_FORWARD:
   1142             mBtnForward = rawEvent->value;
   1143             break;
   1144         case BTN_EXTRA:
   1145             mBtnExtra = rawEvent->value;
   1146             break;
   1147         case BTN_TASK:
   1148             mBtnTask = rawEvent->value;
   1149             break;
   1150         }
   1151     }
   1152 }
   1153 
   1154 uint32_t CursorButtonAccumulator::getButtonState() const {
   1155     uint32_t result = 0;
   1156     if (mBtnLeft) {
   1157         result |= AMOTION_EVENT_BUTTON_PRIMARY;
   1158     }
   1159     if (mBtnRight) {
   1160         result |= AMOTION_EVENT_BUTTON_SECONDARY;
   1161     }
   1162     if (mBtnMiddle) {
   1163         result |= AMOTION_EVENT_BUTTON_TERTIARY;
   1164     }
   1165     if (mBtnBack || mBtnSide) {
   1166         result |= AMOTION_EVENT_BUTTON_BACK;
   1167     }
   1168     if (mBtnForward || mBtnExtra) {
   1169         result |= AMOTION_EVENT_BUTTON_FORWARD;
   1170     }
   1171     return result;
   1172 }
   1173 
   1174 
   1175 // --- CursorMotionAccumulator ---
   1176 
   1177 CursorMotionAccumulator::CursorMotionAccumulator() {
   1178     clearRelativeAxes();
   1179 }
   1180 
   1181 void CursorMotionAccumulator::reset(InputDevice* device) {
   1182     clearRelativeAxes();
   1183 }
   1184 
   1185 void CursorMotionAccumulator::clearRelativeAxes() {
   1186     mRelX = 0;
   1187     mRelY = 0;
   1188 }
   1189 
   1190 void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
   1191     if (rawEvent->type == EV_REL) {
   1192         switch (rawEvent->code) {
   1193         case REL_X:
   1194             mRelX = rawEvent->value;
   1195             break;
   1196         case REL_Y:
   1197             mRelY = rawEvent->value;
   1198             break;
   1199         }
   1200     }
   1201 }
   1202 
   1203 void CursorMotionAccumulator::finishSync() {
   1204     clearRelativeAxes();
   1205 }
   1206 
   1207 
   1208 // --- CursorScrollAccumulator ---
   1209 
   1210 CursorScrollAccumulator::CursorScrollAccumulator() :
   1211         mHaveRelWheel(false), mHaveRelHWheel(false) {
   1212     clearRelativeAxes();
   1213 }
   1214 
   1215 void CursorScrollAccumulator::configure(InputDevice* device) {
   1216     mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
   1217     mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
   1218 }
   1219 
   1220 void CursorScrollAccumulator::reset(InputDevice* device) {
   1221     clearRelativeAxes();
   1222 }
   1223 
   1224 void CursorScrollAccumulator::clearRelativeAxes() {
   1225     mRelWheel = 0;
   1226     mRelHWheel = 0;
   1227 }
   1228 
   1229 void CursorScrollAccumulator::process(const RawEvent* rawEvent) {
   1230     if (rawEvent->type == EV_REL) {
   1231         switch (rawEvent->code) {
   1232         case REL_WHEEL:
   1233             mRelWheel = rawEvent->value;
   1234             break;
   1235         case REL_HWHEEL:
   1236             mRelHWheel = rawEvent->value;
   1237             break;
   1238         }
   1239     }
   1240 }
   1241 
   1242 void CursorScrollAccumulator::finishSync() {
   1243     clearRelativeAxes();
   1244 }
   1245 
   1246 
   1247 // --- TouchButtonAccumulator ---
   1248 
   1249 TouchButtonAccumulator::TouchButtonAccumulator() :
   1250         mHaveBtnTouch(false), mHaveStylus(false) {
   1251     clearButtons();
   1252 }
   1253 
   1254 void TouchButtonAccumulator::configure(InputDevice* device) {
   1255     mHaveBtnTouch = device->hasKey(BTN_TOUCH);
   1256     mHaveStylus = device->hasKey(BTN_TOOL_PEN)
   1257             || device->hasKey(BTN_TOOL_RUBBER)
   1258             || device->hasKey(BTN_TOOL_BRUSH)
   1259             || device->hasKey(BTN_TOOL_PENCIL)
   1260             || device->hasKey(BTN_TOOL_AIRBRUSH);
   1261 }
   1262 
   1263 void TouchButtonAccumulator::reset(InputDevice* device) {
   1264     mBtnTouch = device->isKeyPressed(BTN_TOUCH);
   1265     mBtnStylus = device->isKeyPressed(BTN_STYLUS);
   1266     mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
   1267     mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
   1268     mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
   1269     mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
   1270     mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
   1271     mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
   1272     mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
   1273     mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
   1274     mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
   1275     mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
   1276     mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
   1277     mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
   1278 }
   1279 
   1280 void TouchButtonAccumulator::clearButtons() {
   1281     mBtnTouch = 0;
   1282     mBtnStylus = 0;
   1283     mBtnStylus2 = 0;
   1284     mBtnToolFinger = 0;
   1285     mBtnToolPen = 0;
   1286     mBtnToolRubber = 0;
   1287     mBtnToolBrush = 0;
   1288     mBtnToolPencil = 0;
   1289     mBtnToolAirbrush = 0;
   1290     mBtnToolMouse = 0;
   1291     mBtnToolLens = 0;
   1292     mBtnToolDoubleTap = 0;
   1293     mBtnToolTripleTap = 0;
   1294     mBtnToolQuadTap = 0;
   1295 }
   1296 
   1297 void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
   1298     if (rawEvent->type == EV_KEY) {
   1299         switch (rawEvent->code) {
   1300         case BTN_TOUCH:
   1301             mBtnTouch = rawEvent->value;
   1302             break;
   1303         case BTN_STYLUS:
   1304             mBtnStylus = rawEvent->value;
   1305             break;
   1306         case BTN_STYLUS2:
   1307             mBtnStylus2 = rawEvent->value;
   1308             break;
   1309         case BTN_TOOL_FINGER:
   1310             mBtnToolFinger = rawEvent->value;
   1311             break;
   1312         case BTN_TOOL_PEN:
   1313             mBtnToolPen = rawEvent->value;
   1314             break;
   1315         case BTN_TOOL_RUBBER:
   1316             mBtnToolRubber = rawEvent->value;
   1317             break;
   1318         case BTN_TOOL_BRUSH:
   1319             mBtnToolBrush = rawEvent->value;
   1320             break;
   1321         case BTN_TOOL_PENCIL:
   1322             mBtnToolPencil = rawEvent->value;
   1323             break;
   1324         case BTN_TOOL_AIRBRUSH:
   1325             mBtnToolAirbrush = rawEvent->value;
   1326             break;
   1327         case BTN_TOOL_MOUSE:
   1328             mBtnToolMouse = rawEvent->value;
   1329             break;
   1330         case BTN_TOOL_LENS:
   1331             mBtnToolLens = rawEvent->value;
   1332             break;
   1333         case BTN_TOOL_DOUBLETAP:
   1334             mBtnToolDoubleTap = rawEvent->value;
   1335             break;
   1336         case BTN_TOOL_TRIPLETAP:
   1337             mBtnToolTripleTap = rawEvent->value;
   1338             break;
   1339         case BTN_TOOL_QUADTAP:
   1340             mBtnToolQuadTap = rawEvent->value;
   1341             break;
   1342         }
   1343     }
   1344 }
   1345 
   1346 uint32_t TouchButtonAccumulator::getButtonState() const {
   1347     uint32_t result = 0;
   1348     if (mBtnStylus) {
   1349         result |= AMOTION_EVENT_BUTTON_SECONDARY;
   1350     }
   1351     if (mBtnStylus2) {
   1352         result |= AMOTION_EVENT_BUTTON_TERTIARY;
   1353     }
   1354     return result;
   1355 }
   1356 
   1357 int32_t TouchButtonAccumulator::getToolType() const {
   1358     if (mBtnToolMouse || mBtnToolLens) {
   1359         return AMOTION_EVENT_TOOL_TYPE_MOUSE;
   1360     }
   1361     if (mBtnToolRubber) {
   1362         return AMOTION_EVENT_TOOL_TYPE_ERASER;
   1363     }
   1364     if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
   1365         return AMOTION_EVENT_TOOL_TYPE_STYLUS;
   1366     }
   1367     if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
   1368         return AMOTION_EVENT_TOOL_TYPE_FINGER;
   1369     }
   1370     return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
   1371 }
   1372 
   1373 bool TouchButtonAccumulator::isToolActive() const {
   1374     return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
   1375             || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
   1376             || mBtnToolMouse || mBtnToolLens
   1377             || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
   1378 }
   1379 
   1380 bool TouchButtonAccumulator::isHovering() const {
   1381     return mHaveBtnTouch && !mBtnTouch;
   1382 }
   1383 
   1384 bool TouchButtonAccumulator::hasStylus() const {
   1385     return mHaveStylus;
   1386 }
   1387 
   1388 
   1389 // --- RawPointerAxes ---
   1390 
   1391 RawPointerAxes::RawPointerAxes() {
   1392     clear();
   1393 }
   1394 
   1395 void RawPointerAxes::clear() {
   1396     x.clear();
   1397     y.clear();
   1398     pressure.clear();
   1399     touchMajor.clear();
   1400     touchMinor.clear();
   1401     toolMajor.clear();
   1402     toolMinor.clear();
   1403     orientation.clear();
   1404     distance.clear();
   1405     tiltX.clear();
   1406     tiltY.clear();
   1407     trackingId.clear();
   1408     slot.clear();
   1409 }
   1410 
   1411 
   1412 // --- RawPointerData ---
   1413 
   1414 RawPointerData::RawPointerData() {
   1415     clear();
   1416 }
   1417 
   1418 void RawPointerData::clear() {
   1419     pointerCount = 0;
   1420     clearIdBits();
   1421 }
   1422 
   1423 void RawPointerData::copyFrom(const RawPointerData& other) {
   1424     pointerCount = other.pointerCount;
   1425     hoveringIdBits = other.hoveringIdBits;
   1426     touchingIdBits = other.touchingIdBits;
   1427 
   1428     for (uint32_t i = 0; i < pointerCount; i++) {
   1429         pointers[i] = other.pointers[i];
   1430 
   1431         int id = pointers[i].id;
   1432         idToIndex[id] = other.idToIndex[id];
   1433     }
   1434 }
   1435 
   1436 void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
   1437     float x = 0, y = 0;
   1438     uint32_t count = touchingIdBits.count();
   1439     if (count) {
   1440         for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
   1441             uint32_t id = idBits.clearFirstMarkedBit();
   1442             const Pointer& pointer = pointerForId(id);
   1443             x += pointer.x;
   1444             y += pointer.y;
   1445         }
   1446         x /= count;
   1447         y /= count;
   1448     }
   1449     *outX = x;
   1450     *outY = y;
   1451 }
   1452 
   1453 
   1454 // --- CookedPointerData ---
   1455 
   1456 CookedPointerData::CookedPointerData() {
   1457     clear();
   1458 }
   1459 
   1460 void CookedPointerData::clear() {
   1461     pointerCount = 0;
   1462     hoveringIdBits.clear();
   1463     touchingIdBits.clear();
   1464 }
   1465 
   1466 void CookedPointerData::copyFrom(const CookedPointerData& other) {
   1467     pointerCount = other.pointerCount;
   1468     hoveringIdBits = other.hoveringIdBits;
   1469     touchingIdBits = other.touchingIdBits;
   1470 
   1471     for (uint32_t i = 0; i < pointerCount; i++) {
   1472         pointerProperties[i].copyFrom(other.pointerProperties[i]);
   1473         pointerCoords[i].copyFrom(other.pointerCoords[i]);
   1474 
   1475         int id = pointerProperties[i].id;
   1476         idToIndex[id] = other.idToIndex[id];
   1477     }
   1478 }
   1479 
   1480 
   1481 // --- SingleTouchMotionAccumulator ---
   1482 
   1483 SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
   1484     clearAbsoluteAxes();
   1485 }
   1486 
   1487 void SingleTouchMotionAccumulator::reset(InputDevice* device) {
   1488     mAbsX = device->getAbsoluteAxisValue(ABS_X);
   1489     mAbsY = device->getAbsoluteAxisValue(ABS_Y);
   1490     mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
   1491     mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
   1492     mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
   1493     mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
   1494     mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
   1495 }
   1496 
   1497 void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
   1498     mAbsX = 0;
   1499     mAbsY = 0;
   1500     mAbsPressure = 0;
   1501     mAbsToolWidth = 0;
   1502     mAbsDistance = 0;
   1503     mAbsTiltX = 0;
   1504     mAbsTiltY = 0;
   1505 }
   1506 
   1507 void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
   1508     if (rawEvent->type == EV_ABS) {
   1509         switch (rawEvent->code) {
   1510         case ABS_X:
   1511             mAbsX = rawEvent->value;
   1512             break;
   1513         case ABS_Y:
   1514             mAbsY = rawEvent->value;
   1515             break;
   1516         case ABS_PRESSURE:
   1517             mAbsPressure = rawEvent->value;
   1518             break;
   1519         case ABS_TOOL_WIDTH:
   1520             mAbsToolWidth = rawEvent->value;
   1521             break;
   1522         case ABS_DISTANCE:
   1523             mAbsDistance = rawEvent->value;
   1524             break;
   1525         case ABS_TILT_X:
   1526             mAbsTiltX = rawEvent->value;
   1527             break;
   1528         case ABS_TILT_Y:
   1529             mAbsTiltY = rawEvent->value;
   1530             break;
   1531         }
   1532     }
   1533 }
   1534 
   1535 
   1536 // --- MultiTouchMotionAccumulator ---
   1537 
   1538 MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
   1539         mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
   1540         mHaveStylus(false) {
   1541 }
   1542 
   1543 MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
   1544     delete[] mSlots;
   1545 }
   1546 
   1547 void MultiTouchMotionAccumulator::configure(InputDevice* device,
   1548         size_t slotCount, bool usingSlotsProtocol) {
   1549     mSlotCount = slotCount;
   1550     mUsingSlotsProtocol = usingSlotsProtocol;
   1551     mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
   1552 
   1553     delete[] mSlots;
   1554     mSlots = new Slot[slotCount];
   1555 }
   1556 
   1557 void MultiTouchMotionAccumulator::reset(InputDevice* device) {
   1558     // Unfortunately there is no way to read the initial contents of the slots.
   1559     // So when we reset the accumulator, we must assume they are all zeroes.
   1560     if (mUsingSlotsProtocol) {
   1561         // Query the driver for the current slot index and use it as the initial slot
   1562         // before we start reading events from the device.  It is possible that the
   1563         // current slot index will not be the same as it was when the first event was
   1564         // written into the evdev buffer, which means the input mapper could start
   1565         // out of sync with the initial state of the events in the evdev buffer.
   1566         // In the extremely unlikely case that this happens, the data from
   1567         // two slots will be confused until the next ABS_MT_SLOT event is received.
   1568         // This can cause the touch point to "jump", but at least there will be
   1569         // no stuck touches.
   1570         int32_t initialSlot;
   1571         status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
   1572                 ABS_MT_SLOT, &initialSlot);
   1573         if (status) {
   1574             ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
   1575             initialSlot = -1;
   1576         }
   1577         clearSlots(initialSlot);
   1578     } else {
   1579         clearSlots(-1);
   1580     }
   1581 }
   1582 
   1583 void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
   1584     if (mSlots) {
   1585         for (size_t i = 0; i < mSlotCount; i++) {
   1586             mSlots[i].clear();
   1587         }
   1588     }
   1589     mCurrentSlot = initialSlot;
   1590 }
   1591 
   1592 void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
   1593     if (rawEvent->type == EV_ABS) {
   1594         bool newSlot = false;
   1595         if (mUsingSlotsProtocol) {
   1596             if (rawEvent->code == ABS_MT_SLOT) {
   1597                 mCurrentSlot = rawEvent->value;
   1598                 newSlot = true;
   1599             }
   1600         } else if (mCurrentSlot < 0) {
   1601             mCurrentSlot = 0;
   1602         }
   1603 
   1604         if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
   1605 #if DEBUG_POINTERS
   1606             if (newSlot) {
   1607                 ALOGW("MultiTouch device emitted invalid slot index %d but it "
   1608                         "should be between 0 and %d; ignoring this slot.",
   1609                         mCurrentSlot, mSlotCount - 1);
   1610             }
   1611 #endif
   1612         } else {
   1613             Slot* slot = &mSlots[mCurrentSlot];
   1614 
   1615             switch (rawEvent->code) {
   1616             case ABS_MT_POSITION_X:
   1617                 slot->mInUse = true;
   1618                 slot->mAbsMTPositionX = rawEvent->value;
   1619                 break;
   1620             case ABS_MT_POSITION_Y:
   1621                 slot->mInUse = true;
   1622                 slot->mAbsMTPositionY = rawEvent->value;
   1623                 break;
   1624             case ABS_MT_TOUCH_MAJOR:
   1625                 slot->mInUse = true;
   1626                 slot->mAbsMTTouchMajor = rawEvent->value;
   1627                 break;
   1628             case ABS_MT_TOUCH_MINOR:
   1629                 slot->mInUse = true;
   1630                 slot->mAbsMTTouchMinor = rawEvent->value;
   1631                 slot->mHaveAbsMTTouchMinor = true;
   1632                 break;
   1633             case ABS_MT_WIDTH_MAJOR:
   1634                 slot->mInUse = true;
   1635                 slot->mAbsMTWidthMajor = rawEvent->value;
   1636                 break;
   1637             case ABS_MT_WIDTH_MINOR:
   1638                 slot->mInUse = true;
   1639                 slot->mAbsMTWidthMinor = rawEvent->value;
   1640                 slot->mHaveAbsMTWidthMinor = true;
   1641                 break;
   1642             case ABS_MT_ORIENTATION:
   1643                 slot->mInUse = true;
   1644                 slot->mAbsMTOrientation = rawEvent->value;
   1645                 break;
   1646             case ABS_MT_TRACKING_ID:
   1647                 if (mUsingSlotsProtocol && rawEvent->value < 0) {
   1648                     // The slot is no longer in use but it retains its previous contents,
   1649                     // which may be reused for subsequent touches.
   1650                     slot->mInUse = false;
   1651                 } else {
   1652                     slot->mInUse = true;
   1653                     slot->mAbsMTTrackingId = rawEvent->value;
   1654                 }
   1655                 break;
   1656             case ABS_MT_PRESSURE:
   1657                 slot->mInUse = true;
   1658                 slot->mAbsMTPressure = rawEvent->value;
   1659                 break;
   1660             case ABS_MT_DISTANCE:
   1661                 slot->mInUse = true;
   1662                 slot->mAbsMTDistance = rawEvent->value;
   1663                 break;
   1664             case ABS_MT_TOOL_TYPE:
   1665                 slot->mInUse = true;
   1666                 slot->mAbsMTToolType = rawEvent->value;
   1667                 slot->mHaveAbsMTToolType = true;
   1668                 break;
   1669             }
   1670         }
   1671     } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
   1672         // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
   1673         mCurrentSlot += 1;
   1674     }
   1675 }
   1676 
   1677 void MultiTouchMotionAccumulator::finishSync() {
   1678     if (!mUsingSlotsProtocol) {
   1679         clearSlots(-1);
   1680     }
   1681 }
   1682 
   1683 bool MultiTouchMotionAccumulator::hasStylus() const {
   1684     return mHaveStylus;
   1685 }
   1686 
   1687 
   1688 // --- MultiTouchMotionAccumulator::Slot ---
   1689 
   1690 MultiTouchMotionAccumulator::Slot::Slot() {
   1691     clear();
   1692 }
   1693 
   1694 void MultiTouchMotionAccumulator::Slot::clear() {
   1695     mInUse = false;
   1696     mHaveAbsMTTouchMinor = false;
   1697     mHaveAbsMTWidthMinor = false;
   1698     mHaveAbsMTToolType = false;
   1699     mAbsMTPositionX = 0;
   1700     mAbsMTPositionY = 0;
   1701     mAbsMTTouchMajor = 0;
   1702     mAbsMTTouchMinor = 0;
   1703     mAbsMTWidthMajor = 0;
   1704     mAbsMTWidthMinor = 0;
   1705     mAbsMTOrientation = 0;
   1706     mAbsMTTrackingId = -1;
   1707     mAbsMTPressure = 0;
   1708     mAbsMTDistance = 0;
   1709     mAbsMTToolType = 0;
   1710 }
   1711 
   1712 int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
   1713     if (mHaveAbsMTToolType) {
   1714         switch (mAbsMTToolType) {
   1715         case MT_TOOL_FINGER:
   1716             return AMOTION_EVENT_TOOL_TYPE_FINGER;
   1717         case MT_TOOL_PEN:
   1718             return AMOTION_EVENT_TOOL_TYPE_STYLUS;
   1719         }
   1720     }
   1721     return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
   1722 }
   1723 
   1724 
   1725 // --- InputMapper ---
   1726 
   1727 InputMapper::InputMapper(InputDevice* device) :
   1728         mDevice(device), mContext(device->getContext()) {
   1729 }
   1730 
   1731 InputMapper::~InputMapper() {
   1732 }
   1733 
   1734 void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
   1735     info->addSource(getSources());
   1736 }
   1737 
   1738 void InputMapper::dump(String8& dump) {
   1739 }
   1740 
   1741 void InputMapper::configure(nsecs_t when,
   1742         const InputReaderConfiguration* config, uint32_t changes) {
   1743 }
   1744 
   1745 void InputMapper::reset(nsecs_t when) {
   1746 }
   1747 
   1748 void InputMapper::timeoutExpired(nsecs_t when) {
   1749 }
   1750 
   1751 int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
   1752     return AKEY_STATE_UNKNOWN;
   1753 }
   1754 
   1755 int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
   1756     return AKEY_STATE_UNKNOWN;
   1757 }
   1758 
   1759 int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
   1760     return AKEY_STATE_UNKNOWN;
   1761 }
   1762 
   1763 bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
   1764         const int32_t* keyCodes, uint8_t* outFlags) {
   1765     return false;
   1766 }
   1767 
   1768 void InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
   1769         int32_t token) {
   1770 }
   1771 
   1772 void InputMapper::cancelVibrate(int32_t token) {
   1773 }
   1774 
   1775 int32_t InputMapper::getMetaState() {
   1776     return 0;
   1777 }
   1778 
   1779 void InputMapper::fadePointer() {
   1780 }
   1781 
   1782 status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
   1783     return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
   1784 }
   1785 
   1786 void InputMapper::bumpGeneration() {
   1787     mDevice->bumpGeneration();
   1788 }
   1789 
   1790 void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
   1791         const RawAbsoluteAxisInfo& axis, const char* name) {
   1792     if (axis.valid) {
   1793         dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
   1794                 name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
   1795     } else {
   1796         dump.appendFormat(INDENT4 "%s: unknown range\n", name);
   1797     }
   1798 }
   1799 
   1800 
   1801 // --- SwitchInputMapper ---
   1802 
   1803 SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
   1804         InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
   1805 }
   1806 
   1807 SwitchInputMapper::~SwitchInputMapper() {
   1808 }
   1809 
   1810 uint32_t SwitchInputMapper::getSources() {
   1811     return AINPUT_SOURCE_SWITCH;
   1812 }
   1813 
   1814 void SwitchInputMapper::process(const RawEvent* rawEvent) {
   1815     switch (rawEvent->type) {
   1816     case EV_SW:
   1817         processSwitch(rawEvent->code, rawEvent->value);
   1818         break;
   1819 
   1820     case EV_SYN:
   1821         if (rawEvent->code == SYN_REPORT) {
   1822             sync(rawEvent->when);
   1823         }
   1824     }
   1825 }
   1826 
   1827 void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
   1828     if (switchCode >= 0 && switchCode < 32) {
   1829         if (switchValue) {
   1830             mUpdatedSwitchValues |= 1 << switchCode;
   1831         }
   1832         mUpdatedSwitchMask |= 1 << switchCode;
   1833     }
   1834 }
   1835 
   1836 void SwitchInputMapper::sync(nsecs_t when) {
   1837     if (mUpdatedSwitchMask) {
   1838         NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
   1839         getListener()->notifySwitch(&args);
   1840 
   1841         mUpdatedSwitchValues = 0;
   1842         mUpdatedSwitchMask = 0;
   1843     }
   1844 }
   1845 
   1846 int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
   1847     return getEventHub()->getSwitchState(getDeviceId(), switchCode);
   1848 }
   1849 
   1850 
   1851 // --- VibratorInputMapper ---
   1852 
   1853 VibratorInputMapper::VibratorInputMapper(InputDevice* device) :
   1854         InputMapper(device), mVibrating(false) {
   1855 }
   1856 
   1857 VibratorInputMapper::~VibratorInputMapper() {
   1858 }
   1859 
   1860 uint32_t VibratorInputMapper::getSources() {
   1861     return 0;
   1862 }
   1863 
   1864 void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
   1865     InputMapper::populateDeviceInfo(info);
   1866 
   1867     info->setVibrator(true);
   1868 }
   1869 
   1870 void VibratorInputMapper::process(const RawEvent* rawEvent) {
   1871     // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
   1872 }
   1873 
   1874 void VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
   1875         int32_t token) {
   1876 #if DEBUG_VIBRATOR
   1877     String8 patternStr;
   1878     for (size_t i = 0; i < patternSize; i++) {
   1879         if (i != 0) {
   1880             patternStr.append(", ");
   1881         }
   1882         patternStr.appendFormat("%lld", pattern[i]);
   1883     }
   1884     ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
   1885             getDeviceId(), patternStr.string(), repeat, token);
   1886 #endif
   1887 
   1888     mVibrating = true;
   1889     memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
   1890     mPatternSize = patternSize;
   1891     mRepeat = repeat;
   1892     mToken = token;
   1893     mIndex = -1;
   1894 
   1895     nextStep();
   1896 }
   1897 
   1898 void VibratorInputMapper::cancelVibrate(int32_t token) {
   1899 #if DEBUG_VIBRATOR
   1900     ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
   1901 #endif
   1902 
   1903     if (mVibrating && mToken == token) {
   1904         stopVibrating();
   1905     }
   1906 }
   1907 
   1908 void VibratorInputMapper::timeoutExpired(nsecs_t when) {
   1909     if (mVibrating) {
   1910         if (when >= mNextStepTime) {
   1911             nextStep();
   1912         } else {
   1913             getContext()->requestTimeoutAtTime(mNextStepTime);
   1914         }
   1915     }
   1916 }
   1917 
   1918 void VibratorInputMapper::nextStep() {
   1919     mIndex += 1;
   1920     if (size_t(mIndex) >= mPatternSize) {
   1921         if (mRepeat < 0) {
   1922             // We are done.
   1923             stopVibrating();
   1924             return;
   1925         }
   1926         mIndex = mRepeat;
   1927     }
   1928 
   1929     bool vibratorOn = mIndex & 1;
   1930     nsecs_t duration = mPattern[mIndex];
   1931     if (vibratorOn) {
   1932 #if DEBUG_VIBRATOR
   1933         ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
   1934                 getDeviceId(), duration);
   1935 #endif
   1936         getEventHub()->vibrate(getDeviceId(), duration);
   1937     } else {
   1938 #if DEBUG_VIBRATOR
   1939         ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
   1940 #endif
   1941         getEventHub()->cancelVibrate(getDeviceId());
   1942     }
   1943     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
   1944     mNextStepTime = now + duration;
   1945     getContext()->requestTimeoutAtTime(mNextStepTime);
   1946 #if DEBUG_VIBRATOR
   1947     ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
   1948 #endif
   1949 }
   1950 
   1951 void VibratorInputMapper::stopVibrating() {
   1952     mVibrating = false;
   1953 #if DEBUG_VIBRATOR
   1954     ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
   1955 #endif
   1956     getEventHub()->cancelVibrate(getDeviceId());
   1957 }
   1958 
   1959 void VibratorInputMapper::dump(String8& dump) {
   1960     dump.append(INDENT2 "Vibrator Input Mapper:\n");
   1961     dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
   1962 }
   1963 
   1964 
   1965 // --- KeyboardInputMapper ---
   1966 
   1967 KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
   1968         uint32_t source, int32_t keyboardType) :
   1969         InputMapper(device), mSource(source),
   1970         mKeyboardType(keyboardType) {
   1971 }
   1972 
   1973 KeyboardInputMapper::~KeyboardInputMapper() {
   1974 }
   1975 
   1976 uint32_t KeyboardInputMapper::getSources() {
   1977     return mSource;
   1978 }
   1979 
   1980 void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
   1981     InputMapper::populateDeviceInfo(info);
   1982 
   1983     info->setKeyboardType(mKeyboardType);
   1984     info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
   1985 }
   1986 
   1987 void KeyboardInputMapper::dump(String8& dump) {
   1988     dump.append(INDENT2 "Keyboard Input Mapper:\n");
   1989     dumpParameters(dump);
   1990     dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
   1991     dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
   1992     dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
   1993     dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
   1994     dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
   1995 }
   1996 
   1997 
   1998 void KeyboardInputMapper::configure(nsecs_t when,
   1999         const InputReaderConfiguration* config, uint32_t changes) {
   2000     InputMapper::configure(when, config, changes);
   2001 
   2002     if (!changes) { // first time only
   2003         // Configure basic parameters.
   2004         configureParameters();
   2005     }
   2006 
   2007     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
   2008         if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
   2009             DisplayViewport v;
   2010             if (config->getDisplayInfo(false /*external*/, &v)) {
   2011                 mOrientation = v.orientation;
   2012             } else {
   2013                 mOrientation = DISPLAY_ORIENTATION_0;
   2014             }
   2015         } else {
   2016             mOrientation = DISPLAY_ORIENTATION_0;
   2017         }
   2018     }
   2019 }
   2020 
   2021 void KeyboardInputMapper::configureParameters() {
   2022     mParameters.orientationAware = false;
   2023     getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
   2024             mParameters.orientationAware);
   2025 
   2026     mParameters.hasAssociatedDisplay = false;
   2027     if (mParameters.orientationAware) {
   2028         mParameters.hasAssociatedDisplay = true;
   2029     }
   2030 }
   2031 
   2032 void KeyboardInputMapper::dumpParameters(String8& dump) {
   2033     dump.append(INDENT3 "Parameters:\n");
   2034     dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
   2035             toString(mParameters.hasAssociatedDisplay));
   2036     dump.appendFormat(INDENT4 "OrientationAware: %s\n",
   2037             toString(mParameters.orientationAware));
   2038 }
   2039 
   2040 void KeyboardInputMapper::reset(nsecs_t when) {
   2041     mMetaState = AMETA_NONE;
   2042     mDownTime = 0;
   2043     mKeyDowns.clear();
   2044     mCurrentHidUsage = 0;
   2045 
   2046     resetLedState();
   2047 
   2048     InputMapper::reset(when);
   2049 }
   2050 
   2051 void KeyboardInputMapper::process(const RawEvent* rawEvent) {
   2052     switch (rawEvent->type) {
   2053     case EV_KEY: {
   2054         int32_t scanCode = rawEvent->code;
   2055         int32_t usageCode = mCurrentHidUsage;
   2056         mCurrentHidUsage = 0;
   2057 
   2058         if (isKeyboardOrGamepadKey(scanCode)) {
   2059             int32_t keyCode;
   2060             uint32_t flags;
   2061             if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
   2062                 keyCode = AKEYCODE_UNKNOWN;
   2063                 flags = 0;
   2064             }
   2065             processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
   2066         }
   2067         break;
   2068     }
   2069     case EV_MSC: {
   2070         if (rawEvent->code == MSC_SCAN) {
   2071             mCurrentHidUsage = rawEvent->value;
   2072         }
   2073         break;
   2074     }
   2075     case EV_SYN: {
   2076         if (rawEvent->code == SYN_REPORT) {
   2077             mCurrentHidUsage = 0;
   2078         }
   2079     }
   2080     }
   2081 }
   2082 
   2083 bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
   2084     return scanCode < BTN_MOUSE
   2085         || scanCode >= KEY_OK
   2086         || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
   2087         || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
   2088 }
   2089 
   2090 void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
   2091         int32_t scanCode, uint32_t policyFlags) {
   2092 
   2093     if (down) {
   2094         // Rotate key codes according to orientation if needed.
   2095         if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
   2096             keyCode = rotateKeyCode(keyCode, mOrientation);
   2097         }
   2098 
   2099         // Add key down.
   2100         ssize_t keyDownIndex = findKeyDown(scanCode);
   2101         if (keyDownIndex >= 0) {
   2102             // key repeat, be sure to use same keycode as before in case of rotation
   2103             keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
   2104         } else {
   2105             // key down
   2106             if ((policyFlags & POLICY_FLAG_VIRTUAL)
   2107                     && mContext->shouldDropVirtualKey(when,
   2108                             getDevice(), keyCode, scanCode)) {
   2109                 return;
   2110             }
   2111 
   2112             mKeyDowns.push();
   2113             KeyDown& keyDown = mKeyDowns.editTop();
   2114             keyDown.keyCode = keyCode;
   2115             keyDown.scanCode = scanCode;
   2116         }
   2117 
   2118         mDownTime = when;
   2119     } else {
   2120         // Remove key down.
   2121         ssize_t keyDownIndex = findKeyDown(scanCode);
   2122         if (keyDownIndex >= 0) {
   2123             // key up, be sure to use same keycode as before in case of rotation
   2124             keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
   2125             mKeyDowns.removeAt(size_t(keyDownIndex));
   2126         } else {
   2127             // key was not actually down
   2128             ALOGI("Dropping key up from device %s because the key was not down.  "
   2129                     "keyCode=%d, scanCode=%d",
   2130                     getDeviceName().string(), keyCode, scanCode);
   2131             return;
   2132         }
   2133     }
   2134 
   2135     bool metaStateChanged = false;
   2136     int32_t oldMetaState = mMetaState;
   2137     int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
   2138     if (oldMetaState != newMetaState) {
   2139         mMetaState = newMetaState;
   2140         metaStateChanged = true;
   2141         updateLedState(false);
   2142     }
   2143 
   2144     nsecs_t downTime = mDownTime;
   2145 
   2146     // Key down on external an keyboard should wake the device.
   2147     // We don't do this for internal keyboards to prevent them from waking up in your pocket.
   2148     // For internal keyboards, the key layout file should specify the policy flags for
   2149     // each wake key individually.
   2150     // TODO: Use the input device configuration to control this behavior more finely.
   2151     if (down && getDevice()->isExternal()
   2152             && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
   2153         policyFlags |= POLICY_FLAG_WAKE_DROPPED;
   2154     }
   2155 
   2156     if (metaStateChanged) {
   2157         getContext()->updateGlobalMetaState();
   2158     }
   2159 
   2160     if (down && !isMetaKey(keyCode)) {
   2161         getContext()->fadePointer();
   2162     }
   2163 
   2164     NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
   2165             down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
   2166             AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
   2167     getListener()->notifyKey(&args);
   2168 }
   2169 
   2170 ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
   2171     size_t n = mKeyDowns.size();
   2172     for (size_t i = 0; i < n; i++) {
   2173         if (mKeyDowns[i].scanCode == scanCode) {
   2174             return i;
   2175         }
   2176     }
   2177     return -1;
   2178 }
   2179 
   2180 int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
   2181     return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
   2182 }
   2183 
   2184 int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
   2185     return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
   2186 }
   2187 
   2188 bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
   2189         const int32_t* keyCodes, uint8_t* outFlags) {
   2190     return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
   2191 }
   2192 
   2193 int32_t KeyboardInputMapper::getMetaState() {
   2194     return mMetaState;
   2195 }
   2196 
   2197 void KeyboardInputMapper::resetLedState() {
   2198     initializeLedState(mCapsLockLedState, LED_CAPSL);
   2199     initializeLedState(mNumLockLedState, LED_NUML);
   2200     initializeLedState(mScrollLockLedState, LED_SCROLLL);
   2201 
   2202     updateLedState(true);
   2203 }
   2204 
   2205 void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
   2206     ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
   2207     ledState.on = false;
   2208 }
   2209 
   2210 void KeyboardInputMapper::updateLedState(bool reset) {
   2211     updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
   2212             AMETA_CAPS_LOCK_ON, reset);
   2213     updateLedStateForModifier(mNumLockLedState, LED_NUML,
   2214             AMETA_NUM_LOCK_ON, reset);
   2215     updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
   2216             AMETA_SCROLL_LOCK_ON, reset);
   2217 }
   2218 
   2219 void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
   2220         int32_t led, int32_t modifier, bool reset) {
   2221     if (ledState.avail) {
   2222         bool desiredState = (mMetaState & modifier) != 0;
   2223         if (reset || ledState.on != desiredState) {
   2224             getEventHub()->setLedState(getDeviceId(), led, desiredState);
   2225             ledState.on = desiredState;
   2226         }
   2227     }
   2228 }
   2229 
   2230 
   2231 // --- CursorInputMapper ---
   2232 
   2233 CursorInputMapper::CursorInputMapper(InputDevice* device) :
   2234         InputMapper(device) {
   2235 }
   2236 
   2237 CursorInputMapper::~CursorInputMapper() {
   2238 }
   2239 
   2240 uint32_t CursorInputMapper::getSources() {
   2241     return mSource;
   2242 }
   2243 
   2244 void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
   2245     InputMapper::populateDeviceInfo(info);
   2246 
   2247     if (mParameters.mode == Parameters::MODE_POINTER) {
   2248         float minX, minY, maxX, maxY;
   2249         if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
   2250             info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f);
   2251             info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f);
   2252         }
   2253     } else {
   2254         info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale);
   2255         info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale);
   2256     }
   2257     info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f);
   2258 
   2259     if (mCursorScrollAccumulator.haveRelativeVWheel()) {
   2260         info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
   2261     }
   2262     if (mCursorScrollAccumulator.haveRelativeHWheel()) {
   2263         info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
   2264     }
   2265 }
   2266 
   2267 void CursorInputMapper::dump(String8& dump) {
   2268     dump.append(INDENT2 "Cursor Input Mapper:\n");
   2269     dumpParameters(dump);
   2270     dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
   2271     dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
   2272     dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
   2273     dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
   2274     dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
   2275             toString(mCursorScrollAccumulator.haveRelativeVWheel()));
   2276     dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
   2277             toString(mCursorScrollAccumulator.haveRelativeHWheel()));
   2278     dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
   2279     dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
   2280     dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
   2281     dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
   2282     dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
   2283     dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
   2284 }
   2285 
   2286 void CursorInputMapper::configure(nsecs_t when,
   2287         const InputReaderConfiguration* config, uint32_t changes) {
   2288     InputMapper::configure(when, config, changes);
   2289 
   2290     if (!changes) { // first time only
   2291         mCursorScrollAccumulator.configure(getDevice());
   2292 
   2293         // Configure basic parameters.
   2294         configureParameters();
   2295 
   2296         // Configure device mode.
   2297         switch (mParameters.mode) {
   2298         case Parameters::MODE_POINTER:
   2299             mSource = AINPUT_SOURCE_MOUSE;
   2300             mXPrecision = 1.0f;
   2301             mYPrecision = 1.0f;
   2302             mXScale = 1.0f;
   2303             mYScale = 1.0f;
   2304             mPointerController = getPolicy()->obtainPointerController(getDeviceId());
   2305             break;
   2306         case Parameters::MODE_NAVIGATION:
   2307             mSource = AINPUT_SOURCE_TRACKBALL;
   2308             mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
   2309             mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
   2310             mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
   2311             mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
   2312             break;
   2313         }
   2314 
   2315         mVWheelScale = 1.0f;
   2316         mHWheelScale = 1.0f;
   2317     }
   2318 
   2319     if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
   2320         mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
   2321         mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
   2322         mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
   2323     }
   2324 
   2325     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
   2326         if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
   2327             DisplayViewport v;
   2328             if (config->getDisplayInfo(false /*external*/, &v)) {
   2329                 mOrientation = v.orientation;
   2330             } else {
   2331                 mOrientation = DISPLAY_ORIENTATION_0;
   2332             }
   2333         } else {
   2334             mOrientation = DISPLAY_ORIENTATION_0;
   2335         }
   2336         bumpGeneration();
   2337     }
   2338 }
   2339 
   2340 void CursorInputMapper::configureParameters() {
   2341     mParameters.mode = Parameters::MODE_POINTER;
   2342     String8 cursorModeString;
   2343     if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
   2344         if (cursorModeString == "navigation") {
   2345             mParameters.mode = Parameters::MODE_NAVIGATION;
   2346         } else if (cursorModeString != "pointer" && cursorModeString != "default") {
   2347             ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
   2348         }
   2349     }
   2350 
   2351     mParameters.orientationAware = false;
   2352     getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
   2353             mParameters.orientationAware);
   2354 
   2355     mParameters.hasAssociatedDisplay = false;
   2356     if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
   2357         mParameters.hasAssociatedDisplay = true;
   2358     }
   2359 }
   2360 
   2361 void CursorInputMapper::dumpParameters(String8& dump) {
   2362     dump.append(INDENT3 "Parameters:\n");
   2363     dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
   2364             toString(mParameters.hasAssociatedDisplay));
   2365 
   2366     switch (mParameters.mode) {
   2367     case Parameters::MODE_POINTER:
   2368         dump.append(INDENT4 "Mode: pointer\n");
   2369         break;
   2370     case Parameters::MODE_NAVIGATION:
   2371         dump.append(INDENT4 "Mode: navigation\n");
   2372         break;
   2373     default:
   2374         ALOG_ASSERT(false);
   2375     }
   2376 
   2377     dump.appendFormat(INDENT4 "OrientationAware: %s\n",
   2378             toString(mParameters.orientationAware));
   2379 }
   2380 
   2381 void CursorInputMapper::reset(nsecs_t when) {
   2382     mButtonState = 0;
   2383     mDownTime = 0;
   2384 
   2385     mPointerVelocityControl.reset();
   2386     mWheelXVelocityControl.reset();
   2387     mWheelYVelocityControl.reset();
   2388 
   2389     mCursorButtonAccumulator.reset(getDevice());
   2390     mCursorMotionAccumulator.reset(getDevice());
   2391     mCursorScrollAccumulator.reset(getDevice());
   2392 
   2393     InputMapper::reset(when);
   2394 }
   2395 
   2396 void CursorInputMapper::process(const RawEvent* rawEvent) {
   2397     mCursorButtonAccumulator.process(rawEvent);
   2398     mCursorMotionAccumulator.process(rawEvent);
   2399     mCursorScrollAccumulator.process(rawEvent);
   2400 
   2401     if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
   2402         sync(rawEvent->when);
   2403     }
   2404 }
   2405 
   2406 void CursorInputMapper::sync(nsecs_t when) {
   2407     int32_t lastButtonState = mButtonState;
   2408     int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
   2409     mButtonState = currentButtonState;
   2410 
   2411     bool wasDown = isPointerDown(lastButtonState);
   2412     bool down = isPointerDown(currentButtonState);
   2413     bool downChanged;
   2414     if (!wasDown && down) {
   2415         mDownTime = when;
   2416         downChanged = true;
   2417     } else if (wasDown && !down) {
   2418         downChanged = true;
   2419     } else {
   2420         downChanged = false;
   2421     }
   2422     nsecs_t downTime = mDownTime;
   2423     bool buttonsChanged = currentButtonState != lastButtonState;
   2424     bool buttonsPressed = currentButtonState & ~lastButtonState;
   2425 
   2426     float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
   2427     float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
   2428     bool moved = deltaX != 0 || deltaY != 0;
   2429 
   2430     // Rotate delta according to orientation if needed.
   2431     if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
   2432             && (deltaX != 0.0f || deltaY != 0.0f)) {
   2433         rotateDelta(mOrientation, &deltaX, &deltaY);
   2434     }
   2435 
   2436     // Move the pointer.
   2437     PointerProperties pointerProperties;
   2438     pointerProperties.clear();
   2439     pointerProperties.id = 0;
   2440     pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
   2441 
   2442     PointerCoords pointerCoords;
   2443     pointerCoords.clear();
   2444 
   2445     float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
   2446     float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
   2447     bool scrolled = vscroll != 0 || hscroll != 0;
   2448 
   2449     mWheelYVelocityControl.move(when, NULL, &vscroll);
   2450     mWheelXVelocityControl.move(when, &hscroll, NULL);
   2451 
   2452     mPointerVelocityControl.move(when, &deltaX, &deltaY);
   2453 
   2454     int32_t displayId;
   2455     if (mPointerController != NULL) {
   2456         if (moved || scrolled || buttonsChanged) {
   2457             mPointerController->setPresentation(
   2458                     PointerControllerInterface::PRESENTATION_POINTER);
   2459 
   2460             if (moved) {
   2461                 mPointerController->move(deltaX, deltaY);
   2462             }
   2463 
   2464             if (buttonsChanged) {
   2465                 mPointerController->setButtonState(currentButtonState);
   2466             }
   2467 
   2468             mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
   2469         }
   2470 
   2471         float x, y;
   2472         mPointerController->getPosition(&x, &y);
   2473         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
   2474         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
   2475         displayId = ADISPLAY_ID_DEFAULT;
   2476     } else {
   2477         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
   2478         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
   2479         displayId = ADISPLAY_ID_NONE;
   2480     }
   2481 
   2482     pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
   2483 
   2484     // Moving an external trackball or mouse should wake the device.
   2485     // We don't do this for internal cursor devices to prevent them from waking up
   2486     // the device in your pocket.
   2487     // TODO: Use the input device configuration to control this behavior more finely.
   2488     uint32_t policyFlags = 0;
   2489     if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
   2490         policyFlags |= POLICY_FLAG_WAKE_DROPPED;
   2491     }
   2492 
   2493     // Synthesize key down from buttons if needed.
   2494     synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
   2495             policyFlags, lastButtonState, currentButtonState);
   2496 
   2497     // Send motion event.
   2498     if (downChanged || moved || scrolled || buttonsChanged) {
   2499         int32_t metaState = mContext->getGlobalMetaState();
   2500         int32_t motionEventAction;
   2501         if (downChanged) {
   2502             motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
   2503         } else if (down || mPointerController == NULL) {
   2504             motionEventAction = AMOTION_EVENT_ACTION_MOVE;
   2505         } else {
   2506             motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
   2507         }
   2508 
   2509         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   2510                 motionEventAction, 0, metaState, currentButtonState, 0,
   2511                 displayId, 1, &pointerProperties, &pointerCoords,
   2512                 mXPrecision, mYPrecision, downTime);
   2513         getListener()->notifyMotion(&args);
   2514 
   2515         // Send hover move after UP to tell the application that the mouse is hovering now.
   2516         if (motionEventAction == AMOTION_EVENT_ACTION_UP
   2517                 && mPointerController != NULL) {
   2518             NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
   2519                     AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
   2520                     metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
   2521                     displayId, 1, &pointerProperties, &pointerCoords,
   2522                     mXPrecision, mYPrecision, downTime);
   2523             getListener()->notifyMotion(&hoverArgs);
   2524         }
   2525 
   2526         // Send scroll events.
   2527         if (scrolled) {
   2528             pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
   2529             pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
   2530 
   2531             NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
   2532                     AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
   2533                     AMOTION_EVENT_EDGE_FLAG_NONE,
   2534                     displayId, 1, &pointerProperties, &pointerCoords,
   2535                     mXPrecision, mYPrecision, downTime);
   2536             getListener()->notifyMotion(&scrollArgs);
   2537         }
   2538     }
   2539 
   2540     // Synthesize key up from buttons if needed.
   2541     synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
   2542             policyFlags, lastButtonState, currentButtonState);
   2543 
   2544     mCursorMotionAccumulator.finishSync();
   2545     mCursorScrollAccumulator.finishSync();
   2546 }
   2547 
   2548 int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
   2549     if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
   2550         return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
   2551     } else {
   2552         return AKEY_STATE_UNKNOWN;
   2553     }
   2554 }
   2555 
   2556 void CursorInputMapper::fadePointer() {
   2557     if (mPointerController != NULL) {
   2558         mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
   2559     }
   2560 }
   2561 
   2562 
   2563 // --- TouchInputMapper ---
   2564 
   2565 TouchInputMapper::TouchInputMapper(InputDevice* device) :
   2566         InputMapper(device),
   2567         mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
   2568         mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
   2569         mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
   2570 }
   2571 
   2572 TouchInputMapper::~TouchInputMapper() {
   2573 }
   2574 
   2575 uint32_t TouchInputMapper::getSources() {
   2576     return mSource;
   2577 }
   2578 
   2579 void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
   2580     InputMapper::populateDeviceInfo(info);
   2581 
   2582     if (mDeviceMode != DEVICE_MODE_DISABLED) {
   2583         info->addMotionRange(mOrientedRanges.x);
   2584         info->addMotionRange(mOrientedRanges.y);
   2585         info->addMotionRange(mOrientedRanges.pressure);
   2586 
   2587         if (mOrientedRanges.haveSize) {
   2588             info->addMotionRange(mOrientedRanges.size);
   2589         }
   2590 
   2591         if (mOrientedRanges.haveTouchSize) {
   2592             info->addMotionRange(mOrientedRanges.touchMajor);
   2593             info->addMotionRange(mOrientedRanges.touchMinor);
   2594         }
   2595 
   2596         if (mOrientedRanges.haveToolSize) {
   2597             info->addMotionRange(mOrientedRanges.toolMajor);
   2598             info->addMotionRange(mOrientedRanges.toolMinor);
   2599         }
   2600 
   2601         if (mOrientedRanges.haveOrientation) {
   2602             info->addMotionRange(mOrientedRanges.orientation);
   2603         }
   2604 
   2605         if (mOrientedRanges.haveDistance) {
   2606             info->addMotionRange(mOrientedRanges.distance);
   2607         }
   2608 
   2609         if (mOrientedRanges.haveTilt) {
   2610             info->addMotionRange(mOrientedRanges.tilt);
   2611         }
   2612 
   2613         if (mCursorScrollAccumulator.haveRelativeVWheel()) {
   2614             info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
   2615         }
   2616         if (mCursorScrollAccumulator.haveRelativeHWheel()) {
   2617             info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f);
   2618         }
   2619     }
   2620 }
   2621 
   2622 void TouchInputMapper::dump(String8& dump) {
   2623     dump.append(INDENT2 "Touch Input Mapper:\n");
   2624     dumpParameters(dump);
   2625     dumpVirtualKeys(dump);
   2626     dumpRawPointerAxes(dump);
   2627     dumpCalibration(dump);
   2628     dumpSurface(dump);
   2629 
   2630     dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
   2631     dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
   2632     dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
   2633     dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
   2634     dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
   2635     dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
   2636     dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
   2637     dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
   2638     dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
   2639     dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
   2640     dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
   2641     dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
   2642     dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
   2643     dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
   2644     dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
   2645     dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
   2646     dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
   2647 
   2648     dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
   2649 
   2650     dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
   2651             mLastRawPointerData.pointerCount);
   2652     for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
   2653         const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
   2654         dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
   2655                 "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
   2656                 "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
   2657                 "toolType=%d, isHovering=%s\n", i,
   2658                 pointer.id, pointer.x, pointer.y, pointer.pressure,
   2659                 pointer.touchMajor, pointer.touchMinor,
   2660                 pointer.toolMajor, pointer.toolMinor,
   2661                 pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
   2662                 pointer.toolType, toString(pointer.isHovering));
   2663     }
   2664 
   2665     dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
   2666             mLastCookedPointerData.pointerCount);
   2667     for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
   2668         const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
   2669         const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
   2670         dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
   2671                 "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
   2672                 "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
   2673                 "toolType=%d, isHovering=%s\n", i,
   2674                 pointerProperties.id,
   2675                 pointerCoords.getX(),
   2676                 pointerCoords.getY(),
   2677                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
   2678                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
   2679                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
   2680                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
   2681                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
   2682                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
   2683                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
   2684                 pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
   2685                 pointerProperties.toolType,
   2686                 toString(mLastCookedPointerData.isHovering(i)));
   2687     }
   2688 
   2689     if (mDeviceMode == DEVICE_MODE_POINTER) {
   2690         dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
   2691         dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
   2692                 mPointerXMovementScale);
   2693         dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
   2694                 mPointerYMovementScale);
   2695         dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
   2696                 mPointerXZoomScale);
   2697         dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
   2698                 mPointerYZoomScale);
   2699         dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
   2700                 mPointerGestureMaxSwipeWidth);
   2701     }
   2702 }
   2703 
   2704 void TouchInputMapper::configure(nsecs_t when,
   2705         const InputReaderConfiguration* config, uint32_t changes) {
   2706     InputMapper::configure(when, config, changes);
   2707 
   2708     mConfig = *config;
   2709 
   2710     if (!changes) { // first time only
   2711         // Configure basic parameters.
   2712         configureParameters();
   2713 
   2714         // Configure common accumulators.
   2715         mCursorScrollAccumulator.configure(getDevice());
   2716         mTouchButtonAccumulator.configure(getDevice());
   2717 
   2718         // Configure absolute axis information.
   2719         configureRawPointerAxes();
   2720 
   2721         // Prepare input device calibration.
   2722         parseCalibration();
   2723         resolveCalibration();
   2724     }
   2725 
   2726     if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
   2727         // Update pointer speed.
   2728         mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
   2729         mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
   2730         mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
   2731     }
   2732 
   2733     bool resetNeeded = false;
   2734     if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
   2735             | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
   2736             | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
   2737         // Configure device sources, surface dimensions, orientation and
   2738         // scaling factors.
   2739         configureSurface(when, &resetNeeded);
   2740     }
   2741 
   2742     if (changes && resetNeeded) {
   2743         // Send reset, unless this is the first time the device has been configured,
   2744         // in which case the reader will call reset itself after all mappers are ready.
   2745         getDevice()->notifyReset(when);
   2746     }
   2747 }
   2748 
   2749 void TouchInputMapper::configureParameters() {
   2750     // Use the pointer presentation mode for devices that do not support distinct
   2751     // multitouch.  The spot-based presentation relies on being able to accurately
   2752     // locate two or more fingers on the touch pad.
   2753     mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
   2754             ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
   2755 
   2756     String8 gestureModeString;
   2757     if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
   2758             gestureModeString)) {
   2759         if (gestureModeString == "pointer") {
   2760             mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
   2761         } else if (gestureModeString == "spots") {
   2762             mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
   2763         } else if (gestureModeString != "default") {
   2764             ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
   2765         }
   2766     }
   2767 
   2768     if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
   2769         // The device is a touch screen.
   2770         mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
   2771     } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
   2772         // The device is a pointing device like a track pad.
   2773         mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
   2774     } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
   2775             || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
   2776         // The device is a cursor device with a touch pad attached.
   2777         // By default don't use the touch pad to move the pointer.
   2778         mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
   2779     } else {
   2780         // The device is a touch pad of unknown purpose.
   2781         mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
   2782     }
   2783 
   2784     String8 deviceTypeString;
   2785     if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
   2786             deviceTypeString)) {
   2787         if (deviceTypeString == "touchScreen") {
   2788             mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
   2789         } else if (deviceTypeString == "touchPad") {
   2790             mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
   2791         } else if (deviceTypeString == "pointer") {
   2792             mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
   2793         } else if (deviceTypeString != "default") {
   2794             ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
   2795         }
   2796     }
   2797 
   2798     mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
   2799     getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
   2800             mParameters.orientationAware);
   2801 
   2802     mParameters.hasAssociatedDisplay = false;
   2803     mParameters.associatedDisplayIsExternal = false;
   2804     if (mParameters.orientationAware
   2805             || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
   2806             || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
   2807         mParameters.hasAssociatedDisplay = true;
   2808         mParameters.associatedDisplayIsExternal =
   2809                 mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
   2810                         && getDevice()->isExternal();
   2811     }
   2812 }
   2813 
   2814 void TouchInputMapper::dumpParameters(String8& dump) {
   2815     dump.append(INDENT3 "Parameters:\n");
   2816 
   2817     switch (mParameters.gestureMode) {
   2818     case Parameters::GESTURE_MODE_POINTER:
   2819         dump.append(INDENT4 "GestureMode: pointer\n");
   2820         break;
   2821     case Parameters::GESTURE_MODE_SPOTS:
   2822         dump.append(INDENT4 "GestureMode: spots\n");
   2823         break;
   2824     default:
   2825         assert(false);
   2826     }
   2827 
   2828     switch (mParameters.deviceType) {
   2829     case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
   2830         dump.append(INDENT4 "DeviceType: touchScreen\n");
   2831         break;
   2832     case Parameters::DEVICE_TYPE_TOUCH_PAD:
   2833         dump.append(INDENT4 "DeviceType: touchPad\n");
   2834         break;
   2835     case Parameters::DEVICE_TYPE_POINTER:
   2836         dump.append(INDENT4 "DeviceType: pointer\n");
   2837         break;
   2838     default:
   2839         ALOG_ASSERT(false);
   2840     }
   2841 
   2842     dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
   2843             toString(mParameters.hasAssociatedDisplay),
   2844             toString(mParameters.associatedDisplayIsExternal));
   2845     dump.appendFormat(INDENT4 "OrientationAware: %s\n",
   2846             toString(mParameters.orientationAware));
   2847 }
   2848 
   2849 void TouchInputMapper::configureRawPointerAxes() {
   2850     mRawPointerAxes.clear();
   2851 }
   2852 
   2853 void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
   2854     dump.append(INDENT3 "Raw Touch Axes:\n");
   2855     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
   2856     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
   2857     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
   2858     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
   2859     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
   2860     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
   2861     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
   2862     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
   2863     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
   2864     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
   2865     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
   2866     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
   2867     dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
   2868 }
   2869 
   2870 void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
   2871     int32_t oldDeviceMode = mDeviceMode;
   2872 
   2873     // Determine device mode.
   2874     if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
   2875             && mConfig.pointerGesturesEnabled) {
   2876         mSource = AINPUT_SOURCE_MOUSE;
   2877         mDeviceMode = DEVICE_MODE_POINTER;
   2878         if (hasStylus()) {
   2879             mSource |= AINPUT_SOURCE_STYLUS;
   2880         }
   2881     } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
   2882             && mParameters.hasAssociatedDisplay) {
   2883         mSource = AINPUT_SOURCE_TOUCHSCREEN;
   2884         mDeviceMode = DEVICE_MODE_DIRECT;
   2885         if (hasStylus()) {
   2886             mSource |= AINPUT_SOURCE_STYLUS;
   2887         }
   2888     } else {
   2889         mSource = AINPUT_SOURCE_TOUCHPAD;
   2890         mDeviceMode = DEVICE_MODE_UNSCALED;
   2891     }
   2892 
   2893     // Ensure we have valid X and Y axes.
   2894     if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
   2895         ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
   2896                 "The device will be inoperable.", getDeviceName().string());
   2897         mDeviceMode = DEVICE_MODE_DISABLED;
   2898         return;
   2899     }
   2900 
   2901     // Raw width and height in the natural orientation.
   2902     int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
   2903     int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
   2904 
   2905     // Get associated display dimensions.
   2906     bool viewportChanged = false;
   2907     DisplayViewport newViewport;
   2908     if (mParameters.hasAssociatedDisplay) {
   2909         if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
   2910             ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
   2911                     "display.  The device will be inoperable until the display size "
   2912                     "becomes available.",
   2913                     getDeviceName().string());
   2914             mDeviceMode = DEVICE_MODE_DISABLED;
   2915             return;
   2916         }
   2917     } else {
   2918         newViewport.setNonDisplayViewport(rawWidth, rawHeight);
   2919     }
   2920     if (mViewport != newViewport) {
   2921         mViewport = newViewport;
   2922         viewportChanged = true;
   2923 
   2924         if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
   2925             // Convert rotated viewport to natural surface coordinates.
   2926             int32_t naturalLogicalWidth, naturalLogicalHeight;
   2927             int32_t naturalPhysicalWidth, naturalPhysicalHeight;
   2928             int32_t naturalPhysicalLeft, naturalPhysicalTop;
   2929             int32_t naturalDeviceWidth, naturalDeviceHeight;
   2930             switch (mViewport.orientation) {
   2931             case DISPLAY_ORIENTATION_90:
   2932                 naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
   2933                 naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
   2934                 naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
   2935                 naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
   2936                 naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
   2937                 naturalPhysicalTop = mViewport.physicalLeft;
   2938                 naturalDeviceWidth = mViewport.deviceHeight;
   2939                 naturalDeviceHeight = mViewport.deviceWidth;
   2940                 break;
   2941             case DISPLAY_ORIENTATION_180:
   2942                 naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
   2943                 naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
   2944                 naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
   2945                 naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
   2946                 naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
   2947                 naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
   2948                 naturalDeviceWidth = mViewport.deviceWidth;
   2949                 naturalDeviceHeight = mViewport.deviceHeight;
   2950                 break;
   2951             case DISPLAY_ORIENTATION_270:
   2952                 naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
   2953                 naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
   2954                 naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
   2955                 naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
   2956                 naturalPhysicalLeft = mViewport.physicalTop;
   2957                 naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
   2958                 naturalDeviceWidth = mViewport.deviceHeight;
   2959                 naturalDeviceHeight = mViewport.deviceWidth;
   2960                 break;
   2961             case DISPLAY_ORIENTATION_0:
   2962             default:
   2963                 naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
   2964                 naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
   2965                 naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
   2966                 naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
   2967                 naturalPhysicalLeft = mViewport.physicalLeft;
   2968                 naturalPhysicalTop = mViewport.physicalTop;
   2969                 naturalDeviceWidth = mViewport.deviceWidth;
   2970                 naturalDeviceHeight = mViewport.deviceHeight;
   2971                 break;
   2972             }
   2973 
   2974             mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
   2975             mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
   2976             mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
   2977             mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
   2978 
   2979             mSurfaceOrientation = mParameters.orientationAware ?
   2980                     mViewport.orientation : DISPLAY_ORIENTATION_0;
   2981         } else {
   2982             mSurfaceWidth = rawWidth;
   2983             mSurfaceHeight = rawHeight;
   2984             mSurfaceLeft = 0;
   2985             mSurfaceTop = 0;
   2986             mSurfaceOrientation = DISPLAY_ORIENTATION_0;
   2987         }
   2988     }
   2989 
   2990     // If moving between pointer modes, need to reset some state.
   2991     bool deviceModeChanged;
   2992     if (mDeviceMode != oldDeviceMode) {
   2993         deviceModeChanged = true;
   2994         mOrientedRanges.clear();
   2995     }
   2996 
   2997     // Create pointer controller if needed.
   2998     if (mDeviceMode == DEVICE_MODE_POINTER ||
   2999             (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
   3000         if (mPointerController == NULL) {
   3001             mPointerController = getPolicy()->obtainPointerController(getDeviceId());
   3002         }
   3003     } else {
   3004         mPointerController.clear();
   3005     }
   3006 
   3007     if (viewportChanged || deviceModeChanged) {
   3008         ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
   3009                 "display id %d",
   3010                 getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
   3011                 mSurfaceOrientation, mDeviceMode, mViewport.displayId);
   3012 
   3013         // Configure X and Y factors.
   3014         mXScale = float(mSurfaceWidth) / rawWidth;
   3015         mYScale = float(mSurfaceHeight) / rawHeight;
   3016         mXTranslate = -mSurfaceLeft;
   3017         mYTranslate = -mSurfaceTop;
   3018         mXPrecision = 1.0f / mXScale;
   3019         mYPrecision = 1.0f / mYScale;
   3020 
   3021         mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
   3022         mOrientedRanges.x.source = mSource;
   3023         mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
   3024         mOrientedRanges.y.source = mSource;
   3025 
   3026         configureVirtualKeys();
   3027 
   3028         // Scale factor for terms that are not oriented in a particular axis.
   3029         // If the pixels are square then xScale == yScale otherwise we fake it
   3030         // by choosing an average.
   3031         mGeometricScale = avg(mXScale, mYScale);
   3032 
   3033         // Size of diagonal axis.
   3034         float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
   3035 
   3036         // Size factors.
   3037         if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
   3038             if (mRawPointerAxes.touchMajor.valid
   3039                     && mRawPointerAxes.touchMajor.maxValue != 0) {
   3040                 mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
   3041             } else if (mRawPointerAxes.toolMajor.valid
   3042                     && mRawPointerAxes.toolMajor.maxValue != 0) {
   3043                 mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
   3044             } else {
   3045                 mSizeScale = 0.0f;
   3046             }
   3047 
   3048             mOrientedRanges.haveTouchSize = true;
   3049             mOrientedRanges.haveToolSize = true;
   3050             mOrientedRanges.haveSize = true;
   3051 
   3052             mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
   3053             mOrientedRanges.touchMajor.source = mSource;
   3054             mOrientedRanges.touchMajor.min = 0;
   3055             mOrientedRanges.touchMajor.max = diagonalSize;
   3056             mOrientedRanges.touchMajor.flat = 0;
   3057             mOrientedRanges.touchMajor.fuzz = 0;
   3058 
   3059             mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
   3060             mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
   3061 
   3062             mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
   3063             mOrientedRanges.toolMajor.source = mSource;
   3064             mOrientedRanges.toolMajor.min = 0;
   3065             mOrientedRanges.toolMajor.max = diagonalSize;
   3066             mOrientedRanges.toolMajor.flat = 0;
   3067             mOrientedRanges.toolMajor.fuzz = 0;
   3068 
   3069             mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
   3070             mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
   3071 
   3072             mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
   3073             mOrientedRanges.size.source = mSource;
   3074             mOrientedRanges.size.min = 0;
   3075             mOrientedRanges.size.max = 1.0;
   3076             mOrientedRanges.size.flat = 0;
   3077             mOrientedRanges.size.fuzz = 0;
   3078         } else {
   3079             mSizeScale = 0.0f;
   3080         }
   3081 
   3082         // Pressure factors.
   3083         mPressureScale = 0;
   3084         if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
   3085                 || mCalibration.pressureCalibration
   3086                         == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
   3087             if (mCalibration.havePressureScale) {
   3088                 mPressureScale = mCalibration.pressureScale;
   3089             } else if (mRawPointerAxes.pressure.valid
   3090                     && mRawPointerAxes.pressure.maxValue != 0) {
   3091                 mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
   3092             }
   3093         }
   3094 
   3095         mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
   3096         mOrientedRanges.pressure.source = mSource;
   3097         mOrientedRanges.pressure.min = 0;
   3098         mOrientedRanges.pressure.max = 1.0;
   3099         mOrientedRanges.pressure.flat = 0;
   3100         mOrientedRanges.pressure.fuzz = 0;
   3101 
   3102         // Tilt
   3103         mTiltXCenter = 0;
   3104         mTiltXScale = 0;
   3105         mTiltYCenter = 0;
   3106         mTiltYScale = 0;
   3107         mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
   3108         if (mHaveTilt) {
   3109             mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
   3110                     mRawPointerAxes.tiltX.maxValue);
   3111             mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
   3112                     mRawPointerAxes.tiltY.maxValue);
   3113             mTiltXScale = M_PI / 180;
   3114             mTiltYScale = M_PI / 180;
   3115 
   3116             mOrientedRanges.haveTilt = true;
   3117 
   3118             mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
   3119             mOrientedRanges.tilt.source = mSource;
   3120             mOrientedRanges.tilt.min = 0;
   3121             mOrientedRanges.tilt.max = M_PI_2;
   3122             mOrientedRanges.tilt.flat = 0;
   3123             mOrientedRanges.tilt.fuzz = 0;
   3124         }
   3125 
   3126         // Orientation
   3127         mOrientationScale = 0;
   3128         if (mHaveTilt) {
   3129             mOrientedRanges.haveOrientation = true;
   3130 
   3131             mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
   3132             mOrientedRanges.orientation.source = mSource;
   3133             mOrientedRanges.orientation.min = -M_PI;
   3134             mOrientedRanges.orientation.max = M_PI;
   3135             mOrientedRanges.orientation.flat = 0;
   3136             mOrientedRanges.orientation.fuzz = 0;
   3137         } else if (mCalibration.orientationCalibration !=
   3138                 Calibration::ORIENTATION_CALIBRATION_NONE) {
   3139             if (mCalibration.orientationCalibration
   3140                     == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
   3141                 if (mRawPointerAxes.orientation.valid) {
   3142                     if (mRawPointerAxes.orientation.maxValue > 0) {
   3143                         mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
   3144                     } else if (mRawPointerAxes.orientation.minValue < 0) {
   3145                         mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
   3146                     } else {
   3147                         mOrientationScale = 0;
   3148                     }
   3149                 }
   3150             }
   3151 
   3152             mOrientedRanges.haveOrientation = true;
   3153 
   3154             mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
   3155             mOrientedRanges.orientation.source = mSource;
   3156             mOrientedRanges.orientation.min = -M_PI_2;
   3157             mOrientedRanges.orientation.max = M_PI_2;
   3158             mOrientedRanges.orientation.flat = 0;
   3159             mOrientedRanges.orientation.fuzz = 0;
   3160         }
   3161 
   3162         // Distance
   3163         mDistanceScale = 0;
   3164         if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
   3165             if (mCalibration.distanceCalibration
   3166                     == Calibration::DISTANCE_CALIBRATION_SCALED) {
   3167                 if (mCalibration.haveDistanceScale) {
   3168                     mDistanceScale = mCalibration.distanceScale;
   3169                 } else {
   3170                     mDistanceScale = 1.0f;
   3171                 }
   3172             }
   3173 
   3174             mOrientedRanges.haveDistance = true;
   3175 
   3176             mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
   3177             mOrientedRanges.distance.source = mSource;
   3178             mOrientedRanges.distance.min =
   3179                     mRawPointerAxes.distance.minValue * mDistanceScale;
   3180             mOrientedRanges.distance.max =
   3181                     mRawPointerAxes.distance.maxValue * mDistanceScale;
   3182             mOrientedRanges.distance.flat = 0;
   3183             mOrientedRanges.distance.fuzz =
   3184                     mRawPointerAxes.distance.fuzz * mDistanceScale;
   3185         }
   3186 
   3187         // Compute oriented precision, scales and ranges.
   3188         // Note that the maximum value reported is an inclusive maximum value so it is one
   3189         // unit less than the total width or height of surface.
   3190         switch (mSurfaceOrientation) {
   3191         case DISPLAY_ORIENTATION_90:
   3192         case DISPLAY_ORIENTATION_270:
   3193             mOrientedXPrecision = mYPrecision;
   3194             mOrientedYPrecision = mXPrecision;
   3195 
   3196             mOrientedRanges.x.min = mYTranslate;
   3197             mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
   3198             mOrientedRanges.x.flat = 0;
   3199             mOrientedRanges.x.fuzz = mYScale;
   3200 
   3201             mOrientedRanges.y.min = mXTranslate;
   3202             mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
   3203             mOrientedRanges.y.flat = 0;
   3204             mOrientedRanges.y.fuzz = mXScale;
   3205             break;
   3206 
   3207         default:
   3208             mOrientedXPrecision = mXPrecision;
   3209             mOrientedYPrecision = mYPrecision;
   3210 
   3211             mOrientedRanges.x.min = mXTranslate;
   3212             mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
   3213             mOrientedRanges.x.flat = 0;
   3214             mOrientedRanges.x.fuzz = mXScale;
   3215 
   3216             mOrientedRanges.y.min = mYTranslate;
   3217             mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
   3218             mOrientedRanges.y.flat = 0;
   3219             mOrientedRanges.y.fuzz = mYScale;
   3220             break;
   3221         }
   3222 
   3223         // Compute pointer gesture detection parameters.
   3224         if (mDeviceMode == DEVICE_MODE_POINTER) {
   3225             float rawDiagonal = hypotf(rawWidth, rawHeight);
   3226             float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
   3227 
   3228             // Scale movements such that one whole swipe of the touch pad covers a
   3229             // given area relative to the diagonal size of the display when no acceleration
   3230             // is applied.
   3231             // Assume that the touch pad has a square aspect ratio such that movements in
   3232             // X and Y of the same number of raw units cover the same physical distance.
   3233             mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
   3234                     * displayDiagonal / rawDiagonal;
   3235             mPointerYMovementScale = mPointerXMovementScale;
   3236 
   3237             // Scale zooms to cover a smaller range of the display than movements do.
   3238             // This value determines the area around the pointer that is affected by freeform
   3239             // pointer gestures.
   3240             mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
   3241                     * displayDiagonal / rawDiagonal;
   3242             mPointerYZoomScale = mPointerXZoomScale;
   3243 
   3244             // Max width between pointers to detect a swipe gesture is more than some fraction
   3245             // of the diagonal axis of the touch pad.  Touches that are wider than this are
   3246             // translated into freeform gestures.
   3247             mPointerGestureMaxSwipeWidth =
   3248                     mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
   3249         }
   3250 
   3251         // Abort current pointer usages because the state has changed.
   3252         abortPointerUsage(when, 0 /*policyFlags*/);
   3253 
   3254         // Inform the dispatcher about the changes.
   3255         *outResetNeeded = true;
   3256         bumpGeneration();
   3257     }
   3258 }
   3259 
   3260 void TouchInputMapper::dumpSurface(String8& dump) {
   3261     dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
   3262             "logicalFrame=[%d, %d, %d, %d], "
   3263             "physicalFrame=[%d, %d, %d, %d], "
   3264             "deviceSize=[%d, %d]\n",
   3265             mViewport.displayId, mViewport.orientation,
   3266             mViewport.logicalLeft, mViewport.logicalTop,
   3267             mViewport.logicalRight, mViewport.logicalBottom,
   3268             mViewport.physicalLeft, mViewport.physicalTop,
   3269             mViewport.physicalRight, mViewport.physicalBottom,
   3270             mViewport.deviceWidth, mViewport.deviceHeight);
   3271 
   3272     dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
   3273     dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
   3274     dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
   3275     dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
   3276     dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
   3277 }
   3278 
   3279 void TouchInputMapper::configureVirtualKeys() {
   3280     Vector<VirtualKeyDefinition> virtualKeyDefinitions;
   3281     getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
   3282 
   3283     mVirtualKeys.clear();
   3284 
   3285     if (virtualKeyDefinitions.size() == 0) {
   3286         return;
   3287     }
   3288 
   3289     mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
   3290 
   3291     int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
   3292     int32_t touchScreenTop = mRawPointerAxes.y.minValue;
   3293     int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
   3294     int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
   3295 
   3296     for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
   3297         const VirtualKeyDefinition& virtualKeyDefinition =
   3298                 virtualKeyDefinitions[i];
   3299 
   3300         mVirtualKeys.add();
   3301         VirtualKey& virtualKey = mVirtualKeys.editTop();
   3302 
   3303         virtualKey.scanCode = virtualKeyDefinition.scanCode;
   3304         int32_t keyCode;
   3305         uint32_t flags;
   3306         if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
   3307             ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
   3308                     virtualKey.scanCode);
   3309             mVirtualKeys.pop(); // drop the key
   3310             continue;
   3311         }
   3312 
   3313         virtualKey.keyCode = keyCode;
   3314         virtualKey.flags = flags;
   3315 
   3316         // convert the key definition's display coordinates into touch coordinates for a hit box
   3317         int32_t halfWidth = virtualKeyDefinition.width / 2;
   3318         int32_t halfHeight = virtualKeyDefinition.height / 2;
   3319 
   3320         virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
   3321                 * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
   3322         virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
   3323                 * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
   3324         virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
   3325                 * touchScreenHeight / mSurfaceHeight + touchScreenTop;
   3326         virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
   3327                 * touchScreenHeight / mSurfaceHeight + touchScreenTop;
   3328     }
   3329 }
   3330 
   3331 void TouchInputMapper::dumpVirtualKeys(String8& dump) {
   3332     if (!mVirtualKeys.isEmpty()) {
   3333         dump.append(INDENT3 "Virtual Keys:\n");
   3334 
   3335         for (size_t i = 0; i < mVirtualKeys.size(); i++) {
   3336             const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
   3337             dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
   3338                     "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
   3339                     i, virtualKey.scanCode, virtualKey.keyCode,
   3340                     virtualKey.hitLeft, virtualKey.hitRight,
   3341                     virtualKey.hitTop, virtualKey.hitBottom);
   3342         }
   3343     }
   3344 }
   3345 
   3346 void TouchInputMapper::parseCalibration() {
   3347     const PropertyMap& in = getDevice()->getConfiguration();
   3348     Calibration& out = mCalibration;
   3349 
   3350     // Size
   3351     out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
   3352     String8 sizeCalibrationString;
   3353     if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
   3354         if (sizeCalibrationString == "none") {
   3355             out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
   3356         } else if (sizeCalibrationString == "geometric") {
   3357             out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
   3358         } else if (sizeCalibrationString == "diameter") {
   3359             out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
   3360         } else if (sizeCalibrationString == "box") {
   3361             out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
   3362         } else if (sizeCalibrationString == "area") {
   3363             out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
   3364         } else if (sizeCalibrationString != "default") {
   3365             ALOGW("Invalid value for touch.size.calibration: '%s'",
   3366                     sizeCalibrationString.string());
   3367         }
   3368     }
   3369 
   3370     out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
   3371             out.sizeScale);
   3372     out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
   3373             out.sizeBias);
   3374     out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
   3375             out.sizeIsSummed);
   3376 
   3377     // Pressure
   3378     out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
   3379     String8 pressureCalibrationString;
   3380     if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
   3381         if (pressureCalibrationString == "none") {
   3382             out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
   3383         } else if (pressureCalibrationString == "physical") {
   3384             out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
   3385         } else if (pressureCalibrationString == "amplitude") {
   3386             out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
   3387         } else if (pressureCalibrationString != "default") {
   3388             ALOGW("Invalid value for touch.pressure.calibration: '%s'",
   3389                     pressureCalibrationString.string());
   3390         }
   3391     }
   3392 
   3393     out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
   3394             out.pressureScale);
   3395 
   3396     // Orientation
   3397     out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
   3398     String8 orientationCalibrationString;
   3399     if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
   3400         if (orientationCalibrationString == "none") {
   3401             out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
   3402         } else if (orientationCalibrationString == "interpolated") {
   3403             out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
   3404         } else if (orientationCalibrationString == "vector") {
   3405             out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
   3406         } else if (orientationCalibrationString != "default") {
   3407             ALOGW("Invalid value for touch.orientation.calibration: '%s'",
   3408                     orientationCalibrationString.string());
   3409         }
   3410     }
   3411 
   3412     // Distance
   3413     out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
   3414     String8 distanceCalibrationString;
   3415     if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
   3416         if (distanceCalibrationString == "none") {
   3417             out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
   3418         } else if (distanceCalibrationString == "scaled") {
   3419             out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
   3420         } else if (distanceCalibrationString != "default") {
   3421             ALOGW("Invalid value for touch.distance.calibration: '%s'",
   3422                     distanceCalibrationString.string());
   3423         }
   3424     }
   3425 
   3426     out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
   3427             out.distanceScale);
   3428 }
   3429 
   3430 void TouchInputMapper::resolveCalibration() {
   3431     // Size
   3432     if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
   3433         if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
   3434             mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
   3435         }
   3436     } else {
   3437         mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
   3438     }
   3439 
   3440     // Pressure
   3441     if (mRawPointerAxes.pressure.valid) {
   3442         if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
   3443             mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
   3444         }
   3445     } else {
   3446         mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
   3447     }
   3448 
   3449     // Orientation
   3450     if (mRawPointerAxes.orientation.valid) {
   3451         if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
   3452             mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
   3453         }
   3454     } else {
   3455         mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
   3456     }
   3457 
   3458     // Distance
   3459     if (mRawPointerAxes.distance.valid) {
   3460         if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
   3461             mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
   3462         }
   3463     } else {
   3464         mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
   3465     }
   3466 }
   3467 
   3468 void TouchInputMapper::dumpCalibration(String8& dump) {
   3469     dump.append(INDENT3 "Calibration:\n");
   3470 
   3471     // Size
   3472     switch (mCalibration.sizeCalibration) {
   3473     case Calibration::SIZE_CALIBRATION_NONE:
   3474         dump.append(INDENT4 "touch.size.calibration: none\n");
   3475         break;
   3476     case Calibration::SIZE_CALIBRATION_GEOMETRIC:
   3477         dump.append(INDENT4 "touch.size.calibration: geometric\n");
   3478         break;
   3479     case Calibration::SIZE_CALIBRATION_DIAMETER:
   3480         dump.append(INDENT4 "touch.size.calibration: diameter\n");
   3481         break;
   3482     case Calibration::SIZE_CALIBRATION_BOX:
   3483         dump.append(INDENT4 "touch.size.calibration: box\n");
   3484         break;
   3485     case Calibration::SIZE_CALIBRATION_AREA:
   3486         dump.append(INDENT4 "touch.size.calibration: area\n");
   3487         break;
   3488     default:
   3489         ALOG_ASSERT(false);
   3490     }
   3491 
   3492     if (mCalibration.haveSizeScale) {
   3493         dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
   3494                 mCalibration.sizeScale);
   3495     }
   3496 
   3497     if (mCalibration.haveSizeBias) {
   3498         dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
   3499                 mCalibration.sizeBias);
   3500     }
   3501 
   3502     if (mCalibration.haveSizeIsSummed) {
   3503         dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
   3504                 toString(mCalibration.sizeIsSummed));
   3505     }
   3506 
   3507     // Pressure
   3508     switch (mCalibration.pressureCalibration) {
   3509     case Calibration::PRESSURE_CALIBRATION_NONE:
   3510         dump.append(INDENT4 "touch.pressure.calibration: none\n");
   3511         break;
   3512     case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
   3513         dump.append(INDENT4 "touch.pressure.calibration: physical\n");
   3514         break;
   3515     case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
   3516         dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
   3517         break;
   3518     default:
   3519         ALOG_ASSERT(false);
   3520     }
   3521 
   3522     if (mCalibration.havePressureScale) {
   3523         dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
   3524                 mCalibration.pressureScale);
   3525     }
   3526 
   3527     // Orientation
   3528     switch (mCalibration.orientationCalibration) {
   3529     case Calibration::ORIENTATION_CALIBRATION_NONE:
   3530         dump.append(INDENT4 "touch.orientation.calibration: none\n");
   3531         break;
   3532     case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
   3533         dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
   3534         break;
   3535     case Calibration::ORIENTATION_CALIBRATION_VECTOR:
   3536         dump.append(INDENT4 "touch.orientation.calibration: vector\n");
   3537         break;
   3538     default:
   3539         ALOG_ASSERT(false);
   3540     }
   3541 
   3542     // Distance
   3543     switch (mCalibration.distanceCalibration) {
   3544     case Calibration::DISTANCE_CALIBRATION_NONE:
   3545         dump.append(INDENT4 "touch.distance.calibration: none\n");
   3546         break;
   3547     case Calibration::DISTANCE_CALIBRATION_SCALED:
   3548         dump.append(INDENT4 "touch.distance.calibration: scaled\n");
   3549         break;
   3550     default:
   3551         ALOG_ASSERT(false);
   3552     }
   3553 
   3554     if (mCalibration.haveDistanceScale) {
   3555         dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
   3556                 mCalibration.distanceScale);
   3557     }
   3558 }
   3559 
   3560 void TouchInputMapper::reset(nsecs_t when) {
   3561     mCursorButtonAccumulator.reset(getDevice());
   3562     mCursorScrollAccumulator.reset(getDevice());
   3563     mTouchButtonAccumulator.reset(getDevice());
   3564 
   3565     mPointerVelocityControl.reset();
   3566     mWheelXVelocityControl.reset();
   3567     mWheelYVelocityControl.reset();
   3568 
   3569     mCurrentRawPointerData.clear();
   3570     mLastRawPointerData.clear();
   3571     mCurrentCookedPointerData.clear();
   3572     mLastCookedPointerData.clear();
   3573     mCurrentButtonState = 0;
   3574     mLastButtonState = 0;
   3575     mCurrentRawVScroll = 0;
   3576     mCurrentRawHScroll = 0;
   3577     mCurrentFingerIdBits.clear();
   3578     mLastFingerIdBits.clear();
   3579     mCurrentStylusIdBits.clear();
   3580     mLastStylusIdBits.clear();
   3581     mCurrentMouseIdBits.clear();
   3582     mLastMouseIdBits.clear();
   3583     mPointerUsage = POINTER_USAGE_NONE;
   3584     mSentHoverEnter = false;
   3585     mDownTime = 0;
   3586 
   3587     mCurrentVirtualKey.down = false;
   3588 
   3589     mPointerGesture.reset();
   3590     mPointerSimple.reset();
   3591 
   3592     if (mPointerController != NULL) {
   3593         mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
   3594         mPointerController->clearSpots();
   3595     }
   3596 
   3597     InputMapper::reset(when);
   3598 }
   3599 
   3600 void TouchInputMapper::process(const RawEvent* rawEvent) {
   3601     mCursorButtonAccumulator.process(rawEvent);
   3602     mCursorScrollAccumulator.process(rawEvent);
   3603     mTouchButtonAccumulator.process(rawEvent);
   3604 
   3605     if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
   3606         sync(rawEvent->when);
   3607     }
   3608 }
   3609 
   3610 void TouchInputMapper::sync(nsecs_t when) {
   3611     // Sync button state.
   3612     mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
   3613             | mCursorButtonAccumulator.getButtonState();
   3614 
   3615     // Sync scroll state.
   3616     mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
   3617     mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
   3618     mCursorScrollAccumulator.finishSync();
   3619 
   3620     // Sync touch state.
   3621     bool havePointerIds = true;
   3622     mCurrentRawPointerData.clear();
   3623     syncTouch(when, &havePointerIds);
   3624 
   3625 #if DEBUG_RAW_EVENTS
   3626     if (!havePointerIds) {
   3627         ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
   3628                 mLastRawPointerData.pointerCount,
   3629                 mCurrentRawPointerData.pointerCount);
   3630     } else {
   3631         ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
   3632                 "hovering ids 0x%08x -> 0x%08x",
   3633                 mLastRawPointerData.pointerCount,
   3634                 mCurrentRawPointerData.pointerCount,
   3635                 mLastRawPointerData.touchingIdBits.value,
   3636                 mCurrentRawPointerData.touchingIdBits.value,
   3637                 mLastRawPointerData.hoveringIdBits.value,
   3638                 mCurrentRawPointerData.hoveringIdBits.value);
   3639     }
   3640 #endif
   3641 
   3642     // Reset state that we will compute below.
   3643     mCurrentFingerIdBits.clear();
   3644     mCurrentStylusIdBits.clear();
   3645     mCurrentMouseIdBits.clear();
   3646     mCurrentCookedPointerData.clear();
   3647 
   3648     if (mDeviceMode == DEVICE_MODE_DISABLED) {
   3649         // Drop all input if the device is disabled.
   3650         mCurrentRawPointerData.clear();
   3651         mCurrentButtonState = 0;
   3652     } else {
   3653         // Preprocess pointer data.
   3654         if (!havePointerIds) {
   3655             assignPointerIds();
   3656         }
   3657 
   3658         // Handle policy on initial down or hover events.
   3659         uint32_t policyFlags = 0;
   3660         bool initialDown = mLastRawPointerData.pointerCount == 0
   3661                 && mCurrentRawPointerData.pointerCount != 0;
   3662         bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
   3663         if (initialDown || buttonsPressed) {
   3664             // If this is a touch screen, hide the pointer on an initial down.
   3665             if (mDeviceMode == DEVICE_MODE_DIRECT) {
   3666                 getContext()->fadePointer();
   3667             }
   3668 
   3669             // Initial downs on external touch devices should wake the device.
   3670             // We don't do this for internal touch screens to prevent them from waking
   3671             // up in your pocket.
   3672             // TODO: Use the input device configuration to control this behavior more finely.
   3673             if (getDevice()->isExternal()) {
   3674                 policyFlags |= POLICY_FLAG_WAKE_DROPPED;
   3675             }
   3676         }
   3677 
   3678         // Synthesize key down from raw buttons if needed.
   3679         synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
   3680                 policyFlags, mLastButtonState, mCurrentButtonState);
   3681 
   3682         // Consume raw off-screen touches before cooking pointer data.
   3683         // If touches are consumed, subsequent code will not receive any pointer data.
   3684         if (consumeRawTouches(when, policyFlags)) {
   3685             mCurrentRawPointerData.clear();
   3686         }
   3687 
   3688         // Cook pointer data.  This call populates the mCurrentCookedPointerData structure
   3689         // with cooked pointer data that has the same ids and indices as the raw data.
   3690         // The following code can use either the raw or cooked data, as needed.
   3691         cookPointerData();
   3692 
   3693         // Dispatch the touches either directly or by translation through a pointer on screen.
   3694         if (mDeviceMode == DEVICE_MODE_POINTER) {
   3695             for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
   3696                 uint32_t id = idBits.clearFirstMarkedBit();
   3697                 const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
   3698                 if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
   3699                         || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
   3700                     mCurrentStylusIdBits.markBit(id);
   3701                 } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
   3702                         || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
   3703                     mCurrentFingerIdBits.markBit(id);
   3704                 } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
   3705                     mCurrentMouseIdBits.markBit(id);
   3706                 }
   3707             }
   3708             for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
   3709                 uint32_t id = idBits.clearFirstMarkedBit();
   3710                 const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
   3711                 if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
   3712                         || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
   3713                     mCurrentStylusIdBits.markBit(id);
   3714                 }
   3715             }
   3716 
   3717             // Stylus takes precedence over all tools, then mouse, then finger.
   3718             PointerUsage pointerUsage = mPointerUsage;
   3719             if (!mCurrentStylusIdBits.isEmpty()) {
   3720                 mCurrentMouseIdBits.clear();
   3721                 mCurrentFingerIdBits.clear();
   3722                 pointerUsage = POINTER_USAGE_STYLUS;
   3723             } else if (!mCurrentMouseIdBits.isEmpty()) {
   3724                 mCurrentFingerIdBits.clear();
   3725                 pointerUsage = POINTER_USAGE_MOUSE;
   3726             } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
   3727                 pointerUsage = POINTER_USAGE_GESTURES;
   3728             }
   3729 
   3730             dispatchPointerUsage(when, policyFlags, pointerUsage);
   3731         } else {
   3732             if (mDeviceMode == DEVICE_MODE_DIRECT
   3733                     && mConfig.showTouches && mPointerController != NULL) {
   3734                 mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
   3735                 mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
   3736 
   3737                 mPointerController->setButtonState(mCurrentButtonState);
   3738                 mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
   3739                         mCurrentCookedPointerData.idToIndex,
   3740                         mCurrentCookedPointerData.touchingIdBits);
   3741             }
   3742 
   3743             dispatchHoverExit(when, policyFlags);
   3744             dispatchTouches(when, policyFlags);
   3745             dispatchHoverEnterAndMove(when, policyFlags);
   3746         }
   3747 
   3748         // Synthesize key up from raw buttons if needed.
   3749         synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
   3750                 policyFlags, mLastButtonState, mCurrentButtonState);
   3751     }
   3752 
   3753     // Copy current touch to last touch in preparation for the next cycle.
   3754     mLastRawPointerData.copyFrom(mCurrentRawPointerData);
   3755     mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
   3756     mLastButtonState = mCurrentButtonState;
   3757     mLastFingerIdBits = mCurrentFingerIdBits;
   3758     mLastStylusIdBits = mCurrentStylusIdBits;
   3759     mLastMouseIdBits = mCurrentMouseIdBits;
   3760 
   3761     // Clear some transient state.
   3762     mCurrentRawVScroll = 0;
   3763     mCurrentRawHScroll = 0;
   3764 }
   3765 
   3766 void TouchInputMapper::timeoutExpired(nsecs_t when) {
   3767     if (mDeviceMode == DEVICE_MODE_POINTER) {
   3768         if (mPointerUsage == POINTER_USAGE_GESTURES) {
   3769             dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
   3770         }
   3771     }
   3772 }
   3773 
   3774 bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
   3775     // Check for release of a virtual key.
   3776     if (mCurrentVirtualKey.down) {
   3777         if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
   3778             // Pointer went up while virtual key was down.
   3779             mCurrentVirtualKey.down = false;
   3780             if (!mCurrentVirtualKey.ignored) {
   3781 #if DEBUG_VIRTUAL_KEYS
   3782                 ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
   3783                         mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
   3784 #endif
   3785                 dispatchVirtualKey(when, policyFlags,
   3786                         AKEY_EVENT_ACTION_UP,
   3787                         AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
   3788             }
   3789             return true;
   3790         }
   3791 
   3792         if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
   3793             uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
   3794             const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
   3795             const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
   3796             if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
   3797                 // Pointer is still within the space of the virtual key.
   3798                 return true;
   3799             }
   3800         }
   3801 
   3802         // Pointer left virtual key area or another pointer also went down.
   3803         // Send key cancellation but do not consume the touch yet.
   3804         // This is useful when the user swipes through from the virtual key area
   3805         // into the main display surface.
   3806         mCurrentVirtualKey.down = false;
   3807         if (!mCurrentVirtualKey.ignored) {
   3808 #if DEBUG_VIRTUAL_KEYS
   3809             ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
   3810                     mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
   3811 #endif
   3812             dispatchVirtualKey(when, policyFlags,
   3813                     AKEY_EVENT_ACTION_UP,
   3814                     AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
   3815                             | AKEY_EVENT_FLAG_CANCELED);
   3816         }
   3817     }
   3818 
   3819     if (mLastRawPointerData.touchingIdBits.isEmpty()
   3820             && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
   3821         // Pointer just went down.  Check for virtual key press or off-screen touches.
   3822         uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
   3823         const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
   3824         if (!isPointInsideSurface(pointer.x, pointer.y)) {
   3825             // If exactly one pointer went down, check for virtual key hit.
   3826             // Otherwise we will drop the entire stroke.
   3827             if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
   3828                 const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
   3829                 if (virtualKey) {
   3830                     mCurrentVirtualKey.down = true;
   3831                     mCurrentVirtualKey.downTime = when;
   3832                     mCurrentVirtualKey.keyCode = virtualKey->keyCode;
   3833                     mCurrentVirtualKey.scanCode = virtualKey->scanCode;
   3834                     mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
   3835                             when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
   3836 
   3837                     if (!mCurrentVirtualKey.ignored) {
   3838 #if DEBUG_VIRTUAL_KEYS
   3839                         ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
   3840                                 mCurrentVirtualKey.keyCode,
   3841                                 mCurrentVirtualKey.scanCode);
   3842 #endif
   3843                         dispatchVirtualKey(when, policyFlags,
   3844                                 AKEY_EVENT_ACTION_DOWN,
   3845                                 AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
   3846                     }
   3847                 }
   3848             }
   3849             return true;
   3850         }
   3851     }
   3852 
   3853     // Disable all virtual key touches that happen within a short time interval of the
   3854     // most recent touch within the screen area.  The idea is to filter out stray
   3855     // virtual key presses when interacting with the touch screen.
   3856     //
   3857     // Problems we're trying to solve:
   3858     //
   3859     // 1. While scrolling a list or dragging the window shade, the user swipes down into a
   3860     //    virtual key area that is implemented by a separate touch panel and accidentally
   3861     //    triggers a virtual key.
   3862     //
   3863     // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
   3864     //    area and accidentally triggers a virtual key.  This often happens when virtual keys
   3865     //    are layed out below the screen near to where the on screen keyboard's space bar
   3866     //    is displayed.
   3867     if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
   3868         mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
   3869     }
   3870     return false;
   3871 }
   3872 
   3873 void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
   3874         int32_t keyEventAction, int32_t keyEventFlags) {
   3875     int32_t keyCode = mCurrentVirtualKey.keyCode;
   3876     int32_t scanCode = mCurrentVirtualKey.scanCode;
   3877     nsecs_t downTime = mCurrentVirtualKey.downTime;
   3878     int32_t metaState = mContext->getGlobalMetaState();
   3879     policyFlags |= POLICY_FLAG_VIRTUAL;
   3880 
   3881     NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
   3882             keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
   3883     getListener()->notifyKey(&args);
   3884 }
   3885 
   3886 void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
   3887     BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
   3888     BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
   3889     int32_t metaState = getContext()->getGlobalMetaState();
   3890     int32_t buttonState = mCurrentButtonState;
   3891 
   3892     if (currentIdBits == lastIdBits) {
   3893         if (!currentIdBits.isEmpty()) {
   3894             // No pointer id changes so this is a move event.
   3895             // The listener takes care of batching moves so we don't have to deal with that here.
   3896             dispatchMotion(when, policyFlags, mSource,
   3897                     AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
   3898                     AMOTION_EVENT_EDGE_FLAG_NONE,
   3899                     mCurrentCookedPointerData.pointerProperties,
   3900                     mCurrentCookedPointerData.pointerCoords,
   3901                     mCurrentCookedPointerData.idToIndex,
   3902                     currentIdBits, -1,
   3903                     mOrientedXPrecision, mOrientedYPrecision, mDownTime);
   3904         }
   3905     } else {
   3906         // There may be pointers going up and pointers going down and pointers moving
   3907         // all at the same time.
   3908         BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
   3909         BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
   3910         BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
   3911         BitSet32 dispatchedIdBits(lastIdBits.value);
   3912 
   3913         // Update last coordinates of pointers that have moved so that we observe the new
   3914         // pointer positions at the same time as other pointers that have just gone up.
   3915         bool moveNeeded = updateMovedPointers(
   3916                 mCurrentCookedPointerData.pointerProperties,
   3917                 mCurrentCookedPointerData.pointerCoords,
   3918                 mCurrentCookedPointerData.idToIndex,
   3919                 mLastCookedPointerData.pointerProperties,
   3920                 mLastCookedPointerData.pointerCoords,
   3921                 mLastCookedPointerData.idToIndex,
   3922                 moveIdBits);
   3923         if (buttonState != mLastButtonState) {
   3924             moveNeeded = true;
   3925         }
   3926 
   3927         // Dispatch pointer up events.
   3928         while (!upIdBits.isEmpty()) {
   3929             uint32_t upId = upIdBits.clearFirstMarkedBit();
   3930 
   3931             dispatchMotion(when, policyFlags, mSource,
   3932                     AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
   3933                     mLastCookedPointerData.pointerProperties,
   3934                     mLastCookedPointerData.pointerCoords,
   3935                     mLastCookedPointerData.idToIndex,
   3936                     dispatchedIdBits, upId,
   3937                     mOrientedXPrecision, mOrientedYPrecision, mDownTime);
   3938             dispatchedIdBits.clearBit(upId);
   3939         }
   3940 
   3941         // Dispatch move events if any of the remaining pointers moved from their old locations.
   3942         // Although applications receive new locations as part of individual pointer up
   3943         // events, they do not generally handle them except when presented in a move event.
   3944         if (moveNeeded) {
   3945             ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
   3946             dispatchMotion(when, policyFlags, mSource,
   3947                     AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
   3948                     mCurrentCookedPointerData.pointerProperties,
   3949                     mCurrentCookedPointerData.pointerCoords,
   3950                     mCurrentCookedPointerData.idToIndex,
   3951                     dispatchedIdBits, -1,
   3952                     mOrientedXPrecision, mOrientedYPrecision, mDownTime);
   3953         }
   3954 
   3955         // Dispatch pointer down events using the new pointer locations.
   3956         while (!downIdBits.isEmpty()) {
   3957             uint32_t downId = downIdBits.clearFirstMarkedBit();
   3958             dispatchedIdBits.markBit(downId);
   3959 
   3960             if (dispatchedIdBits.count() == 1) {
   3961                 // First pointer is going down.  Set down time.
   3962                 mDownTime = when;
   3963             }
   3964 
   3965             dispatchMotion(when, policyFlags, mSource,
   3966                     AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
   3967                     mCurrentCookedPointerData.pointerProperties,
   3968                     mCurrentCookedPointerData.pointerCoords,
   3969                     mCurrentCookedPointerData.idToIndex,
   3970                     dispatchedIdBits, downId,
   3971                     mOrientedXPrecision, mOrientedYPrecision, mDownTime);
   3972         }
   3973     }
   3974 }
   3975 
   3976 void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
   3977     if (mSentHoverEnter &&
   3978             (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
   3979                     || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
   3980         int32_t metaState = getContext()->getGlobalMetaState();
   3981         dispatchMotion(when, policyFlags, mSource,
   3982                 AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
   3983                 mLastCookedPointerData.pointerProperties,
   3984                 mLastCookedPointerData.pointerCoords,
   3985                 mLastCookedPointerData.idToIndex,
   3986                 mLastCookedPointerData.hoveringIdBits, -1,
   3987                 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
   3988         mSentHoverEnter = false;
   3989     }
   3990 }
   3991 
   3992 void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
   3993     if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
   3994             && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
   3995         int32_t metaState = getContext()->getGlobalMetaState();
   3996         if (!mSentHoverEnter) {
   3997             dispatchMotion(when, policyFlags, mSource,
   3998                     AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
   3999                     mCurrentCookedPointerData.pointerProperties,
   4000                     mCurrentCookedPointerData.pointerCoords,
   4001                     mCurrentCookedPointerData.idToIndex,
   4002                     mCurrentCookedPointerData.hoveringIdBits, -1,
   4003                     mOrientedXPrecision, mOrientedYPrecision, mDownTime);
   4004             mSentHoverEnter = true;
   4005         }
   4006 
   4007         dispatchMotion(when, policyFlags, mSource,
   4008                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
   4009                 mCurrentCookedPointerData.pointerProperties,
   4010                 mCurrentCookedPointerData.pointerCoords,
   4011                 mCurrentCookedPointerData.idToIndex,
   4012                 mCurrentCookedPointerData.hoveringIdBits, -1,
   4013                 mOrientedXPrecision, mOrientedYPrecision, mDownTime);
   4014     }
   4015 }
   4016 
   4017 void TouchInputMapper::cookPointerData() {
   4018     uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
   4019 
   4020     mCurrentCookedPointerData.clear();
   4021     mCurrentCookedPointerData.pointerCount = currentPointerCount;
   4022     mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
   4023     mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
   4024 
   4025     // Walk through the the active pointers and map device coordinates onto
   4026     // surface coordinates and adjust for display orientation.
   4027     for (uint32_t i = 0; i < currentPointerCount; i++) {
   4028         const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
   4029 
   4030         // Size
   4031         float touchMajor, touchMinor, toolMajor, toolMinor, size;
   4032         switch (mCalibration.sizeCalibration) {
   4033         case Calibration::SIZE_CALIBRATION_GEOMETRIC:
   4034         case Calibration::SIZE_CALIBRATION_DIAMETER:
   4035         case Calibration::SIZE_CALIBRATION_BOX:
   4036         case Calibration::SIZE_CALIBRATION_AREA:
   4037             if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
   4038                 touchMajor = in.touchMajor;
   4039                 touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
   4040                 toolMajor = in.toolMajor;
   4041                 toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
   4042                 size = mRawPointerAxes.touchMinor.valid
   4043                         ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
   4044             } else if (mRawPointerAxes.touchMajor.valid) {
   4045                 toolMajor = touchMajor = in.touchMajor;
   4046                 toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
   4047                         ? in.touchMinor : in.touchMajor;
   4048                 size = mRawPointerAxes.touchMinor.valid
   4049                         ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
   4050             } else if (mRawPointerAxes.toolMajor.valid) {
   4051                 touchMajor = toolMajor = in.toolMajor;
   4052                 touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
   4053                         ? in.toolMinor : in.toolMajor;
   4054                 size = mRawPointerAxes.toolMinor.valid
   4055                         ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
   4056             } else {
   4057                 ALOG_ASSERT(false, "No touch or tool axes.  "
   4058                         "Size calibration should have been resolved to NONE.");
   4059                 touchMajor = 0;
   4060                 touchMinor = 0;
   4061                 toolMajor = 0;
   4062                 toolMinor = 0;
   4063                 size = 0;
   4064             }
   4065 
   4066             if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
   4067                 uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
   4068                 if (touchingCount > 1) {
   4069                     touchMajor /= touchingCount;
   4070                     touchMinor /= touchingCount;
   4071                     toolMajor /= touchingCount;
   4072                     toolMinor /= touchingCount;
   4073                     size /= touchingCount;
   4074                 }
   4075             }
   4076 
   4077             if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
   4078                 touchMajor *= mGeometricScale;
   4079                 touchMinor *= mGeometricScale;
   4080                 toolMajor *= mGeometricScale;
   4081                 toolMinor *= mGeometricScale;
   4082             } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
   4083                 touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
   4084                 touchMinor = touchMajor;
   4085                 toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
   4086                 toolMinor = toolMajor;
   4087             } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
   4088                 touchMinor = touchMajor;
   4089                 toolMinor = toolMajor;
   4090             }
   4091 
   4092             mCalibration.applySizeScaleAndBias(&touchMajor);
   4093             mCalibration.applySizeScaleAndBias(&touchMinor);
   4094             mCalibration.applySizeScaleAndBias(&toolMajor);
   4095             mCalibration.applySizeScaleAndBias(&toolMinor);
   4096             size *= mSizeScale;
   4097             break;
   4098         default:
   4099             touchMajor = 0;
   4100             touchMinor = 0;
   4101             toolMajor = 0;
   4102             toolMinor = 0;
   4103             size = 0;
   4104             break;
   4105         }
   4106 
   4107         // Pressure
   4108         float pressure;
   4109         switch (mCalibration.pressureCalibration) {
   4110         case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
   4111         case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
   4112             pressure = in.pressure * mPressureScale;
   4113             break;
   4114         default:
   4115             pressure = in.isHovering ? 0 : 1;
   4116             break;
   4117         }
   4118 
   4119         // Tilt and Orientation
   4120         float tilt;
   4121         float orientation;
   4122         if (mHaveTilt) {
   4123             float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
   4124             float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
   4125             orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
   4126             tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
   4127         } else {
   4128             tilt = 0;
   4129 
   4130             switch (mCalibration.orientationCalibration) {
   4131             case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
   4132                 orientation = in.orientation * mOrientationScale;
   4133                 break;
   4134             case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
   4135                 int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
   4136                 int32_t c2 = signExtendNybble(in.orientation & 0x0f);
   4137                 if (c1 != 0 || c2 != 0) {
   4138                     orientation = atan2f(c1, c2) * 0.5f;
   4139                     float confidence = hypotf(c1, c2);
   4140                     float scale = 1.0f + confidence / 16.0f;
   4141                     touchMajor *= scale;
   4142                     touchMinor /= scale;
   4143                     toolMajor *= scale;
   4144                     toolMinor /= scale;
   4145                 } else {
   4146                     orientation = 0;
   4147                 }
   4148                 break;
   4149             }
   4150             default:
   4151                 orientation = 0;
   4152             }
   4153         }
   4154 
   4155         // Distance
   4156         float distance;
   4157         switch (mCalibration.distanceCalibration) {
   4158         case Calibration::DISTANCE_CALIBRATION_SCALED:
   4159             distance = in.distance * mDistanceScale;
   4160             break;
   4161         default:
   4162             distance = 0;
   4163         }
   4164 
   4165         // X and Y
   4166         // Adjust coords for surface orientation.
   4167         float x, y;
   4168         switch (mSurfaceOrientation) {
   4169         case DISPLAY_ORIENTATION_90:
   4170             x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
   4171             y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
   4172             orientation -= M_PI_2;
   4173             if (orientation < - M_PI_2) {
   4174                 orientation += M_PI;
   4175             }
   4176             break;
   4177         case DISPLAY_ORIENTATION_180:
   4178             x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
   4179             y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
   4180             break;
   4181         case DISPLAY_ORIENTATION_270:
   4182             x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
   4183             y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
   4184             orientation += M_PI_2;
   4185             if (orientation > M_PI_2) {
   4186                 orientation -= M_PI;
   4187             }
   4188             break;
   4189         default:
   4190             x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
   4191             y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
   4192             break;
   4193         }
   4194 
   4195         // Write output coords.
   4196         PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
   4197         out.clear();
   4198         out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
   4199         out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
   4200         out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
   4201         out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
   4202         out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
   4203         out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
   4204         out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
   4205         out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
   4206         out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
   4207         out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
   4208         out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
   4209 
   4210         // Write output properties.
   4211         PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
   4212         uint32_t id = in.id;
   4213         properties.clear();
   4214         properties.id = id;
   4215         properties.toolType = in.toolType;
   4216 
   4217         // Write id index.
   4218         mCurrentCookedPointerData.idToIndex[id] = i;
   4219     }
   4220 }
   4221 
   4222 void TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
   4223         PointerUsage pointerUsage) {
   4224     if (pointerUsage != mPointerUsage) {
   4225         abortPointerUsage(when, policyFlags);
   4226         mPointerUsage = pointerUsage;
   4227     }
   4228 
   4229     switch (mPointerUsage) {
   4230     case POINTER_USAGE_GESTURES:
   4231         dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
   4232         break;
   4233     case POINTER_USAGE_STYLUS:
   4234         dispatchPointerStylus(when, policyFlags);
   4235         break;
   4236     case POINTER_USAGE_MOUSE:
   4237         dispatchPointerMouse(when, policyFlags);
   4238         break;
   4239     default:
   4240         break;
   4241     }
   4242 }
   4243 
   4244 void TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
   4245     switch (mPointerUsage) {
   4246     case POINTER_USAGE_GESTURES:
   4247         abortPointerGestures(when, policyFlags);
   4248         break;
   4249     case POINTER_USAGE_STYLUS:
   4250         abortPointerStylus(when, policyFlags);
   4251         break;
   4252     case POINTER_USAGE_MOUSE:
   4253         abortPointerMouse(when, policyFlags);
   4254         break;
   4255     default:
   4256         break;
   4257     }
   4258 
   4259     mPointerUsage = POINTER_USAGE_NONE;
   4260 }
   4261 
   4262 void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
   4263         bool isTimeout) {
   4264     // Update current gesture coordinates.
   4265     bool cancelPreviousGesture, finishPreviousGesture;
   4266     bool sendEvents = preparePointerGestures(when,
   4267             &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
   4268     if (!sendEvents) {
   4269         return;
   4270     }
   4271     if (finishPreviousGesture) {
   4272         cancelPreviousGesture = false;
   4273     }
   4274 
   4275     // Update the pointer presentation and spots.
   4276     if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
   4277         mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
   4278         if (finishPreviousGesture || cancelPreviousGesture) {
   4279             mPointerController->clearSpots();
   4280         }
   4281         mPointerController->setSpots(mPointerGesture.currentGestureCoords,
   4282                 mPointerGesture.currentGestureIdToIndex,
   4283                 mPointerGesture.currentGestureIdBits);
   4284     } else {
   4285         mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
   4286     }
   4287 
   4288     // Show or hide the pointer if needed.
   4289     switch (mPointerGesture.currentGestureMode) {
   4290     case PointerGesture::NEUTRAL:
   4291     case PointerGesture::QUIET:
   4292         if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
   4293                 && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
   4294                         || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
   4295             // Remind the user of where the pointer is after finishing a gesture with spots.
   4296             mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
   4297         }
   4298         break;
   4299     case PointerGesture::TAP:
   4300     case PointerGesture::TAP_DRAG:
   4301     case PointerGesture::BUTTON_CLICK_OR_DRAG:
   4302     case PointerGesture::HOVER:
   4303     case PointerGesture::PRESS:
   4304         // Unfade the pointer when the current gesture manipulates the
   4305         // area directly under the pointer.
   4306         mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
   4307         break;
   4308     case PointerGesture::SWIPE:
   4309     case PointerGesture::FREEFORM:
   4310         // Fade the pointer when the current gesture manipulates a different
   4311         // area and there are spots to guide the user experience.
   4312         if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
   4313             mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
   4314         } else {
   4315             mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
   4316         }
   4317         break;
   4318     }
   4319 
   4320     // Send events!
   4321     int32_t metaState = getContext()->getGlobalMetaState();
   4322     int32_t buttonState = mCurrentButtonState;
   4323 
   4324     // Update last coordinates of pointers that have moved so that we observe the new
   4325     // pointer positions at the same time as other pointers that have just gone up.
   4326     bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
   4327             || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
   4328             || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
   4329             || mPointerGesture.currentGestureMode == PointerGesture::PRESS
   4330             || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
   4331             || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
   4332     bool moveNeeded = false;
   4333     if (down && !cancelPreviousGesture && !finishPreviousGesture
   4334             && !mPointerGesture.lastGestureIdBits.isEmpty()
   4335             && !mPointerGesture.currentGestureIdBits.isEmpty()) {
   4336         BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
   4337                 & mPointerGesture.lastGestureIdBits.value);
   4338         moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
   4339                 mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
   4340                 mPointerGesture.lastGestureProperties,
   4341                 mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
   4342                 movedGestureIdBits);
   4343         if (buttonState != mLastButtonState) {
   4344             moveNeeded = true;
   4345         }
   4346     }
   4347 
   4348     // Send motion events for all pointers that went up or were canceled.
   4349     BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
   4350     if (!dispatchedGestureIdBits.isEmpty()) {
   4351         if (cancelPreviousGesture) {
   4352             dispatchMotion(when, policyFlags, mSource,
   4353                     AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
   4354                     AMOTION_EVENT_EDGE_FLAG_NONE,
   4355                     mPointerGesture.lastGestureProperties,
   4356                     mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
   4357                     dispatchedGestureIdBits, -1,
   4358                     0, 0, mPointerGesture.downTime);
   4359 
   4360             dispatchedGestureIdBits.clear();
   4361         } else {
   4362             BitSet32 upGestureIdBits;
   4363             if (finishPreviousGesture) {
   4364                 upGestureIdBits = dispatchedGestureIdBits;
   4365             } else {
   4366                 upGestureIdBits.value = dispatchedGestureIdBits.value
   4367                         & ~mPointerGesture.currentGestureIdBits.value;
   4368             }
   4369             while (!upGestureIdBits.isEmpty()) {
   4370                 uint32_t id = upGestureIdBits.clearFirstMarkedBit();
   4371 
   4372                 dispatchMotion(when, policyFlags, mSource,
   4373                         AMOTION_EVENT_ACTION_POINTER_UP, 0,
   4374                         metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
   4375                         mPointerGesture.lastGestureProperties,
   4376                         mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
   4377                         dispatchedGestureIdBits, id,
   4378                         0, 0, mPointerGesture.downTime);
   4379 
   4380                 dispatchedGestureIdBits.clearBit(id);
   4381             }
   4382         }
   4383     }
   4384 
   4385     // Send motion events for all pointers that moved.
   4386     if (moveNeeded) {
   4387         dispatchMotion(when, policyFlags, mSource,
   4388                 AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
   4389                 mPointerGesture.currentGestureProperties,
   4390                 mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
   4391                 dispatchedGestureIdBits, -1,
   4392                 0, 0, mPointerGesture.downTime);
   4393     }
   4394 
   4395     // Send motion events for all pointers that went down.
   4396     if (down) {
   4397         BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
   4398                 & ~dispatchedGestureIdBits.value);
   4399         while (!downGestureIdBits.isEmpty()) {
   4400             uint32_t id = downGestureIdBits.clearFirstMarkedBit();
   4401             dispatchedGestureIdBits.markBit(id);
   4402 
   4403             if (dispatchedGestureIdBits.count() == 1) {
   4404                 mPointerGesture.downTime = when;
   4405             }
   4406 
   4407             dispatchMotion(when, policyFlags, mSource,
   4408                     AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
   4409                     mPointerGesture.currentGestureProperties,
   4410                     mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
   4411                     dispatchedGestureIdBits, id,
   4412                     0, 0, mPointerGesture.downTime);
   4413         }
   4414     }
   4415 
   4416     // Send motion events for hover.
   4417     if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
   4418         dispatchMotion(when, policyFlags, mSource,
   4419                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
   4420                 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
   4421                 mPointerGesture.currentGestureProperties,
   4422                 mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
   4423                 mPointerGesture.currentGestureIdBits, -1,
   4424                 0, 0, mPointerGesture.downTime);
   4425     } else if (dispatchedGestureIdBits.isEmpty()
   4426             && !mPointerGesture.lastGestureIdBits.isEmpty()) {
   4427         // Synthesize a hover move event after all pointers go up to indicate that
   4428         // the pointer is hovering again even if the user is not currently touching
   4429         // the touch pad.  This ensures that a view will receive a fresh hover enter
   4430         // event after a tap.
   4431         float x, y;
   4432         mPointerController->getPosition(&x, &y);
   4433 
   4434         PointerProperties pointerProperties;
   4435         pointerProperties.clear();
   4436         pointerProperties.id = 0;
   4437         pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
   4438 
   4439         PointerCoords pointerCoords;
   4440         pointerCoords.clear();
   4441         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
   4442         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
   4443 
   4444         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   4445                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
   4446                 metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
   4447                 mViewport.displayId, 1, &pointerProperties, &pointerCoords,
   4448                 0, 0, mPointerGesture.downTime);
   4449         getListener()->notifyMotion(&args);
   4450     }
   4451 
   4452     // Update state.
   4453     mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
   4454     if (!down) {
   4455         mPointerGesture.lastGestureIdBits.clear();
   4456     } else {
   4457         mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
   4458         for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
   4459             uint32_t id = idBits.clearFirstMarkedBit();
   4460             uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
   4461             mPointerGesture.lastGestureProperties[index].copyFrom(
   4462                     mPointerGesture.currentGestureProperties[index]);
   4463             mPointerGesture.lastGestureCoords[index].copyFrom(
   4464                     mPointerGesture.currentGestureCoords[index]);
   4465             mPointerGesture.lastGestureIdToIndex[id] = index;
   4466         }
   4467     }
   4468 }
   4469 
   4470 void TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
   4471     // Cancel previously dispatches pointers.
   4472     if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
   4473         int32_t metaState = getContext()->getGlobalMetaState();
   4474         int32_t buttonState = mCurrentButtonState;
   4475         dispatchMotion(when, policyFlags, mSource,
   4476                 AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
   4477                 AMOTION_EVENT_EDGE_FLAG_NONE,
   4478                 mPointerGesture.lastGestureProperties,
   4479                 mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
   4480                 mPointerGesture.lastGestureIdBits, -1,
   4481                 0, 0, mPointerGesture.downTime);
   4482     }
   4483 
   4484     // Reset the current pointer gesture.
   4485     mPointerGesture.reset();
   4486     mPointerVelocityControl.reset();
   4487 
   4488     // Remove any current spots.
   4489     if (mPointerController != NULL) {
   4490         mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
   4491         mPointerController->clearSpots();
   4492     }
   4493 }
   4494 
   4495 bool TouchInputMapper::preparePointerGestures(nsecs_t when,
   4496         bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
   4497     *outCancelPreviousGesture = false;
   4498     *outFinishPreviousGesture = false;
   4499 
   4500     // Handle TAP timeout.
   4501     if (isTimeout) {
   4502 #if DEBUG_GESTURES
   4503         ALOGD("Gestures: Processing timeout");
   4504 #endif
   4505 
   4506         if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
   4507             if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
   4508                 // The tap/drag timeout has not yet expired.
   4509                 getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
   4510                         + mConfig.pointerGestureTapDragInterval);
   4511             } else {
   4512                 // The tap is finished.
   4513 #if DEBUG_GESTURES
   4514                 ALOGD("Gestures: TAP finished");
   4515 #endif
   4516                 *outFinishPreviousGesture = true;
   4517 
   4518                 mPointerGesture.activeGestureId = -1;
   4519                 mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
   4520                 mPointerGesture.currentGestureIdBits.clear();
   4521 
   4522                 mPointerVelocityControl.reset();
   4523                 return true;
   4524             }
   4525         }
   4526 
   4527         // We did not handle this timeout.
   4528         return false;
   4529     }
   4530 
   4531     const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
   4532     const uint32_t lastFingerCount = mLastFingerIdBits.count();
   4533 
   4534     // Update the velocity tracker.
   4535     {
   4536         VelocityTracker::Position positions[MAX_POINTERS];
   4537         uint32_t count = 0;
   4538         for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
   4539             uint32_t id = idBits.clearFirstMarkedBit();
   4540             const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
   4541             positions[count].x = pointer.x * mPointerXMovementScale;
   4542             positions[count].y = pointer.y * mPointerYMovementScale;
   4543         }
   4544         mPointerGesture.velocityTracker.addMovement(when,
   4545                 mCurrentFingerIdBits, positions);
   4546     }
   4547 
   4548     // Pick a new active touch id if needed.
   4549     // Choose an arbitrary pointer that just went down, if there is one.
   4550     // Otherwise choose an arbitrary remaining pointer.
   4551     // This guarantees we always have an active touch id when there is at least one pointer.
   4552     // We keep the same active touch id for as long as possible.
   4553     bool activeTouchChanged = false;
   4554     int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
   4555     int32_t activeTouchId = lastActiveTouchId;
   4556     if (activeTouchId < 0) {
   4557         if (!mCurrentFingerIdBits.isEmpty()) {
   4558             activeTouchChanged = true;
   4559             activeTouchId = mPointerGesture.activeTouchId =
   4560                     mCurrentFingerIdBits.firstMarkedBit();
   4561             mPointerGesture.firstTouchTime = when;
   4562         }
   4563     } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
   4564         activeTouchChanged = true;
   4565         if (!mCurrentFingerIdBits.isEmpty()) {
   4566             activeTouchId = mPointerGesture.activeTouchId =
   4567                     mCurrentFingerIdBits.firstMarkedBit();
   4568         } else {
   4569             activeTouchId = mPointerGesture.activeTouchId = -1;
   4570         }
   4571     }
   4572 
   4573     // Determine whether we are in quiet time.
   4574     bool isQuietTime = false;
   4575     if (activeTouchId < 0) {
   4576         mPointerGesture.resetQuietTime();
   4577     } else {
   4578         isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
   4579         if (!isQuietTime) {
   4580             if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
   4581                     || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
   4582                     || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
   4583                     && currentFingerCount < 2) {
   4584                 // Enter quiet time when exiting swipe or freeform state.
   4585                 // This is to prevent accidentally entering the hover state and flinging the
   4586                 // pointer when finishing a swipe and there is still one pointer left onscreen.
   4587                 isQuietTime = true;
   4588             } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
   4589                     && currentFingerCount >= 2
   4590                     && !isPointerDown(mCurrentButtonState)) {
   4591                 // Enter quiet time when releasing the button and there are still two or more
   4592                 // fingers down.  This may indicate that one finger was used to press the button
   4593                 // but it has not gone up yet.
   4594                 isQuietTime = true;
   4595             }
   4596             if (isQuietTime) {
   4597                 mPointerGesture.quietTime = when;
   4598             }
   4599         }
   4600     }
   4601 
   4602     // Switch states based on button and pointer state.
   4603     if (isQuietTime) {
   4604         // Case 1: Quiet time. (QUIET)
   4605 #if DEBUG_GESTURES
   4606         ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
   4607                 + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
   4608 #endif
   4609         if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
   4610             *outFinishPreviousGesture = true;
   4611         }
   4612 
   4613         mPointerGesture.activeGestureId = -1;
   4614         mPointerGesture.currentGestureMode = PointerGesture::QUIET;
   4615         mPointerGesture.currentGestureIdBits.clear();
   4616 
   4617         mPointerVelocityControl.reset();
   4618     } else if (isPointerDown(mCurrentButtonState)) {
   4619         // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
   4620         // The pointer follows the active touch point.
   4621         // Emit DOWN, MOVE, UP events at the pointer location.
   4622         //
   4623         // Only the active touch matters; other fingers are ignored.  This policy helps
   4624         // to handle the case where the user places a second finger on the touch pad
   4625         // to apply the necessary force to depress an integrated button below the surface.
   4626         // We don't want the second finger to be delivered to applications.
   4627         //
   4628         // For this to work well, we need to make sure to track the pointer that is really
   4629         // active.  If the user first puts one finger down to click then adds another
   4630         // finger to drag then the active pointer should switch to the finger that is
   4631         // being dragged.
   4632 #if DEBUG_GESTURES
   4633         ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
   4634                 "currentFingerCount=%d", activeTouchId, currentFingerCount);
   4635 #endif
   4636         // Reset state when just starting.
   4637         if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
   4638             *outFinishPreviousGesture = true;
   4639             mPointerGesture.activeGestureId = 0;
   4640         }
   4641 
   4642         // Switch pointers if needed.
   4643         // Find the fastest pointer and follow it.
   4644         if (activeTouchId >= 0 && currentFingerCount > 1) {
   4645             int32_t bestId = -1;
   4646             float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
   4647             for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
   4648                 uint32_t id = idBits.clearFirstMarkedBit();
   4649                 float vx, vy;
   4650                 if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
   4651                     float speed = hypotf(vx, vy);
   4652                     if (speed > bestSpeed) {
   4653                         bestId = id;
   4654                         bestSpeed = speed;
   4655                     }
   4656                 }
   4657             }
   4658             if (bestId >= 0 && bestId != activeTouchId) {
   4659                 mPointerGesture.activeTouchId = activeTouchId = bestId;
   4660                 activeTouchChanged = true;
   4661 #if DEBUG_GESTURES
   4662                 ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
   4663                         "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
   4664 #endif
   4665             }
   4666         }
   4667 
   4668         if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
   4669             const RawPointerData::Pointer& currentPointer =
   4670                     mCurrentRawPointerData.pointerForId(activeTouchId);
   4671             const RawPointerData::Pointer& lastPointer =
   4672                     mLastRawPointerData.pointerForId(activeTouchId);
   4673             float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
   4674             float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
   4675 
   4676             rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
   4677             mPointerVelocityControl.move(when, &deltaX, &deltaY);
   4678 
   4679             // Move the pointer using a relative motion.
   4680             // When using spots, the click will occur at the position of the anchor
   4681             // spot and all other spots will move there.
   4682             mPointerController->move(deltaX, deltaY);
   4683         } else {
   4684             mPointerVelocityControl.reset();
   4685         }
   4686 
   4687         float x, y;
   4688         mPointerController->getPosition(&x, &y);
   4689 
   4690         mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
   4691         mPointerGesture.currentGestureIdBits.clear();
   4692         mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
   4693         mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
   4694         mPointerGesture.currentGestureProperties[0].clear();
   4695         mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
   4696         mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
   4697         mPointerGesture.currentGestureCoords[0].clear();
   4698         mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
   4699         mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
   4700         mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
   4701     } else if (currentFingerCount == 0) {
   4702         // Case 3. No fingers down and button is not pressed. (NEUTRAL)
   4703         if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
   4704             *outFinishPreviousGesture = true;
   4705         }
   4706 
   4707         // Watch for taps coming out of HOVER or TAP_DRAG mode.
   4708         // Checking for taps after TAP_DRAG allows us to detect double-taps.
   4709         bool tapped = false;
   4710         if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
   4711                 || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
   4712                 && lastFingerCount == 1) {
   4713             if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
   4714                 float x, y;
   4715                 mPointerController->getPosition(&x, &y);
   4716                 if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
   4717                         && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
   4718 #if DEBUG_GESTURES
   4719                     ALOGD("Gestures: TAP");
   4720 #endif
   4721 
   4722                     mPointerGesture.tapUpTime = when;
   4723                     getContext()->requestTimeoutAtTime(when
   4724                             + mConfig.pointerGestureTapDragInterval);
   4725 
   4726                     mPointerGesture.activeGestureId = 0;
   4727                     mPointerGesture.currentGestureMode = PointerGesture::TAP;
   4728                     mPointerGesture.currentGestureIdBits.clear();
   4729                     mPointerGesture.currentGestureIdBits.markBit(
   4730                             mPointerGesture.activeGestureId);
   4731                     mPointerGesture.currentGestureIdToIndex[
   4732                             mPointerGesture.activeGestureId] = 0;
   4733                     mPointerGesture.currentGestureProperties[0].clear();
   4734                     mPointerGesture.currentGestureProperties[0].id =
   4735                             mPointerGesture.activeGestureId;
   4736                     mPointerGesture.currentGestureProperties[0].toolType =
   4737                             AMOTION_EVENT_TOOL_TYPE_FINGER;
   4738                     mPointerGesture.currentGestureCoords[0].clear();
   4739                     mPointerGesture.currentGestureCoords[0].setAxisValue(
   4740                             AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
   4741                     mPointerGesture.currentGestureCoords[0].setAxisValue(
   4742                             AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
   4743                     mPointerGesture.currentGestureCoords[0].setAxisValue(
   4744                             AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
   4745 
   4746                     tapped = true;
   4747                 } else {
   4748 #if DEBUG_GESTURES
   4749                     ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
   4750                             x - mPointerGesture.tapX,
   4751                             y - mPointerGesture.tapY);
   4752 #endif
   4753                 }
   4754             } else {
   4755 #if DEBUG_GESTURES
   4756                 ALOGD("Gestures: Not a TAP, %0.3fms since down",
   4757                         (when - mPointerGesture.tapDownTime) * 0.000001f);
   4758 #endif
   4759             }
   4760         }
   4761 
   4762         mPointerVelocityControl.reset();
   4763 
   4764         if (!tapped) {
   4765 #if DEBUG_GESTURES
   4766             ALOGD("Gestures: NEUTRAL");
   4767 #endif
   4768             mPointerGesture.activeGestureId = -1;
   4769             mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
   4770             mPointerGesture.currentGestureIdBits.clear();
   4771         }
   4772     } else if (currentFingerCount == 1) {
   4773         // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
   4774         // The pointer follows the active touch point.
   4775         // When in HOVER, emit HOVER_MOVE events at the pointer location.
   4776         // When in TAP_DRAG, emit MOVE events at the pointer location.
   4777         ALOG_ASSERT(activeTouchId >= 0);
   4778 
   4779         mPointerGesture.currentGestureMode = PointerGesture::HOVER;
   4780         if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
   4781             if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
   4782                 float x, y;
   4783                 mPointerController->getPosition(&x, &y);
   4784                 if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
   4785                         && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
   4786                     mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
   4787                 } else {
   4788 #if DEBUG_GESTURES
   4789                     ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
   4790                             x - mPointerGesture.tapX,
   4791                             y - mPointerGesture.tapY);
   4792 #endif
   4793                 }
   4794             } else {
   4795 #if DEBUG_GESTURES
   4796                 ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
   4797                         (when - mPointerGesture.tapUpTime) * 0.000001f);
   4798 #endif
   4799             }
   4800         } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
   4801             mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
   4802         }
   4803 
   4804         if (mLastFingerIdBits.hasBit(activeTouchId)) {
   4805             const RawPointerData::Pointer& currentPointer =
   4806                     mCurrentRawPointerData.pointerForId(activeTouchId);
   4807             const RawPointerData::Pointer& lastPointer =
   4808                     mLastRawPointerData.pointerForId(activeTouchId);
   4809             float deltaX = (currentPointer.x - lastPointer.x)
   4810                     * mPointerXMovementScale;
   4811             float deltaY = (currentPointer.y - lastPointer.y)
   4812                     * mPointerYMovementScale;
   4813 
   4814             rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
   4815             mPointerVelocityControl.move(when, &deltaX, &deltaY);
   4816 
   4817             // Move the pointer using a relative motion.
   4818             // When using spots, the hover or drag will occur at the position of the anchor spot.
   4819             mPointerController->move(deltaX, deltaY);
   4820         } else {
   4821             mPointerVelocityControl.reset();
   4822         }
   4823 
   4824         bool down;
   4825         if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
   4826 #if DEBUG_GESTURES
   4827             ALOGD("Gestures: TAP_DRAG");
   4828 #endif
   4829             down = true;
   4830         } else {
   4831 #if DEBUG_GESTURES
   4832             ALOGD("Gestures: HOVER");
   4833 #endif
   4834             if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
   4835                 *outFinishPreviousGesture = true;
   4836             }
   4837             mPointerGesture.activeGestureId = 0;
   4838             down = false;
   4839         }
   4840 
   4841         float x, y;
   4842         mPointerController->getPosition(&x, &y);
   4843 
   4844         mPointerGesture.currentGestureIdBits.clear();
   4845         mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
   4846         mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
   4847         mPointerGesture.currentGestureProperties[0].clear();
   4848         mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
   4849         mPointerGesture.currentGestureProperties[0].toolType =
   4850                 AMOTION_EVENT_TOOL_TYPE_FINGER;
   4851         mPointerGesture.currentGestureCoords[0].clear();
   4852         mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
   4853         mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
   4854         mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
   4855                 down ? 1.0f : 0.0f);
   4856 
   4857         if (lastFingerCount == 0 && currentFingerCount != 0) {
   4858             mPointerGesture.resetTap();
   4859             mPointerGesture.tapDownTime = when;
   4860             mPointerGesture.tapX = x;
   4861             mPointerGesture.tapY = y;
   4862         }
   4863     } else {
   4864         // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
   4865         // We need to provide feedback for each finger that goes down so we cannot wait
   4866         // for the fingers to move before deciding what to do.
   4867         //
   4868         // The ambiguous case is deciding what to do when there are two fingers down but they
   4869         // have not moved enough to determine whether they are part of a drag or part of a
   4870         // freeform gesture, or just a press or long-press at the pointer location.
   4871         //
   4872         // When there are two fingers we start with the PRESS hypothesis and we generate a
   4873         // down at the pointer location.
   4874         //
   4875         // When the two fingers move enough or when additional fingers are added, we make
   4876         // a decision to transition into SWIPE or FREEFORM mode accordingly.
   4877         ALOG_ASSERT(activeTouchId >= 0);
   4878 
   4879         bool settled = when >= mPointerGesture.firstTouchTime
   4880                 + mConfig.pointerGestureMultitouchSettleInterval;
   4881         if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
   4882                 && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
   4883                 && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
   4884             *outFinishPreviousGesture = true;
   4885         } else if (!settled && currentFingerCount > lastFingerCount) {
   4886             // Additional pointers have gone down but not yet settled.
   4887             // Reset the gesture.
   4888 #if DEBUG_GESTURES
   4889             ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
   4890                     "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
   4891                             + mConfig.pointerGestureMultitouchSettleInterval - when)
   4892                             * 0.000001f);
   4893 #endif
   4894             *outCancelPreviousGesture = true;
   4895         } else {
   4896             // Continue previous gesture.
   4897             mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
   4898         }
   4899 
   4900         if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
   4901             mPointerGesture.currentGestureMode = PointerGesture::PRESS;
   4902             mPointerGesture.activeGestureId = 0;
   4903             mPointerGesture.referenceIdBits.clear();
   4904             mPointerVelocityControl.reset();
   4905 
   4906             // Use the centroid and pointer location as the reference points for the gesture.
   4907 #if DEBUG_GESTURES
   4908             ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
   4909                     "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
   4910                             + mConfig.pointerGestureMultitouchSettleInterval - when)
   4911                             * 0.000001f);
   4912 #endif
   4913             mCurrentRawPointerData.getCentroidOfTouchingPointers(
   4914                     &mPointerGesture.referenceTouchX,
   4915                     &mPointerGesture.referenceTouchY);
   4916             mPointerController->getPosition(&mPointerGesture.referenceGestureX,
   4917                     &mPointerGesture.referenceGestureY);
   4918         }
   4919 
   4920         // Clear the reference deltas for fingers not yet included in the reference calculation.
   4921         for (BitSet32 idBits(mCurrentFingerIdBits.value
   4922                 & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
   4923             uint32_t id = idBits.clearFirstMarkedBit();
   4924             mPointerGesture.referenceDeltas[id].dx = 0;
   4925             mPointerGesture.referenceDeltas[id].dy = 0;
   4926         }
   4927         mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
   4928 
   4929         // Add delta for all fingers and calculate a common movement delta.
   4930         float commonDeltaX = 0, commonDeltaY = 0;
   4931         BitSet32 commonIdBits(mLastFingerIdBits.value
   4932                 & mCurrentFingerIdBits.value);
   4933         for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
   4934             bool first = (idBits == commonIdBits);
   4935             uint32_t id = idBits.clearFirstMarkedBit();
   4936             const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
   4937             const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
   4938             PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
   4939             delta.dx += cpd.x - lpd.x;
   4940             delta.dy += cpd.y - lpd.y;
   4941 
   4942             if (first) {
   4943                 commonDeltaX = delta.dx;
   4944                 commonDeltaY = delta.dy;
   4945             } else {
   4946                 commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
   4947                 commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
   4948             }
   4949         }
   4950 
   4951         // Consider transitions from PRESS to SWIPE or MULTITOUCH.
   4952         if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
   4953             float dist[MAX_POINTER_ID + 1];
   4954             int32_t distOverThreshold = 0;
   4955             for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
   4956                 uint32_t id = idBits.clearFirstMarkedBit();
   4957                 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
   4958                 dist[id] = hypotf(delta.dx * mPointerXZoomScale,
   4959                         delta.dy * mPointerYZoomScale);
   4960                 if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
   4961                     distOverThreshold += 1;
   4962                 }
   4963             }
   4964 
   4965             // Only transition when at least two pointers have moved further than
   4966             // the minimum distance threshold.
   4967             if (distOverThreshold >= 2) {
   4968                 if (currentFingerCount > 2) {
   4969                     // There are more than two pointers, switch to FREEFORM.
   4970 #if DEBUG_GESTURES
   4971                     ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
   4972                             currentFingerCount);
   4973 #endif
   4974                     *outCancelPreviousGesture = true;
   4975                     mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
   4976                 } else {
   4977                     // There are exactly two pointers.
   4978                     BitSet32 idBits(mCurrentFingerIdBits);
   4979                     uint32_t id1 = idBits.clearFirstMarkedBit();
   4980                     uint32_t id2 = idBits.firstMarkedBit();
   4981                     const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
   4982                     const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
   4983                     float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
   4984                     if (mutualDistance > mPointerGestureMaxSwipeWidth) {
   4985                         // There are two pointers but they are too far apart for a SWIPE,
   4986                         // switch to FREEFORM.
   4987 #if DEBUG_GESTURES
   4988                         ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
   4989                                 mutualDistance, mPointerGestureMaxSwipeWidth);
   4990 #endif
   4991                         *outCancelPreviousGesture = true;
   4992                         mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
   4993                     } else {
   4994                         // There are two pointers.  Wait for both pointers to start moving
   4995                         // before deciding whether this is a SWIPE or FREEFORM gesture.
   4996                         float dist1 = dist[id1];
   4997                         float dist2 = dist[id2];
   4998                         if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
   4999                                 && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
   5000                             // Calculate the dot product of the displacement vectors.
   5001                             // When the vectors are oriented in approximately the same direction,
   5002                             // the angle betweeen them is near zero and the cosine of the angle
   5003                             // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
   5004                             PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
   5005                             PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
   5006                             float dx1 = delta1.dx * mPointerXZoomScale;
   5007                             float dy1 = delta1.dy * mPointerYZoomScale;
   5008                             float dx2 = delta2.dx * mPointerXZoomScale;
   5009                             float dy2 = delta2.dy * mPointerYZoomScale;
   5010                             float dot = dx1 * dx2 + dy1 * dy2;
   5011                             float cosine = dot / (dist1 * dist2); // denominator always > 0
   5012                             if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
   5013                                 // Pointers are moving in the same direction.  Switch to SWIPE.
   5014 #if DEBUG_GESTURES
   5015                                 ALOGD("Gestures: PRESS transitioned to SWIPE, "
   5016                                         "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
   5017                                         "cosine %0.3f >= %0.3f",
   5018                                         dist1, mConfig.pointerGestureMultitouchMinDistance,
   5019                                         dist2, mConfig.pointerGestureMultitouchMinDistance,
   5020                                         cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
   5021 #endif
   5022                                 mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
   5023                             } else {
   5024                                 // Pointers are moving in different directions.  Switch to FREEFORM.
   5025 #if DEBUG_GESTURES
   5026                                 ALOGD("Gestures: PRESS transitioned to FREEFORM, "
   5027                                         "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
   5028                                         "cosine %0.3f < %0.3f",
   5029                                         dist1, mConfig.pointerGestureMultitouchMinDistance,
   5030                                         dist2, mConfig.pointerGestureMultitouchMinDistance,
   5031                                         cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
   5032 #endif
   5033                                 *outCancelPreviousGesture = true;
   5034                                 mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
   5035                             }
   5036                         }
   5037                     }
   5038                 }
   5039             }
   5040         } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
   5041             // Switch from SWIPE to FREEFORM if additional pointers go down.
   5042             // Cancel previous gesture.
   5043             if (currentFingerCount > 2) {
   5044 #if DEBUG_GESTURES
   5045                 ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
   5046                         currentFingerCount);
   5047 #endif
   5048                 *outCancelPreviousGesture = true;
   5049                 mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
   5050             }
   5051         }
   5052 
   5053         // Move the reference points based on the overall group motion of the fingers
   5054         // except in PRESS mode while waiting for a transition to occur.
   5055         if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
   5056                 && (commonDeltaX || commonDeltaY)) {
   5057             for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
   5058                 uint32_t id = idBits.clearFirstMarkedBit();
   5059                 PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
   5060                 delta.dx = 0;
   5061                 delta.dy = 0;
   5062             }
   5063 
   5064             mPointerGesture.referenceTouchX += commonDeltaX;
   5065             mPointerGesture.referenceTouchY += commonDeltaY;
   5066 
   5067             commonDeltaX *= mPointerXMovementScale;
   5068             commonDeltaY *= mPointerYMovementScale;
   5069 
   5070             rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
   5071             mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
   5072 
   5073             mPointerGesture.referenceGestureX += commonDeltaX;
   5074             mPointerGesture.referenceGestureY += commonDeltaY;
   5075         }
   5076 
   5077         // Report gestures.
   5078         if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
   5079                 || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
   5080             // PRESS or SWIPE mode.
   5081 #if DEBUG_GESTURES
   5082             ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
   5083                     "activeGestureId=%d, currentTouchPointerCount=%d",
   5084                     activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
   5085 #endif
   5086             ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
   5087 
   5088             mPointerGesture.currentGestureIdBits.clear();
   5089             mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
   5090             mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
   5091             mPointerGesture.currentGestureProperties[0].clear();
   5092             mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
   5093             mPointerGesture.currentGestureProperties[0].toolType =
   5094                     AMOTION_EVENT_TOOL_TYPE_FINGER;
   5095             mPointerGesture.currentGestureCoords[0].clear();
   5096             mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
   5097                     mPointerGesture.referenceGestureX);
   5098             mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
   5099                     mPointerGesture.referenceGestureY);
   5100             mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
   5101         } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
   5102             // FREEFORM mode.
   5103 #if DEBUG_GESTURES
   5104             ALOGD("Gestures: FREEFORM activeTouchId=%d,"
   5105                     "activeGestureId=%d, currentTouchPointerCount=%d",
   5106                     activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
   5107 #endif
   5108             ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
   5109 
   5110             mPointerGesture.currentGestureIdBits.clear();
   5111 
   5112             BitSet32 mappedTouchIdBits;
   5113             BitSet32 usedGestureIdBits;
   5114             if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
   5115                 // Initially, assign the active gesture id to the active touch point
   5116                 // if there is one.  No other touch id bits are mapped yet.
   5117                 if (!*outCancelPreviousGesture) {
   5118                     mappedTouchIdBits.markBit(activeTouchId);
   5119                     usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
   5120                     mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
   5121                             mPointerGesture.activeGestureId;
   5122                 } else {
   5123                     mPointerGesture.activeGestureId = -1;
   5124                 }
   5125             } else {
   5126                 // Otherwise, assume we mapped all touches from the previous frame.
   5127                 // Reuse all mappings that are still applicable.
   5128                 mappedTouchIdBits.value = mLastFingerIdBits.value
   5129                         & mCurrentFingerIdBits.value;
   5130                 usedGestureIdBits = mPointerGesture.lastGestureIdBits;
   5131 
   5132                 // Check whether we need to choose a new active gesture id because the
   5133                 // current went went up.
   5134                 for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
   5135                         & ~mCurrentFingerIdBits.value);
   5136                         !upTouchIdBits.isEmpty(); ) {
   5137                     uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
   5138                     uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
   5139                     if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
   5140                         mPointerGesture.activeGestureId = -1;
   5141                         break;
   5142                     }
   5143                 }
   5144             }
   5145 
   5146 #if DEBUG_GESTURES
   5147             ALOGD("Gestures: FREEFORM follow up "
   5148                     "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
   5149                     "activeGestureId=%d",
   5150                     mappedTouchIdBits.value, usedGestureIdBits.value,
   5151                     mPointerGesture.activeGestureId);
   5152 #endif
   5153 
   5154             BitSet32 idBits(mCurrentFingerIdBits);
   5155             for (uint32_t i = 0; i < currentFingerCount; i++) {
   5156                 uint32_t touchId = idBits.clearFirstMarkedBit();
   5157                 uint32_t gestureId;
   5158                 if (!mappedTouchIdBits.hasBit(touchId)) {
   5159                     gestureId = usedGestureIdBits.markFirstUnmarkedBit();
   5160                     mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
   5161 #if DEBUG_GESTURES
   5162                     ALOGD("Gestures: FREEFORM "
   5163                             "new mapping for touch id %d -> gesture id %d",
   5164                             touchId, gestureId);
   5165 #endif
   5166                 } else {
   5167                     gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
   5168 #if DEBUG_GESTURES
   5169                     ALOGD("Gestures: FREEFORM "
   5170                             "existing mapping for touch id %d -> gesture id %d",
   5171                             touchId, gestureId);
   5172 #endif
   5173                 }
   5174                 mPointerGesture.currentGestureIdBits.markBit(gestureId);
   5175                 mPointerGesture.currentGestureIdToIndex[gestureId] = i;
   5176 
   5177                 const RawPointerData::Pointer& pointer =
   5178                         mCurrentRawPointerData.pointerForId(touchId);
   5179                 float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
   5180                         * mPointerXZoomScale;
   5181                 float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
   5182                         * mPointerYZoomScale;
   5183                 rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
   5184 
   5185                 mPointerGesture.currentGestureProperties[i].clear();
   5186                 mPointerGesture.currentGestureProperties[i].id = gestureId;
   5187                 mPointerGesture.currentGestureProperties[i].toolType =
   5188                         AMOTION_EVENT_TOOL_TYPE_FINGER;
   5189                 mPointerGesture.currentGestureCoords[i].clear();
   5190                 mPointerGesture.currentGestureCoords[i].setAxisValue(
   5191                         AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
   5192                 mPointerGesture.currentGestureCoords[i].setAxisValue(
   5193                         AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
   5194                 mPointerGesture.currentGestureCoords[i].setAxisValue(
   5195                         AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
   5196             }
   5197 
   5198             if (mPointerGesture.activeGestureId < 0) {
   5199                 mPointerGesture.activeGestureId =
   5200                         mPointerGesture.currentGestureIdBits.firstMarkedBit();
   5201 #if DEBUG_GESTURES
   5202                 ALOGD("Gestures: FREEFORM new "
   5203                         "activeGestureId=%d", mPointerGesture.activeGestureId);
   5204 #endif
   5205             }
   5206         }
   5207     }
   5208 
   5209     mPointerController->setButtonState(mCurrentButtonState);
   5210 
   5211 #if DEBUG_GESTURES
   5212     ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
   5213             "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
   5214             "lastGestureMode=%d, lastGestureIdBits=0x%08x",
   5215             toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
   5216             mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
   5217             mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
   5218     for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
   5219         uint32_t id = idBits.clearFirstMarkedBit();
   5220         uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
   5221         const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
   5222         const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
   5223         ALOGD("  currentGesture[%d]: index=%d, toolType=%d, "
   5224                 "x=%0.3f, y=%0.3f, pressure=%0.3f",
   5225                 id, index, properties.toolType,
   5226                 coords.getAxisValue(AMOTION_EVENT_AXIS_X),
   5227                 coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
   5228                 coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
   5229     }
   5230     for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
   5231         uint32_t id = idBits.clearFirstMarkedBit();
   5232         uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
   5233         const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
   5234         const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
   5235         ALOGD("  lastGesture[%d]: index=%d, toolType=%d, "
   5236                 "x=%0.3f, y=%0.3f, pressure=%0.3f",
   5237                 id, index, properties.toolType,
   5238                 coords.getAxisValue(AMOTION_EVENT_AXIS_X),
   5239                 coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
   5240                 coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
   5241     }
   5242 #endif
   5243     return true;
   5244 }
   5245 
   5246 void TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
   5247     mPointerSimple.currentCoords.clear();
   5248     mPointerSimple.currentProperties.clear();
   5249 
   5250     bool down, hovering;
   5251     if (!mCurrentStylusIdBits.isEmpty()) {
   5252         uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
   5253         uint32_t index = mCurrentCookedPointerData.idToIndex[id];
   5254         float x = mCurrentCookedPointerData.pointerCoords[index].getX();
   5255         float y = mCurrentCookedPointerData.pointerCoords[index].getY();
   5256         mPointerController->setPosition(x, y);
   5257 
   5258         hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
   5259         down = !hovering;
   5260 
   5261         mPointerController->getPosition(&x, &y);
   5262         mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
   5263         mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
   5264         mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
   5265         mPointerSimple.currentProperties.id = 0;
   5266         mPointerSimple.currentProperties.toolType =
   5267                 mCurrentCookedPointerData.pointerProperties[index].toolType;
   5268     } else {
   5269         down = false;
   5270         hovering = false;
   5271     }
   5272 
   5273     dispatchPointerSimple(when, policyFlags, down, hovering);
   5274 }
   5275 
   5276 void TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
   5277     abortPointerSimple(when, policyFlags);
   5278 }
   5279 
   5280 void TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
   5281     mPointerSimple.currentCoords.clear();
   5282     mPointerSimple.currentProperties.clear();
   5283 
   5284     bool down, hovering;
   5285     if (!mCurrentMouseIdBits.isEmpty()) {
   5286         uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
   5287         uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
   5288         if (mLastMouseIdBits.hasBit(id)) {
   5289             uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
   5290             float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
   5291                     - mLastRawPointerData.pointers[lastIndex].x)
   5292                     * mPointerXMovementScale;
   5293             float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
   5294                     - mLastRawPointerData.pointers[lastIndex].y)
   5295                     * mPointerYMovementScale;
   5296 
   5297             rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
   5298             mPointerVelocityControl.move(when, &deltaX, &deltaY);
   5299 
   5300             mPointerController->move(deltaX, deltaY);
   5301         } else {
   5302             mPointerVelocityControl.reset();
   5303         }
   5304 
   5305         down = isPointerDown(mCurrentButtonState);
   5306         hovering = !down;
   5307 
   5308         float x, y;
   5309         mPointerController->getPosition(&x, &y);
   5310         mPointerSimple.currentCoords.copyFrom(
   5311                 mCurrentCookedPointerData.pointerCoords[currentIndex]);
   5312         mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
   5313         mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
   5314         mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
   5315                 hovering ? 0.0f : 1.0f);
   5316         mPointerSimple.currentProperties.id = 0;
   5317         mPointerSimple.currentProperties.toolType =
   5318                 mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
   5319     } else {
   5320         mPointerVelocityControl.reset();
   5321 
   5322         down = false;
   5323         hovering = false;
   5324     }
   5325 
   5326     dispatchPointerSimple(when, policyFlags, down, hovering);
   5327 }
   5328 
   5329 void TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
   5330     abortPointerSimple(when, policyFlags);
   5331 
   5332     mPointerVelocityControl.reset();
   5333 }
   5334 
   5335 void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
   5336         bool down, bool hovering) {
   5337     int32_t metaState = getContext()->getGlobalMetaState();
   5338 
   5339     if (mPointerController != NULL) {
   5340         if (down || hovering) {
   5341             mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
   5342             mPointerController->clearSpots();
   5343             mPointerController->setButtonState(mCurrentButtonState);
   5344             mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
   5345         } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
   5346             mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
   5347         }
   5348     }
   5349 
   5350     if (mPointerSimple.down && !down) {
   5351         mPointerSimple.down = false;
   5352 
   5353         // Send up.
   5354         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   5355                  AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
   5356                  mViewport.displayId,
   5357                  1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
   5358                  mOrientedXPrecision, mOrientedYPrecision,
   5359                  mPointerSimple.downTime);
   5360         getListener()->notifyMotion(&args);
   5361     }
   5362 
   5363     if (mPointerSimple.hovering && !hovering) {
   5364         mPointerSimple.hovering = false;
   5365 
   5366         // Send hover exit.
   5367         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   5368                 AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
   5369                 mViewport.displayId,
   5370                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
   5371                 mOrientedXPrecision, mOrientedYPrecision,
   5372                 mPointerSimple.downTime);
   5373         getListener()->notifyMotion(&args);
   5374     }
   5375 
   5376     if (down) {
   5377         if (!mPointerSimple.down) {
   5378             mPointerSimple.down = true;
   5379             mPointerSimple.downTime = when;
   5380 
   5381             // Send down.
   5382             NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   5383                     AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
   5384                     mViewport.displayId,
   5385                     1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
   5386                     mOrientedXPrecision, mOrientedYPrecision,
   5387                     mPointerSimple.downTime);
   5388             getListener()->notifyMotion(&args);
   5389         }
   5390 
   5391         // Send move.
   5392         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   5393                 AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
   5394                 mViewport.displayId,
   5395                 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
   5396                 mOrientedXPrecision, mOrientedYPrecision,
   5397                 mPointerSimple.downTime);
   5398         getListener()->notifyMotion(&args);
   5399     }
   5400 
   5401     if (hovering) {
   5402         if (!mPointerSimple.hovering) {
   5403             mPointerSimple.hovering = true;
   5404 
   5405             // Send hover enter.
   5406             NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   5407                     AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
   5408                     mViewport.displayId,
   5409                     1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
   5410                     mOrientedXPrecision, mOrientedYPrecision,
   5411                     mPointerSimple.downTime);
   5412             getListener()->notifyMotion(&args);
   5413         }
   5414 
   5415         // Send hover move.
   5416         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   5417                 AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
   5418                 mViewport.displayId,
   5419                 1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
   5420                 mOrientedXPrecision, mOrientedYPrecision,
   5421                 mPointerSimple.downTime);
   5422         getListener()->notifyMotion(&args);
   5423     }
   5424 
   5425     if (mCurrentRawVScroll || mCurrentRawHScroll) {
   5426         float vscroll = mCurrentRawVScroll;
   5427         float hscroll = mCurrentRawHScroll;
   5428         mWheelYVelocityControl.move(when, NULL, &vscroll);
   5429         mWheelXVelocityControl.move(when, &hscroll, NULL);
   5430 
   5431         // Send scroll.
   5432         PointerCoords pointerCoords;
   5433         pointerCoords.copyFrom(mPointerSimple.currentCoords);
   5434         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
   5435         pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
   5436 
   5437         NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
   5438                 AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
   5439                 mViewport.displayId,
   5440                 1, &mPointerSimple.currentProperties, &pointerCoords,
   5441                 mOrientedXPrecision, mOrientedYPrecision,
   5442                 mPointerSimple.downTime);
   5443         getListener()->notifyMotion(&args);
   5444     }
   5445 
   5446     // Save state.
   5447     if (down || hovering) {
   5448         mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
   5449         mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
   5450     } else {
   5451         mPointerSimple.reset();
   5452     }
   5453 }
   5454 
   5455 void TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
   5456     mPointerSimple.currentCoords.clear();
   5457     mPointerSimple.currentProperties.clear();
   5458 
   5459     dispatchPointerSimple(when, policyFlags, false, false);
   5460 }
   5461 
   5462 void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
   5463         int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
   5464         const PointerProperties* properties, const PointerCoords* coords,
   5465         const uint32_t* idToIndex, BitSet32 idBits,
   5466         int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
   5467     PointerCoords pointerCoords[MAX_POINTERS];
   5468     PointerProperties pointerProperties[MAX_POINTERS];
   5469     uint32_t pointerCount = 0;
   5470     while (!idBits.isEmpty()) {
   5471         uint32_t id = idBits.clearFirstMarkedBit();
   5472         uint32_t index = idToIndex[id];
   5473         pointerProperties[pointerCount].copyFrom(properties[index]);
   5474         pointerCoords[pointerCount].copyFrom(coords[index]);
   5475 
   5476         if (changedId >= 0 && id == uint32_t(changedId)) {
   5477             action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
   5478         }
   5479 
   5480         pointerCount += 1;
   5481     }
   5482 
   5483     ALOG_ASSERT(pointerCount != 0);
   5484 
   5485     if (changedId >= 0 && pointerCount == 1) {
   5486         // Replace initial down and final up action.
   5487         // We can compare the action without masking off the changed pointer index
   5488         // because we know the index is 0.
   5489         if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
   5490             action = AMOTION_EVENT_ACTION_DOWN;
   5491         } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
   5492             action = AMOTION_EVENT_ACTION_UP;
   5493         } else {
   5494             // Can't happen.
   5495             ALOG_ASSERT(false);
   5496         }
   5497     }
   5498 
   5499     NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
   5500             action, flags, metaState, buttonState, edgeFlags,
   5501             mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
   5502             xPrecision, yPrecision, downTime);
   5503     getListener()->notifyMotion(&args);
   5504 }
   5505 
   5506 bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
   5507         const PointerCoords* inCoords, const uint32_t* inIdToIndex,
   5508         PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
   5509         BitSet32 idBits) const {
   5510     bool changed = false;
   5511     while (!idBits.isEmpty()) {
   5512         uint32_t id = idBits.clearFirstMarkedBit();
   5513         uint32_t inIndex = inIdToIndex[id];
   5514         uint32_t outIndex = outIdToIndex[id];
   5515 
   5516         const PointerProperties& curInProperties = inProperties[inIndex];
   5517         const PointerCoords& curInCoords = inCoords[inIndex];
   5518         PointerProperties& curOutProperties = outProperties[outIndex];
   5519         PointerCoords& curOutCoords = outCoords[outIndex];
   5520 
   5521         if (curInProperties != curOutProperties) {
   5522             curOutProperties.copyFrom(curInProperties);
   5523             changed = true;
   5524         }
   5525 
   5526         if (curInCoords != curOutCoords) {
   5527             curOutCoords.copyFrom(curInCoords);
   5528             changed = true;
   5529         }
   5530     }
   5531     return changed;
   5532 }
   5533 
   5534 void TouchInputMapper::fadePointer() {
   5535     if (mPointerController != NULL) {
   5536         mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
   5537     }
   5538 }
   5539 
   5540 bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
   5541     return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
   5542             && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
   5543 }
   5544 
   5545 const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
   5546         int32_t x, int32_t y) {
   5547     size_t numVirtualKeys = mVirtualKeys.size();
   5548     for (size_t i = 0; i < numVirtualKeys; i++) {
   5549         const VirtualKey& virtualKey = mVirtualKeys[i];
   5550 
   5551 #if DEBUG_VIRTUAL_KEYS
   5552         ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
   5553                 "left=%d, top=%d, right=%d, bottom=%d",
   5554                 x, y,
   5555                 virtualKey.keyCode, virtualKey.scanCode,
   5556                 virtualKey.hitLeft, virtualKey.hitTop,
   5557                 virtualKey.hitRight, virtualKey.hitBottom);
   5558 #endif
   5559 
   5560         if (virtualKey.isHit(x, y)) {
   5561             return & virtualKey;
   5562         }
   5563     }
   5564 
   5565     return NULL;
   5566 }
   5567 
   5568 void TouchInputMapper::assignPointerIds() {
   5569     uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
   5570     uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
   5571 
   5572     mCurrentRawPointerData.clearIdBits();
   5573 
   5574     if (currentPointerCount == 0) {
   5575         // No pointers to assign.
   5576         return;
   5577     }
   5578 
   5579     if (lastPointerCount == 0) {
   5580         // All pointers are new.
   5581         for (uint32_t i = 0; i < currentPointerCount; i++) {
   5582             uint32_t id = i;
   5583             mCurrentRawPointerData.pointers[i].id = id;
   5584             mCurrentRawPointerData.idToIndex[id] = i;
   5585             mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
   5586         }
   5587         return;
   5588     }
   5589 
   5590     if (currentPointerCount == 1 && lastPointerCount == 1
   5591             && mCurrentRawPointerData.pointers[0].toolType
   5592                     == mLastRawPointerData.pointers[0].toolType) {
   5593         // Only one pointer and no change in count so it must have the same id as before.
   5594         uint32_t id = mLastRawPointerData.pointers[0].id;
   5595         mCurrentRawPointerData.pointers[0].id = id;
   5596         mCurrentRawPointerData.idToIndex[id] = 0;
   5597         mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
   5598         return;
   5599     }
   5600 
   5601     // General case.
   5602     // We build a heap of squared euclidean distances between current and last pointers
   5603     // associated with the current and last pointer indices.  Then, we find the best
   5604     // match (by distance) for each current pointer.
   5605     // The pointers must have the same tool type but it is possible for them to
   5606     // transition from hovering to touching or vice-versa while retaining the same id.
   5607     PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
   5608 
   5609     uint32_t heapSize = 0;
   5610     for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
   5611             currentPointerIndex++) {
   5612         for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
   5613                 lastPointerIndex++) {
   5614             const RawPointerData::Pointer& currentPointer =
   5615                     mCurrentRawPointerData.pointers[currentPointerIndex];
   5616             const RawPointerData::Pointer& lastPointer =
   5617                     mLastRawPointerData.pointers[lastPointerIndex];
   5618             if (currentPointer.toolType == lastPointer.toolType) {
   5619                 int64_t deltaX = currentPointer.x - lastPointer.x;
   5620                 int64_t deltaY = currentPointer.y - lastPointer.y;
   5621 
   5622                 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
   5623 
   5624                 // Insert new element into the heap (sift up).
   5625                 heap[heapSize].currentPointerIndex = currentPointerIndex;
   5626                 heap[heapSize].lastPointerIndex = lastPointerIndex;
   5627                 heap[heapSize].distance = distance;
   5628                 heapSize += 1;
   5629             }
   5630         }
   5631     }
   5632 
   5633     // Heapify
   5634     for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
   5635         startIndex -= 1;
   5636         for (uint32_t parentIndex = startIndex; ;) {
   5637             uint32_t childIndex = parentIndex * 2 + 1;
   5638             if (childIndex >= heapSize) {
   5639                 break;
   5640             }
   5641 
   5642             if (childIndex + 1 < heapSize
   5643                     && heap[childIndex + 1].distance < heap[childIndex].distance) {
   5644                 childIndex += 1;
   5645             }
   5646 
   5647             if (heap[parentIndex].distance <= heap[childIndex].distance) {
   5648                 break;
   5649             }
   5650 
   5651             swap(heap[parentIndex], heap[childIndex]);
   5652             parentIndex = childIndex;
   5653         }
   5654     }
   5655 
   5656 #if DEBUG_POINTER_ASSIGNMENT
   5657     ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
   5658     for (size_t i = 0; i < heapSize; i++) {
   5659         ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
   5660                 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
   5661                 heap[i].distance);
   5662     }
   5663 #endif
   5664 
   5665     // Pull matches out by increasing order of distance.
   5666     // To avoid reassigning pointers that have already been matched, the loop keeps track
   5667     // of which last and current pointers have been matched using the matchedXXXBits variables.
   5668     // It also tracks the used pointer id bits.
   5669     BitSet32 matchedLastBits(0);
   5670     BitSet32 matchedCurrentBits(0);
   5671     BitSet32 usedIdBits(0);
   5672     bool first = true;
   5673     for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
   5674         while (heapSize > 0) {
   5675             if (first) {
   5676                 // The first time through the loop, we just consume the root element of
   5677                 // the heap (the one with smallest distance).
   5678                 first = false;
   5679             } else {
   5680                 // Previous iterations consumed the root element of the heap.
   5681                 // Pop root element off of the heap (sift down).
   5682                 heap[0] = heap[heapSize];
   5683                 for (uint32_t parentIndex = 0; ;) {
   5684                     uint32_t childIndex = parentIndex * 2 + 1;
   5685                     if (childIndex >= heapSize) {
   5686                         break;
   5687                     }
   5688 
   5689                     if (childIndex + 1 < heapSize
   5690                             && heap[childIndex + 1].distance < heap[childIndex].distance) {
   5691                         childIndex += 1;
   5692                     }
   5693 
   5694                     if (heap[parentIndex].distance <= heap[childIndex].distance) {
   5695                         break;
   5696                     }
   5697 
   5698                     swap(heap[parentIndex], heap[childIndex]);
   5699                     parentIndex = childIndex;
   5700                 }
   5701 
   5702 #if DEBUG_POINTER_ASSIGNMENT
   5703                 ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
   5704                 for (size_t i = 0; i < heapSize; i++) {
   5705                     ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
   5706                             i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
   5707                             heap[i].distance);
   5708                 }
   5709 #endif
   5710             }
   5711 
   5712             heapSize -= 1;
   5713 
   5714             uint32_t currentPointerIndex = heap[0].currentPointerIndex;
   5715             if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
   5716 
   5717             uint32_t lastPointerIndex = heap[0].lastPointerIndex;
   5718             if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
   5719 
   5720             matchedCurrentBits.markBit(currentPointerIndex);
   5721             matchedLastBits.markBit(lastPointerIndex);
   5722 
   5723             uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
   5724             mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
   5725             mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
   5726             mCurrentRawPointerData.markIdBit(id,
   5727                     mCurrentRawPointerData.isHovering(currentPointerIndex));
   5728             usedIdBits.markBit(id);
   5729 
   5730 #if DEBUG_POINTER_ASSIGNMENT
   5731             ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
   5732                     lastPointerIndex, currentPointerIndex, id, heap[0].distance);
   5733 #endif
   5734             break;
   5735         }
   5736     }
   5737 
   5738     // Assign fresh ids to pointers that were not matched in the process.
   5739     for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
   5740         uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
   5741         uint32_t id = usedIdBits.markFirstUnmarkedBit();
   5742 
   5743         mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
   5744         mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
   5745         mCurrentRawPointerData.markIdBit(id,
   5746                 mCurrentRawPointerData.isHovering(currentPointerIndex));
   5747 
   5748 #if DEBUG_POINTER_ASSIGNMENT
   5749         ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
   5750                 currentPointerIndex, id);
   5751 #endif
   5752     }
   5753 }
   5754 
   5755 int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
   5756     if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
   5757         return AKEY_STATE_VIRTUAL;
   5758     }
   5759 
   5760     size_t numVirtualKeys = mVirtualKeys.size();
   5761     for (size_t i = 0; i < numVirtualKeys; i++) {
   5762         const VirtualKey& virtualKey = mVirtualKeys[i];
   5763         if (virtualKey.keyCode == keyCode) {
   5764             return AKEY_STATE_UP;
   5765         }
   5766     }
   5767 
   5768     return AKEY_STATE_UNKNOWN;
   5769 }
   5770 
   5771 int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
   5772     if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
   5773         return AKEY_STATE_VIRTUAL;
   5774     }
   5775 
   5776     size_t numVirtualKeys = mVirtualKeys.size();
   5777     for (size_t i = 0; i < numVirtualKeys; i++) {
   5778         const VirtualKey& virtualKey = mVirtualKeys[i];
   5779         if (virtualKey.scanCode == scanCode) {
   5780             return AKEY_STATE_UP;
   5781         }
   5782     }
   5783 
   5784     return AKEY_STATE_UNKNOWN;
   5785 }
   5786 
   5787 bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
   5788         const int32_t* keyCodes, uint8_t* outFlags) {
   5789     size_t numVirtualKeys = mVirtualKeys.size();
   5790     for (size_t i = 0; i < numVirtualKeys; i++) {
   5791         const VirtualKey& virtualKey = mVirtualKeys[i];
   5792 
   5793         for (size_t i = 0; i < numCodes; i++) {
   5794             if (virtualKey.keyCode == keyCodes[i]) {
   5795                 outFlags[i] = 1;
   5796             }
   5797         }
   5798     }
   5799 
   5800     return true;
   5801 }
   5802 
   5803 
   5804 // --- SingleTouchInputMapper ---
   5805 
   5806 SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
   5807         TouchInputMapper(device) {
   5808 }
   5809 
   5810 SingleTouchInputMapper::~SingleTouchInputMapper() {
   5811 }
   5812 
   5813 void SingleTouchInputMapper::reset(nsecs_t when) {
   5814     mSingleTouchMotionAccumulator.reset(getDevice());
   5815 
   5816     TouchInputMapper::reset(when);
   5817 }
   5818 
   5819 void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
   5820     TouchInputMapper::process(rawEvent);
   5821 
   5822     mSingleTouchMotionAccumulator.process(rawEvent);
   5823 }
   5824 
   5825 void SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
   5826     if (mTouchButtonAccumulator.isToolActive()) {
   5827         mCurrentRawPointerData.pointerCount = 1;
   5828         mCurrentRawPointerData.idToIndex[0] = 0;
   5829 
   5830         bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
   5831                 && (mTouchButtonAccumulator.isHovering()
   5832                         || (mRawPointerAxes.pressure.valid
   5833                                 && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
   5834         mCurrentRawPointerData.markIdBit(0, isHovering);
   5835 
   5836         RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
   5837         outPointer.id = 0;
   5838         outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
   5839         outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
   5840         outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
   5841         outPointer.touchMajor = 0;
   5842         outPointer.touchMinor = 0;
   5843         outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
   5844         outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
   5845         outPointer.orientation = 0;
   5846         outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
   5847         outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
   5848         outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
   5849         outPointer.toolType = mTouchButtonAccumulator.getToolType();
   5850         if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
   5851             outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
   5852         }
   5853         outPointer.isHovering = isHovering;
   5854     }
   5855 }
   5856 
   5857 void SingleTouchInputMapper::configureRawPointerAxes() {
   5858     TouchInputMapper::configureRawPointerAxes();
   5859 
   5860     getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
   5861     getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
   5862     getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
   5863     getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
   5864     getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
   5865     getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
   5866     getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
   5867 }
   5868 
   5869 bool SingleTouchInputMapper::hasStylus() const {
   5870     return mTouchButtonAccumulator.hasStylus();
   5871 }
   5872 
   5873 
   5874 // --- MultiTouchInputMapper ---
   5875 
   5876 MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
   5877         TouchInputMapper(device) {
   5878 }
   5879 
   5880 MultiTouchInputMapper::~MultiTouchInputMapper() {
   5881 }
   5882 
   5883 void MultiTouchInputMapper::reset(nsecs_t when) {
   5884     mMultiTouchMotionAccumulator.reset(getDevice());
   5885 
   5886     mPointerIdBits.clear();
   5887 
   5888     TouchInputMapper::reset(when);
   5889 }
   5890 
   5891 void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
   5892     TouchInputMapper::process(rawEvent);
   5893 
   5894     mMultiTouchMotionAccumulator.process(rawEvent);
   5895 }
   5896 
   5897 void MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
   5898     size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
   5899     size_t outCount = 0;
   5900     BitSet32 newPointerIdBits;
   5901 
   5902     for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
   5903         const MultiTouchMotionAccumulator::Slot* inSlot =
   5904                 mMultiTouchMotionAccumulator.getSlot(inIndex);
   5905         if (!inSlot->isInUse()) {
   5906             continue;
   5907         }
   5908 
   5909         if (outCount >= MAX_POINTERS) {
   5910 #if DEBUG_POINTERS
   5911             ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
   5912                     "ignoring the rest.",
   5913                     getDeviceName().string(), MAX_POINTERS);
   5914 #endif
   5915             break; // too many fingers!
   5916         }
   5917 
   5918         RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
   5919         outPointer.x = inSlot->getX();
   5920         outPointer.y = inSlot->getY();
   5921         outPointer.pressure = inSlot->getPressure();
   5922         outPointer.touchMajor = inSlot->getTouchMajor();
   5923         outPointer.touchMinor = inSlot->getTouchMinor();
   5924         outPointer.toolMajor = inSlot->getToolMajor();
   5925         outPointer.toolMinor = inSlot->getToolMinor();
   5926         outPointer.orientation = inSlot->getOrientation();
   5927         outPointer.distance = inSlot->getDistance();
   5928         outPointer.tiltX = 0;
   5929         outPointer.tiltY = 0;
   5930 
   5931         outPointer.toolType = inSlot->getToolType();
   5932         if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
   5933             outPointer.toolType = mTouchButtonAccumulator.getToolType();
   5934             if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
   5935                 outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
   5936             }
   5937         }
   5938 
   5939         bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
   5940                 && (mTouchButtonAccumulator.isHovering()
   5941                         || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
   5942         outPointer.isHovering = isHovering;
   5943 
   5944         // Assign pointer id using tracking id if available.
   5945         if (*outHavePointerIds) {
   5946             int32_t trackingId = inSlot->getTrackingId();
   5947             int32_t id = -1;
   5948             if (trackingId >= 0) {
   5949                 for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
   5950                     uint32_t n = idBits.clearFirstMarkedBit();
   5951                     if (mPointerTrackingIdMap[n] == trackingId) {
   5952                         id = n;
   5953                     }
   5954                 }
   5955 
   5956                 if (id < 0 && !mPointerIdBits.isFull()) {
   5957                     id = mPointerIdBits.markFirstUnmarkedBit();
   5958                     mPointerTrackingIdMap[id] = trackingId;
   5959                 }
   5960             }
   5961             if (id < 0) {
   5962                 *outHavePointerIds = false;
   5963                 mCurrentRawPointerData.clearIdBits();
   5964                 newPointerIdBits.clear();
   5965             } else {
   5966                 outPointer.id = id;
   5967                 mCurrentRawPointerData.idToIndex[id] = outCount;
   5968                 mCurrentRawPointerData.markIdBit(id, isHovering);
   5969                 newPointerIdBits.markBit(id);
   5970             }
   5971         }
   5972 
   5973         outCount += 1;
   5974     }
   5975 
   5976     mCurrentRawPointerData.pointerCount = outCount;
   5977     mPointerIdBits = newPointerIdBits;
   5978 
   5979     mMultiTouchMotionAccumulator.finishSync();
   5980 }
   5981 
   5982 void MultiTouchInputMapper::configureRawPointerAxes() {
   5983     TouchInputMapper::configureRawPointerAxes();
   5984 
   5985     getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
   5986     getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
   5987     getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
   5988     getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
   5989     getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
   5990     getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
   5991     getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
   5992     getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
   5993     getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
   5994     getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
   5995     getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
   5996 
   5997     if (mRawPointerAxes.trackingId.valid
   5998             && mRawPointerAxes.slot.valid
   5999             && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
   6000         size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
   6001         if (slotCount > MAX_SLOTS) {
   6002             ALOGW("MultiTouch Device %s reported %d slots but the framework "
   6003                     "only supports a maximum of %d slots at this time.",
   6004                     getDeviceName().string(), slotCount, MAX_SLOTS);
   6005             slotCount = MAX_SLOTS;
   6006         }
   6007         mMultiTouchMotionAccumulator.configure(getDevice(),
   6008                 slotCount, true /*usingSlotsProtocol*/);
   6009     } else {
   6010         mMultiTouchMotionAccumulator.configure(getDevice(),
   6011                 MAX_POINTERS, false /*usingSlotsProtocol*/);
   6012     }
   6013 }
   6014 
   6015 bool MultiTouchInputMapper::hasStylus() const {
   6016     return mMultiTouchMotionAccumulator.hasStylus()
   6017             || mTouchButtonAccumulator.hasStylus();
   6018 }
   6019 
   6020 
   6021 // --- JoystickInputMapper ---
   6022 
   6023 JoystickInputMapper::JoystickInputMapper(InputDevice* device) :
   6024         InputMapper(device) {
   6025 }
   6026 
   6027 JoystickInputMapper::~JoystickInputMapper() {
   6028 }
   6029 
   6030 uint32_t JoystickInputMapper::getSources() {
   6031     return AINPUT_SOURCE_JOYSTICK;
   6032 }
   6033 
   6034 void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
   6035     InputMapper::populateDeviceInfo(info);
   6036 
   6037     for (size_t i = 0; i < mAxes.size(); i++) {
   6038         const Axis& axis = mAxes.valueAt(i);
   6039         info->addMotionRange(axis.axisInfo.axis, AINPUT_SOURCE_JOYSTICK,
   6040                 axis.min, axis.max, axis.flat, axis.fuzz);
   6041         if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
   6042             info->addMotionRange(axis.axisInfo.highAxis, AINPUT_SOURCE_JOYSTICK,
   6043                     axis.min, axis.max, axis.flat, axis.fuzz);
   6044         }
   6045     }
   6046 }
   6047 
   6048 void JoystickInputMapper::dump(String8& dump) {
   6049     dump.append(INDENT2 "Joystick Input Mapper:\n");
   6050 
   6051     dump.append(INDENT3 "Axes:\n");
   6052     size_t numAxes = mAxes.size();
   6053     for (size_t i = 0; i < numAxes; i++) {
   6054         const Axis& axis = mAxes.valueAt(i);
   6055         const char* label = getAxisLabel(axis.axisInfo.axis);
   6056         if (label) {
   6057             dump.appendFormat(INDENT4 "%s", label);
   6058         } else {
   6059             dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
   6060         }
   6061         if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
   6062             label = getAxisLabel(axis.axisInfo.highAxis);
   6063             if (label) {
   6064                 dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
   6065             } else {
   6066                 dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
   6067                         axis.axisInfo.splitValue);
   6068             }
   6069         } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
   6070             dump.append(" (invert)");
   6071         }
   6072 
   6073         dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f\n",
   6074                 axis.min, axis.max, axis.flat, axis.fuzz);
   6075         dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
   6076                 "highScale=%0.5f, highOffset=%0.5f\n",
   6077                 axis.scale, axis.offset, axis.highScale, axis.highOffset);
   6078         dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, "
   6079                 "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
   6080                 mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
   6081                 axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
   6082     }
   6083 }
   6084 
   6085 void JoystickInputMapper::configure(nsecs_t when,
   6086         const InputReaderConfiguration* config, uint32_t changes) {
   6087     InputMapper::configure(when, config, changes);
   6088 
   6089     if (!changes) { // first time only
   6090         // Collect all axes.
   6091         for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
   6092             if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
   6093                     & INPUT_DEVICE_CLASS_JOYSTICK)) {
   6094                 continue; // axis must be claimed by a different device
   6095             }
   6096 
   6097             RawAbsoluteAxisInfo rawAxisInfo;
   6098             getAbsoluteAxisInfo(abs, &rawAxisInfo);
   6099             if (rawAxisInfo.valid) {
   6100                 // Map axis.
   6101                 AxisInfo axisInfo;
   6102                 bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
   6103                 if (!explicitlyMapped) {
   6104                     // Axis is not explicitly mapped, will choose a generic axis later.
   6105                     axisInfo.mode = AxisInfo::MODE_NORMAL;
   6106                     axisInfo.axis = -1;
   6107                 }
   6108 
   6109                 // Apply flat override.
   6110                 int32_t rawFlat = axisInfo.flatOverride < 0
   6111                         ? rawAxisInfo.flat : axisInfo.flatOverride;
   6112 
   6113                 // Calculate scaling factors and limits.
   6114                 Axis axis;
   6115                 if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
   6116                     float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
   6117                     float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
   6118                     axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
   6119                             scale, 0.0f, highScale, 0.0f,
   6120                             0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
   6121                 } else if (isCenteredAxis(axisInfo.axis)) {
   6122                     float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
   6123                     float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
   6124                     axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
   6125                             scale, offset, scale, offset,
   6126                             -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
   6127                 } else {
   6128                     float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
   6129                     axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
   6130                             scale, 0.0f, scale, 0.0f,
   6131                             0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
   6132                 }
   6133 
   6134                 // To eliminate noise while the joystick is at rest, filter out small variations
   6135                 // in axis values up front.
   6136                 axis.filter = axis.flat * 0.25f;
   6137 
   6138                 mAxes.add(abs, axis);
   6139             }
   6140         }
   6141 
   6142         // If there are too many axes, start dropping them.
   6143         // Prefer to keep explicitly mapped axes.
   6144         if (mAxes.size() > PointerCoords::MAX_AXES) {
   6145             ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
   6146                     getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
   6147             pruneAxes(true);
   6148             pruneAxes(false);
   6149         }
   6150 
   6151         // Assign generic axis ids to remaining axes.
   6152         int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
   6153         size_t numAxes = mAxes.size();
   6154         for (size_t i = 0; i < numAxes; i++) {
   6155             Axis& axis = mAxes.editValueAt(i);
   6156             if (axis.axisInfo.axis < 0) {
   6157                 while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
   6158                         && haveAxis(nextGenericAxisId)) {
   6159                     nextGenericAxisId += 1;
   6160                 }
   6161 
   6162                 if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
   6163                     axis.axisInfo.axis = nextGenericAxisId;
   6164                     nextGenericAxisId += 1;
   6165                 } else {
   6166                     ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
   6167                             "have already been assigned to other axes.",
   6168                             getDeviceName().string(), mAxes.keyAt(i));
   6169                     mAxes.removeItemsAt(i--);
   6170                     numAxes -= 1;
   6171                 }
   6172             }
   6173         }
   6174     }
   6175 }
   6176 
   6177 bool JoystickInputMapper::haveAxis(int32_t axisId) {
   6178     size_t numAxes = mAxes.size();
   6179     for (size_t i = 0; i < numAxes; i++) {
   6180         const Axis& axis = mAxes.valueAt(i);
   6181         if (axis.axisInfo.axis == axisId
   6182                 || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
   6183                         && axis.axisInfo.highAxis == axisId)) {
   6184             return true;
   6185         }
   6186     }
   6187     return false;
   6188 }
   6189 
   6190 void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
   6191     size_t i = mAxes.size();
   6192     while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
   6193         if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
   6194             continue;
   6195         }
   6196         ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
   6197                 getDeviceName().string(), mAxes.keyAt(i));
   6198         mAxes.removeItemsAt(i);
   6199     }
   6200 }
   6201 
   6202 bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
   6203     switch (axis) {
   6204     case AMOTION_EVENT_AXIS_X:
   6205     case AMOTION_EVENT_AXIS_Y:
   6206     case AMOTION_EVENT_AXIS_Z:
   6207     case AMOTION_EVENT_AXIS_RX:
   6208     case AMOTION_EVENT_AXIS_RY:
   6209     case AMOTION_EVENT_AXIS_RZ:
   6210     case AMOTION_EVENT_AXIS_HAT_X:
   6211     case AMOTION_EVENT_AXIS_HAT_Y:
   6212     case AMOTION_EVENT_AXIS_ORIENTATION:
   6213     case AMOTION_EVENT_AXIS_RUDDER:
   6214     case AMOTION_EVENT_AXIS_WHEEL:
   6215         return true;
   6216     default:
   6217         return false;
   6218     }
   6219 }
   6220 
   6221 void JoystickInputMapper::reset(nsecs_t when) {
   6222     // Recenter all axes.
   6223     size_t numAxes = mAxes.size();
   6224     for (size_t i = 0; i < numAxes; i++) {
   6225         Axis& axis = mAxes.editValueAt(i);
   6226         axis.resetValue();
   6227     }
   6228 
   6229     InputMapper::reset(when);
   6230 }
   6231 
   6232 void JoystickInputMapper::process(const RawEvent* rawEvent) {
   6233     switch (rawEvent->type) {
   6234     case EV_ABS: {
   6235         ssize_t index = mAxes.indexOfKey(rawEvent->code);
   6236         if (index >= 0) {
   6237             Axis& axis = mAxes.editValueAt(index);
   6238             float newValue, highNewValue;
   6239             switch (axis.axisInfo.mode) {
   6240             case AxisInfo::MODE_INVERT:
   6241                 newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
   6242                         * axis.scale + axis.offset;
   6243                 highNewValue = 0.0f;
   6244                 break;
   6245             case AxisInfo::MODE_SPLIT:
   6246                 if (rawEvent->value < axis.axisInfo.splitValue) {
   6247                     newValue = (axis.axisInfo.splitValue - rawEvent->value)
   6248                             * axis.scale + axis.offset;
   6249                     highNewValue = 0.0f;
   6250                 } else if (rawEvent->value > axis.axisInfo.splitValue) {
   6251                     newValue = 0.0f;
   6252                     highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
   6253                             * axis.highScale + axis.highOffset;
   6254                 } else {
   6255                     newValue = 0.0f;
   6256                     highNewValue = 0.0f;
   6257                 }
   6258                 break;
   6259             default:
   6260                 newValue = rawEvent->value * axis.scale + axis.offset;
   6261                 highNewValue = 0.0f;
   6262                 break;
   6263             }
   6264             axis.newValue = newValue;
   6265             axis.highNewValue = highNewValue;
   6266         }
   6267         break;
   6268     }
   6269 
   6270     case EV_SYN:
   6271         switch (rawEvent->code) {
   6272         case SYN_REPORT:
   6273             sync(rawEvent->when, false /*force*/);
   6274             break;
   6275         }
   6276         break;
   6277     }
   6278 }
   6279 
   6280 void JoystickInputMapper::sync(nsecs_t when, bool force) {
   6281     if (!filterAxes(force)) {
   6282         return;
   6283     }
   6284 
   6285     int32_t metaState = mContext->getGlobalMetaState();
   6286     int32_t buttonState = 0;
   6287 
   6288     PointerProperties pointerProperties;
   6289     pointerProperties.clear();
   6290     pointerProperties.id = 0;
   6291     pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
   6292 
   6293     PointerCoords pointerCoords;
   6294     pointerCoords.clear();
   6295 
   6296     size_t numAxes = mAxes.size();
   6297     for (size_t i = 0; i < numAxes; i++) {
   6298         const Axis& axis = mAxes.valueAt(i);
   6299         pointerCoords.setAxisValue(axis.axisInfo.axis, axis.currentValue);
   6300         if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
   6301             pointerCoords.setAxisValue(axis.axisInfo.highAxis, axis.highCurrentValue);
   6302         }
   6303     }
   6304 
   6305     // Moving a joystick axis should not wake the device because joysticks can
   6306     // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
   6307     // button will likely wake the device.
   6308     // TODO: Use the input device configuration to control this behavior more finely.
   6309     uint32_t policyFlags = 0;
   6310 
   6311     NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
   6312             AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
   6313             ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
   6314     getListener()->notifyMotion(&args);
   6315 }
   6316 
   6317 bool JoystickInputMapper::filterAxes(bool force) {
   6318     bool atLeastOneSignificantChange = force;
   6319     size_t numAxes = mAxes.size();
   6320     for (size_t i = 0; i < numAxes; i++) {
   6321         Axis& axis = mAxes.editValueAt(i);
   6322         if (force || hasValueChangedSignificantly(axis.filter,
   6323                 axis.newValue, axis.currentValue, axis.min, axis.max)) {
   6324             axis.currentValue = axis.newValue;
   6325             atLeastOneSignificantChange = true;
   6326         }
   6327         if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
   6328             if (force || hasValueChangedSignificantly(axis.filter,
   6329                     axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
   6330                 axis.highCurrentValue = axis.highNewValue;
   6331                 atLeastOneSignificantChange = true;
   6332             }
   6333         }
   6334     }
   6335     return atLeastOneSignificantChange;
   6336 }
   6337 
   6338 bool JoystickInputMapper::hasValueChangedSignificantly(
   6339         float filter, float newValue, float currentValue, float min, float max) {
   6340     if (newValue != currentValue) {
   6341         // Filter out small changes in value unless the value is converging on the axis
   6342         // bounds or center point.  This is intended to reduce the amount of information
   6343         // sent to applications by particularly noisy joysticks (such as PS3).
   6344         if (fabs(newValue - currentValue) > filter
   6345                 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
   6346                 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
   6347                 || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
   6348             return true;
   6349         }
   6350     }
   6351     return false;
   6352 }
   6353 
   6354 bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
   6355         float filter, float newValue, float currentValue, float thresholdValue) {
   6356     float newDistance = fabs(newValue - thresholdValue);
   6357     if (newDistance < filter) {
   6358         float oldDistance = fabs(currentValue - thresholdValue);
   6359         if (newDistance < oldDistance) {
   6360             return true;
   6361         }
   6362     }
   6363     return false;
   6364 }
   6365 
   6366 } // namespace android
   6367