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