• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2010 The Android Open Source Project
3 //
4 // The input reader.
5 //
6 #define LOG_TAG "InputReader"
7 
8 //#define LOG_NDEBUG 0
9 
10 // Log debug messages for each raw event received from the EventHub.
11 #define DEBUG_RAW_EVENTS 0
12 
13 // Log debug messages about touch screen filtering hacks.
14 #define DEBUG_HACKS 0
15 
16 // Log debug messages about virtual key processing.
17 #define DEBUG_VIRTUAL_KEYS 0
18 
19 // Log debug messages about pointers.
20 #define DEBUG_POINTERS 0
21 
22 // Log debug messages about pointer assignment calculations.
23 #define DEBUG_POINTER_ASSIGNMENT 0
24 
25 #include <cutils/log.h>
26 #include <ui/InputReader.h>
27 
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <limits.h>
33 #include <math.h>
34 
35 #define INDENT "  "
36 #define INDENT2 "    "
37 #define INDENT3 "      "
38 #define INDENT4 "        "
39 
40 namespace android {
41 
42 // --- Static Functions ---
43 
44 template<typename T>
abs(const T & value)45 inline static T abs(const T& value) {
46     return value < 0 ? - value : value;
47 }
48 
49 template<typename T>
min(const T & a,const T & b)50 inline static T min(const T& a, const T& b) {
51     return a < b ? a : b;
52 }
53 
54 template<typename T>
swap(T & a,T & b)55 inline static void swap(T& a, T& b) {
56     T temp = a;
57     a = b;
58     b = temp;
59 }
60 
avg(float x,float y)61 inline static float avg(float x, float y) {
62     return (x + y) / 2;
63 }
64 
pythag(float x,float y)65 inline static float pythag(float x, float y) {
66     return sqrtf(x * x + y * y);
67 }
68 
toString(bool value)69 static inline const char* toString(bool value) {
70     return value ? "true" : "false";
71 }
72 
73 
updateMetaState(int32_t keyCode,bool down,int32_t oldMetaState)74 int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
75     int32_t mask;
76     switch (keyCode) {
77     case AKEYCODE_ALT_LEFT:
78         mask = AMETA_ALT_LEFT_ON;
79         break;
80     case AKEYCODE_ALT_RIGHT:
81         mask = AMETA_ALT_RIGHT_ON;
82         break;
83     case AKEYCODE_SHIFT_LEFT:
84         mask = AMETA_SHIFT_LEFT_ON;
85         break;
86     case AKEYCODE_SHIFT_RIGHT:
87         mask = AMETA_SHIFT_RIGHT_ON;
88         break;
89     case AKEYCODE_SYM:
90         mask = AMETA_SYM_ON;
91         break;
92     default:
93         return oldMetaState;
94     }
95 
96     int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask
97             & ~ (AMETA_ALT_ON | AMETA_SHIFT_ON);
98 
99     if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
100         newMetaState |= AMETA_ALT_ON;
101     }
102 
103     if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
104         newMetaState |= AMETA_SHIFT_ON;
105     }
106 
107     return newMetaState;
108 }
109 
110 static const int32_t keyCodeRotationMap[][4] = {
111         // key codes enumerated counter-clockwise with the original (unrotated) key first
112         // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
113         { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
114         { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
115         { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
116         { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
117 };
118 static const int keyCodeRotationMapSize =
119         sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
120 
rotateKeyCode(int32_t keyCode,int32_t orientation)121 int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
122     if (orientation != InputReaderPolicyInterface::ROTATION_0) {
123         for (int i = 0; i < keyCodeRotationMapSize; i++) {
124             if (keyCode == keyCodeRotationMap[i][0]) {
125                 return keyCodeRotationMap[i][orientation];
126             }
127         }
128     }
129     return keyCode;
130 }
131 
sourcesMatchMask(uint32_t sources,uint32_t sourceMask)132 static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
133     return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
134 }
135 
136 
137 // --- InputDeviceCalibration ---
138 
InputDeviceCalibration()139 InputDeviceCalibration::InputDeviceCalibration() {
140 }
141 
clear()142 void InputDeviceCalibration::clear() {
143     mProperties.clear();
144 }
145 
addProperty(const String8 & key,const String8 & value)146 void InputDeviceCalibration::addProperty(const String8& key, const String8& value) {
147     mProperties.add(key, value);
148 }
149 
tryGetProperty(const String8 & key,String8 & outValue) const150 bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const {
151     ssize_t index = mProperties.indexOfKey(key);
152     if (index < 0) {
153         return false;
154     }
155 
156     outValue = mProperties.valueAt(index);
157     return true;
158 }
159 
tryGetProperty(const String8 & key,int32_t & outValue) const160 bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const {
161     String8 stringValue;
162     if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
163         return false;
164     }
165 
166     char* end;
167     int value = strtol(stringValue.string(), & end, 10);
168     if (*end != '\0') {
169         LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected an integer.",
170                 key.string(), stringValue.string());
171         return false;
172     }
173     outValue = value;
174     return true;
175 }
176 
tryGetProperty(const String8 & key,float & outValue) const177 bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const {
178     String8 stringValue;
179     if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
180         return false;
181     }
182 
183     char* end;
184     float value = strtof(stringValue.string(), & end);
185     if (*end != '\0') {
186         LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected a float.",
187                 key.string(), stringValue.string());
188         return false;
189     }
190     outValue = value;
191     return true;
192 }
193 
194 
195 // --- InputReader ---
196 
InputReader(const sp<EventHubInterface> & eventHub,const sp<InputReaderPolicyInterface> & policy,const sp<InputDispatcherInterface> & dispatcher)197 InputReader::InputReader(const sp<EventHubInterface>& eventHub,
198         const sp<InputReaderPolicyInterface>& policy,
199         const sp<InputDispatcherInterface>& dispatcher) :
200         mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
201         mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
202     configureExcludedDevices();
203     updateGlobalMetaState();
204     updateInputConfiguration();
205 }
206 
~InputReader()207 InputReader::~InputReader() {
208     for (size_t i = 0; i < mDevices.size(); i++) {
209         delete mDevices.valueAt(i);
210     }
211 }
212 
loopOnce()213 void InputReader::loopOnce() {
214     RawEvent rawEvent;
215     mEventHub->getEvent(& rawEvent);
216 
217 #if DEBUG_RAW_EVENTS
218     LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d",
219             rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
220             rawEvent.value);
221 #endif
222 
223     process(& rawEvent);
224 }
225 
process(const RawEvent * rawEvent)226 void InputReader::process(const RawEvent* rawEvent) {
227     switch (rawEvent->type) {
228     case EventHubInterface::DEVICE_ADDED:
229         addDevice(rawEvent->deviceId);
230         break;
231 
232     case EventHubInterface::DEVICE_REMOVED:
233         removeDevice(rawEvent->deviceId);
234         break;
235 
236     case EventHubInterface::FINISHED_DEVICE_SCAN:
237         handleConfigurationChanged(rawEvent->when);
238         break;
239 
240     default:
241         consumeEvent(rawEvent);
242         break;
243     }
244 }
245 
addDevice(int32_t deviceId)246 void InputReader::addDevice(int32_t deviceId) {
247     String8 name = mEventHub->getDeviceName(deviceId);
248     uint32_t classes = mEventHub->getDeviceClasses(deviceId);
249 
250     InputDevice* device = createDevice(deviceId, name, classes);
251     device->configure();
252 
253     if (device->isIgnored()) {
254         LOGI("Device added: id=0x%x, name=%s (ignored non-input device)", deviceId, name.string());
255     } else {
256         LOGI("Device added: id=0x%x, name=%s, sources=%08x", deviceId, name.string(),
257                 device->getSources());
258     }
259 
260     bool added = false;
261     { // acquire device registry writer lock
262         RWLock::AutoWLock _wl(mDeviceRegistryLock);
263 
264         ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
265         if (deviceIndex < 0) {
266             mDevices.add(deviceId, device);
267             added = true;
268         }
269     } // release device registry writer lock
270 
271     if (! added) {
272         LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
273         delete device;
274         return;
275     }
276 }
277 
removeDevice(int32_t deviceId)278 void InputReader::removeDevice(int32_t deviceId) {
279     bool removed = false;
280     InputDevice* device = NULL;
281     { // acquire device registry writer lock
282         RWLock::AutoWLock _wl(mDeviceRegistryLock);
283 
284         ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
285         if (deviceIndex >= 0) {
286             device = mDevices.valueAt(deviceIndex);
287             mDevices.removeItemsAt(deviceIndex, 1);
288             removed = true;
289         }
290     } // release device registry writer lock
291 
292     if (! removed) {
293         LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
294         return;
295     }
296 
297     if (device->isIgnored()) {
298         LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)",
299                 device->getId(), device->getName().string());
300     } else {
301         LOGI("Device removed: id=0x%x, name=%s, sources=%08x",
302                 device->getId(), device->getName().string(), device->getSources());
303     }
304 
305     device->reset();
306 
307     delete device;
308 }
309 
createDevice(int32_t deviceId,const String8 & name,uint32_t classes)310 InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
311     InputDevice* device = new InputDevice(this, deviceId, name);
312 
313     const int32_t associatedDisplayId = 0; // FIXME: hardcoded for current single-display devices
314 
315     // Switch-like devices.
316     if (classes & INPUT_DEVICE_CLASS_SWITCH) {
317         device->addMapper(new SwitchInputMapper(device));
318     }
319 
320     // Keyboard-like devices.
321     uint32_t keyboardSources = 0;
322     int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
323     if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
324         keyboardSources |= AINPUT_SOURCE_KEYBOARD;
325     }
326     if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
327         keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
328     }
329     if (classes & INPUT_DEVICE_CLASS_DPAD) {
330         keyboardSources |= AINPUT_SOURCE_DPAD;
331     }
332 
333     if (keyboardSources != 0) {
334         device->addMapper(new KeyboardInputMapper(device,
335                 associatedDisplayId, keyboardSources, keyboardType));
336     }
337 
338     // Trackball-like devices.
339     if (classes & INPUT_DEVICE_CLASS_TRACKBALL) {
340         device->addMapper(new TrackballInputMapper(device, associatedDisplayId));
341     }
342 
343     // Touchscreen-like devices.
344     if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT) {
345         device->addMapper(new MultiTouchInputMapper(device, associatedDisplayId));
346     } else if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN) {
347         device->addMapper(new SingleTouchInputMapper(device, associatedDisplayId));
348     }
349 
350     return device;
351 }
352 
consumeEvent(const RawEvent * rawEvent)353 void InputReader::consumeEvent(const RawEvent* rawEvent) {
354     int32_t deviceId = rawEvent->deviceId;
355 
356     { // acquire device registry reader lock
357         RWLock::AutoRLock _rl(mDeviceRegistryLock);
358 
359         ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
360         if (deviceIndex < 0) {
361             LOGW("Discarding event for unknown deviceId %d.", deviceId);
362             return;
363         }
364 
365         InputDevice* device = mDevices.valueAt(deviceIndex);
366         if (device->isIgnored()) {
367             //LOGD("Discarding event for ignored deviceId %d.", deviceId);
368             return;
369         }
370 
371         device->process(rawEvent);
372     } // release device registry reader lock
373 }
374 
handleConfigurationChanged(nsecs_t when)375 void InputReader::handleConfigurationChanged(nsecs_t when) {
376     // Reset global meta state because it depends on the list of all configured devices.
377     updateGlobalMetaState();
378 
379     // Update input configuration.
380     updateInputConfiguration();
381 
382     // Enqueue configuration changed.
383     mDispatcher->notifyConfigurationChanged(when);
384 }
385 
configureExcludedDevices()386 void InputReader::configureExcludedDevices() {
387     Vector<String8> excludedDeviceNames;
388     mPolicy->getExcludedDeviceNames(excludedDeviceNames);
389 
390     for (size_t i = 0; i < excludedDeviceNames.size(); i++) {
391         mEventHub->addExcludedDevice(excludedDeviceNames[i]);
392     }
393 }
394 
updateGlobalMetaState()395 void InputReader::updateGlobalMetaState() {
396     { // acquire state lock
397         AutoMutex _l(mStateLock);
398 
399         mGlobalMetaState = 0;
400 
401         { // acquire device registry reader lock
402             RWLock::AutoRLock _rl(mDeviceRegistryLock);
403 
404             for (size_t i = 0; i < mDevices.size(); i++) {
405                 InputDevice* device = mDevices.valueAt(i);
406                 mGlobalMetaState |= device->getMetaState();
407             }
408         } // release device registry reader lock
409     } // release state lock
410 }
411 
getGlobalMetaState()412 int32_t InputReader::getGlobalMetaState() {
413     { // acquire state lock
414         AutoMutex _l(mStateLock);
415 
416         return mGlobalMetaState;
417     } // release state lock
418 }
419 
updateInputConfiguration()420 void InputReader::updateInputConfiguration() {
421     { // acquire state lock
422         AutoMutex _l(mStateLock);
423 
424         int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
425         int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
426         int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
427         { // acquire device registry reader lock
428             RWLock::AutoRLock _rl(mDeviceRegistryLock);
429 
430             InputDeviceInfo deviceInfo;
431             for (size_t i = 0; i < mDevices.size(); i++) {
432                 InputDevice* device = mDevices.valueAt(i);
433                 device->getDeviceInfo(& deviceInfo);
434                 uint32_t sources = deviceInfo.getSources();
435 
436                 if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
437                     touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
438                 }
439                 if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
440                     navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
441                 } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
442                     navigationConfig = InputConfiguration::NAVIGATION_DPAD;
443                 }
444                 if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
445                     keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
446                 }
447             }
448         } // release device registry reader lock
449 
450         mInputConfiguration.touchScreen = touchScreenConfig;
451         mInputConfiguration.keyboard = keyboardConfig;
452         mInputConfiguration.navigation = navigationConfig;
453     } // release state lock
454 }
455 
disableVirtualKeysUntil(nsecs_t time)456 void InputReader::disableVirtualKeysUntil(nsecs_t time) {
457     mDisableVirtualKeysTimeout = time;
458 }
459 
shouldDropVirtualKey(nsecs_t now,InputDevice * device,int32_t keyCode,int32_t scanCode)460 bool InputReader::shouldDropVirtualKey(nsecs_t now,
461         InputDevice* device, int32_t keyCode, int32_t scanCode) {
462     if (now < mDisableVirtualKeysTimeout) {
463         LOGI("Dropping virtual key from device %s because virtual keys are "
464                 "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
465                 device->getName().string(),
466                 (mDisableVirtualKeysTimeout - now) * 0.000001,
467                 keyCode, scanCode);
468         return true;
469     } else {
470         return false;
471     }
472 }
473 
getInputConfiguration(InputConfiguration * outConfiguration)474 void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
475     { // acquire state lock
476         AutoMutex _l(mStateLock);
477 
478         *outConfiguration = mInputConfiguration;
479     } // release state lock
480 }
481 
getInputDeviceInfo(int32_t deviceId,InputDeviceInfo * outDeviceInfo)482 status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
483     { // acquire device registry reader lock
484         RWLock::AutoRLock _rl(mDeviceRegistryLock);
485 
486         ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
487         if (deviceIndex < 0) {
488             return NAME_NOT_FOUND;
489         }
490 
491         InputDevice* device = mDevices.valueAt(deviceIndex);
492         if (device->isIgnored()) {
493             return NAME_NOT_FOUND;
494         }
495 
496         device->getDeviceInfo(outDeviceInfo);
497         return OK;
498     } // release device registy reader lock
499 }
500 
getInputDeviceIds(Vector<int32_t> & outDeviceIds)501 void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
502     outDeviceIds.clear();
503 
504     { // acquire device registry reader lock
505         RWLock::AutoRLock _rl(mDeviceRegistryLock);
506 
507         size_t numDevices = mDevices.size();
508         for (size_t i = 0; i < numDevices; i++) {
509             InputDevice* device = mDevices.valueAt(i);
510             if (! device->isIgnored()) {
511                 outDeviceIds.add(device->getId());
512             }
513         }
514     } // release device registy reader lock
515 }
516 
getKeyCodeState(int32_t deviceId,uint32_t sourceMask,int32_t keyCode)517 int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
518         int32_t keyCode) {
519     return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState);
520 }
521 
getScanCodeState(int32_t deviceId,uint32_t sourceMask,int32_t scanCode)522 int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
523         int32_t scanCode) {
524     return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState);
525 }
526 
getSwitchState(int32_t deviceId,uint32_t sourceMask,int32_t switchCode)527 int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
528     return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState);
529 }
530 
getState(int32_t deviceId,uint32_t sourceMask,int32_t code,GetStateFunc getStateFunc)531 int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
532         GetStateFunc getStateFunc) {
533     { // acquire device registry reader lock
534         RWLock::AutoRLock _rl(mDeviceRegistryLock);
535 
536         int32_t result = AKEY_STATE_UNKNOWN;
537         if (deviceId >= 0) {
538             ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
539             if (deviceIndex >= 0) {
540                 InputDevice* device = mDevices.valueAt(deviceIndex);
541                 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
542                     result = (device->*getStateFunc)(sourceMask, code);
543                 }
544             }
545         } else {
546             size_t numDevices = mDevices.size();
547             for (size_t i = 0; i < numDevices; i++) {
548                 InputDevice* device = mDevices.valueAt(i);
549                 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
550                     result = (device->*getStateFunc)(sourceMask, code);
551                     if (result >= AKEY_STATE_DOWN) {
552                         return result;
553                     }
554                 }
555             }
556         }
557         return result;
558     } // release device registy reader lock
559 }
560 
hasKeys(int32_t deviceId,uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)561 bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
562         size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
563     memset(outFlags, 0, numCodes);
564     return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags);
565 }
566 
markSupportedKeyCodes(int32_t deviceId,uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)567 bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
568         const int32_t* keyCodes, uint8_t* outFlags) {
569     { // acquire device registry reader lock
570         RWLock::AutoRLock _rl(mDeviceRegistryLock);
571         bool result = false;
572         if (deviceId >= 0) {
573             ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
574             if (deviceIndex >= 0) {
575                 InputDevice* device = mDevices.valueAt(deviceIndex);
576                 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
577                     result = device->markSupportedKeyCodes(sourceMask,
578                             numCodes, keyCodes, outFlags);
579                 }
580             }
581         } else {
582             size_t numDevices = mDevices.size();
583             for (size_t i = 0; i < numDevices; i++) {
584                 InputDevice* device = mDevices.valueAt(i);
585                 if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
586                     result |= device->markSupportedKeyCodes(sourceMask,
587                             numCodes, keyCodes, outFlags);
588                 }
589             }
590         }
591         return result;
592     } // release device registy reader lock
593 }
594 
dump(String8 & dump)595 void InputReader::dump(String8& dump) {
596     mEventHub->dump(dump);
597     dump.append("\n");
598 
599     dump.append("Input Reader State:\n");
600 
601     { // acquire device registry reader lock
602         RWLock::AutoRLock _rl(mDeviceRegistryLock);
603 
604         for (size_t i = 0; i < mDevices.size(); i++) {
605             mDevices.valueAt(i)->dump(dump);
606         }
607     } // release device registy reader lock
608 }
609 
610 
611 // --- InputReaderThread ---
612 
InputReaderThread(const sp<InputReaderInterface> & reader)613 InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
614         Thread(/*canCallJava*/ true), mReader(reader) {
615 }
616 
~InputReaderThread()617 InputReaderThread::~InputReaderThread() {
618 }
619 
threadLoop()620 bool InputReaderThread::threadLoop() {
621     mReader->loopOnce();
622     return true;
623 }
624 
625 
626 // --- InputDevice ---
627 
InputDevice(InputReaderContext * context,int32_t id,const String8 & name)628 InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) :
629         mContext(context), mId(id), mName(name), mSources(0) {
630 }
631 
~InputDevice()632 InputDevice::~InputDevice() {
633     size_t numMappers = mMappers.size();
634     for (size_t i = 0; i < numMappers; i++) {
635         delete mMappers[i];
636     }
637     mMappers.clear();
638 }
639 
dumpMotionRange(String8 & dump,const InputDeviceInfo & deviceInfo,int32_t rangeType,const char * name)640 static void dumpMotionRange(String8& dump, const InputDeviceInfo& deviceInfo,
641         int32_t rangeType, const char* name) {
642     const InputDeviceInfo::MotionRange* range = deviceInfo.getMotionRange(rangeType);
643     if (range) {
644         dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
645                 name, range->min, range->max, range->flat, range->fuzz);
646     }
647 }
648 
dump(String8 & dump)649 void InputDevice::dump(String8& dump) {
650     InputDeviceInfo deviceInfo;
651     getDeviceInfo(& deviceInfo);
652 
653     dump.appendFormat(INDENT "Device 0x%x: %s\n", deviceInfo.getId(),
654             deviceInfo.getName().string());
655     dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
656     dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
657     if (!deviceInfo.getMotionRanges().isEmpty()) {
658         dump.append(INDENT2 "Motion Ranges:\n");
659         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_X, "X");
660         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_Y, "Y");
661         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_PRESSURE, "Pressure");
662         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_SIZE, "Size");
663         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MAJOR, "TouchMajor");
664         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MINOR, "TouchMinor");
665         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MAJOR, "ToolMajor");
666         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MINOR, "ToolMinor");
667         dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_ORIENTATION, "Orientation");
668     }
669 
670     size_t numMappers = mMappers.size();
671     for (size_t i = 0; i < numMappers; i++) {
672         InputMapper* mapper = mMappers[i];
673         mapper->dump(dump);
674     }
675 }
676 
addMapper(InputMapper * mapper)677 void InputDevice::addMapper(InputMapper* mapper) {
678     mMappers.add(mapper);
679 }
680 
configure()681 void InputDevice::configure() {
682     if (! isIgnored()) {
683         mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration);
684     }
685 
686     mSources = 0;
687 
688     size_t numMappers = mMappers.size();
689     for (size_t i = 0; i < numMappers; i++) {
690         InputMapper* mapper = mMappers[i];
691         mapper->configure();
692         mSources |= mapper->getSources();
693     }
694 }
695 
reset()696 void InputDevice::reset() {
697     size_t numMappers = mMappers.size();
698     for (size_t i = 0; i < numMappers; i++) {
699         InputMapper* mapper = mMappers[i];
700         mapper->reset();
701     }
702 }
703 
process(const RawEvent * rawEvent)704 void InputDevice::process(const RawEvent* rawEvent) {
705     size_t numMappers = mMappers.size();
706     for (size_t i = 0; i < numMappers; i++) {
707         InputMapper* mapper = mMappers[i];
708         mapper->process(rawEvent);
709     }
710 }
711 
getDeviceInfo(InputDeviceInfo * outDeviceInfo)712 void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
713     outDeviceInfo->initialize(mId, mName);
714 
715     size_t numMappers = mMappers.size();
716     for (size_t i = 0; i < numMappers; i++) {
717         InputMapper* mapper = mMappers[i];
718         mapper->populateDeviceInfo(outDeviceInfo);
719     }
720 }
721 
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)722 int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
723     return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
724 }
725 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)726 int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
727     return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
728 }
729 
getSwitchState(uint32_t sourceMask,int32_t switchCode)730 int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
731     return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
732 }
733 
getState(uint32_t sourceMask,int32_t code,GetStateFunc getStateFunc)734 int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
735     int32_t result = AKEY_STATE_UNKNOWN;
736     size_t numMappers = mMappers.size();
737     for (size_t i = 0; i < numMappers; i++) {
738         InputMapper* mapper = mMappers[i];
739         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
740             result = (mapper->*getStateFunc)(sourceMask, code);
741             if (result >= AKEY_STATE_DOWN) {
742                 return result;
743             }
744         }
745     }
746     return result;
747 }
748 
markSupportedKeyCodes(uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)749 bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
750         const int32_t* keyCodes, uint8_t* outFlags) {
751     bool result = false;
752     size_t numMappers = mMappers.size();
753     for (size_t i = 0; i < numMappers; i++) {
754         InputMapper* mapper = mMappers[i];
755         if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
756             result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
757         }
758     }
759     return result;
760 }
761 
getMetaState()762 int32_t InputDevice::getMetaState() {
763     int32_t result = 0;
764     size_t numMappers = mMappers.size();
765     for (size_t i = 0; i < numMappers; i++) {
766         InputMapper* mapper = mMappers[i];
767         result |= mapper->getMetaState();
768     }
769     return result;
770 }
771 
772 
773 // --- InputMapper ---
774 
InputMapper(InputDevice * device)775 InputMapper::InputMapper(InputDevice* device) :
776         mDevice(device), mContext(device->getContext()) {
777 }
778 
~InputMapper()779 InputMapper::~InputMapper() {
780 }
781 
populateDeviceInfo(InputDeviceInfo * info)782 void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
783     info->addSource(getSources());
784 }
785 
dump(String8 & dump)786 void InputMapper::dump(String8& dump) {
787 }
788 
configure()789 void InputMapper::configure() {
790 }
791 
reset()792 void InputMapper::reset() {
793 }
794 
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)795 int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
796     return AKEY_STATE_UNKNOWN;
797 }
798 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)799 int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
800     return AKEY_STATE_UNKNOWN;
801 }
802 
getSwitchState(uint32_t sourceMask,int32_t switchCode)803 int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
804     return AKEY_STATE_UNKNOWN;
805 }
806 
markSupportedKeyCodes(uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)807 bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
808         const int32_t* keyCodes, uint8_t* outFlags) {
809     return false;
810 }
811 
getMetaState()812 int32_t InputMapper::getMetaState() {
813     return 0;
814 }
815 
816 
817 // --- SwitchInputMapper ---
818 
SwitchInputMapper(InputDevice * device)819 SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
820         InputMapper(device) {
821 }
822 
~SwitchInputMapper()823 SwitchInputMapper::~SwitchInputMapper() {
824 }
825 
getSources()826 uint32_t SwitchInputMapper::getSources() {
827     return 0;
828 }
829 
process(const RawEvent * rawEvent)830 void SwitchInputMapper::process(const RawEvent* rawEvent) {
831     switch (rawEvent->type) {
832     case EV_SW:
833         processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value);
834         break;
835     }
836 }
837 
processSwitch(nsecs_t when,int32_t switchCode,int32_t switchValue)838 void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
839     getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
840 }
841 
getSwitchState(uint32_t sourceMask,int32_t switchCode)842 int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
843     return getEventHub()->getSwitchState(getDeviceId(), switchCode);
844 }
845 
846 
847 // --- KeyboardInputMapper ---
848 
KeyboardInputMapper(InputDevice * device,int32_t associatedDisplayId,uint32_t sources,int32_t keyboardType)849 KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId,
850         uint32_t sources, int32_t keyboardType) :
851         InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources),
852         mKeyboardType(keyboardType) {
853     initializeLocked();
854 }
855 
~KeyboardInputMapper()856 KeyboardInputMapper::~KeyboardInputMapper() {
857 }
858 
initializeLocked()859 void KeyboardInputMapper::initializeLocked() {
860     mLocked.metaState = AMETA_NONE;
861     mLocked.downTime = 0;
862 }
863 
getSources()864 uint32_t KeyboardInputMapper::getSources() {
865     return mSources;
866 }
867 
populateDeviceInfo(InputDeviceInfo * info)868 void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
869     InputMapper::populateDeviceInfo(info);
870 
871     info->setKeyboardType(mKeyboardType);
872 }
873 
dump(String8 & dump)874 void KeyboardInputMapper::dump(String8& dump) {
875     { // acquire lock
876         AutoMutex _l(mLock);
877         dump.append(INDENT2 "Keyboard Input Mapper:\n");
878         dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
879         dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
880         dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size());
881         dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState);
882         dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
883     } // release lock
884 }
885 
reset()886 void KeyboardInputMapper::reset() {
887     for (;;) {
888         int32_t keyCode, scanCode;
889         { // acquire lock
890             AutoMutex _l(mLock);
891 
892             // Synthesize key up event on reset if keys are currently down.
893             if (mLocked.keyDowns.isEmpty()) {
894                 initializeLocked();
895                 break; // done
896             }
897 
898             const KeyDown& keyDown = mLocked.keyDowns.top();
899             keyCode = keyDown.keyCode;
900             scanCode = keyDown.scanCode;
901         } // release lock
902 
903         nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
904         processKey(when, false, keyCode, scanCode, 0);
905     }
906 
907     InputMapper::reset();
908     getContext()->updateGlobalMetaState();
909 }
910 
process(const RawEvent * rawEvent)911 void KeyboardInputMapper::process(const RawEvent* rawEvent) {
912     switch (rawEvent->type) {
913     case EV_KEY: {
914         int32_t scanCode = rawEvent->scanCode;
915         if (isKeyboardOrGamepadKey(scanCode)) {
916             processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
917                     rawEvent->flags);
918         }
919         break;
920     }
921     }
922 }
923 
isKeyboardOrGamepadKey(int32_t scanCode)924 bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
925     return scanCode < BTN_MOUSE
926         || scanCode >= KEY_OK
927         || (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
928 }
929 
processKey(nsecs_t when,bool down,int32_t keyCode,int32_t scanCode,uint32_t policyFlags)930 void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
931         int32_t scanCode, uint32_t policyFlags) {
932     int32_t newMetaState;
933     nsecs_t downTime;
934     bool metaStateChanged = false;
935 
936     { // acquire lock
937         AutoMutex _l(mLock);
938 
939         if (down) {
940             // Rotate key codes according to orientation if needed.
941             // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
942             if (mAssociatedDisplayId >= 0) {
943                 int32_t orientation;
944                 if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
945                     return;
946                 }
947 
948                 keyCode = rotateKeyCode(keyCode, orientation);
949             }
950 
951             // Add key down.
952             ssize_t keyDownIndex = findKeyDownLocked(scanCode);
953             if (keyDownIndex >= 0) {
954                 // key repeat, be sure to use same keycode as before in case of rotation
955                 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
956             } else {
957                 // key down
958                 if ((policyFlags & POLICY_FLAG_VIRTUAL)
959                         && mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {
960                     return;
961                 }
962 
963                 mLocked.keyDowns.push();
964                 KeyDown& keyDown = mLocked.keyDowns.editTop();
965                 keyDown.keyCode = keyCode;
966                 keyDown.scanCode = scanCode;
967             }
968 
969             mLocked.downTime = when;
970         } else {
971             // Remove key down.
972             ssize_t keyDownIndex = findKeyDownLocked(scanCode);
973             if (keyDownIndex >= 0) {
974                 // key up, be sure to use same keycode as before in case of rotation
975                 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
976                 mLocked.keyDowns.removeAt(size_t(keyDownIndex));
977             } else {
978                 // key was not actually down
979                 LOGI("Dropping key up from device %s because the key was not down.  "
980                         "keyCode=%d, scanCode=%d",
981                         getDeviceName().string(), keyCode, scanCode);
982                 return;
983             }
984         }
985 
986         int32_t oldMetaState = mLocked.metaState;
987         newMetaState = updateMetaState(keyCode, down, oldMetaState);
988         if (oldMetaState != newMetaState) {
989             mLocked.metaState = newMetaState;
990             metaStateChanged = true;
991         }
992 
993         downTime = mLocked.downTime;
994     } // release lock
995 
996     if (metaStateChanged) {
997         getContext()->updateGlobalMetaState();
998     }
999 
1000     getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
1001             down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
1002             AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
1003 }
1004 
findKeyDownLocked(int32_t scanCode)1005 ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
1006     size_t n = mLocked.keyDowns.size();
1007     for (size_t i = 0; i < n; i++) {
1008         if (mLocked.keyDowns[i].scanCode == scanCode) {
1009             return i;
1010         }
1011     }
1012     return -1;
1013 }
1014 
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)1015 int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
1016     return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
1017 }
1018 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)1019 int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
1020     return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
1021 }
1022 
markSupportedKeyCodes(uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)1023 bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
1024         const int32_t* keyCodes, uint8_t* outFlags) {
1025     return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
1026 }
1027 
getMetaState()1028 int32_t KeyboardInputMapper::getMetaState() {
1029     { // acquire lock
1030         AutoMutex _l(mLock);
1031         return mLocked.metaState;
1032     } // release lock
1033 }
1034 
1035 
1036 // --- TrackballInputMapper ---
1037 
TrackballInputMapper(InputDevice * device,int32_t associatedDisplayId)1038 TrackballInputMapper::TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId) :
1039         InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
1040     mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
1041     mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
1042     mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
1043     mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
1044 
1045     initializeLocked();
1046 }
1047 
~TrackballInputMapper()1048 TrackballInputMapper::~TrackballInputMapper() {
1049 }
1050 
getSources()1051 uint32_t TrackballInputMapper::getSources() {
1052     return AINPUT_SOURCE_TRACKBALL;
1053 }
1054 
populateDeviceInfo(InputDeviceInfo * info)1055 void TrackballInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1056     InputMapper::populateDeviceInfo(info);
1057 
1058     info->addMotionRange(AINPUT_MOTION_RANGE_X, -1.0f, 1.0f, 0.0f, mXScale);
1059     info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
1060 }
1061 
dump(String8 & dump)1062 void TrackballInputMapper::dump(String8& dump) {
1063     { // acquire lock
1064         AutoMutex _l(mLock);
1065         dump.append(INDENT2 "Trackball Input Mapper:\n");
1066         dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
1067         dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
1068         dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
1069         dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
1070         dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
1071     } // release lock
1072 }
1073 
initializeLocked()1074 void TrackballInputMapper::initializeLocked() {
1075     mAccumulator.clear();
1076 
1077     mLocked.down = false;
1078     mLocked.downTime = 0;
1079 }
1080 
reset()1081 void TrackballInputMapper::reset() {
1082     for (;;) {
1083         { // acquire lock
1084             AutoMutex _l(mLock);
1085 
1086             if (! mLocked.down) {
1087                 initializeLocked();
1088                 break; // done
1089             }
1090         } // release lock
1091 
1092         // Synthesize trackball button up event on reset.
1093         nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
1094         mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
1095         mAccumulator.btnMouse = false;
1096         sync(when);
1097     }
1098 
1099     InputMapper::reset();
1100 }
1101 
process(const RawEvent * rawEvent)1102 void TrackballInputMapper::process(const RawEvent* rawEvent) {
1103     switch (rawEvent->type) {
1104     case EV_KEY:
1105         switch (rawEvent->scanCode) {
1106         case BTN_MOUSE:
1107             mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
1108             mAccumulator.btnMouse = rawEvent->value != 0;
1109             // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
1110             // we need to ensure that we report the up/down promptly.
1111             sync(rawEvent->when);
1112             break;
1113         }
1114         break;
1115 
1116     case EV_REL:
1117         switch (rawEvent->scanCode) {
1118         case REL_X:
1119             mAccumulator.fields |= Accumulator::FIELD_REL_X;
1120             mAccumulator.relX = rawEvent->value;
1121             break;
1122         case REL_Y:
1123             mAccumulator.fields |= Accumulator::FIELD_REL_Y;
1124             mAccumulator.relY = rawEvent->value;
1125             break;
1126         }
1127         break;
1128 
1129     case EV_SYN:
1130         switch (rawEvent->scanCode) {
1131         case SYN_REPORT:
1132             sync(rawEvent->when);
1133             break;
1134         }
1135         break;
1136     }
1137 }
1138 
sync(nsecs_t when)1139 void TrackballInputMapper::sync(nsecs_t when) {
1140     uint32_t fields = mAccumulator.fields;
1141     if (fields == 0) {
1142         return; // no new state changes, so nothing to do
1143     }
1144 
1145     int motionEventAction;
1146     PointerCoords pointerCoords;
1147     nsecs_t downTime;
1148     { // acquire lock
1149         AutoMutex _l(mLock);
1150 
1151         bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
1152 
1153         if (downChanged) {
1154             if (mAccumulator.btnMouse) {
1155                 mLocked.down = true;
1156                 mLocked.downTime = when;
1157             } else {
1158                 mLocked.down = false;
1159             }
1160         }
1161 
1162         downTime = mLocked.downTime;
1163         float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
1164         float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
1165 
1166         if (downChanged) {
1167             motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
1168         } else {
1169             motionEventAction = AMOTION_EVENT_ACTION_MOVE;
1170         }
1171 
1172         pointerCoords.x = x;
1173         pointerCoords.y = y;
1174         pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
1175         pointerCoords.size = 0;
1176         pointerCoords.touchMajor = 0;
1177         pointerCoords.touchMinor = 0;
1178         pointerCoords.toolMajor = 0;
1179         pointerCoords.toolMinor = 0;
1180         pointerCoords.orientation = 0;
1181 
1182         if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) {
1183             // Rotate motion based on display orientation if needed.
1184             // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
1185             int32_t orientation;
1186             if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
1187                 return;
1188             }
1189 
1190             float temp;
1191             switch (orientation) {
1192             case InputReaderPolicyInterface::ROTATION_90:
1193                 temp = pointerCoords.x;
1194                 pointerCoords.x = pointerCoords.y;
1195                 pointerCoords.y = - temp;
1196                 break;
1197 
1198             case InputReaderPolicyInterface::ROTATION_180:
1199                 pointerCoords.x = - pointerCoords.x;
1200                 pointerCoords.y = - pointerCoords.y;
1201                 break;
1202 
1203             case InputReaderPolicyInterface::ROTATION_270:
1204                 temp = pointerCoords.x;
1205                 pointerCoords.x = - pointerCoords.y;
1206                 pointerCoords.y = temp;
1207                 break;
1208             }
1209         }
1210     } // release lock
1211 
1212     int32_t metaState = mContext->getGlobalMetaState();
1213     int32_t pointerId = 0;
1214     getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, 0,
1215             motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
1216             1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
1217 
1218     mAccumulator.clear();
1219 }
1220 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)1221 int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
1222     if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
1223         return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
1224     } else {
1225         return AKEY_STATE_UNKNOWN;
1226     }
1227 }
1228 
1229 
1230 // --- TouchInputMapper ---
1231 
TouchInputMapper(InputDevice * device,int32_t associatedDisplayId)1232 TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
1233         InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
1234     mLocked.surfaceOrientation = -1;
1235     mLocked.surfaceWidth = -1;
1236     mLocked.surfaceHeight = -1;
1237 
1238     initializeLocked();
1239 }
1240 
~TouchInputMapper()1241 TouchInputMapper::~TouchInputMapper() {
1242 }
1243 
getSources()1244 uint32_t TouchInputMapper::getSources() {
1245     return mAssociatedDisplayId >= 0 ? AINPUT_SOURCE_TOUCHSCREEN : AINPUT_SOURCE_TOUCHPAD;
1246 }
1247 
populateDeviceInfo(InputDeviceInfo * info)1248 void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
1249     InputMapper::populateDeviceInfo(info);
1250 
1251     { // acquire lock
1252         AutoMutex _l(mLock);
1253 
1254         // Ensure surface information is up to date so that orientation changes are
1255         // noticed immediately.
1256         configureSurfaceLocked();
1257 
1258         info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
1259         info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
1260 
1261         if (mLocked.orientedRanges.havePressure) {
1262             info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
1263                     mLocked.orientedRanges.pressure);
1264         }
1265 
1266         if (mLocked.orientedRanges.haveSize) {
1267             info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
1268                     mLocked.orientedRanges.size);
1269         }
1270 
1271         if (mLocked.orientedRanges.haveTouchSize) {
1272             info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
1273                     mLocked.orientedRanges.touchMajor);
1274             info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
1275                     mLocked.orientedRanges.touchMinor);
1276         }
1277 
1278         if (mLocked.orientedRanges.haveToolSize) {
1279             info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
1280                     mLocked.orientedRanges.toolMajor);
1281             info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
1282                     mLocked.orientedRanges.toolMinor);
1283         }
1284 
1285         if (mLocked.orientedRanges.haveOrientation) {
1286             info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
1287                     mLocked.orientedRanges.orientation);
1288         }
1289     } // release lock
1290 }
1291 
dump(String8 & dump)1292 void TouchInputMapper::dump(String8& dump) {
1293     { // acquire lock
1294         AutoMutex _l(mLock);
1295         dump.append(INDENT2 "Touch Input Mapper:\n");
1296         dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
1297         dumpParameters(dump);
1298         dumpVirtualKeysLocked(dump);
1299         dumpRawAxes(dump);
1300         dumpCalibration(dump);
1301         dumpSurfaceLocked(dump);
1302         dump.appendFormat(INDENT3 "Translation and Scaling Factors:");
1303         dump.appendFormat(INDENT4 "XOrigin: %d\n", mLocked.xOrigin);
1304         dump.appendFormat(INDENT4 "YOrigin: %d\n", mLocked.yOrigin);
1305         dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
1306         dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
1307         dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision);
1308         dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision);
1309         dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale);
1310         dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale);
1311         dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias);
1312         dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale);
1313         dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
1314         dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
1315         dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
1316         dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale);
1317     } // release lock
1318 }
1319 
initializeLocked()1320 void TouchInputMapper::initializeLocked() {
1321     mCurrentTouch.clear();
1322     mLastTouch.clear();
1323     mDownTime = 0;
1324 
1325     for (uint32_t i = 0; i < MAX_POINTERS; i++) {
1326         mAveragingTouchFilter.historyStart[i] = 0;
1327         mAveragingTouchFilter.historyEnd[i] = 0;
1328     }
1329 
1330     mJumpyTouchFilter.jumpyPointsDropped = 0;
1331 
1332     mLocked.currentVirtualKey.down = false;
1333 
1334     mLocked.orientedRanges.havePressure = false;
1335     mLocked.orientedRanges.haveSize = false;
1336     mLocked.orientedRanges.haveTouchSize = false;
1337     mLocked.orientedRanges.haveToolSize = false;
1338     mLocked.orientedRanges.haveOrientation = false;
1339 }
1340 
configure()1341 void TouchInputMapper::configure() {
1342     InputMapper::configure();
1343 
1344     // Configure basic parameters.
1345     configureParameters();
1346 
1347     // Configure absolute axis information.
1348     configureRawAxes();
1349 
1350     // Prepare input device calibration.
1351     parseCalibration();
1352     resolveCalibration();
1353 
1354     { // acquire lock
1355         AutoMutex _l(mLock);
1356 
1357          // Configure surface dimensions and orientation.
1358         configureSurfaceLocked();
1359     } // release lock
1360 }
1361 
configureParameters()1362 void TouchInputMapper::configureParameters() {
1363     mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
1364     mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
1365     mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
1366     mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
1367 }
1368 
dumpParameters(String8 & dump)1369 void TouchInputMapper::dumpParameters(String8& dump) {
1370     dump.appendFormat(INDENT3 "UseBadTouchFilter: %s\n",
1371             toString(mParameters.useBadTouchFilter));
1372     dump.appendFormat(INDENT3 "UseAveragingTouchFilter: %s\n",
1373             toString(mParameters.useAveragingTouchFilter));
1374     dump.appendFormat(INDENT3 "UseJumpyTouchFilter: %s\n",
1375             toString(mParameters.useJumpyTouchFilter));
1376 }
1377 
configureRawAxes()1378 void TouchInputMapper::configureRawAxes() {
1379     mRawAxes.x.clear();
1380     mRawAxes.y.clear();
1381     mRawAxes.pressure.clear();
1382     mRawAxes.touchMajor.clear();
1383     mRawAxes.touchMinor.clear();
1384     mRawAxes.toolMajor.clear();
1385     mRawAxes.toolMinor.clear();
1386     mRawAxes.orientation.clear();
1387 }
1388 
dumpAxisInfo(String8 & dump,RawAbsoluteAxisInfo axis,const char * name)1389 static void dumpAxisInfo(String8& dump, RawAbsoluteAxisInfo axis, const char* name) {
1390     if (axis.valid) {
1391         dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d\n",
1392                 name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
1393     } else {
1394         dump.appendFormat(INDENT4 "%s: unknown range\n", name);
1395     }
1396 }
1397 
dumpRawAxes(String8 & dump)1398 void TouchInputMapper::dumpRawAxes(String8& dump) {
1399     dump.append(INDENT3 "Raw Axes:\n");
1400     dumpAxisInfo(dump, mRawAxes.x, "X");
1401     dumpAxisInfo(dump, mRawAxes.y, "Y");
1402     dumpAxisInfo(dump, mRawAxes.pressure, "Pressure");
1403     dumpAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor");
1404     dumpAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor");
1405     dumpAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor");
1406     dumpAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor");
1407     dumpAxisInfo(dump, mRawAxes.orientation, "Orientation");
1408 }
1409 
configureSurfaceLocked()1410 bool TouchInputMapper::configureSurfaceLocked() {
1411     // Update orientation and dimensions if needed.
1412     int32_t orientation;
1413     int32_t width, height;
1414     if (mAssociatedDisplayId >= 0) {
1415         // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
1416         if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) {
1417             return false;
1418         }
1419     } else {
1420         orientation = InputReaderPolicyInterface::ROTATION_0;
1421         width = mRawAxes.x.getRange();
1422         height = mRawAxes.y.getRange();
1423     }
1424 
1425     bool orientationChanged = mLocked.surfaceOrientation != orientation;
1426     if (orientationChanged) {
1427         mLocked.surfaceOrientation = orientation;
1428     }
1429 
1430     bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
1431     if (sizeChanged) {
1432         LOGI("Device reconfigured: id=0x%x, name=%s, display size is now %dx%d",
1433                 getDeviceId(), getDeviceName().string(), width, height);
1434 
1435         mLocked.surfaceWidth = width;
1436         mLocked.surfaceHeight = height;
1437 
1438         // Configure X and Y factors.
1439         if (mRawAxes.x.valid && mRawAxes.y.valid) {
1440             mLocked.xOrigin = mRawAxes.x.minValue;
1441             mLocked.yOrigin = mRawAxes.y.minValue;
1442             mLocked.xScale = float(width) / mRawAxes.x.getRange();
1443             mLocked.yScale = float(height) / mRawAxes.y.getRange();
1444             mLocked.xPrecision = 1.0f / mLocked.xScale;
1445             mLocked.yPrecision = 1.0f / mLocked.yScale;
1446 
1447             configureVirtualKeysLocked();
1448         } else {
1449             LOGW(INDENT "Touch device did not report support for X or Y axis!");
1450             mLocked.xOrigin = 0;
1451             mLocked.yOrigin = 0;
1452             mLocked.xScale = 1.0f;
1453             mLocked.yScale = 1.0f;
1454             mLocked.xPrecision = 1.0f;
1455             mLocked.yPrecision = 1.0f;
1456         }
1457 
1458         // Scale factor for terms that are not oriented in a particular axis.
1459         // If the pixels are square then xScale == yScale otherwise we fake it
1460         // by choosing an average.
1461         mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
1462 
1463         // Size of diagonal axis.
1464         float diagonalSize = pythag(width, height);
1465 
1466         // TouchMajor and TouchMinor factors.
1467         if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
1468             mLocked.orientedRanges.haveTouchSize = true;
1469             mLocked.orientedRanges.touchMajor.min = 0;
1470             mLocked.orientedRanges.touchMajor.max = diagonalSize;
1471             mLocked.orientedRanges.touchMajor.flat = 0;
1472             mLocked.orientedRanges.touchMajor.fuzz = 0;
1473             mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
1474         }
1475 
1476         // ToolMajor and ToolMinor factors.
1477         mLocked.toolSizeLinearScale = 0;
1478         mLocked.toolSizeLinearBias = 0;
1479         mLocked.toolSizeAreaScale = 0;
1480         mLocked.toolSizeAreaBias = 0;
1481         if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
1482             if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) {
1483                 if (mCalibration.haveToolSizeLinearScale) {
1484                     mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
1485                 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
1486                     mLocked.toolSizeLinearScale = float(min(width, height))
1487                             / mRawAxes.toolMajor.maxValue;
1488                 }
1489 
1490                 if (mCalibration.haveToolSizeLinearBias) {
1491                     mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
1492                 }
1493             } else if (mCalibration.toolSizeCalibration ==
1494                     Calibration::TOOL_SIZE_CALIBRATION_AREA) {
1495                 if (mCalibration.haveToolSizeLinearScale) {
1496                     mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
1497                 } else {
1498                     mLocked.toolSizeLinearScale = min(width, height);
1499                 }
1500 
1501                 if (mCalibration.haveToolSizeLinearBias) {
1502                     mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
1503                 }
1504 
1505                 if (mCalibration.haveToolSizeAreaScale) {
1506                     mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale;
1507                 } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
1508                     mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue;
1509                 }
1510 
1511                 if (mCalibration.haveToolSizeAreaBias) {
1512                     mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias;
1513                 }
1514             }
1515 
1516             mLocked.orientedRanges.haveToolSize = true;
1517             mLocked.orientedRanges.toolMajor.min = 0;
1518             mLocked.orientedRanges.toolMajor.max = diagonalSize;
1519             mLocked.orientedRanges.toolMajor.flat = 0;
1520             mLocked.orientedRanges.toolMajor.fuzz = 0;
1521             mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
1522         }
1523 
1524         // Pressure factors.
1525         mLocked.pressureScale = 0;
1526         if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
1527             RawAbsoluteAxisInfo rawPressureAxis;
1528             switch (mCalibration.pressureSource) {
1529             case Calibration::PRESSURE_SOURCE_PRESSURE:
1530                 rawPressureAxis = mRawAxes.pressure;
1531                 break;
1532             case Calibration::PRESSURE_SOURCE_TOUCH:
1533                 rawPressureAxis = mRawAxes.touchMajor;
1534                 break;
1535             default:
1536                 rawPressureAxis.clear();
1537             }
1538 
1539             if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
1540                     || mCalibration.pressureCalibration
1541                             == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
1542                 if (mCalibration.havePressureScale) {
1543                     mLocked.pressureScale = mCalibration.pressureScale;
1544                 } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
1545                     mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
1546                 }
1547             }
1548 
1549             mLocked.orientedRanges.havePressure = true;
1550             mLocked.orientedRanges.pressure.min = 0;
1551             mLocked.orientedRanges.pressure.max = 1.0;
1552             mLocked.orientedRanges.pressure.flat = 0;
1553             mLocked.orientedRanges.pressure.fuzz = 0;
1554         }
1555 
1556         // Size factors.
1557         mLocked.sizeScale = 0;
1558         if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
1559             if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
1560                 if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
1561                     mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
1562                 }
1563             }
1564 
1565             mLocked.orientedRanges.haveSize = true;
1566             mLocked.orientedRanges.size.min = 0;
1567             mLocked.orientedRanges.size.max = 1.0;
1568             mLocked.orientedRanges.size.flat = 0;
1569             mLocked.orientedRanges.size.fuzz = 0;
1570         }
1571 
1572         // Orientation
1573         mLocked.orientationScale = 0;
1574         if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
1575             if (mCalibration.orientationCalibration
1576                     == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
1577                 if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
1578                     mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
1579                 }
1580             }
1581 
1582             mLocked.orientedRanges.orientation.min = - M_PI_2;
1583             mLocked.orientedRanges.orientation.max = M_PI_2;
1584             mLocked.orientedRanges.orientation.flat = 0;
1585             mLocked.orientedRanges.orientation.fuzz = 0;
1586         }
1587     }
1588 
1589     if (orientationChanged || sizeChanged) {
1590         // Compute oriented surface dimensions, precision, and scales.
1591         float orientedXScale, orientedYScale;
1592         switch (mLocked.surfaceOrientation) {
1593         case InputReaderPolicyInterface::ROTATION_90:
1594         case InputReaderPolicyInterface::ROTATION_270:
1595             mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
1596             mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
1597             mLocked.orientedXPrecision = mLocked.yPrecision;
1598             mLocked.orientedYPrecision = mLocked.xPrecision;
1599             orientedXScale = mLocked.yScale;
1600             orientedYScale = mLocked.xScale;
1601             break;
1602         default:
1603             mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
1604             mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
1605             mLocked.orientedXPrecision = mLocked.xPrecision;
1606             mLocked.orientedYPrecision = mLocked.yPrecision;
1607             orientedXScale = mLocked.xScale;
1608             orientedYScale = mLocked.yScale;
1609             break;
1610         }
1611 
1612         // Configure position ranges.
1613         mLocked.orientedRanges.x.min = 0;
1614         mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth;
1615         mLocked.orientedRanges.x.flat = 0;
1616         mLocked.orientedRanges.x.fuzz = orientedXScale;
1617 
1618         mLocked.orientedRanges.y.min = 0;
1619         mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight;
1620         mLocked.orientedRanges.y.flat = 0;
1621         mLocked.orientedRanges.y.fuzz = orientedYScale;
1622     }
1623 
1624     return true;
1625 }
1626 
dumpSurfaceLocked(String8 & dump)1627 void TouchInputMapper::dumpSurfaceLocked(String8& dump) {
1628     dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth);
1629     dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight);
1630     dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation);
1631 }
1632 
configureVirtualKeysLocked()1633 void TouchInputMapper::configureVirtualKeysLocked() {
1634     assert(mRawAxes.x.valid && mRawAxes.y.valid);
1635 
1636     // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
1637     Vector<VirtualKeyDefinition> virtualKeyDefinitions;
1638     getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
1639 
1640     mLocked.virtualKeys.clear();
1641 
1642     if (virtualKeyDefinitions.size() == 0) {
1643         return;
1644     }
1645 
1646     mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
1647 
1648     int32_t touchScreenLeft = mRawAxes.x.minValue;
1649     int32_t touchScreenTop = mRawAxes.y.minValue;
1650     int32_t touchScreenWidth = mRawAxes.x.getRange();
1651     int32_t touchScreenHeight = mRawAxes.y.getRange();
1652 
1653     for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
1654         const VirtualKeyDefinition& virtualKeyDefinition =
1655                 virtualKeyDefinitions[i];
1656 
1657         mLocked.virtualKeys.add();
1658         VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
1659 
1660         virtualKey.scanCode = virtualKeyDefinition.scanCode;
1661         int32_t keyCode;
1662         uint32_t flags;
1663         if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
1664                 & keyCode, & flags)) {
1665             LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
1666                     virtualKey.scanCode);
1667             mLocked.virtualKeys.pop(); // drop the key
1668             continue;
1669         }
1670 
1671         virtualKey.keyCode = keyCode;
1672         virtualKey.flags = flags;
1673 
1674         // convert the key definition's display coordinates into touch coordinates for a hit box
1675         int32_t halfWidth = virtualKeyDefinition.width / 2;
1676         int32_t halfHeight = virtualKeyDefinition.height / 2;
1677 
1678         virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
1679                 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
1680         virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
1681                 * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
1682         virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
1683                 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
1684         virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
1685                 * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
1686 
1687     }
1688 }
1689 
dumpVirtualKeysLocked(String8 & dump)1690 void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) {
1691     if (!mLocked.virtualKeys.isEmpty()) {
1692         dump.append(INDENT3 "Virtual Keys:\n");
1693 
1694         for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) {
1695             const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i);
1696             dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
1697                     "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
1698                     i, virtualKey.scanCode, virtualKey.keyCode,
1699                     virtualKey.hitLeft, virtualKey.hitRight,
1700                     virtualKey.hitTop, virtualKey.hitBottom);
1701         }
1702     }
1703 }
1704 
parseCalibration()1705 void TouchInputMapper::parseCalibration() {
1706     const InputDeviceCalibration& in = getDevice()->getCalibration();
1707     Calibration& out = mCalibration;
1708 
1709     // Touch Size
1710     out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT;
1711     String8 touchSizeCalibrationString;
1712     if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) {
1713         if (touchSizeCalibrationString == "none") {
1714             out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE;
1715         } else if (touchSizeCalibrationString == "geometric") {
1716             out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC;
1717         } else if (touchSizeCalibrationString == "pressure") {
1718             out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
1719         } else if (touchSizeCalibrationString != "default") {
1720             LOGW("Invalid value for touch.touchSize.calibration: '%s'",
1721                     touchSizeCalibrationString.string());
1722         }
1723     }
1724 
1725     // Tool Size
1726     out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT;
1727     String8 toolSizeCalibrationString;
1728     if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) {
1729         if (toolSizeCalibrationString == "none") {
1730             out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
1731         } else if (toolSizeCalibrationString == "geometric") {
1732             out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC;
1733         } else if (toolSizeCalibrationString == "linear") {
1734             out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
1735         } else if (toolSizeCalibrationString == "area") {
1736             out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA;
1737         } else if (toolSizeCalibrationString != "default") {
1738             LOGW("Invalid value for touch.toolSize.calibration: '%s'",
1739                     toolSizeCalibrationString.string());
1740         }
1741     }
1742 
1743     out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"),
1744             out.toolSizeLinearScale);
1745     out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"),
1746             out.toolSizeLinearBias);
1747     out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"),
1748             out.toolSizeAreaScale);
1749     out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"),
1750             out.toolSizeAreaBias);
1751     out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"),
1752             out.toolSizeIsSummed);
1753 
1754     // Pressure
1755     out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
1756     String8 pressureCalibrationString;
1757     if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
1758         if (pressureCalibrationString == "none") {
1759             out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
1760         } else if (pressureCalibrationString == "physical") {
1761             out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
1762         } else if (pressureCalibrationString == "amplitude") {
1763             out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
1764         } else if (pressureCalibrationString != "default") {
1765             LOGW("Invalid value for touch.pressure.calibration: '%s'",
1766                     pressureCalibrationString.string());
1767         }
1768     }
1769 
1770     out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT;
1771     String8 pressureSourceString;
1772     if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) {
1773         if (pressureSourceString == "pressure") {
1774             out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
1775         } else if (pressureSourceString == "touch") {
1776             out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
1777         } else if (pressureSourceString != "default") {
1778             LOGW("Invalid value for touch.pressure.source: '%s'",
1779                     pressureSourceString.string());
1780         }
1781     }
1782 
1783     out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
1784             out.pressureScale);
1785 
1786     // Size
1787     out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
1788     String8 sizeCalibrationString;
1789     if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
1790         if (sizeCalibrationString == "none") {
1791             out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
1792         } else if (sizeCalibrationString == "normalized") {
1793             out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
1794         } else if (sizeCalibrationString != "default") {
1795             LOGW("Invalid value for touch.size.calibration: '%s'",
1796                     sizeCalibrationString.string());
1797         }
1798     }
1799 
1800     // Orientation
1801     out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
1802     String8 orientationCalibrationString;
1803     if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
1804         if (orientationCalibrationString == "none") {
1805             out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
1806         } else if (orientationCalibrationString == "interpolated") {
1807             out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
1808         } else if (orientationCalibrationString != "default") {
1809             LOGW("Invalid value for touch.orientation.calibration: '%s'",
1810                     orientationCalibrationString.string());
1811         }
1812     }
1813 }
1814 
resolveCalibration()1815 void TouchInputMapper::resolveCalibration() {
1816     // Pressure
1817     switch (mCalibration.pressureSource) {
1818     case Calibration::PRESSURE_SOURCE_DEFAULT:
1819         if (mRawAxes.pressure.valid) {
1820             mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
1821         } else if (mRawAxes.touchMajor.valid) {
1822             mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
1823         }
1824         break;
1825 
1826     case Calibration::PRESSURE_SOURCE_PRESSURE:
1827         if (! mRawAxes.pressure.valid) {
1828             LOGW("Calibration property touch.pressure.source is 'pressure' but "
1829                     "the pressure axis is not available.");
1830         }
1831         break;
1832 
1833     case Calibration::PRESSURE_SOURCE_TOUCH:
1834         if (! mRawAxes.touchMajor.valid) {
1835             LOGW("Calibration property touch.pressure.source is 'touch' but "
1836                     "the touchMajor axis is not available.");
1837         }
1838         break;
1839 
1840     default:
1841         break;
1842     }
1843 
1844     switch (mCalibration.pressureCalibration) {
1845     case Calibration::PRESSURE_CALIBRATION_DEFAULT:
1846         if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) {
1847             mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
1848         } else {
1849             mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
1850         }
1851         break;
1852 
1853     default:
1854         break;
1855     }
1856 
1857     // Tool Size
1858     switch (mCalibration.toolSizeCalibration) {
1859     case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT:
1860         if (mRawAxes.toolMajor.valid) {
1861             mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
1862         } else {
1863             mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
1864         }
1865         break;
1866 
1867     default:
1868         break;
1869     }
1870 
1871     // Touch Size
1872     switch (mCalibration.touchSizeCalibration) {
1873     case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT:
1874         if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
1875                 && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
1876             mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
1877         } else {
1878             mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE;
1879         }
1880         break;
1881 
1882     default:
1883         break;
1884     }
1885 
1886     // Size
1887     switch (mCalibration.sizeCalibration) {
1888     case Calibration::SIZE_CALIBRATION_DEFAULT:
1889         if (mRawAxes.toolMajor.valid) {
1890             mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
1891         } else {
1892             mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
1893         }
1894         break;
1895 
1896     default:
1897         break;
1898     }
1899 
1900     // Orientation
1901     switch (mCalibration.orientationCalibration) {
1902     case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
1903         if (mRawAxes.orientation.valid) {
1904             mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
1905         } else {
1906             mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
1907         }
1908         break;
1909 
1910     default:
1911         break;
1912     }
1913 }
1914 
dumpCalibration(String8 & dump)1915 void TouchInputMapper::dumpCalibration(String8& dump) {
1916     dump.append(INDENT3 "Calibration:\n");
1917 
1918     // Touch Size
1919     switch (mCalibration.touchSizeCalibration) {
1920     case Calibration::TOUCH_SIZE_CALIBRATION_NONE:
1921         dump.append(INDENT4 "touch.touchSize.calibration: none\n");
1922         break;
1923     case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
1924         dump.append(INDENT4 "touch.touchSize.calibration: geometric\n");
1925         break;
1926     case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE:
1927         dump.append(INDENT4 "touch.touchSize.calibration: pressure\n");
1928         break;
1929     default:
1930         assert(false);
1931     }
1932 
1933     // Tool Size
1934     switch (mCalibration.toolSizeCalibration) {
1935     case Calibration::TOOL_SIZE_CALIBRATION_NONE:
1936         dump.append(INDENT4 "touch.toolSize.calibration: none\n");
1937         break;
1938     case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
1939         dump.append(INDENT4 "touch.toolSize.calibration: geometric\n");
1940         break;
1941     case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
1942         dump.append(INDENT4 "touch.toolSize.calibration: linear\n");
1943         break;
1944     case Calibration::TOOL_SIZE_CALIBRATION_AREA:
1945         dump.append(INDENT4 "touch.toolSize.calibration: area\n");
1946         break;
1947     default:
1948         assert(false);
1949     }
1950 
1951     if (mCalibration.haveToolSizeLinearScale) {
1952         dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n",
1953                 mCalibration.toolSizeLinearScale);
1954     }
1955 
1956     if (mCalibration.haveToolSizeLinearBias) {
1957         dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n",
1958                 mCalibration.toolSizeLinearBias);
1959     }
1960 
1961     if (mCalibration.haveToolSizeAreaScale) {
1962         dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n",
1963                 mCalibration.toolSizeAreaScale);
1964     }
1965 
1966     if (mCalibration.haveToolSizeAreaBias) {
1967         dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n",
1968                 mCalibration.toolSizeAreaBias);
1969     }
1970 
1971     if (mCalibration.haveToolSizeIsSummed) {
1972         dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %d\n",
1973                 mCalibration.toolSizeIsSummed);
1974     }
1975 
1976     // Pressure
1977     switch (mCalibration.pressureCalibration) {
1978     case Calibration::PRESSURE_CALIBRATION_NONE:
1979         dump.append(INDENT4 "touch.pressure.calibration: none\n");
1980         break;
1981     case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
1982         dump.append(INDENT4 "touch.pressure.calibration: physical\n");
1983         break;
1984     case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
1985         dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
1986         break;
1987     default:
1988         assert(false);
1989     }
1990 
1991     switch (mCalibration.pressureSource) {
1992     case Calibration::PRESSURE_SOURCE_PRESSURE:
1993         dump.append(INDENT4 "touch.pressure.source: pressure\n");
1994         break;
1995     case Calibration::PRESSURE_SOURCE_TOUCH:
1996         dump.append(INDENT4 "touch.pressure.source: touch\n");
1997         break;
1998     case Calibration::PRESSURE_SOURCE_DEFAULT:
1999         break;
2000     default:
2001         assert(false);
2002     }
2003 
2004     if (mCalibration.havePressureScale) {
2005         dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
2006                 mCalibration.pressureScale);
2007     }
2008 
2009     // Size
2010     switch (mCalibration.sizeCalibration) {
2011     case Calibration::SIZE_CALIBRATION_NONE:
2012         dump.append(INDENT4 "touch.size.calibration: none\n");
2013         break;
2014     case Calibration::SIZE_CALIBRATION_NORMALIZED:
2015         dump.append(INDENT4 "touch.size.calibration: normalized\n");
2016         break;
2017     default:
2018         assert(false);
2019     }
2020 
2021     // Orientation
2022     switch (mCalibration.orientationCalibration) {
2023     case Calibration::ORIENTATION_CALIBRATION_NONE:
2024         dump.append(INDENT4 "touch.orientation.calibration: none\n");
2025         break;
2026     case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
2027         dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
2028         break;
2029     default:
2030         assert(false);
2031     }
2032 }
2033 
reset()2034 void TouchInputMapper::reset() {
2035     // Synthesize touch up event if touch is currently down.
2036     // This will also take care of finishing virtual key processing if needed.
2037     if (mLastTouch.pointerCount != 0) {
2038         nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
2039         mCurrentTouch.clear();
2040         syncTouch(when, true);
2041     }
2042 
2043     { // acquire lock
2044         AutoMutex _l(mLock);
2045         initializeLocked();
2046     } // release lock
2047 
2048     InputMapper::reset();
2049 }
2050 
syncTouch(nsecs_t when,bool havePointerIds)2051 void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
2052     uint32_t policyFlags = 0;
2053 
2054     // Preprocess pointer data.
2055 
2056     if (mParameters.useBadTouchFilter) {
2057         if (applyBadTouchFilter()) {
2058             havePointerIds = false;
2059         }
2060     }
2061 
2062     if (mParameters.useJumpyTouchFilter) {
2063         if (applyJumpyTouchFilter()) {
2064             havePointerIds = false;
2065         }
2066     }
2067 
2068     if (! havePointerIds) {
2069         calculatePointerIds();
2070     }
2071 
2072     TouchData temp;
2073     TouchData* savedTouch;
2074     if (mParameters.useAveragingTouchFilter) {
2075         temp.copyFrom(mCurrentTouch);
2076         savedTouch = & temp;
2077 
2078         applyAveragingTouchFilter();
2079     } else {
2080         savedTouch = & mCurrentTouch;
2081     }
2082 
2083     // Process touches and virtual keys.
2084 
2085     TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
2086     if (touchResult == DISPATCH_TOUCH) {
2087         detectGestures(when);
2088         dispatchTouches(when, policyFlags);
2089     }
2090 
2091     // Copy current touch to last touch in preparation for the next cycle.
2092 
2093     if (touchResult == DROP_STROKE) {
2094         mLastTouch.clear();
2095     } else {
2096         mLastTouch.copyFrom(*savedTouch);
2097     }
2098 }
2099 
consumeOffScreenTouches(nsecs_t when,uint32_t policyFlags)2100 TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
2101         nsecs_t when, uint32_t policyFlags) {
2102     int32_t keyEventAction, keyEventFlags;
2103     int32_t keyCode, scanCode, downTime;
2104     TouchResult touchResult;
2105 
2106     { // acquire lock
2107         AutoMutex _l(mLock);
2108 
2109         // Update surface size and orientation, including virtual key positions.
2110         if (! configureSurfaceLocked()) {
2111             return DROP_STROKE;
2112         }
2113 
2114         // Check for virtual key press.
2115         if (mLocked.currentVirtualKey.down) {
2116             if (mCurrentTouch.pointerCount == 0) {
2117                 // Pointer went up while virtual key was down.
2118                 mLocked.currentVirtualKey.down = false;
2119 #if DEBUG_VIRTUAL_KEYS
2120                 LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
2121                         mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
2122 #endif
2123                 keyEventAction = AKEY_EVENT_ACTION_UP;
2124                 keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2125                 touchResult = SKIP_TOUCH;
2126                 goto DispatchVirtualKey;
2127             }
2128 
2129             if (mCurrentTouch.pointerCount == 1) {
2130                 int32_t x = mCurrentTouch.pointers[0].x;
2131                 int32_t y = mCurrentTouch.pointers[0].y;
2132                 const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
2133                 if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
2134                     // Pointer is still within the space of the virtual key.
2135                     return SKIP_TOUCH;
2136                 }
2137             }
2138 
2139             // Pointer left virtual key area or another pointer also went down.
2140             // Send key cancellation and drop the stroke so subsequent motions will be
2141             // considered fresh downs.  This is useful when the user swipes away from the
2142             // virtual key area into the main display surface.
2143             mLocked.currentVirtualKey.down = false;
2144 #if DEBUG_VIRTUAL_KEYS
2145             LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
2146                     mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
2147 #endif
2148             keyEventAction = AKEY_EVENT_ACTION_UP;
2149             keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
2150                     | AKEY_EVENT_FLAG_CANCELED;
2151 
2152             // Check whether the pointer moved inside the display area where we should
2153             // start a new stroke.
2154             int32_t x = mCurrentTouch.pointers[0].x;
2155             int32_t y = mCurrentTouch.pointers[0].y;
2156             if (isPointInsideSurfaceLocked(x, y)) {
2157                 mLastTouch.clear();
2158                 touchResult = DISPATCH_TOUCH;
2159             } else {
2160                 touchResult = DROP_STROKE;
2161             }
2162         } else {
2163             if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
2164                 // Pointer just went down.  Handle off-screen touches, if needed.
2165                 int32_t x = mCurrentTouch.pointers[0].x;
2166                 int32_t y = mCurrentTouch.pointers[0].y;
2167                 if (! isPointInsideSurfaceLocked(x, y)) {
2168                     // If exactly one pointer went down, check for virtual key hit.
2169                     // Otherwise we will drop the entire stroke.
2170                     if (mCurrentTouch.pointerCount == 1) {
2171                         const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
2172                         if (virtualKey) {
2173                             if (mContext->shouldDropVirtualKey(when, getDevice(),
2174                                     virtualKey->keyCode, virtualKey->scanCode)) {
2175                                 return DROP_STROKE;
2176                             }
2177 
2178                             mLocked.currentVirtualKey.down = true;
2179                             mLocked.currentVirtualKey.downTime = when;
2180                             mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
2181                             mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
2182 #if DEBUG_VIRTUAL_KEYS
2183                             LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
2184                                     mLocked.currentVirtualKey.keyCode,
2185                                     mLocked.currentVirtualKey.scanCode);
2186 #endif
2187                             keyEventAction = AKEY_EVENT_ACTION_DOWN;
2188                             keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
2189                                     | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
2190                             touchResult = SKIP_TOUCH;
2191                             goto DispatchVirtualKey;
2192                         }
2193                     }
2194                     return DROP_STROKE;
2195                 }
2196             }
2197             return DISPATCH_TOUCH;
2198         }
2199 
2200     DispatchVirtualKey:
2201         // Collect remaining state needed to dispatch virtual key.
2202         keyCode = mLocked.currentVirtualKey.keyCode;
2203         scanCode = mLocked.currentVirtualKey.scanCode;
2204         downTime = mLocked.currentVirtualKey.downTime;
2205     } // release lock
2206 
2207     // Dispatch virtual key.
2208     int32_t metaState = mContext->getGlobalMetaState();
2209     policyFlags |= POLICY_FLAG_VIRTUAL;
2210     getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
2211             keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
2212     return touchResult;
2213 }
2214 
detectGestures(nsecs_t when)2215 void TouchInputMapper::detectGestures(nsecs_t when) {
2216     // Disable all virtual key touches that happen within a short time interval of the
2217     // most recent touch.  The idea is to filter out stray virtual key presses when
2218     // interacting with the touch screen.
2219     //
2220     // Problems we're trying to solve:
2221     //
2222     // 1. While scrolling a list or dragging the window shade, the user swipes down into a
2223     //    virtual key area that is implemented by a separate touch panel and accidentally
2224     //    triggers a virtual key.
2225     //
2226     // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
2227     //    area and accidentally triggers a virtual key.  This often happens when virtual keys
2228     //    are layed out below the screen near to where the on screen keyboard's space bar
2229     //    is displayed.
2230     if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
2231         mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
2232     }
2233 }
2234 
dispatchTouches(nsecs_t when,uint32_t policyFlags)2235 void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
2236     uint32_t currentPointerCount = mCurrentTouch.pointerCount;
2237     uint32_t lastPointerCount = mLastTouch.pointerCount;
2238     if (currentPointerCount == 0 && lastPointerCount == 0) {
2239         return; // nothing to do!
2240     }
2241 
2242     BitSet32 currentIdBits = mCurrentTouch.idBits;
2243     BitSet32 lastIdBits = mLastTouch.idBits;
2244 
2245     if (currentIdBits == lastIdBits) {
2246         // No pointer id changes so this is a move event.
2247         // The dispatcher takes care of batching moves so we don't have to deal with that here.
2248         int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
2249         dispatchTouch(when, policyFlags, & mCurrentTouch,
2250                 currentIdBits, -1, currentPointerCount, motionEventAction);
2251     } else {
2252         // There may be pointers going up and pointers going down and pointers moving
2253         // all at the same time.
2254         BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
2255         BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
2256         BitSet32 activeIdBits(lastIdBits.value);
2257         uint32_t pointerCount = lastPointerCount;
2258 
2259         // Produce an intermediate representation of the touch data that consists of the
2260         // old location of pointers that have just gone up and the new location of pointers that
2261         // have just moved but omits the location of pointers that have just gone down.
2262         TouchData interimTouch;
2263         interimTouch.copyFrom(mLastTouch);
2264 
2265         BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
2266         bool moveNeeded = false;
2267         while (!moveIdBits.isEmpty()) {
2268             uint32_t moveId = moveIdBits.firstMarkedBit();
2269             moveIdBits.clearBit(moveId);
2270 
2271             int32_t oldIndex = mLastTouch.idToIndex[moveId];
2272             int32_t newIndex = mCurrentTouch.idToIndex[moveId];
2273             if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) {
2274                 interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex];
2275                 moveNeeded = true;
2276             }
2277         }
2278 
2279         // Dispatch pointer up events using the interim pointer locations.
2280         while (!upIdBits.isEmpty()) {
2281             uint32_t upId = upIdBits.firstMarkedBit();
2282             upIdBits.clearBit(upId);
2283             BitSet32 oldActiveIdBits = activeIdBits;
2284             activeIdBits.clearBit(upId);
2285 
2286             int32_t motionEventAction;
2287             if (activeIdBits.isEmpty()) {
2288                 motionEventAction = AMOTION_EVENT_ACTION_UP;
2289             } else {
2290                 motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP;
2291             }
2292 
2293             dispatchTouch(when, policyFlags, &interimTouch,
2294                     oldActiveIdBits, upId, pointerCount, motionEventAction);
2295             pointerCount -= 1;
2296         }
2297 
2298         // Dispatch move events if any of the remaining pointers moved from their old locations.
2299         // Although applications receive new locations as part of individual pointer up
2300         // events, they do not generally handle them except when presented in a move event.
2301         if (moveNeeded) {
2302             dispatchTouch(when, policyFlags, &mCurrentTouch,
2303                     activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE);
2304         }
2305 
2306         // Dispatch pointer down events using the new pointer locations.
2307         while (!downIdBits.isEmpty()) {
2308             uint32_t downId = downIdBits.firstMarkedBit();
2309             downIdBits.clearBit(downId);
2310             BitSet32 oldActiveIdBits = activeIdBits;
2311             activeIdBits.markBit(downId);
2312 
2313             int32_t motionEventAction;
2314             if (oldActiveIdBits.isEmpty()) {
2315                 motionEventAction = AMOTION_EVENT_ACTION_DOWN;
2316                 mDownTime = when;
2317             } else {
2318                 motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
2319             }
2320 
2321             pointerCount += 1;
2322             dispatchTouch(when, policyFlags, &mCurrentTouch,
2323                     activeIdBits, downId, pointerCount, motionEventAction);
2324         }
2325     }
2326 }
2327 
dispatchTouch(nsecs_t when,uint32_t policyFlags,TouchData * touch,BitSet32 idBits,uint32_t changedId,uint32_t pointerCount,int32_t motionEventAction)2328 void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
2329         TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
2330         int32_t motionEventAction) {
2331     int32_t pointerIds[MAX_POINTERS];
2332     PointerCoords pointerCoords[MAX_POINTERS];
2333     int32_t motionEventEdgeFlags = 0;
2334     float xPrecision, yPrecision;
2335 
2336     { // acquire lock
2337         AutoMutex _l(mLock);
2338 
2339         // Walk through the the active pointers and map touch screen coordinates (TouchData) into
2340         // display coordinates (PointerCoords) and adjust for display orientation.
2341         for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
2342             uint32_t id = idBits.firstMarkedBit();
2343             idBits.clearBit(id);
2344             uint32_t inIndex = touch->idToIndex[id];
2345 
2346             const PointerData& in = touch->pointers[inIndex];
2347 
2348             // X and Y
2349             float x = float(in.x - mLocked.xOrigin) * mLocked.xScale;
2350             float y = float(in.y - mLocked.yOrigin) * mLocked.yScale;
2351 
2352             // ToolMajor and ToolMinor
2353             float toolMajor, toolMinor;
2354             switch (mCalibration.toolSizeCalibration) {
2355             case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
2356                 toolMajor = in.toolMajor * mLocked.geometricScale;
2357                 if (mRawAxes.toolMinor.valid) {
2358                     toolMinor = in.toolMinor * mLocked.geometricScale;
2359                 } else {
2360                     toolMinor = toolMajor;
2361                 }
2362                 break;
2363             case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
2364                 toolMajor = in.toolMajor != 0
2365                         ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias
2366                         : 0;
2367                 if (mRawAxes.toolMinor.valid) {
2368                     toolMinor = in.toolMinor != 0
2369                             ? in.toolMinor * mLocked.toolSizeLinearScale
2370                                     + mLocked.toolSizeLinearBias
2371                             : 0;
2372                 } else {
2373                     toolMinor = toolMajor;
2374                 }
2375                 break;
2376             case Calibration::TOOL_SIZE_CALIBRATION_AREA:
2377                 if (in.toolMajor != 0) {
2378                     float diameter = sqrtf(in.toolMajor
2379                             * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias);
2380                     toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias;
2381                 } else {
2382                     toolMajor = 0;
2383                 }
2384                 toolMinor = toolMajor;
2385                 break;
2386             default:
2387                 toolMajor = 0;
2388                 toolMinor = 0;
2389                 break;
2390             }
2391 
2392             if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) {
2393                 toolMajor /= pointerCount;
2394                 toolMinor /= pointerCount;
2395             }
2396 
2397             // Pressure
2398             float rawPressure;
2399             switch (mCalibration.pressureSource) {
2400             case Calibration::PRESSURE_SOURCE_PRESSURE:
2401                 rawPressure = in.pressure;
2402                 break;
2403             case Calibration::PRESSURE_SOURCE_TOUCH:
2404                 rawPressure = in.touchMajor;
2405                 break;
2406             default:
2407                 rawPressure = 0;
2408             }
2409 
2410             float pressure;
2411             switch (mCalibration.pressureCalibration) {
2412             case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
2413             case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
2414                 pressure = rawPressure * mLocked.pressureScale;
2415                 break;
2416             default:
2417                 pressure = 1;
2418                 break;
2419             }
2420 
2421             // TouchMajor and TouchMinor
2422             float touchMajor, touchMinor;
2423             switch (mCalibration.touchSizeCalibration) {
2424             case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
2425                 touchMajor = in.touchMajor * mLocked.geometricScale;
2426                 if (mRawAxes.touchMinor.valid) {
2427                     touchMinor = in.touchMinor * mLocked.geometricScale;
2428                 } else {
2429                     touchMinor = touchMajor;
2430                 }
2431                 break;
2432             case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE:
2433                 touchMajor = toolMajor * pressure;
2434                 touchMinor = toolMinor * pressure;
2435                 break;
2436             default:
2437                 touchMajor = 0;
2438                 touchMinor = 0;
2439                 break;
2440             }
2441 
2442             if (touchMajor > toolMajor) {
2443                 touchMajor = toolMajor;
2444             }
2445             if (touchMinor > toolMinor) {
2446                 touchMinor = toolMinor;
2447             }
2448 
2449             // Size
2450             float size;
2451             switch (mCalibration.sizeCalibration) {
2452             case Calibration::SIZE_CALIBRATION_NORMALIZED: {
2453                 float rawSize = mRawAxes.toolMinor.valid
2454                         ? avg(in.toolMajor, in.toolMinor)
2455                         : in.toolMajor;
2456                 size = rawSize * mLocked.sizeScale;
2457                 break;
2458             }
2459             default:
2460                 size = 0;
2461                 break;
2462             }
2463 
2464             // Orientation
2465             float orientation;
2466             switch (mCalibration.orientationCalibration) {
2467             case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
2468                 orientation = in.orientation * mLocked.orientationScale;
2469                 break;
2470             default:
2471                 orientation = 0;
2472             }
2473 
2474             // Adjust coords for orientation.
2475             switch (mLocked.surfaceOrientation) {
2476             case InputReaderPolicyInterface::ROTATION_90: {
2477                 float xTemp = x;
2478                 x = y;
2479                 y = mLocked.surfaceWidth - xTemp;
2480                 orientation -= M_PI_2;
2481                 if (orientation < - M_PI_2) {
2482                     orientation += M_PI;
2483                 }
2484                 break;
2485             }
2486             case InputReaderPolicyInterface::ROTATION_180: {
2487                 x = mLocked.surfaceWidth - x;
2488                 y = mLocked.surfaceHeight - y;
2489                 orientation = - orientation;
2490                 break;
2491             }
2492             case InputReaderPolicyInterface::ROTATION_270: {
2493                 float xTemp = x;
2494                 x = mLocked.surfaceHeight - y;
2495                 y = xTemp;
2496                 orientation += M_PI_2;
2497                 if (orientation > M_PI_2) {
2498                     orientation -= M_PI;
2499                 }
2500                 break;
2501             }
2502             }
2503 
2504             // Write output coords.
2505             PointerCoords& out = pointerCoords[outIndex];
2506             out.x = x;
2507             out.y = y;
2508             out.pressure = pressure;
2509             out.size = size;
2510             out.touchMajor = touchMajor;
2511             out.touchMinor = touchMinor;
2512             out.toolMajor = toolMajor;
2513             out.toolMinor = toolMinor;
2514             out.orientation = orientation;
2515 
2516             pointerIds[outIndex] = int32_t(id);
2517 
2518             if (id == changedId) {
2519                 motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
2520             }
2521         }
2522 
2523         // Check edge flags by looking only at the first pointer since the flags are
2524         // global to the event.
2525         if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
2526             if (pointerCoords[0].x <= 0) {
2527                 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
2528             } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
2529                 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
2530             }
2531             if (pointerCoords[0].y <= 0) {
2532                 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
2533             } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
2534                 motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
2535             }
2536         }
2537 
2538         xPrecision = mLocked.orientedXPrecision;
2539         yPrecision = mLocked.orientedYPrecision;
2540     } // release lock
2541 
2542     getDispatcher()->notifyMotion(when, getDeviceId(), getSources(), policyFlags,
2543             motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
2544             pointerCount, pointerIds, pointerCoords,
2545             xPrecision, yPrecision, mDownTime);
2546 }
2547 
isPointInsideSurfaceLocked(int32_t x,int32_t y)2548 bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
2549     if (mRawAxes.x.valid && mRawAxes.y.valid) {
2550         return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
2551                 && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
2552     }
2553     return true;
2554 }
2555 
findVirtualKeyHitLocked(int32_t x,int32_t y)2556 const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
2557         int32_t x, int32_t y) {
2558     size_t numVirtualKeys = mLocked.virtualKeys.size();
2559     for (size_t i = 0; i < numVirtualKeys; i++) {
2560         const VirtualKey& virtualKey = mLocked.virtualKeys[i];
2561 
2562 #if DEBUG_VIRTUAL_KEYS
2563         LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
2564                 "left=%d, top=%d, right=%d, bottom=%d",
2565                 x, y,
2566                 virtualKey.keyCode, virtualKey.scanCode,
2567                 virtualKey.hitLeft, virtualKey.hitTop,
2568                 virtualKey.hitRight, virtualKey.hitBottom);
2569 #endif
2570 
2571         if (virtualKey.isHit(x, y)) {
2572             return & virtualKey;
2573         }
2574     }
2575 
2576     return NULL;
2577 }
2578 
calculatePointerIds()2579 void TouchInputMapper::calculatePointerIds() {
2580     uint32_t currentPointerCount = mCurrentTouch.pointerCount;
2581     uint32_t lastPointerCount = mLastTouch.pointerCount;
2582 
2583     if (currentPointerCount == 0) {
2584         // No pointers to assign.
2585         mCurrentTouch.idBits.clear();
2586     } else if (lastPointerCount == 0) {
2587         // All pointers are new.
2588         mCurrentTouch.idBits.clear();
2589         for (uint32_t i = 0; i < currentPointerCount; i++) {
2590             mCurrentTouch.pointers[i].id = i;
2591             mCurrentTouch.idToIndex[i] = i;
2592             mCurrentTouch.idBits.markBit(i);
2593         }
2594     } else if (currentPointerCount == 1 && lastPointerCount == 1) {
2595         // Only one pointer and no change in count so it must have the same id as before.
2596         uint32_t id = mLastTouch.pointers[0].id;
2597         mCurrentTouch.pointers[0].id = id;
2598         mCurrentTouch.idToIndex[id] = 0;
2599         mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
2600     } else {
2601         // General case.
2602         // We build a heap of squared euclidean distances between current and last pointers
2603         // associated with the current and last pointer indices.  Then, we find the best
2604         // match (by distance) for each current pointer.
2605         PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
2606 
2607         uint32_t heapSize = 0;
2608         for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
2609                 currentPointerIndex++) {
2610             for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
2611                     lastPointerIndex++) {
2612                 int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
2613                         - mLastTouch.pointers[lastPointerIndex].x;
2614                 int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
2615                         - mLastTouch.pointers[lastPointerIndex].y;
2616 
2617                 uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
2618 
2619                 // Insert new element into the heap (sift up).
2620                 heap[heapSize].currentPointerIndex = currentPointerIndex;
2621                 heap[heapSize].lastPointerIndex = lastPointerIndex;
2622                 heap[heapSize].distance = distance;
2623                 heapSize += 1;
2624             }
2625         }
2626 
2627         // Heapify
2628         for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
2629             startIndex -= 1;
2630             for (uint32_t parentIndex = startIndex; ;) {
2631                 uint32_t childIndex = parentIndex * 2 + 1;
2632                 if (childIndex >= heapSize) {
2633                     break;
2634                 }
2635 
2636                 if (childIndex + 1 < heapSize
2637                         && heap[childIndex + 1].distance < heap[childIndex].distance) {
2638                     childIndex += 1;
2639                 }
2640 
2641                 if (heap[parentIndex].distance <= heap[childIndex].distance) {
2642                     break;
2643                 }
2644 
2645                 swap(heap[parentIndex], heap[childIndex]);
2646                 parentIndex = childIndex;
2647             }
2648         }
2649 
2650 #if DEBUG_POINTER_ASSIGNMENT
2651         LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
2652         for (size_t i = 0; i < heapSize; i++) {
2653             LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
2654                     i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
2655                     heap[i].distance);
2656         }
2657 #endif
2658 
2659         // Pull matches out by increasing order of distance.
2660         // To avoid reassigning pointers that have already been matched, the loop keeps track
2661         // of which last and current pointers have been matched using the matchedXXXBits variables.
2662         // It also tracks the used pointer id bits.
2663         BitSet32 matchedLastBits(0);
2664         BitSet32 matchedCurrentBits(0);
2665         BitSet32 usedIdBits(0);
2666         bool first = true;
2667         for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
2668             for (;;) {
2669                 if (first) {
2670                     // The first time through the loop, we just consume the root element of
2671                     // the heap (the one with smallest distance).
2672                     first = false;
2673                 } else {
2674                     // Previous iterations consumed the root element of the heap.
2675                     // Pop root element off of the heap (sift down).
2676                     heapSize -= 1;
2677                     assert(heapSize > 0);
2678 
2679                     // Sift down.
2680                     heap[0] = heap[heapSize];
2681                     for (uint32_t parentIndex = 0; ;) {
2682                         uint32_t childIndex = parentIndex * 2 + 1;
2683                         if (childIndex >= heapSize) {
2684                             break;
2685                         }
2686 
2687                         if (childIndex + 1 < heapSize
2688                                 && heap[childIndex + 1].distance < heap[childIndex].distance) {
2689                             childIndex += 1;
2690                         }
2691 
2692                         if (heap[parentIndex].distance <= heap[childIndex].distance) {
2693                             break;
2694                         }
2695 
2696                         swap(heap[parentIndex], heap[childIndex]);
2697                         parentIndex = childIndex;
2698                     }
2699 
2700 #if DEBUG_POINTER_ASSIGNMENT
2701                     LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
2702                     for (size_t i = 0; i < heapSize; i++) {
2703                         LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
2704                                 i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
2705                                 heap[i].distance);
2706                     }
2707 #endif
2708                 }
2709 
2710                 uint32_t currentPointerIndex = heap[0].currentPointerIndex;
2711                 if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
2712 
2713                 uint32_t lastPointerIndex = heap[0].lastPointerIndex;
2714                 if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
2715 
2716                 matchedCurrentBits.markBit(currentPointerIndex);
2717                 matchedLastBits.markBit(lastPointerIndex);
2718 
2719                 uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
2720                 mCurrentTouch.pointers[currentPointerIndex].id = id;
2721                 mCurrentTouch.idToIndex[id] = currentPointerIndex;
2722                 usedIdBits.markBit(id);
2723 
2724 #if DEBUG_POINTER_ASSIGNMENT
2725                 LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
2726                         lastPointerIndex, currentPointerIndex, id, heap[0].distance);
2727 #endif
2728                 break;
2729             }
2730         }
2731 
2732         // Assign fresh ids to new pointers.
2733         if (currentPointerCount > lastPointerCount) {
2734             for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
2735                 uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
2736                 uint32_t id = usedIdBits.firstUnmarkedBit();
2737 
2738                 mCurrentTouch.pointers[currentPointerIndex].id = id;
2739                 mCurrentTouch.idToIndex[id] = currentPointerIndex;
2740                 usedIdBits.markBit(id);
2741 
2742 #if DEBUG_POINTER_ASSIGNMENT
2743                 LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
2744                         currentPointerIndex, id);
2745 #endif
2746 
2747                 if (--i == 0) break; // done
2748                 matchedCurrentBits.markBit(currentPointerIndex);
2749             }
2750         }
2751 
2752         // Fix id bits.
2753         mCurrentTouch.idBits = usedIdBits;
2754     }
2755 }
2756 
2757 /* Special hack for devices that have bad screen data: if one of the
2758  * points has moved more than a screen height from the last position,
2759  * then drop it. */
applyBadTouchFilter()2760 bool TouchInputMapper::applyBadTouchFilter() {
2761     // This hack requires valid axis parameters.
2762     if (! mRawAxes.y.valid) {
2763         return false;
2764     }
2765 
2766     uint32_t pointerCount = mCurrentTouch.pointerCount;
2767 
2768     // Nothing to do if there are no points.
2769     if (pointerCount == 0) {
2770         return false;
2771     }
2772 
2773     // Don't do anything if a finger is going down or up.  We run
2774     // here before assigning pointer IDs, so there isn't a good
2775     // way to do per-finger matching.
2776     if (pointerCount != mLastTouch.pointerCount) {
2777         return false;
2778     }
2779 
2780     // We consider a single movement across more than a 7/16 of
2781     // the long size of the screen to be bad.  This was a magic value
2782     // determined by looking at the maximum distance it is feasible
2783     // to actually move in one sample.
2784     int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16;
2785 
2786     // XXX The original code in InputDevice.java included commented out
2787     //     code for testing the X axis.  Note that when we drop a point
2788     //     we don't actually restore the old X either.  Strange.
2789     //     The old code also tries to track when bad points were previously
2790     //     detected but it turns out that due to the placement of a "break"
2791     //     at the end of the loop, we never set mDroppedBadPoint to true
2792     //     so it is effectively dead code.
2793     // Need to figure out if the old code is busted or just overcomplicated
2794     // but working as intended.
2795 
2796     // Look through all new points and see if any are farther than
2797     // acceptable from all previous points.
2798     for (uint32_t i = pointerCount; i-- > 0; ) {
2799         int32_t y = mCurrentTouch.pointers[i].y;
2800         int32_t closestY = INT_MAX;
2801         int32_t closestDeltaY = 0;
2802 
2803 #if DEBUG_HACKS
2804         LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y);
2805 #endif
2806 
2807         for (uint32_t j = pointerCount; j-- > 0; ) {
2808             int32_t lastY = mLastTouch.pointers[j].y;
2809             int32_t deltaY = abs(y - lastY);
2810 
2811 #if DEBUG_HACKS
2812             LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d",
2813                     j, lastY, deltaY);
2814 #endif
2815 
2816             if (deltaY < maxDeltaY) {
2817                 goto SkipSufficientlyClosePoint;
2818             }
2819             if (deltaY < closestDeltaY) {
2820                 closestDeltaY = deltaY;
2821                 closestY = lastY;
2822             }
2823         }
2824 
2825         // Must not have found a close enough match.
2826 #if DEBUG_HACKS
2827         LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d",
2828                 i, y, closestY, closestDeltaY, maxDeltaY);
2829 #endif
2830 
2831         mCurrentTouch.pointers[i].y = closestY;
2832         return true; // XXX original code only corrects one point
2833 
2834     SkipSufficientlyClosePoint: ;
2835     }
2836 
2837     // No change.
2838     return false;
2839 }
2840 
2841 /* Special hack for devices that have bad screen data: drop points where
2842  * the coordinate value for one axis has jumped to the other pointer's location.
2843  */
applyJumpyTouchFilter()2844 bool TouchInputMapper::applyJumpyTouchFilter() {
2845     // This hack requires valid axis parameters.
2846     if (! mRawAxes.y.valid) {
2847         return false;
2848     }
2849 
2850     uint32_t pointerCount = mCurrentTouch.pointerCount;
2851     if (mLastTouch.pointerCount != pointerCount) {
2852 #if DEBUG_HACKS
2853         LOGD("JumpyTouchFilter: Different pointer count %d -> %d",
2854                 mLastTouch.pointerCount, pointerCount);
2855         for (uint32_t i = 0; i < pointerCount; i++) {
2856             LOGD("  Pointer %d (%d, %d)", i,
2857                     mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
2858         }
2859 #endif
2860 
2861         if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
2862             if (mLastTouch.pointerCount == 1 && pointerCount == 2) {
2863                 // Just drop the first few events going from 1 to 2 pointers.
2864                 // They're bad often enough that they're not worth considering.
2865                 mCurrentTouch.pointerCount = 1;
2866                 mJumpyTouchFilter.jumpyPointsDropped += 1;
2867 
2868 #if DEBUG_HACKS
2869                 LOGD("JumpyTouchFilter: Pointer 2 dropped");
2870 #endif
2871                 return true;
2872             } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) {
2873                 // The event when we go from 2 -> 1 tends to be messed up too
2874                 mCurrentTouch.pointerCount = 2;
2875                 mCurrentTouch.pointers[0] = mLastTouch.pointers[0];
2876                 mCurrentTouch.pointers[1] = mLastTouch.pointers[1];
2877                 mJumpyTouchFilter.jumpyPointsDropped += 1;
2878 
2879 #if DEBUG_HACKS
2880                 for (int32_t i = 0; i < 2; i++) {
2881                     LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i,
2882                             mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
2883                 }
2884 #endif
2885                 return true;
2886             }
2887         }
2888         // Reset jumpy points dropped on other transitions or if limit exceeded.
2889         mJumpyTouchFilter.jumpyPointsDropped = 0;
2890 
2891 #if DEBUG_HACKS
2892         LOGD("JumpyTouchFilter: Transition - drop limit reset");
2893 #endif
2894         return false;
2895     }
2896 
2897     // We have the same number of pointers as last time.
2898     // A 'jumpy' point is one where the coordinate value for one axis
2899     // has jumped to the other pointer's location. No need to do anything
2900     // else if we only have one pointer.
2901     if (pointerCount < 2) {
2902         return false;
2903     }
2904 
2905     if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
2906         int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
2907 
2908         // We only replace the single worst jumpy point as characterized by pointer distance
2909         // in a single axis.
2910         int32_t badPointerIndex = -1;
2911         int32_t badPointerReplacementIndex = -1;
2912         int32_t badPointerDistance = INT_MIN; // distance to be corrected
2913 
2914         for (uint32_t i = pointerCount; i-- > 0; ) {
2915             int32_t x = mCurrentTouch.pointers[i].x;
2916             int32_t y = mCurrentTouch.pointers[i].y;
2917 
2918 #if DEBUG_HACKS
2919             LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y);
2920 #endif
2921 
2922             // Check if a touch point is too close to another's coordinates
2923             bool dropX = false, dropY = false;
2924             for (uint32_t j = 0; j < pointerCount; j++) {
2925                 if (i == j) {
2926                     continue;
2927                 }
2928 
2929                 if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) {
2930                     dropX = true;
2931                     break;
2932                 }
2933 
2934                 if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) {
2935                     dropY = true;
2936                     break;
2937                 }
2938             }
2939             if (! dropX && ! dropY) {
2940                 continue; // not jumpy
2941             }
2942 
2943             // Find a replacement candidate by comparing with older points on the
2944             // complementary (non-jumpy) axis.
2945             int32_t distance = INT_MIN; // distance to be corrected
2946             int32_t replacementIndex = -1;
2947 
2948             if (dropX) {
2949                 // X looks too close.  Find an older replacement point with a close Y.
2950                 int32_t smallestDeltaY = INT_MAX;
2951                 for (uint32_t j = 0; j < pointerCount; j++) {
2952                     int32_t deltaY = abs(y - mLastTouch.pointers[j].y);
2953                     if (deltaY < smallestDeltaY) {
2954                         smallestDeltaY = deltaY;
2955                         replacementIndex = j;
2956                     }
2957                 }
2958                 distance = abs(x - mLastTouch.pointers[replacementIndex].x);
2959             } else {
2960                 // Y looks too close.  Find an older replacement point with a close X.
2961                 int32_t smallestDeltaX = INT_MAX;
2962                 for (uint32_t j = 0; j < pointerCount; j++) {
2963                     int32_t deltaX = abs(x - mLastTouch.pointers[j].x);
2964                     if (deltaX < smallestDeltaX) {
2965                         smallestDeltaX = deltaX;
2966                         replacementIndex = j;
2967                     }
2968                 }
2969                 distance = abs(y - mLastTouch.pointers[replacementIndex].y);
2970             }
2971 
2972             // If replacing this pointer would correct a worse error than the previous ones
2973             // considered, then use this replacement instead.
2974             if (distance > badPointerDistance) {
2975                 badPointerIndex = i;
2976                 badPointerReplacementIndex = replacementIndex;
2977                 badPointerDistance = distance;
2978             }
2979         }
2980 
2981         // Correct the jumpy pointer if one was found.
2982         if (badPointerIndex >= 0) {
2983 #if DEBUG_HACKS
2984             LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)",
2985                     badPointerIndex,
2986                     mLastTouch.pointers[badPointerReplacementIndex].x,
2987                     mLastTouch.pointers[badPointerReplacementIndex].y);
2988 #endif
2989 
2990             mCurrentTouch.pointers[badPointerIndex].x =
2991                     mLastTouch.pointers[badPointerReplacementIndex].x;
2992             mCurrentTouch.pointers[badPointerIndex].y =
2993                     mLastTouch.pointers[badPointerReplacementIndex].y;
2994             mJumpyTouchFilter.jumpyPointsDropped += 1;
2995             return true;
2996         }
2997     }
2998 
2999     mJumpyTouchFilter.jumpyPointsDropped = 0;
3000     return false;
3001 }
3002 
3003 /* Special hack for devices that have bad screen data: aggregate and
3004  * compute averages of the coordinate data, to reduce the amount of
3005  * jitter seen by applications. */
applyAveragingTouchFilter()3006 void TouchInputMapper::applyAveragingTouchFilter() {
3007     for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) {
3008         uint32_t id = mCurrentTouch.pointers[currentIndex].id;
3009         int32_t x = mCurrentTouch.pointers[currentIndex].x;
3010         int32_t y = mCurrentTouch.pointers[currentIndex].y;
3011         int32_t pressure;
3012         switch (mCalibration.pressureSource) {
3013         case Calibration::PRESSURE_SOURCE_PRESSURE:
3014             pressure = mCurrentTouch.pointers[currentIndex].pressure;
3015             break;
3016         case Calibration::PRESSURE_SOURCE_TOUCH:
3017             pressure = mCurrentTouch.pointers[currentIndex].touchMajor;
3018             break;
3019         default:
3020             pressure = 1;
3021             break;
3022         }
3023 
3024         if (mLastTouch.idBits.hasBit(id)) {
3025             // Pointer was down before and is still down now.
3026             // Compute average over history trace.
3027             uint32_t start = mAveragingTouchFilter.historyStart[id];
3028             uint32_t end = mAveragingTouchFilter.historyEnd[id];
3029 
3030             int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x;
3031             int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y;
3032             uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
3033 
3034 #if DEBUG_HACKS
3035             LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld",
3036                     id, distance);
3037 #endif
3038 
3039             if (distance < AVERAGING_DISTANCE_LIMIT) {
3040                 // Increment end index in preparation for recording new historical data.
3041                 end += 1;
3042                 if (end > AVERAGING_HISTORY_SIZE) {
3043                     end = 0;
3044                 }
3045 
3046                 // If the end index has looped back to the start index then we have filled
3047                 // the historical trace up to the desired size so we drop the historical
3048                 // data at the start of the trace.
3049                 if (end == start) {
3050                     start += 1;
3051                     if (start > AVERAGING_HISTORY_SIZE) {
3052                         start = 0;
3053                     }
3054                 }
3055 
3056                 // Add the raw data to the historical trace.
3057                 mAveragingTouchFilter.historyStart[id] = start;
3058                 mAveragingTouchFilter.historyEnd[id] = end;
3059                 mAveragingTouchFilter.historyData[end].pointers[id].x = x;
3060                 mAveragingTouchFilter.historyData[end].pointers[id].y = y;
3061                 mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure;
3062 
3063                 // Average over all historical positions in the trace by total pressure.
3064                 int32_t averagedX = 0;
3065                 int32_t averagedY = 0;
3066                 int32_t totalPressure = 0;
3067                 for (;;) {
3068                     int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x;
3069                     int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y;
3070                     int32_t historicalPressure = mAveragingTouchFilter.historyData[start]
3071                             .pointers[id].pressure;
3072 
3073                     averagedX += historicalX * historicalPressure;
3074                     averagedY += historicalY * historicalPressure;
3075                     totalPressure += historicalPressure;
3076 
3077                     if (start == end) {
3078                         break;
3079                     }
3080 
3081                     start += 1;
3082                     if (start > AVERAGING_HISTORY_SIZE) {
3083                         start = 0;
3084                     }
3085                 }
3086 
3087                 if (totalPressure != 0) {
3088                     averagedX /= totalPressure;
3089                     averagedY /= totalPressure;
3090 
3091 #if DEBUG_HACKS
3092                     LOGD("AveragingTouchFilter: Pointer id %d - "
3093                             "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
3094                             averagedX, averagedY);
3095 #endif
3096 
3097                     mCurrentTouch.pointers[currentIndex].x = averagedX;
3098                     mCurrentTouch.pointers[currentIndex].y = averagedY;
3099                 }
3100             } else {
3101 #if DEBUG_HACKS
3102                 LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
3103 #endif
3104             }
3105         } else {
3106 #if DEBUG_HACKS
3107             LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id);
3108 #endif
3109         }
3110 
3111         // Reset pointer history.
3112         mAveragingTouchFilter.historyStart[id] = 0;
3113         mAveragingTouchFilter.historyEnd[id] = 0;
3114         mAveragingTouchFilter.historyData[0].pointers[id].x = x;
3115         mAveragingTouchFilter.historyData[0].pointers[id].y = y;
3116         mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure;
3117     }
3118 }
3119 
getKeyCodeState(uint32_t sourceMask,int32_t keyCode)3120 int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
3121     { // acquire lock
3122         AutoMutex _l(mLock);
3123 
3124         if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
3125             return AKEY_STATE_VIRTUAL;
3126         }
3127 
3128         size_t numVirtualKeys = mLocked.virtualKeys.size();
3129         for (size_t i = 0; i < numVirtualKeys; i++) {
3130             const VirtualKey& virtualKey = mLocked.virtualKeys[i];
3131             if (virtualKey.keyCode == keyCode) {
3132                 return AKEY_STATE_UP;
3133             }
3134         }
3135     } // release lock
3136 
3137     return AKEY_STATE_UNKNOWN;
3138 }
3139 
getScanCodeState(uint32_t sourceMask,int32_t scanCode)3140 int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
3141     { // acquire lock
3142         AutoMutex _l(mLock);
3143 
3144         if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
3145             return AKEY_STATE_VIRTUAL;
3146         }
3147 
3148         size_t numVirtualKeys = mLocked.virtualKeys.size();
3149         for (size_t i = 0; i < numVirtualKeys; i++) {
3150             const VirtualKey& virtualKey = mLocked.virtualKeys[i];
3151             if (virtualKey.scanCode == scanCode) {
3152                 return AKEY_STATE_UP;
3153             }
3154         }
3155     } // release lock
3156 
3157     return AKEY_STATE_UNKNOWN;
3158 }
3159 
markSupportedKeyCodes(uint32_t sourceMask,size_t numCodes,const int32_t * keyCodes,uint8_t * outFlags)3160 bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
3161         const int32_t* keyCodes, uint8_t* outFlags) {
3162     { // acquire lock
3163         AutoMutex _l(mLock);
3164 
3165         size_t numVirtualKeys = mLocked.virtualKeys.size();
3166         for (size_t i = 0; i < numVirtualKeys; i++) {
3167             const VirtualKey& virtualKey = mLocked.virtualKeys[i];
3168 
3169             for (size_t i = 0; i < numCodes; i++) {
3170                 if (virtualKey.keyCode == keyCodes[i]) {
3171                     outFlags[i] = 1;
3172                 }
3173             }
3174         }
3175     } // release lock
3176 
3177     return true;
3178 }
3179 
3180 
3181 // --- SingleTouchInputMapper ---
3182 
SingleTouchInputMapper(InputDevice * device,int32_t associatedDisplayId)3183 SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
3184         TouchInputMapper(device, associatedDisplayId) {
3185     initialize();
3186 }
3187 
~SingleTouchInputMapper()3188 SingleTouchInputMapper::~SingleTouchInputMapper() {
3189 }
3190 
initialize()3191 void SingleTouchInputMapper::initialize() {
3192     mAccumulator.clear();
3193 
3194     mDown = false;
3195     mX = 0;
3196     mY = 0;
3197     mPressure = 0; // default to 0 for devices that don't report pressure
3198     mToolWidth = 0; // default to 0 for devices that don't report tool width
3199 }
3200 
reset()3201 void SingleTouchInputMapper::reset() {
3202     TouchInputMapper::reset();
3203 
3204     initialize();
3205  }
3206 
process(const RawEvent * rawEvent)3207 void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
3208     switch (rawEvent->type) {
3209     case EV_KEY:
3210         switch (rawEvent->scanCode) {
3211         case BTN_TOUCH:
3212             mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;
3213             mAccumulator.btnTouch = rawEvent->value != 0;
3214             // Don't sync immediately.  Wait until the next SYN_REPORT since we might
3215             // not have received valid position information yet.  This logic assumes that
3216             // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet.
3217             break;
3218         }
3219         break;
3220 
3221     case EV_ABS:
3222         switch (rawEvent->scanCode) {
3223         case ABS_X:
3224             mAccumulator.fields |= Accumulator::FIELD_ABS_X;
3225             mAccumulator.absX = rawEvent->value;
3226             break;
3227         case ABS_Y:
3228             mAccumulator.fields |= Accumulator::FIELD_ABS_Y;
3229             mAccumulator.absY = rawEvent->value;
3230             break;
3231         case ABS_PRESSURE:
3232             mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE;
3233             mAccumulator.absPressure = rawEvent->value;
3234             break;
3235         case ABS_TOOL_WIDTH:
3236             mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH;
3237             mAccumulator.absToolWidth = rawEvent->value;
3238             break;
3239         }
3240         break;
3241 
3242     case EV_SYN:
3243         switch (rawEvent->scanCode) {
3244         case SYN_REPORT:
3245             sync(rawEvent->when);
3246             break;
3247         }
3248         break;
3249     }
3250 }
3251 
sync(nsecs_t when)3252 void SingleTouchInputMapper::sync(nsecs_t when) {
3253     uint32_t fields = mAccumulator.fields;
3254     if (fields == 0) {
3255         return; // no new state changes, so nothing to do
3256     }
3257 
3258     if (fields & Accumulator::FIELD_BTN_TOUCH) {
3259         mDown = mAccumulator.btnTouch;
3260     }
3261 
3262     if (fields & Accumulator::FIELD_ABS_X) {
3263         mX = mAccumulator.absX;
3264     }
3265 
3266     if (fields & Accumulator::FIELD_ABS_Y) {
3267         mY = mAccumulator.absY;
3268     }
3269 
3270     if (fields & Accumulator::FIELD_ABS_PRESSURE) {
3271         mPressure = mAccumulator.absPressure;
3272     }
3273 
3274     if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) {
3275         mToolWidth = mAccumulator.absToolWidth;
3276     }
3277 
3278     mCurrentTouch.clear();
3279 
3280     if (mDown) {
3281         mCurrentTouch.pointerCount = 1;
3282         mCurrentTouch.pointers[0].id = 0;
3283         mCurrentTouch.pointers[0].x = mX;
3284         mCurrentTouch.pointers[0].y = mY;
3285         mCurrentTouch.pointers[0].pressure = mPressure;
3286         mCurrentTouch.pointers[0].touchMajor = 0;
3287         mCurrentTouch.pointers[0].touchMinor = 0;
3288         mCurrentTouch.pointers[0].toolMajor = mToolWidth;
3289         mCurrentTouch.pointers[0].toolMinor = mToolWidth;
3290         mCurrentTouch.pointers[0].orientation = 0;
3291         mCurrentTouch.idToIndex[0] = 0;
3292         mCurrentTouch.idBits.markBit(0);
3293     }
3294 
3295     syncTouch(when, true);
3296 
3297     mAccumulator.clear();
3298 }
3299 
configureRawAxes()3300 void SingleTouchInputMapper::configureRawAxes() {
3301     TouchInputMapper::configureRawAxes();
3302 
3303     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
3304     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
3305     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
3306     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
3307 }
3308 
3309 
3310 // --- MultiTouchInputMapper ---
3311 
MultiTouchInputMapper(InputDevice * device,int32_t associatedDisplayId)3312 MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
3313         TouchInputMapper(device, associatedDisplayId) {
3314     initialize();
3315 }
3316 
~MultiTouchInputMapper()3317 MultiTouchInputMapper::~MultiTouchInputMapper() {
3318 }
3319 
initialize()3320 void MultiTouchInputMapper::initialize() {
3321     mAccumulator.clear();
3322 }
3323 
reset()3324 void MultiTouchInputMapper::reset() {
3325     TouchInputMapper::reset();
3326 
3327     initialize();
3328 }
3329 
process(const RawEvent * rawEvent)3330 void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
3331     switch (rawEvent->type) {
3332     case EV_ABS: {
3333         uint32_t pointerIndex = mAccumulator.pointerCount;
3334         Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex];
3335 
3336         switch (rawEvent->scanCode) {
3337         case ABS_MT_POSITION_X:
3338             pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X;
3339             pointer->absMTPositionX = rawEvent->value;
3340             break;
3341         case ABS_MT_POSITION_Y:
3342             pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y;
3343             pointer->absMTPositionY = rawEvent->value;
3344             break;
3345         case ABS_MT_TOUCH_MAJOR:
3346             pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR;
3347             pointer->absMTTouchMajor = rawEvent->value;
3348             break;
3349         case ABS_MT_TOUCH_MINOR:
3350             pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR;
3351             pointer->absMTTouchMinor = rawEvent->value;
3352             break;
3353         case ABS_MT_WIDTH_MAJOR:
3354             pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
3355             pointer->absMTWidthMajor = rawEvent->value;
3356             break;
3357         case ABS_MT_WIDTH_MINOR:
3358             pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR;
3359             pointer->absMTWidthMinor = rawEvent->value;
3360             break;
3361         case ABS_MT_ORIENTATION:
3362             pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION;
3363             pointer->absMTOrientation = rawEvent->value;
3364             break;
3365         case ABS_MT_TRACKING_ID:
3366             pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID;
3367             pointer->absMTTrackingId = rawEvent->value;
3368             break;
3369         case ABS_MT_PRESSURE:
3370             pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE;
3371             pointer->absMTPressure = rawEvent->value;
3372             break;
3373         }
3374         break;
3375     }
3376 
3377     case EV_SYN:
3378         switch (rawEvent->scanCode) {
3379         case SYN_MT_REPORT: {
3380             // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
3381             uint32_t pointerIndex = mAccumulator.pointerCount;
3382 
3383             if (mAccumulator.pointers[pointerIndex].fields) {
3384                 if (pointerIndex == MAX_POINTERS) {
3385                     LOGW("MultiTouch device driver returned more than maximum of %d pointers.",
3386                             MAX_POINTERS);
3387                 } else {
3388                     pointerIndex += 1;
3389                     mAccumulator.pointerCount = pointerIndex;
3390                 }
3391             }
3392 
3393             mAccumulator.pointers[pointerIndex].clear();
3394             break;
3395         }
3396 
3397         case SYN_REPORT:
3398             sync(rawEvent->when);
3399             break;
3400         }
3401         break;
3402     }
3403 }
3404 
sync(nsecs_t when)3405 void MultiTouchInputMapper::sync(nsecs_t when) {
3406     static const uint32_t REQUIRED_FIELDS =
3407             Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y;
3408 
3409     uint32_t inCount = mAccumulator.pointerCount;
3410     uint32_t outCount = 0;
3411     bool havePointerIds = true;
3412 
3413     mCurrentTouch.clear();
3414 
3415     for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
3416         const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex];
3417         uint32_t fields = inPointer.fields;
3418 
3419         if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
3420             // Some drivers send empty MT sync packets without X / Y to indicate a pointer up.
3421             // Drop this finger.
3422             continue;
3423         }
3424 
3425         PointerData& outPointer = mCurrentTouch.pointers[outCount];
3426         outPointer.x = inPointer.absMTPositionX;
3427         outPointer.y = inPointer.absMTPositionY;
3428 
3429         if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
3430             if (inPointer.absMTPressure <= 0) {
3431                 // Some devices send sync packets with X / Y but with a 0 pressure to indicate
3432                 // a pointer going up.  Drop this finger.
3433                 continue;
3434             }
3435             outPointer.pressure = inPointer.absMTPressure;
3436         } else {
3437             // Default pressure to 0 if absent.
3438             outPointer.pressure = 0;
3439         }
3440 
3441         if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
3442             if (inPointer.absMTTouchMajor <= 0) {
3443                 // Some devices send sync packets with X / Y but with a 0 touch major to indicate
3444                 // a pointer going up.  Drop this finger.
3445                 continue;
3446             }
3447             outPointer.touchMajor = inPointer.absMTTouchMajor;
3448         } else {
3449             // Default touch area to 0 if absent.
3450             outPointer.touchMajor = 0;
3451         }
3452 
3453         if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
3454             outPointer.touchMinor = inPointer.absMTTouchMinor;
3455         } else {
3456             // Assume touch area is circular.
3457             outPointer.touchMinor = outPointer.touchMajor;
3458         }
3459 
3460         if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
3461             outPointer.toolMajor = inPointer.absMTWidthMajor;
3462         } else {
3463             // Default tool area to 0 if absent.
3464             outPointer.toolMajor = 0;
3465         }
3466 
3467         if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
3468             outPointer.toolMinor = inPointer.absMTWidthMinor;
3469         } else {
3470             // Assume tool area is circular.
3471             outPointer.toolMinor = outPointer.toolMajor;
3472         }
3473 
3474         if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
3475             outPointer.orientation = inPointer.absMTOrientation;
3476         } else {
3477             // Default orientation to vertical if absent.
3478             outPointer.orientation = 0;
3479         }
3480 
3481         // Assign pointer id using tracking id if available.
3482         if (havePointerIds) {
3483             if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
3484                 uint32_t id = uint32_t(inPointer.absMTTrackingId);
3485 
3486                 if (id > MAX_POINTER_ID) {
3487 #if DEBUG_POINTERS
3488                     LOGD("Pointers: Ignoring driver provided pointer id %d because "
3489                             "it is larger than max supported id %d",
3490                             id, MAX_POINTER_ID);
3491 #endif
3492                     havePointerIds = false;
3493                 }
3494                 else {
3495                     outPointer.id = id;
3496                     mCurrentTouch.idToIndex[id] = outCount;
3497                     mCurrentTouch.idBits.markBit(id);
3498                 }
3499             } else {
3500                 havePointerIds = false;
3501             }
3502         }
3503 
3504         outCount += 1;
3505     }
3506 
3507     mCurrentTouch.pointerCount = outCount;
3508 
3509     syncTouch(when, havePointerIds);
3510 
3511     mAccumulator.clear();
3512 }
3513 
configureRawAxes()3514 void MultiTouchInputMapper::configureRawAxes() {
3515     TouchInputMapper::configureRawAxes();
3516 
3517     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x);
3518     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y);
3519     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor);
3520     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor);
3521     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor);
3522     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor);
3523     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation);
3524     getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure);
3525 }
3526 
3527 
3528 } // namespace android
3529