OSDN Git Service

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