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