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