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