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