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