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