PageRenderTime 559ms CodeModel.GetById 18ms app.highlight 495ms RepoModel.GetById 2ms app.codeStats 2ms

/services/input/InputReader.cpp

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