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