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