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