Mir

Merge lp:~dandrader/mir/InputReader_tests into lp:~mir-team/mir/trunk

Proposed by Daniel d'Andrada
Status: Superseded
Proposed branch: lp:~dandrader/mir/InputReader_tests
Merge into: lp:~mir-team/mir/trunk
Diff against target: 5237 lines (+5153/-27)
6 files modified
3rd_party/android-deps/android/input.h (+0/-21)
3rd_party/android-deps/std/PropertyMap.h (+14/-4)
3rd_party/android-deps/std/Vector.h (+1/-1)
3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp (+2/-1)
tests/unit-tests/android_input/CMakeLists.txt (+1/-0)
tests/unit-tests/android_input/input_reader.cpp (+5135/-0)
To merge this branch: bzr merge lp:~dandrader/mir/InputReader_tests
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve
Kevin DuBois (community) test run on mako Approve
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Approve
Review via email: mp+186654@code.launchpad.net

This proposal has been superseded by a proposal from 2013-09-25.

Commit message

Add tests for Android's InputReader & friends

To help detecting regressions once we start making more intrusive (or deeper)
modifications to this code.

Interestingly enough, one of the tests is failing already and was disabled.

Taken from https://android.googlesource.com/platform/frameworks/base with head
at commit 4fd42e5a90e88e34d2e870852a4d26457a712d16

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Looks good to me! Didn't go through all the tests line by line obviously though :)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Robert Carr (robertcarr) wrote :

Running jenkins again.

Revision history for this message
Daniel d'Andrada (dandrader) wrote :

> Running jenkins again.

Jenkins seems to fail because valgrind shows some possible memory leaks in those tests. Which is actually quite possible. I gonna check then myself after I'm done with my current task. So if jenkins fail again I should probably set this MP to "work in progress" in the meantime.

Revision history for this message
Robert Carr (robertcarr) wrote :

I think the failure is only here:
[ RUN ] DisplayConfigurationTest.display_configuration_reaches_client
unknown file: Failure
C++ exception with description "Failed to find server" thrown in the test body.

which was due to some intermittent CI issues we were having (amd64 CI was running slow slow slowww).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

I'm okay with adding the android tests. I don't understand at a low level what is going on in all these tests, but then again i'm not sure what's going on in the android input stack, so I'd feel better with the tests than without.

Revision history for this message
Kevin DuBois (kdub) :
review: Approve (test run on mako)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

... but it would probably be better to retarget this at lp:~mir-team/mir/development-branch, to help keep devel and trunk in sync.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '3rd_party/android-deps/android/input.h'
2--- 3rd_party/android-deps/android/input.h 2013-05-03 16:38:07 +0000
3+++ 3rd_party/android-deps/android/input.h 2013-09-24 17:50:10 +0000
4@@ -460,27 +460,6 @@
5 AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2
6 };
7
8-/*
9- * Constants used to retrieve information about the range of motion for a particular
10- * coordinate of a motion event.
11- *
12- * Refer to the documentation on android.view.InputDevice for more details about input sources
13- * and their correct interpretation.
14- *
15- * DEPRECATION NOTICE: These constants are deprecated. Use AMOTION_EVENT_AXIS_* constants instead.
16- */
17-enum {
18- AINPUT_MOTION_RANGE_X = AMOTION_EVENT_AXIS_X,
19- AINPUT_MOTION_RANGE_Y = AMOTION_EVENT_AXIS_Y,
20- AINPUT_MOTION_RANGE_PRESSURE = AMOTION_EVENT_AXIS_PRESSURE,
21- AINPUT_MOTION_RANGE_SIZE = AMOTION_EVENT_AXIS_SIZE,
22- AINPUT_MOTION_RANGE_TOUCH_MAJOR = AMOTION_EVENT_AXIS_TOUCH_MAJOR,
23- AINPUT_MOTION_RANGE_TOUCH_MINOR = AMOTION_EVENT_AXIS_TOUCH_MINOR,
24- AINPUT_MOTION_RANGE_TOOL_MAJOR = AMOTION_EVENT_AXIS_TOOL_MAJOR,
25- AINPUT_MOTION_RANGE_TOOL_MINOR = AMOTION_EVENT_AXIS_TOOL_MINOR,
26- AINPUT_MOTION_RANGE_ORIENTATION = AMOTION_EVENT_AXIS_ORIENTATION
27-} __attribute__ ((deprecated));
28-
29 #ifdef __cplusplus
30 }
31 #endif
32
33=== modified file '3rd_party/android-deps/std/PropertyMap.h'
34--- 3rd_party/android-deps/std/PropertyMap.h 2013-05-03 16:38:07 +0000
35+++ 3rd_party/android-deps/std/PropertyMap.h 2013-09-24 17:50:10 +0000
36@@ -62,10 +62,20 @@
37 /* Clears the property map. */
38 void clear() { options = boost::program_options::variables_map(); }
39
40-// /* Adds a property.
41-// * Replaces the property with the same key if it is already present.
42-// */
43-// void addProperty(const String8& key, const String8& value);
44+ /* Adds a property.
45+ * Replaces the property with the same key if it is already present.
46+ */
47+ void addProperty(const String8& key, const String8& value)
48+ {
49+ namespace po = boost::program_options;
50+ options.insert(std::make_pair(key, po::variable_value(value, false)));
51+ }
52+
53+ void addAll(const PropertyMap* other)
54+ {
55+ options.insert(other->options.begin(), other->options.end());
56+ }
57+
58 //
59 // /* Returns true if the property map contains the specified key. */
60 // bool hasProperty(const String8& key) const;
61
62=== modified file '3rd_party/android-deps/std/Vector.h'
63--- 3rd_party/android-deps/std/Vector.h 2013-03-13 04:54:15 +0000
64+++ 3rd_party/android-deps/std/Vector.h 2013-09-24 17:50:10 +0000
65@@ -62,7 +62,7 @@
66
67 /*! copy operator */
68 // const Vector<ValueType>& operator = (const Vector<ValueType>& rhs) const;
69- Vector<ValueType>& operator=(const Vector<ValueType>& rhs) = default;
70+ Vector<ValueType>& operator=(const Vector<ValueType>& /* rhs */) = default;
71
72 // const Vector<ValueType>& operator = (const SortedVector<ValueType>& rhs) const;
73 // Vector<ValueType>& operator = (const SortedVector<ValueType>& rhs);
74
75=== modified file '3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp'
76--- 3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp 2013-03-13 04:54:15 +0000
77+++ 3rd_party/android-input/android/frameworks/base/services/input/InputReader.cpp 2013-09-24 17:50:10 +0000
78@@ -2553,7 +2553,8 @@
79 TouchInputMapper::TouchInputMapper(InputDevice* device) :
80 InputMapper(device),
81 mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
82- mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
83+ mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1),
84+ mPointerUsage(POINTER_USAGE_NONE) {
85 }
86
87 TouchInputMapper::~TouchInputMapper() {
88
89=== modified file 'tests/unit-tests/android_input/CMakeLists.txt'
90--- tests/unit-tests/android_input/CMakeLists.txt 2013-03-13 04:54:15 +0000
91+++ tests/unit-tests/android_input/CMakeLists.txt 2013-09-24 17:50:10 +0000
92@@ -1,4 +1,5 @@
93 list(APPEND UNIT_TEST_SOURCES
94+ ${CMAKE_CURRENT_SOURCE_DIR}/input_reader.cpp
95 ${CMAKE_CURRENT_SOURCE_DIR}/sorted_vector.cpp
96 ${CMAKE_CURRENT_SOURCE_DIR}/property_map.cpp
97 ${CMAKE_CURRENT_SOURCE_DIR}/string8.cpp
98
99=== added file 'tests/unit-tests/android_input/input_reader.cpp'
100--- tests/unit-tests/android_input/input_reader.cpp 1970-01-01 00:00:00 +0000
101+++ tests/unit-tests/android_input/input_reader.cpp 2013-09-24 17:50:10 +0000
102@@ -0,0 +1,5135 @@
103+/*
104+ * Copyright (C) 2010 The Android Open Source Project
105+ *
106+ * Licensed under the Apache License, Version 2.0 (the "License");
107+ * you may not use this file except in compliance with the License.
108+ * You may obtain a copy of the License at
109+ *
110+ * http://www.apache.org/licenses/LICENSE-2.0
111+ *
112+ * Unless required by applicable law or agreed to in writing, software
113+ * distributed under the License is distributed on an "AS IS" BASIS,
114+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
115+ * See the License for the specific language governing permissions and
116+ * limitations under the License.
117+ */
118+
119+#include <InputReader.h>
120+
121+#include <android/keycodes.h>
122+
123+#include <utils/List.h>
124+#include <gtest/gtest.h>
125+#include <gmock/gmock.h>
126+#include <math.h>
127+
128+#include <mir/logging/logger.h>
129+#include <mir/logging/input_report.h>
130+
131+namespace ml = mir::logging;
132+
133+using std::string;
134+
135+namespace
136+{
137+class TestLogger : public ml::Logger
138+{
139+public:
140+ void log(Severity severity, const string& message, const string& component) override {
141+ (void)severity;
142+ (void)message;
143+ (void)component;
144+ }
145+};
146+}
147+
148+
149+namespace android {
150+
151+// An arbitrary time value.
152+static const nsecs_t ARBITRARY_TIME = 1234;
153+
154+// Arbitrary display properties.
155+static const int32_t DISPLAY_ID = 0;
156+static const int32_t DISPLAY_WIDTH = 480;
157+static const int32_t DISPLAY_HEIGHT = 800;
158+
159+// Error tolerance for floating point assertions.
160+static const float EPSILON = 0.001f;
161+
162+template<typename T>
163+static inline T min(T a, T b) {
164+ return a < b ? a : b;
165+}
166+
167+static inline float avg(float x, float y) {
168+ return (x + y) / 2;
169+}
170+
171+
172+// --- FakePointerController ---
173+
174+class FakePointerController : public PointerControllerInterface {
175+ bool mHaveBounds;
176+ float mMinX, mMinY, mMaxX, mMaxY;
177+ float mX, mY;
178+ int32_t mButtonState;
179+
180+protected:
181+ virtual ~FakePointerController() { }
182+
183+public:
184+ FakePointerController() :
185+ mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
186+ mButtonState(0) {
187+ }
188+
189+ void setBounds(float minX, float minY, float maxX, float maxY) {
190+ mHaveBounds = true;
191+ mMinX = minX;
192+ mMinY = minY;
193+ mMaxX = maxX;
194+ mMaxY = maxY;
195+ }
196+
197+ virtual void setPosition(float x, float y) {
198+ mX = x;
199+ mY = y;
200+ }
201+
202+ virtual void setButtonState(int32_t buttonState) {
203+ mButtonState = buttonState;
204+ }
205+
206+ virtual int32_t getButtonState() const {
207+ return mButtonState;
208+ }
209+
210+ virtual void getPosition(float* outX, float* outY) const {
211+ *outX = mX;
212+ *outY = mY;
213+ }
214+
215+private:
216+ virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
217+ *outMinX = mMinX;
218+ *outMinY = mMinY;
219+ *outMaxX = mMaxX;
220+ *outMaxY = mMaxY;
221+ return mHaveBounds;
222+ }
223+
224+ virtual void move(float deltaX, float deltaY) {
225+ mX += deltaX;
226+ if (mX < mMinX) mX = mMinX;
227+ if (mX > mMaxX) mX = mMaxX;
228+ mY += deltaY;
229+ if (mY < mMinY) mY = mMinY;
230+ if (mY > mMaxY) mY = mMaxY;
231+ }
232+
233+ void fade(Transition /*transition*/) override {}
234+
235+ void unfade(Transition /*transition*/) override {}
236+
237+ void setPresentation(Presentation /*presentation*/) override {}
238+
239+ void setSpots(const PointerCoords* /*spotCoords*/, const uint32_t* /*spotIdToIndex*/,
240+ BitSet32 /*spotIdBits*/) override {}
241+
242+ void clearSpots() override {}
243+};
244+
245+
246+// --- FakeInputReaderPolicy ---
247+
248+class FakeInputReaderPolicy : public InputReaderPolicyInterface {
249+ InputReaderConfiguration mConfig;
250+ KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
251+ Vector<InputDeviceInfo> mInputDevices;
252+
253+protected:
254+ virtual ~FakeInputReaderPolicy() { }
255+
256+public:
257+ FakeInputReaderPolicy() {
258+ }
259+
260+ void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) {
261+ // Set the size of both the internal and external display at the same time.
262+ mConfig.setDisplayInfo(displayId, false /*external*/, width, height, orientation);
263+ mConfig.setDisplayInfo(displayId, true /*external*/, width, height, orientation);
264+ }
265+
266+ void addExcludedDeviceName(const String8& deviceName) {
267+ mConfig.excludedDeviceNames.push(deviceName);
268+ }
269+
270+ void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) {
271+ mPointerControllers.add(deviceId, controller);
272+ }
273+
274+ const InputReaderConfiguration* getReaderConfiguration() const {
275+ return &mConfig;
276+ }
277+
278+ const Vector<InputDeviceInfo>& getInputDevices() const {
279+ return mInputDevices;
280+ }
281+
282+private:
283+ virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
284+ *outConfig = mConfig;
285+ }
286+
287+ virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
288+ return mPointerControllers.valueFor(deviceId);
289+ }
290+
291+ virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) {
292+ mInputDevices = inputDevices;
293+ }
294+
295+ sp<KeyCharacterMap> getKeyboardLayoutOverlay(const String8& inputDeviceDescriptor) override {
296+ (void) inputDeviceDescriptor;
297+ return NULL;
298+ }
299+
300+ String8 getDeviceAlias(const InputDeviceIdentifier& identifier) override {
301+ (void)identifier;
302+ return String8();
303+ }
304+};
305+
306+
307+// --- FakeInputListener ---
308+
309+class FakeInputListener : public InputListenerInterface {
310+private:
311+ List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgsQueue;
312+ List<NotifyDeviceResetArgs> mNotifyDeviceResetArgsQueue;
313+ List<NotifyKeyArgs> mNotifyKeyArgsQueue;
314+ List<NotifyMotionArgs> mNotifyMotionArgsQueue;
315+ List<NotifySwitchArgs> mNotifySwitchArgsQueue;
316+
317+protected:
318+ virtual ~FakeInputListener() { }
319+
320+public:
321+ FakeInputListener() {
322+ }
323+
324+ void assertNotifyConfigurationChangedWasCalled(
325+ NotifyConfigurationChangedArgs* outEventArgs = NULL) {
326+ ASSERT_FALSE(mNotifyConfigurationChangedArgsQueue.empty())
327+ << "Expected notifyConfigurationChanged() to have been called.";
328+ if (outEventArgs) {
329+ *outEventArgs = *mNotifyConfigurationChangedArgsQueue.begin();
330+ }
331+ mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
332+ }
333+
334+ void assertNotifyDeviceResetWasCalled(
335+ NotifyDeviceResetArgs* outEventArgs = NULL) {
336+ ASSERT_FALSE(mNotifyDeviceResetArgsQueue.empty())
337+ << "Expected notifyDeviceReset() to have been called.";
338+ if (outEventArgs) {
339+ *outEventArgs = *mNotifyDeviceResetArgsQueue.begin();
340+ }
341+ mNotifyDeviceResetArgsQueue.erase(mNotifyDeviceResetArgsQueue.begin());
342+ }
343+
344+ void assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs = NULL) {
345+ ASSERT_FALSE(mNotifyKeyArgsQueue.empty())
346+ << "Expected notifyKey() to have been called.";
347+ if (outEventArgs) {
348+ *outEventArgs = *mNotifyKeyArgsQueue.begin();
349+ }
350+ mNotifyKeyArgsQueue.erase(mNotifyKeyArgsQueue.begin());
351+ }
352+
353+ void assertNotifyKeyWasNotCalled() {
354+ ASSERT_TRUE(mNotifyKeyArgsQueue.empty())
355+ << "Expected notifyKey() to not have been called.";
356+ }
357+
358+ void assertNotifyMotionWasCalled(NotifyMotionArgs* outEventArgs = NULL) {
359+ ASSERT_FALSE(mNotifyMotionArgsQueue.empty())
360+ << "Expected notifyMotion() to have been called.";
361+ if (outEventArgs) {
362+ *outEventArgs = *mNotifyMotionArgsQueue.begin();
363+ }
364+ mNotifyMotionArgsQueue.erase(mNotifyMotionArgsQueue.begin());
365+ }
366+
367+ void assertNotifyMotionWasNotCalled() {
368+ ASSERT_TRUE(mNotifyMotionArgsQueue.empty())
369+ << "Expected notifyMotion() to not have been called.";
370+ }
371+
372+ void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = NULL) {
373+ ASSERT_FALSE(mNotifySwitchArgsQueue.empty())
374+ << "Expected notifySwitch() to have been called.";
375+ if (outEventArgs) {
376+ *outEventArgs = *mNotifySwitchArgsQueue.begin();
377+ }
378+ mNotifySwitchArgsQueue.erase(mNotifySwitchArgsQueue.begin());
379+ }
380+
381+private:
382+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
383+ mNotifyConfigurationChangedArgsQueue.push_back(*args);
384+ }
385+
386+ virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) {
387+ mNotifyDeviceResetArgsQueue.push_back(*args);
388+ }
389+
390+ virtual void notifyKey(const NotifyKeyArgs* args) {
391+ mNotifyKeyArgsQueue.push_back(*args);
392+ }
393+
394+ virtual void notifyMotion(const NotifyMotionArgs* args) {
395+ mNotifyMotionArgsQueue.push_back(*args);
396+ }
397+
398+ virtual void notifySwitch(const NotifySwitchArgs* args) {
399+ mNotifySwitchArgsQueue.push_back(*args);
400+ }
401+};
402+
403+
404+// --- FakeEventHub ---
405+
406+class FakeEventHub : public EventHubInterface {
407+ struct KeyInfo {
408+ int32_t keyCode;
409+ uint32_t flags;
410+ };
411+
412+ struct Device {
413+ InputDeviceIdentifier identifier;
414+ uint32_t classes;
415+ PropertyMap configuration;
416+ KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
417+ KeyedVector<int, bool> relativeAxes;
418+ KeyedVector<int32_t, int32_t> keyCodeStates;
419+ KeyedVector<int32_t, int32_t> scanCodeStates;
420+ KeyedVector<int32_t, int32_t> switchStates;
421+ KeyedVector<int32_t, int32_t> absoluteAxisValue;
422+ KeyedVector<int32_t, KeyInfo> keysByScanCode;
423+ KeyedVector<int32_t, KeyInfo> keysByUsageCode;
424+ KeyedVector<int32_t, bool> leds;
425+ Vector<VirtualKeyDefinition> virtualKeys;
426+
427+ Device(uint32_t classes) :
428+ classes(classes) {
429+ }
430+ };
431+
432+ KeyedVector<int32_t, Device*> mDevices;
433+ Vector<String8> mExcludedDevices;
434+ List<RawEvent> mEvents;
435+
436+protected:
437+ virtual ~FakeEventHub() {
438+ for (size_t i = 0; i < mDevices.size(); i++) {
439+ delete mDevices.valueAt(i);
440+ }
441+ }
442+
443+public:
444+ FakeEventHub() { }
445+
446+ void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
447+ Device* device = new Device(classes);
448+ device->identifier.name = name;
449+ mDevices.add(deviceId, device);
450+
451+ enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0);
452+ }
453+
454+ void removeDevice(int32_t deviceId) {
455+ delete mDevices.valueFor(deviceId);
456+ mDevices.removeItem(deviceId);
457+
458+ enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
459+ }
460+
461+ void finishDeviceScan() {
462+ enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
463+ }
464+
465+ void addConfigurationProperty(int32_t deviceId, const String8& key, const String8& value) {
466+ Device* device = getDevice(deviceId);
467+ device->configuration.addProperty(key, value);
468+ }
469+
470+ void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) {
471+ Device* device = getDevice(deviceId);
472+ device->configuration.addAll(configuration);
473+ }
474+
475+ void addAbsoluteAxis(int32_t deviceId, int axis,
476+ int32_t minValue, int32_t maxValue, int flat, int fuzz, int resolution = 0) {
477+ Device* device = getDevice(deviceId);
478+
479+ RawAbsoluteAxisInfo info;
480+ info.valid = true;
481+ info.minValue = minValue;
482+ info.maxValue = maxValue;
483+ info.flat = flat;
484+ info.fuzz = fuzz;
485+ info.resolution = resolution;
486+ device->absoluteAxes.add(axis, info);
487+ }
488+
489+ void addRelativeAxis(int32_t deviceId, int32_t axis) {
490+ Device* device = getDevice(deviceId);
491+ device->relativeAxes.add(axis, true);
492+ }
493+
494+ void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
495+ Device* device = getDevice(deviceId);
496+ device->keyCodeStates.replaceValueFor(keyCode, state);
497+ }
498+
499+ void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
500+ Device* device = getDevice(deviceId);
501+ device->scanCodeStates.replaceValueFor(scanCode, state);
502+ }
503+
504+ void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
505+ Device* device = getDevice(deviceId);
506+ device->switchStates.replaceValueFor(switchCode, state);
507+ }
508+
509+ void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
510+ Device* device = getDevice(deviceId);
511+ device->absoluteAxisValue.replaceValueFor(axis, value);
512+ }
513+
514+ void addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
515+ int32_t keyCode, uint32_t flags) {
516+ Device* device = getDevice(deviceId);
517+ KeyInfo info;
518+ info.keyCode = keyCode;
519+ info.flags = flags;
520+ if (scanCode) {
521+ device->keysByScanCode.add(scanCode, info);
522+ }
523+ if (usageCode) {
524+ device->keysByUsageCode.add(usageCode, info);
525+ }
526+ }
527+
528+ void addLed(int32_t deviceId, int32_t led, bool initialState) {
529+ Device* device = getDevice(deviceId);
530+ device->leds.add(led, initialState);
531+ }
532+
533+ bool getLedState(int32_t deviceId, int32_t led) {
534+ Device* device = getDevice(deviceId);
535+ return device->leds.valueFor(led);
536+ }
537+
538+ Vector<String8>& getExcludedDevices() {
539+ return mExcludedDevices;
540+ }
541+
542+ void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) {
543+ Device* device = getDevice(deviceId);
544+ device->virtualKeys.push(definition);
545+ }
546+
547+ void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
548+ int32_t code, int32_t value) {
549+ RawEvent event;
550+ event.when = when;
551+ event.deviceId = deviceId;
552+ event.type = type;
553+ event.code = code;
554+ event.value = value;
555+ mEvents.push_back(event);
556+
557+ if (type == EV_ABS) {
558+ setAbsoluteAxisValue(deviceId, code, value);
559+ }
560+ }
561+
562+ void assertQueueIsEmpty() {
563+ ASSERT_EQ(size_t(0), mEvents.size())
564+ << "Expected the event queue to be empty (fully consumed).";
565+ }
566+
567+private:
568+ Device* getDevice(int32_t deviceId) const {
569+ ssize_t index = mDevices.indexOfKey(deviceId);
570+ return index >= 0 ? mDevices.valueAt(index) : NULL;
571+ }
572+
573+ virtual uint32_t getDeviceClasses(int32_t deviceId) const {
574+ Device* device = getDevice(deviceId);
575+ return device ? device->classes : 0;
576+ }
577+
578+ virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const {
579+ Device* device = getDevice(deviceId);
580+ return device ? device->identifier : InputDeviceIdentifier();
581+ }
582+
583+ virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const {
584+ Device* device = getDevice(deviceId);
585+ if (device) {
586+ *outConfiguration = device->configuration;
587+ }
588+ }
589+
590+ virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
591+ RawAbsoluteAxisInfo* outAxisInfo) const {
592+ outAxisInfo->clear();
593+ Device* device = getDevice(deviceId);
594+ if (device) {
595+ ssize_t index = device->absoluteAxes.indexOfKey(axis);
596+ if (index >= 0) {
597+ *outAxisInfo = device->absoluteAxes.valueAt(index);
598+ return OK;
599+ }
600+ }
601+ return -1;
602+ }
603+
604+ virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
605+ Device* device = getDevice(deviceId);
606+ if (device) {
607+ return device->relativeAxes.indexOfKey(axis) >= 0;
608+ }
609+ return false;
610+ }
611+
612+ bool hasInputProperty(int32_t deviceId, int property) const override {
613+ (void)deviceId;
614+ (void)property;
615+ return false;
616+ }
617+
618+ virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
619+ int32_t* outKeycode, uint32_t* outFlags) const {
620+ Device* device = getDevice(deviceId);
621+ if (device) {
622+ const KeyInfo* key = getKey(device, scanCode, usageCode);
623+ if (key) {
624+ if (outKeycode) {
625+ *outKeycode = key->keyCode;
626+ }
627+ if (outFlags) {
628+ *outFlags = key->flags;
629+ }
630+ return OK;
631+ }
632+ }
633+ return NAME_NOT_FOUND;
634+ }
635+
636+ const KeyInfo* getKey(Device* device, int32_t scanCode, int32_t usageCode) const {
637+ if (usageCode) {
638+ ssize_t index = device->keysByUsageCode.indexOfKey(usageCode);
639+ if (index >= 0) {
640+ return &device->keysByUsageCode.valueAt(index);
641+ }
642+ }
643+ if (scanCode) {
644+ ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
645+ if (index >= 0) {
646+ return &device->keysByScanCode.valueAt(index);
647+ }
648+ }
649+ return NULL;
650+ }
651+
652+ status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const override {
653+ (void)deviceId;
654+ (void)scanCode;
655+ (void)outAxisInfo;
656+ return NAME_NOT_FOUND;
657+ }
658+
659+ virtual void setExcludedDevices(const Vector<String8>& devices) {
660+ mExcludedDevices = devices;
661+ }
662+
663+ size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) override {
664+ (void)timeoutMillis;
665+ (void)bufferSize;
666+
667+ if (mEvents.empty()) {
668+ return 0;
669+ }
670+
671+ *buffer = *mEvents.begin();
672+ mEvents.erase(mEvents.begin());
673+ return 1;
674+ }
675+
676+ int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
677+ Device* device = getDevice(deviceId);
678+ if (device) {
679+ ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
680+ if (index >= 0) {
681+ return device->scanCodeStates.valueAt(index);
682+ }
683+ }
684+ return AKEY_STATE_UNKNOWN;
685+ }
686+
687+ int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
688+ Device* device = getDevice(deviceId);
689+ if (device) {
690+ ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
691+ if (index >= 0) {
692+ return device->keyCodeStates.valueAt(index);
693+ }
694+ }
695+ return AKEY_STATE_UNKNOWN;
696+ }
697+
698+ int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
699+ Device* device = getDevice(deviceId);
700+ if (device) {
701+ ssize_t index = device->switchStates.indexOfKey(sw);
702+ if (index >= 0) {
703+ return device->switchStates.valueAt(index);
704+ }
705+ }
706+ return AKEY_STATE_UNKNOWN;
707+ }
708+
709+ virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
710+ int32_t* outValue) const {
711+ Device* device = getDevice(deviceId);
712+ if (device) {
713+ ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
714+ if (index >= 0) {
715+ *outValue = device->absoluteAxisValue.valueAt(index);
716+ return OK;
717+ }
718+ }
719+ *outValue = 0;
720+ return -1;
721+ }
722+
723+ virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
724+ uint8_t* outFlags) const {
725+ bool result = false;
726+ Device* device = getDevice(deviceId);
727+ if (device) {
728+ for (size_t i = 0; i < numCodes; i++) {
729+ for (size_t j = 0; j < device->keysByScanCode.size(); j++) {
730+ if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
731+ outFlags[i] = 1;
732+ result = true;
733+ }
734+ }
735+ for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
736+ if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
737+ outFlags[i] = 1;
738+ result = true;
739+ }
740+ }
741+ }
742+ }
743+ return result;
744+ }
745+
746+ virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const {
747+ Device* device = getDevice(deviceId);
748+ if (device) {
749+ ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
750+ return index >= 0;
751+ }
752+ return false;
753+ }
754+
755+ virtual bool hasLed(int32_t deviceId, int32_t led) const {
756+ Device* device = getDevice(deviceId);
757+ return device && device->leds.indexOfKey(led) >= 0;
758+ }
759+
760+ virtual void setLedState(int32_t deviceId, int32_t led, bool on) {
761+ Device* device = getDevice(deviceId);
762+ if (device) {
763+ ssize_t index = device->leds.indexOfKey(led);
764+ if (index >= 0) {
765+ device->leds.replaceValueAt(led, on);
766+ } else {
767+ ADD_FAILURE()
768+ << "Attempted to set the state of an LED that the EventHub declared "
769+ "was not present. led=" << led;
770+ }
771+ }
772+ }
773+
774+ void getVirtualKeyDefinitions(int32_t deviceId,
775+ Vector<VirtualKeyDefinition>& outVirtualKeys) const override {
776+ outVirtualKeys.clear();
777+
778+ Device* device = getDevice(deviceId);
779+ if (device) {
780+ outVirtualKeys.appendVector(device->virtualKeys);
781+ }
782+ }
783+
784+ sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const override {
785+ (void)deviceId;
786+ return NULL;
787+ }
788+
789+ bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) override {
790+ (void)deviceId;
791+ (void)map;
792+ return false;
793+ }
794+
795+ void vibrate(int32_t /*deviceId*/, nsecs_t /*duration*/) override {}
796+
797+ void cancelVibrate(int32_t /*deviceId*/) override {}
798+
799+ void wake() override {}
800+
801+ void dump(String8& /*dump*/) override {}
802+
803+ void monitor() override {}
804+
805+ void flush() override {}
806+
807+ void requestReopenDevices() override {}
808+
809+};
810+
811+
812+// --- FakeInputReaderContext ---
813+
814+class FakeInputReaderContext : public InputReaderContext {
815+ sp<EventHubInterface> mEventHub;
816+ sp<InputReaderPolicyInterface> mPolicy;
817+ sp<InputListenerInterface> mListener;
818+ int32_t mGlobalMetaState;
819+ bool mUpdateGlobalMetaStateWasCalled;
820+ int32_t mGeneration;
821+
822+public:
823+ FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
824+ const sp<InputReaderPolicyInterface>& policy,
825+ const sp<InputListenerInterface>& listener) :
826+ mEventHub(eventHub), mPolicy(policy), mListener(listener),
827+ mGlobalMetaState(0) {
828+ }
829+
830+ virtual ~FakeInputReaderContext() { }
831+
832+ void assertUpdateGlobalMetaStateWasCalled() {
833+ ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
834+ << "Expected updateGlobalMetaState() to have been called.";
835+ mUpdateGlobalMetaStateWasCalled = false;
836+ }
837+
838+ void setGlobalMetaState(int32_t state) {
839+ mGlobalMetaState = state;
840+ }
841+
842+private:
843+ virtual void updateGlobalMetaState() {
844+ mUpdateGlobalMetaStateWasCalled = true;
845+ }
846+
847+ virtual int32_t getGlobalMetaState() {
848+ return mGlobalMetaState;
849+ }
850+
851+ virtual EventHubInterface* getEventHub() {
852+ return mEventHub.get();
853+ }
854+
855+ virtual InputReaderPolicyInterface* getPolicy() {
856+ return mPolicy.get();
857+ }
858+
859+ virtual InputListenerInterface* getListener() {
860+ return mListener.get();
861+ }
862+
863+ void disableVirtualKeysUntil(nsecs_t /*time*/) override {}
864+
865+ bool shouldDropVirtualKey(nsecs_t now,
866+ InputDevice* device, int32_t keyCode, int32_t scanCode) override {
867+ (void) now;
868+ (void) device;
869+ (void) keyCode;
870+ (void) scanCode;
871+ return false;
872+ }
873+
874+ void fadePointer() override {}
875+
876+ void requestTimeoutAtTime(nsecs_t /*when*/) override {}
877+
878+ int32_t bumpGeneration() override {
879+ return ++mGeneration;
880+ }
881+};
882+
883+
884+// --- FakeInputMapper ---
885+
886+class FakeInputMapper : public InputMapper {
887+ uint32_t mSources;
888+ int32_t mKeyboardType;
889+ int32_t mMetaState;
890+ KeyedVector<int32_t, int32_t> mKeyCodeStates;
891+ KeyedVector<int32_t, int32_t> mScanCodeStates;
892+ KeyedVector<int32_t, int32_t> mSwitchStates;
893+ Vector<int32_t> mSupportedKeyCodes;
894+ RawEvent mLastEvent;
895+
896+ bool mConfigureWasCalled;
897+ bool mResetWasCalled;
898+ bool mProcessWasCalled;
899+
900+public:
901+ FakeInputMapper(InputDevice* device, uint32_t sources) :
902+ InputMapper(device),
903+ mSources(sources), mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
904+ mMetaState(0),
905+ mConfigureWasCalled(false), mResetWasCalled(false), mProcessWasCalled(false) {
906+ }
907+
908+ virtual ~FakeInputMapper() { }
909+
910+ void setKeyboardType(int32_t keyboardType) {
911+ mKeyboardType = keyboardType;
912+ }
913+
914+ void setMetaState(int32_t metaState) {
915+ mMetaState = metaState;
916+ }
917+
918+ void assertConfigureWasCalled() {
919+ ASSERT_TRUE(mConfigureWasCalled)
920+ << "Expected configure() to have been called.";
921+ mConfigureWasCalled = false;
922+ }
923+
924+ void assertResetWasCalled() {
925+ ASSERT_TRUE(mResetWasCalled)
926+ << "Expected reset() to have been called.";
927+ mResetWasCalled = false;
928+ }
929+
930+ void assertProcessWasCalled(RawEvent* outLastEvent = NULL) {
931+ ASSERT_TRUE(mProcessWasCalled)
932+ << "Expected process() to have been called.";
933+ if (outLastEvent) {
934+ *outLastEvent = mLastEvent;
935+ }
936+ mProcessWasCalled = false;
937+ }
938+
939+ void setKeyCodeState(int32_t keyCode, int32_t state) {
940+ mKeyCodeStates.replaceValueFor(keyCode, state);
941+ }
942+
943+ void setScanCodeState(int32_t scanCode, int32_t state) {
944+ mScanCodeStates.replaceValueFor(scanCode, state);
945+ }
946+
947+ void setSwitchState(int32_t switchCode, int32_t state) {
948+ mSwitchStates.replaceValueFor(switchCode, state);
949+ }
950+
951+ void addSupportedKeyCode(int32_t keyCode) {
952+ mSupportedKeyCodes.add(keyCode);
953+ }
954+
955+private:
956+ virtual uint32_t getSources() {
957+ return mSources;
958+ }
959+
960+ virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) {
961+ InputMapper::populateDeviceInfo(deviceInfo);
962+
963+ if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
964+ deviceInfo->setKeyboardType(mKeyboardType);
965+ }
966+ }
967+
968+ void configure(nsecs_t when,
969+ const InputReaderConfiguration* config, uint32_t changes) override {
970+ (void)when;
971+ (void)config;
972+ (void)changes;
973+ mConfigureWasCalled = true;
974+ }
975+
976+ void reset(nsecs_t when) override {
977+ (void)when;
978+ mResetWasCalled = true;
979+ }
980+
981+ void process(const RawEvent* rawEvent) override {
982+ mLastEvent = *rawEvent;
983+ mProcessWasCalled = true;
984+ }
985+
986+ int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override {
987+ (void)sourceMask;
988+ ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
989+ return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
990+ }
991+
992+ int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override {
993+ (void)sourceMask;
994+ ssize_t index = mScanCodeStates.indexOfKey(scanCode);
995+ return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
996+ }
997+
998+ int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode) override {
999+ (void)sourceMask;
1000+ ssize_t index = mSwitchStates.indexOfKey(switchCode);
1001+ return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
1002+ }
1003+
1004+ bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
1005+ const int32_t* keyCodes, uint8_t* outFlags) override {
1006+ (void)sourceMask;
1007+ bool result = false;
1008+ for (size_t i = 0; i < numCodes; i++) {
1009+ for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
1010+ if (keyCodes[i] == mSupportedKeyCodes[j]) {
1011+ outFlags[i] = 1;
1012+ result = true;
1013+ }
1014+ }
1015+ }
1016+ return result;
1017+ }
1018+
1019+ int32_t getMetaState() override {
1020+ return mMetaState;
1021+ }
1022+};
1023+
1024+
1025+// --- InstrumentedInputReader ---
1026+
1027+class InstrumentedInputReader : public InputReader {
1028+ InputDevice* mNextDevice;
1029+
1030+public:
1031+ InstrumentedInputReader(const sp<EventHubInterface>& eventHub,
1032+ const sp<InputReaderPolicyInterface>& policy,
1033+ const sp<InputListenerInterface>& listener) :
1034+ InputReader(eventHub, policy, listener),
1035+ mNextDevice(NULL) {
1036+ }
1037+
1038+ virtual ~InstrumentedInputReader() {
1039+ if (mNextDevice) {
1040+ delete mNextDevice;
1041+ }
1042+ }
1043+
1044+ void setNextDevice(InputDevice* device) {
1045+ mNextDevice = device;
1046+ }
1047+
1048+ InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) {
1049+ InputDeviceIdentifier identifier;
1050+ identifier.name = name;
1051+ int32_t generation = deviceId + 1;
1052+ return new InputDevice(&mContext, deviceId, generation, identifier, classes);
1053+ }
1054+
1055+protected:
1056+ virtual InputDevice* createDeviceLocked(int32_t deviceId,
1057+ const InputDeviceIdentifier& identifier, uint32_t classes) {
1058+ if (mNextDevice) {
1059+ InputDevice* device = mNextDevice;
1060+ mNextDevice = NULL;
1061+ return device;
1062+ }
1063+ return InputReader::createDeviceLocked(deviceId, identifier, classes);
1064+ }
1065+
1066+ friend class InputReaderTest;
1067+};
1068+
1069+
1070+// --- InputReaderTest ---
1071+
1072+class InputReaderTest : public testing::Test {
1073+protected:
1074+ sp<FakeInputListener> mFakeListener;
1075+ sp<FakeInputReaderPolicy> mFakePolicy;
1076+ sp<FakeEventHub> mFakeEventHub;
1077+ sp<InstrumentedInputReader> mReader;
1078+
1079+ virtual void SetUp() {
1080+ mir::logging::legacy_input_report::initialize(std::make_shared<TestLogger>());
1081+ mFakeEventHub = new FakeEventHub();
1082+ mFakePolicy = new FakeInputReaderPolicy();
1083+ mFakeListener = new FakeInputListener();
1084+
1085+ mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeListener);
1086+ }
1087+
1088+ virtual void TearDown() {
1089+ mReader.clear();
1090+
1091+ mFakeListener.clear();
1092+ mFakePolicy.clear();
1093+ mFakeEventHub.clear();
1094+ }
1095+
1096+ void addDevice(int32_t deviceId, const String8& name, uint32_t classes,
1097+ const PropertyMap* configuration) {
1098+ mFakeEventHub->addDevice(deviceId, name, classes);
1099+
1100+ if (configuration) {
1101+ mFakeEventHub->addConfigurationMap(deviceId, configuration);
1102+ }
1103+ mFakeEventHub->finishDeviceScan();
1104+ mReader->loopOnce();
1105+ mReader->loopOnce();
1106+ mFakeEventHub->assertQueueIsEmpty();
1107+ }
1108+
1109+ FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
1110+ const String8& name, uint32_t classes, uint32_t sources,
1111+ const PropertyMap* configuration) {
1112+ InputDevice* device = mReader->newDevice(deviceId, name, classes);
1113+ FakeInputMapper* mapper = new FakeInputMapper(device, sources);
1114+ device->addMapper(mapper);
1115+ mReader->setNextDevice(device);
1116+ addDevice(deviceId, name, classes, configuration);
1117+ return mapper;
1118+ }
1119+};
1120+
1121+TEST_F(InputReaderTest, GetInputDevices) {
1122+ ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
1123+ INPUT_DEVICE_CLASS_KEYBOARD, NULL));
1124+ ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("ignored"),
1125+ 0, NULL)); // no classes so device will be ignored
1126+
1127+ Vector<InputDeviceInfo> inputDevices;
1128+ mReader->getInputDevices(inputDevices);
1129+
1130+ ASSERT_EQ(1U, inputDevices.size());
1131+ ASSERT_EQ(1, inputDevices[0].getId());
1132+ ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
1133+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
1134+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
1135+ ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
1136+
1137+ // Should also have received a notification describing the new input devices.
1138+ inputDevices = mFakePolicy->getInputDevices();
1139+ ASSERT_EQ(1U, inputDevices.size());
1140+ ASSERT_EQ(1, inputDevices[0].getId());
1141+ ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
1142+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
1143+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
1144+ ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
1145+}
1146+
1147+TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
1148+ FakeInputMapper* mapper = NULL;
1149+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
1150+ INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
1151+ mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1152+
1153+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
1154+ AINPUT_SOURCE_ANY, AKEYCODE_A))
1155+ << "Should return unknown when the device id is >= 0 but unknown.";
1156+
1157+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(1,
1158+ AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1159+ << "Should return unknown when the device id is valid but the sources are not supported by the device.";
1160+
1161+ ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(1,
1162+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1163+ << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
1164+
1165+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
1166+ AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1167+ << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
1168+
1169+ ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
1170+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1171+ << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
1172+}
1173+
1174+TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
1175+ FakeInputMapper* mapper = NULL;
1176+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
1177+ INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
1178+ mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN);
1179+
1180+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
1181+ AINPUT_SOURCE_ANY, KEY_A))
1182+ << "Should return unknown when the device id is >= 0 but unknown.";
1183+
1184+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(1,
1185+ AINPUT_SOURCE_TRACKBALL, KEY_A))
1186+ << "Should return unknown when the device id is valid but the sources are not supported by the device.";
1187+
1188+ ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(1,
1189+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
1190+ << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
1191+
1192+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
1193+ AINPUT_SOURCE_TRACKBALL, KEY_A))
1194+ << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
1195+
1196+ ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
1197+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
1198+ << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
1199+}
1200+
1201+TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
1202+ FakeInputMapper* mapper = NULL;
1203+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
1204+ INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
1205+ mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN);
1206+
1207+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
1208+ AINPUT_SOURCE_ANY, SW_LID))
1209+ << "Should return unknown when the device id is >= 0 but unknown.";
1210+
1211+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(1,
1212+ AINPUT_SOURCE_TRACKBALL, SW_LID))
1213+ << "Should return unknown when the device id is valid but the sources are not supported by the device.";
1214+
1215+ ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(1,
1216+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
1217+ << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
1218+
1219+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
1220+ AINPUT_SOURCE_TRACKBALL, SW_LID))
1221+ << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
1222+
1223+ ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
1224+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
1225+ << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
1226+}
1227+
1228+TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
1229+ FakeInputMapper* mapper = NULL;
1230+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
1231+ INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
1232+ mapper->addSupportedKeyCode(AKEYCODE_A);
1233+ mapper->addSupportedKeyCode(AKEYCODE_B);
1234+
1235+ const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
1236+ uint8_t flags[4] = { 0, 0, 0, 1 };
1237+
1238+ ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, 4, keyCodes, flags))
1239+ << "Should return false when device id is >= 0 but unknown.";
1240+ ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
1241+
1242+ flags[3] = 1;
1243+ ASSERT_FALSE(mReader->hasKeys(1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
1244+ << "Should return false when device id is valid but the sources are not supported by the device.";
1245+ ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
1246+
1247+ flags[3] = 1;
1248+ ASSERT_TRUE(mReader->hasKeys(1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
1249+ << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
1250+ ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
1251+
1252+ flags[3] = 1;
1253+ ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
1254+ << "Should return false when the device id is < 0 but the sources are not supported by any device.";
1255+ ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
1256+
1257+ flags[3] = 1;
1258+ ASSERT_TRUE(mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
1259+ << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
1260+ ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
1261+}
1262+
1263+TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
1264+ addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD, NULL);
1265+
1266+ NotifyConfigurationChangedArgs args;
1267+
1268+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
1269+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
1270+}
1271+
1272+TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
1273+ FakeInputMapper* mapper = NULL;
1274+ ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
1275+ INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD, NULL));
1276+
1277+ mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, 1);
1278+ mReader->loopOnce();
1279+ ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
1280+
1281+ RawEvent event;
1282+ ASSERT_NO_FATAL_FAILURE(mapper->assertProcessWasCalled(&event));
1283+ ASSERT_EQ(0, event.when);
1284+ ASSERT_EQ(1, event.deviceId);
1285+ ASSERT_EQ(EV_KEY, event.type);
1286+ ASSERT_EQ(KEY_A, event.code);
1287+ ASSERT_EQ(1, event.value);
1288+}
1289+
1290+
1291+// --- InputDeviceTest ---
1292+
1293+class InputDeviceTest : public testing::Test {
1294+protected:
1295+ static const char* DEVICE_NAME;
1296+ static const int32_t DEVICE_ID;
1297+ static const int32_t DEVICE_GENERATION;
1298+ static const uint32_t DEVICE_CLASSES;
1299+
1300+ sp<FakeEventHub> mFakeEventHub;
1301+ sp<FakeInputReaderPolicy> mFakePolicy;
1302+ sp<FakeInputListener> mFakeListener;
1303+ FakeInputReaderContext* mFakeContext;
1304+
1305+ InputDevice* mDevice;
1306+
1307+ virtual void SetUp() {
1308+ mir::logging::legacy_input_report::initialize(std::make_shared<TestLogger>());
1309+ mFakeEventHub = new FakeEventHub();
1310+ mFakePolicy = new FakeInputReaderPolicy();
1311+ mFakeListener = new FakeInputListener();
1312+ mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
1313+
1314+ mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
1315+ InputDeviceIdentifier identifier;
1316+ identifier.name = DEVICE_NAME;
1317+ mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
1318+ identifier, DEVICE_CLASSES);
1319+ }
1320+
1321+ virtual void TearDown() {
1322+ delete mDevice;
1323+
1324+ delete mFakeContext;
1325+ mFakeListener.clear();
1326+ mFakePolicy.clear();
1327+ mFakeEventHub.clear();
1328+ }
1329+};
1330+
1331+const char* InputDeviceTest::DEVICE_NAME = "device";
1332+const int32_t InputDeviceTest::DEVICE_ID = 1;
1333+const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
1334+const uint32_t InputDeviceTest::DEVICE_CLASSES = INPUT_DEVICE_CLASS_KEYBOARD
1335+ | INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_JOYSTICK;
1336+
1337+TEST_F(InputDeviceTest, ImmutableProperties) {
1338+ ASSERT_EQ(DEVICE_ID, mDevice->getId());
1339+ ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
1340+ ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses());
1341+}
1342+
1343+TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
1344+ // Configuration.
1345+ InputReaderConfiguration config;
1346+ mDevice->configure(ARBITRARY_TIME, &config, 0);
1347+
1348+ // Reset.
1349+ mDevice->reset(ARBITRARY_TIME);
1350+
1351+ NotifyDeviceResetArgs resetArgs;
1352+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1353+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
1354+ ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
1355+
1356+ // Metadata.
1357+ ASSERT_TRUE(mDevice->isIgnored());
1358+ ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
1359+
1360+ InputDeviceInfo info;
1361+ mDevice->getDeviceInfo(&info);
1362+ ASSERT_EQ(DEVICE_ID, info.getId());
1363+ ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
1364+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
1365+ ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
1366+
1367+ // State queries.
1368+ ASSERT_EQ(0, mDevice->getMetaState());
1369+
1370+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
1371+ << "Ignored device should return unknown key code state.";
1372+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
1373+ << "Ignored device should return unknown scan code state.";
1374+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
1375+ << "Ignored device should return unknown switch state.";
1376+
1377+ const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
1378+ uint8_t flags[2] = { 0, 1 };
1379+ ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 2, keyCodes, flags))
1380+ << "Ignored device should never mark any key codes.";
1381+ ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
1382+ ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
1383+}
1384+
1385+TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
1386+ // Configuration.
1387+ mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8("key"), String8("value"));
1388+
1389+ FakeInputMapper* mapper1 = new FakeInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD);
1390+ mapper1->setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1391+ mapper1->setMetaState(AMETA_ALT_ON);
1392+ mapper1->addSupportedKeyCode(AKEYCODE_A);
1393+ mapper1->addSupportedKeyCode(AKEYCODE_B);
1394+ mapper1->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1395+ mapper1->setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
1396+ mapper1->setScanCodeState(2, AKEY_STATE_DOWN);
1397+ mapper1->setScanCodeState(3, AKEY_STATE_UP);
1398+ mapper1->setSwitchState(4, AKEY_STATE_DOWN);
1399+ mDevice->addMapper(mapper1);
1400+
1401+ FakeInputMapper* mapper2 = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN);
1402+ mapper2->setMetaState(AMETA_SHIFT_ON);
1403+ mDevice->addMapper(mapper2);
1404+
1405+ InputReaderConfiguration config;
1406+ mDevice->configure(ARBITRARY_TIME, &config, 0);
1407+
1408+ String8 propertyValue;
1409+ ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty(String8("key"), propertyValue))
1410+ << "Device should have read configuration during configuration phase.";
1411+ ASSERT_STREQ("value", propertyValue.c_str());
1412+
1413+ ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled());
1414+ ASSERT_NO_FATAL_FAILURE(mapper2->assertConfigureWasCalled());
1415+
1416+ // Reset
1417+ mDevice->reset(ARBITRARY_TIME);
1418+ ASSERT_NO_FATAL_FAILURE(mapper1->assertResetWasCalled());
1419+ ASSERT_NO_FATAL_FAILURE(mapper2->assertResetWasCalled());
1420+
1421+ NotifyDeviceResetArgs resetArgs;
1422+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1423+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
1424+ ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
1425+
1426+ // Metadata.
1427+ ASSERT_FALSE(mDevice->isIgnored());
1428+ ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
1429+
1430+ InputDeviceInfo info;
1431+ mDevice->getDeviceInfo(&info);
1432+ ASSERT_EQ(DEVICE_ID, info.getId());
1433+ ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
1434+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
1435+ ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
1436+
1437+ // State queries.
1438+ ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
1439+ << "Should query mappers and combine meta states.";
1440+
1441+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1442+ << "Should return unknown key code state when source not supported.";
1443+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1444+ << "Should return unknown scan code state when source not supported.";
1445+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
1446+ << "Should return unknown switch state when source not supported.";
1447+
1448+ ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
1449+ << "Should query mapper when source is supported.";
1450+ ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
1451+ << "Should query mapper when source is supported.";
1452+ ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
1453+ << "Should query mapper when source is supported.";
1454+
1455+ const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
1456+ uint8_t flags[4] = { 0, 0, 0, 1 };
1457+ ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
1458+ << "Should do nothing when source is unsupported.";
1459+ ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
1460+ ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
1461+ ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
1462+ ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
1463+
1464+ ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 4, keyCodes, flags))
1465+ << "Should query mapper when source is supported.";
1466+ ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
1467+ ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
1468+ ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
1469+ ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
1470+
1471+ // Event handling.
1472+ RawEvent event;
1473+ event.type = EV_KEY; // some arbitrary event type and code
1474+ event.code = KEY_A;
1475+ mDevice->process(&event, 1);
1476+
1477+ ASSERT_NO_FATAL_FAILURE(mapper1->assertProcessWasCalled());
1478+ ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled());
1479+}
1480+
1481+
1482+// --- InputMapperTest ---
1483+
1484+class InputMapperTest : public testing::Test {
1485+protected:
1486+ static const char* DEVICE_NAME;
1487+ static const int32_t DEVICE_ID;
1488+ static const int32_t DEVICE_GENERATION;
1489+ static const uint32_t DEVICE_CLASSES;
1490+
1491+ sp<FakeEventHub> mFakeEventHub;
1492+ sp<FakeInputReaderPolicy> mFakePolicy;
1493+ sp<FakeInputListener> mFakeListener;
1494+ FakeInputReaderContext* mFakeContext;
1495+ InputDevice* mDevice;
1496+
1497+ virtual void SetUp() {
1498+ mir::logging::legacy_input_report::initialize(std::make_shared<TestLogger>());
1499+ mFakeEventHub = new FakeEventHub();
1500+ mFakePolicy = new FakeInputReaderPolicy();
1501+ mFakeListener = new FakeInputListener();
1502+ mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
1503+ InputDeviceIdentifier identifier;
1504+ identifier.name = DEVICE_NAME;
1505+ mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
1506+ identifier, DEVICE_CLASSES);
1507+
1508+ mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
1509+ }
1510+
1511+ virtual void TearDown() {
1512+ delete mDevice;
1513+ delete mFakeContext;
1514+ mFakeListener.clear();
1515+ mFakePolicy.clear();
1516+ mFakeEventHub.clear();
1517+ }
1518+
1519+ void addConfigurationProperty(const char* key, const char* value) {
1520+ mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8(key), String8(value));
1521+ }
1522+
1523+ void addMapperAndConfigure(InputMapper* mapper) {
1524+ mDevice->addMapper(mapper);
1525+ mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
1526+ mDevice->reset(ARBITRARY_TIME);
1527+ }
1528+
1529+ void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
1530+ int32_t orientation) {
1531+ mFakePolicy->setDisplayInfo(displayId, width, height, orientation);
1532+ mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
1533+ InputReaderConfiguration::CHANGE_DISPLAY_INFO);
1534+ }
1535+
1536+ static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type,
1537+ int32_t code, int32_t value) {
1538+ RawEvent event;
1539+ event.when = when;
1540+ event.deviceId = deviceId;
1541+ event.type = type;
1542+ event.code = code;
1543+ event.value = value;
1544+ mapper->process(&event);
1545+ }
1546+
1547+ static void assertMotionRange(const InputDeviceInfo& info,
1548+ int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
1549+ const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
1550+ ASSERT_TRUE(range != NULL) << "Axis: " << axis << " Source: " << source;
1551+ ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
1552+ ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
1553+ ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
1554+ ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
1555+ ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
1556+ ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
1557+ }
1558+
1559+ static void assertPointerCoords(const PointerCoords& coords,
1560+ float x, float y, float pressure, float size,
1561+ float touchMajor, float touchMinor, float toolMajor, float toolMinor,
1562+ float orientation, float distance) {
1563+ ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1);
1564+ ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
1565+ ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
1566+ ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
1567+ ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 1);
1568+ ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 1);
1569+ ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1);
1570+ ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1);
1571+ ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
1572+ ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
1573+ }
1574+
1575+ static void assertPosition(const sp<FakePointerController>& controller, float x, float y) {
1576+ float actualX, actualY;
1577+ controller->getPosition(&actualX, &actualY);
1578+ ASSERT_NEAR(x, actualX, 1);
1579+ ASSERT_NEAR(y, actualY, 1);
1580+ }
1581+};
1582+
1583+const char* InputMapperTest::DEVICE_NAME = "device";
1584+const int32_t InputMapperTest::DEVICE_ID = 1;
1585+const int32_t InputMapperTest::DEVICE_GENERATION = 2;
1586+const uint32_t InputMapperTest::DEVICE_CLASSES = 0; // not needed for current tests
1587+
1588+
1589+// --- SwitchInputMapperTest ---
1590+
1591+class SwitchInputMapperTest : public InputMapperTest {
1592+protected:
1593+};
1594+
1595+TEST_F(SwitchInputMapperTest, GetSources) {
1596+ SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
1597+ addMapperAndConfigure(mapper);
1598+
1599+ ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources());
1600+}
1601+
1602+TEST_F(SwitchInputMapperTest, GetSwitchState) {
1603+ SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
1604+ addMapperAndConfigure(mapper);
1605+
1606+ mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 1);
1607+ ASSERT_EQ(1, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
1608+
1609+ mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 0);
1610+ ASSERT_EQ(0, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
1611+}
1612+
1613+TEST_F(SwitchInputMapperTest, Process) {
1614+ SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
1615+ addMapperAndConfigure(mapper);
1616+
1617+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 1);
1618+
1619+ NotifySwitchArgs args;
1620+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySwitchWasCalled(&args));
1621+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
1622+ ASSERT_EQ(SW_LID, args.switchCode);
1623+ ASSERT_EQ(1, args.switchValue);
1624+ ASSERT_EQ(uint32_t(0), args.policyFlags);
1625+}
1626+
1627+
1628+// --- KeyboardInputMapperTest ---
1629+
1630+class KeyboardInputMapperTest : public InputMapperTest {
1631+protected:
1632+ void testDPadKeyRotation(KeyboardInputMapper* mapper,
1633+ int32_t originalScanCode, int32_t rotatedKeyCode);
1634+};
1635+
1636+void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper,
1637+ int32_t originalScanCode, int32_t rotatedKeyCode) {
1638+ NotifyKeyArgs args;
1639+
1640+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, 1);
1641+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1642+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
1643+ ASSERT_EQ(originalScanCode, args.scanCode);
1644+ ASSERT_EQ(rotatedKeyCode, args.keyCode);
1645+
1646+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, 0);
1647+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1648+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
1649+ ASSERT_EQ(originalScanCode, args.scanCode);
1650+ ASSERT_EQ(rotatedKeyCode, args.keyCode);
1651+}
1652+
1653+
1654+TEST_F(KeyboardInputMapperTest, GetSources) {
1655+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1656+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1657+ addMapperAndConfigure(mapper);
1658+
1659+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper->getSources());
1660+}
1661+
1662+TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
1663+ const int32_t USAGE_A = 0x070004;
1664+ const int32_t USAGE_UNKNOWN = 0x07ffff;
1665+ mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
1666+ mFakeEventHub->addKey(DEVICE_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
1667+
1668+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1669+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1670+ addMapperAndConfigure(mapper);
1671+
1672+ // Key down by scan code.
1673+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1674+ EV_KEY, KEY_HOME, 1);
1675+ NotifyKeyArgs args;
1676+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1677+ ASSERT_EQ(DEVICE_ID, args.deviceId);
1678+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
1679+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
1680+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
1681+ ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
1682+ ASSERT_EQ(KEY_HOME, args.scanCode);
1683+ ASSERT_EQ(AMETA_NONE, args.metaState);
1684+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
1685+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
1686+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
1687+
1688+ // Key up by scan code.
1689+ process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
1690+ EV_KEY, KEY_HOME, 0);
1691+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1692+ ASSERT_EQ(DEVICE_ID, args.deviceId);
1693+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
1694+ ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
1695+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
1696+ ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
1697+ ASSERT_EQ(KEY_HOME, args.scanCode);
1698+ ASSERT_EQ(AMETA_NONE, args.metaState);
1699+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
1700+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
1701+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
1702+
1703+ // Key down by usage code.
1704+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1705+ EV_MSC, MSC_SCAN, USAGE_A);
1706+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1707+ EV_KEY, 0, 1);
1708+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1709+ ASSERT_EQ(DEVICE_ID, args.deviceId);
1710+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
1711+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
1712+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
1713+ ASSERT_EQ(AKEYCODE_A, args.keyCode);
1714+ ASSERT_EQ(0, args.scanCode);
1715+ ASSERT_EQ(AMETA_NONE, args.metaState);
1716+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
1717+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
1718+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
1719+
1720+ // Key up by usage code.
1721+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1722+ EV_MSC, MSC_SCAN, USAGE_A);
1723+ process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
1724+ EV_KEY, 0, 0);
1725+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1726+ ASSERT_EQ(DEVICE_ID, args.deviceId);
1727+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
1728+ ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
1729+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
1730+ ASSERT_EQ(AKEYCODE_A, args.keyCode);
1731+ ASSERT_EQ(0, args.scanCode);
1732+ ASSERT_EQ(AMETA_NONE, args.metaState);
1733+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
1734+ ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
1735+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
1736+
1737+ // Key down with unknown scan code or usage code.
1738+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1739+ EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
1740+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1741+ EV_KEY, KEY_UNKNOWN, 1);
1742+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1743+ ASSERT_EQ(DEVICE_ID, args.deviceId);
1744+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
1745+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
1746+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
1747+ ASSERT_EQ(0, args.keyCode);
1748+ ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
1749+ ASSERT_EQ(AMETA_NONE, args.metaState);
1750+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
1751+ ASSERT_EQ(0U, args.policyFlags);
1752+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
1753+
1754+ // Key up with unknown scan code or usage code.
1755+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1756+ EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
1757+ process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
1758+ EV_KEY, KEY_UNKNOWN, 0);
1759+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1760+ ASSERT_EQ(DEVICE_ID, args.deviceId);
1761+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
1762+ ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
1763+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
1764+ ASSERT_EQ(0, args.keyCode);
1765+ ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
1766+ ASSERT_EQ(AMETA_NONE, args.metaState);
1767+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
1768+ ASSERT_EQ(0U, args.policyFlags);
1769+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
1770+}
1771+
1772+TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
1773+ mFakeEventHub->addKey(DEVICE_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
1774+ mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0);
1775+
1776+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1777+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1778+ addMapperAndConfigure(mapper);
1779+
1780+ // Initial metastate.
1781+ ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
1782+
1783+ // Metakey down.
1784+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1785+ EV_KEY, KEY_LEFTSHIFT, 1);
1786+ NotifyKeyArgs args;
1787+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1788+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
1789+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
1790+ ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
1791+
1792+ // Key down.
1793+ process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
1794+ EV_KEY, KEY_A, 1);
1795+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1796+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
1797+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
1798+
1799+ // Key up.
1800+ process(mapper, ARBITRARY_TIME + 2, DEVICE_ID,
1801+ EV_KEY, KEY_A, 0);
1802+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1803+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
1804+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
1805+
1806+ // Metakey up.
1807+ process(mapper, ARBITRARY_TIME + 3, DEVICE_ID,
1808+ EV_KEY, KEY_LEFTSHIFT, 0);
1809+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1810+ ASSERT_EQ(AMETA_NONE, args.metaState);
1811+ ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
1812+ ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
1813+}
1814+
1815+TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
1816+ mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
1817+ mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
1818+ mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
1819+ mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
1820+
1821+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1822+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1823+ addMapperAndConfigure(mapper);
1824+
1825+ setDisplayInfoAndReconfigure(DISPLAY_ID,
1826+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
1827+ DISPLAY_ORIENTATION_90);
1828+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1829+ KEY_UP, AKEYCODE_DPAD_UP));
1830+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1831+ KEY_RIGHT, AKEYCODE_DPAD_RIGHT));
1832+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1833+ KEY_DOWN, AKEYCODE_DPAD_DOWN));
1834+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1835+ KEY_LEFT, AKEYCODE_DPAD_LEFT));
1836+}
1837+
1838+TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
1839+ mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
1840+ mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
1841+ mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
1842+ mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
1843+
1844+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1845+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1846+ addConfigurationProperty("keyboard.orientationAware", "1");
1847+ addMapperAndConfigure(mapper);
1848+
1849+ setDisplayInfoAndReconfigure(DISPLAY_ID,
1850+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
1851+ DISPLAY_ORIENTATION_0);
1852+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1853+ KEY_UP, AKEYCODE_DPAD_UP));
1854+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1855+ KEY_RIGHT, AKEYCODE_DPAD_RIGHT));
1856+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1857+ KEY_DOWN, AKEYCODE_DPAD_DOWN));
1858+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1859+ KEY_LEFT, AKEYCODE_DPAD_LEFT));
1860+
1861+ setDisplayInfoAndReconfigure(DISPLAY_ID,
1862+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
1863+ DISPLAY_ORIENTATION_90);
1864+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1865+ KEY_UP, AKEYCODE_DPAD_LEFT));
1866+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1867+ KEY_RIGHT, AKEYCODE_DPAD_UP));
1868+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1869+ KEY_DOWN, AKEYCODE_DPAD_RIGHT));
1870+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1871+ KEY_LEFT, AKEYCODE_DPAD_DOWN));
1872+
1873+ setDisplayInfoAndReconfigure(DISPLAY_ID,
1874+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
1875+ DISPLAY_ORIENTATION_180);
1876+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1877+ KEY_UP, AKEYCODE_DPAD_DOWN));
1878+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1879+ KEY_RIGHT, AKEYCODE_DPAD_LEFT));
1880+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1881+ KEY_DOWN, AKEYCODE_DPAD_UP));
1882+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1883+ KEY_LEFT, AKEYCODE_DPAD_RIGHT));
1884+
1885+ setDisplayInfoAndReconfigure(DISPLAY_ID,
1886+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
1887+ DISPLAY_ORIENTATION_270);
1888+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1889+ KEY_UP, AKEYCODE_DPAD_RIGHT));
1890+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1891+ KEY_RIGHT, AKEYCODE_DPAD_DOWN));
1892+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1893+ KEY_DOWN, AKEYCODE_DPAD_LEFT));
1894+ ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
1895+ KEY_LEFT, AKEYCODE_DPAD_UP));
1896+
1897+ // Special case: if orientation changes while key is down, we still emit the same keycode
1898+ // in the key up as we did in the key down.
1899+ NotifyKeyArgs args;
1900+
1901+ setDisplayInfoAndReconfigure(DISPLAY_ID,
1902+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
1903+ DISPLAY_ORIENTATION_270);
1904+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
1905+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1906+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
1907+ ASSERT_EQ(KEY_UP, args.scanCode);
1908+ ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
1909+
1910+ setDisplayInfoAndReconfigure(DISPLAY_ID,
1911+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
1912+ DISPLAY_ORIENTATION_180);
1913+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
1914+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
1915+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
1916+ ASSERT_EQ(KEY_UP, args.scanCode);
1917+ ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
1918+}
1919+
1920+TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
1921+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1922+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1923+ addMapperAndConfigure(mapper);
1924+
1925+ mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 1);
1926+ ASSERT_EQ(1, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
1927+
1928+ mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 0);
1929+ ASSERT_EQ(0, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
1930+}
1931+
1932+TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
1933+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1934+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1935+ addMapperAndConfigure(mapper);
1936+
1937+ mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 1);
1938+ ASSERT_EQ(1, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
1939+
1940+ mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 0);
1941+ ASSERT_EQ(0, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
1942+}
1943+
1944+TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
1945+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1946+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1947+ addMapperAndConfigure(mapper);
1948+
1949+ mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0);
1950+
1951+ const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
1952+ uint8_t flags[2] = { 0, 0 };
1953+ ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 1, keyCodes, flags));
1954+ ASSERT_TRUE(flags[0]);
1955+ ASSERT_FALSE(flags[1]);
1956+}
1957+
1958+TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
1959+ mFakeEventHub->addLed(DEVICE_ID, LED_CAPSL, true /*initially on*/);
1960+ mFakeEventHub->addLed(DEVICE_ID, LED_NUML, false /*initially off*/);
1961+ mFakeEventHub->addLed(DEVICE_ID, LED_SCROLLL, false /*initially off*/);
1962+ mFakeEventHub->addKey(DEVICE_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
1963+ mFakeEventHub->addKey(DEVICE_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
1964+ mFakeEventHub->addKey(DEVICE_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
1965+
1966+ KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
1967+ AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
1968+ addMapperAndConfigure(mapper);
1969+
1970+ // Initialization should have turned all of the lights off.
1971+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
1972+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
1973+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
1974+
1975+ // Toggle caps lock on.
1976+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1977+ EV_KEY, KEY_CAPSLOCK, 1);
1978+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1979+ EV_KEY, KEY_CAPSLOCK, 0);
1980+ ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
1981+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
1982+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
1983+ ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper->getMetaState());
1984+
1985+ // Toggle num lock on.
1986+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1987+ EV_KEY, KEY_NUMLOCK, 1);
1988+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1989+ EV_KEY, KEY_NUMLOCK, 0);
1990+ ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
1991+ ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
1992+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
1993+ ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper->getMetaState());
1994+
1995+ // Toggle caps lock off.
1996+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1997+ EV_KEY, KEY_CAPSLOCK, 1);
1998+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
1999+ EV_KEY, KEY_CAPSLOCK, 0);
2000+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
2001+ ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
2002+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
2003+ ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper->getMetaState());
2004+
2005+ // Toggle scroll lock on.
2006+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
2007+ EV_KEY, KEY_SCROLLLOCK, 1);
2008+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
2009+ EV_KEY, KEY_SCROLLLOCK, 0);
2010+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
2011+ ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
2012+ ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
2013+ ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
2014+
2015+ // Toggle num lock off.
2016+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
2017+ EV_KEY, KEY_NUMLOCK, 1);
2018+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
2019+ EV_KEY, KEY_NUMLOCK, 0);
2020+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
2021+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
2022+ ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
2023+ ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
2024+
2025+ // Toggle scroll lock off.
2026+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
2027+ EV_KEY, KEY_SCROLLLOCK, 1);
2028+ process(mapper, ARBITRARY_TIME, DEVICE_ID,
2029+ EV_KEY, KEY_SCROLLLOCK, 0);
2030+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
2031+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
2032+ ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
2033+ ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
2034+}
2035+
2036+
2037+// --- CursorInputMapperTest ---
2038+
2039+class CursorInputMapperTest : public InputMapperTest {
2040+protected:
2041+ static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
2042+
2043+ sp<FakePointerController> mFakePointerController;
2044+
2045+ virtual void SetUp() {
2046+ InputMapperTest::SetUp();
2047+
2048+ mFakePointerController = new FakePointerController();
2049+ mFakePolicy->setPointerController(DEVICE_ID, mFakePointerController);
2050+ }
2051+
2052+ void testMotionRotation(CursorInputMapper* mapper,
2053+ int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY);
2054+};
2055+
2056+const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
2057+
2058+void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper,
2059+ int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
2060+ NotifyMotionArgs args;
2061+
2062+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, originalX);
2063+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, originalY);
2064+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2065+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2066+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2067+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2068+ float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
2069+ float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD,
2070+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2071+}
2072+
2073+TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
2074+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2075+ addConfigurationProperty("cursor.mode", "pointer");
2076+ addMapperAndConfigure(mapper);
2077+
2078+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
2079+}
2080+
2081+TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
2082+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2083+ addConfigurationProperty("cursor.mode", "navigation");
2084+ addMapperAndConfigure(mapper);
2085+
2086+ ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources());
2087+}
2088+
2089+TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
2090+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2091+ addConfigurationProperty("cursor.mode", "pointer");
2092+ addMapperAndConfigure(mapper);
2093+
2094+ InputDeviceInfo info;
2095+ mapper->populateDeviceInfo(&info);
2096+
2097+ // Initially there may not be a valid motion range.
2098+ ASSERT_EQ(NULL, info.getMotionRange(AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_MOUSE));
2099+ ASSERT_EQ(NULL, info.getMotionRange(AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_MOUSE));
2100+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
2101+ AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
2102+
2103+ // When the bounds are set, then there should be a valid motion range.
2104+ mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
2105+
2106+ InputDeviceInfo info2;
2107+ mapper->populateDeviceInfo(&info2);
2108+
2109+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
2110+ AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_MOUSE,
2111+ 1, 800 - 1, 0.0f, 0.0f));
2112+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
2113+ AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_MOUSE,
2114+ 2, 480 - 1, 0.0f, 0.0f));
2115+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
2116+ AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_MOUSE,
2117+ 0.0f, 1.0f, 0.0f, 0.0f));
2118+}
2119+
2120+TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
2121+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2122+ addConfigurationProperty("cursor.mode", "navigation");
2123+ addMapperAndConfigure(mapper);
2124+
2125+ InputDeviceInfo info;
2126+ mapper->populateDeviceInfo(&info);
2127+
2128+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
2129+ AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_TRACKBALL,
2130+ -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
2131+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
2132+ AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_TRACKBALL,
2133+ -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
2134+ ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
2135+ AMOTION_EVENT_AXIS_PRESSURE, AINPUT_SOURCE_TRACKBALL,
2136+ 0.0f, 1.0f, 0.0f, 0.0f));
2137+}
2138+
2139+TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
2140+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2141+ addConfigurationProperty("cursor.mode", "navigation");
2142+ addMapperAndConfigure(mapper);
2143+
2144+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
2145+
2146+ NotifyMotionArgs args;
2147+
2148+ // Button press.
2149+ // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
2150+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
2151+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2152+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2153+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
2154+ ASSERT_EQ(DEVICE_ID, args.deviceId);
2155+ ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
2156+ ASSERT_EQ(uint32_t(0), args.policyFlags);
2157+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
2158+ ASSERT_EQ(0, args.flags);
2159+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
2160+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
2161+ ASSERT_EQ(0, args.edgeFlags);
2162+ ASSERT_EQ(uint32_t(1), args.pointerCount);
2163+ ASSERT_EQ(0, args.pointerProperties[0].id);
2164+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
2165+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2166+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2167+ ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
2168+ ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
2169+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2170+
2171+ // Button release. Should have same down time.
2172+ process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
2173+ process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2174+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2175+ ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
2176+ ASSERT_EQ(DEVICE_ID, args.deviceId);
2177+ ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
2178+ ASSERT_EQ(uint32_t(0), args.policyFlags);
2179+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
2180+ ASSERT_EQ(0, args.flags);
2181+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
2182+ ASSERT_EQ(0, args.buttonState);
2183+ ASSERT_EQ(0, args.edgeFlags);
2184+ ASSERT_EQ(uint32_t(1), args.pointerCount);
2185+ ASSERT_EQ(0, args.pointerProperties[0].id);
2186+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
2187+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2188+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2189+ ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
2190+ ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
2191+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2192+}
2193+
2194+TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
2195+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2196+ addConfigurationProperty("cursor.mode", "navigation");
2197+ addMapperAndConfigure(mapper);
2198+
2199+ NotifyMotionArgs args;
2200+
2201+ // Motion in X but not Y.
2202+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
2203+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2204+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2205+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2206+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2207+ 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2208+
2209+ // Motion in Y but not X.
2210+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
2211+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2212+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2213+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2214+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2215+ 0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2216+}
2217+
2218+TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
2219+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2220+ addConfigurationProperty("cursor.mode", "navigation");
2221+ addMapperAndConfigure(mapper);
2222+
2223+ NotifyMotionArgs args;
2224+
2225+ // Button press.
2226+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
2227+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2228+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2229+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
2230+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2231+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2232+
2233+ // Button release.
2234+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
2235+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2236+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2237+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
2238+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2239+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2240+}
2241+
2242+TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
2243+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2244+ addConfigurationProperty("cursor.mode", "navigation");
2245+ addMapperAndConfigure(mapper);
2246+
2247+ NotifyMotionArgs args;
2248+
2249+ // Combined X, Y and Button.
2250+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
2251+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
2252+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
2253+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2254+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2255+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
2256+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2257+ 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
2258+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2259+
2260+ // Move X, Y a bit while pressed.
2261+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 2);
2262+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 1);
2263+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2264+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2265+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2266+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2267+ 2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
2268+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2269+
2270+ // Release Button.
2271+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
2272+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2273+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2274+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
2275+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2276+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2277+}
2278+
2279+TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) {
2280+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2281+ addConfigurationProperty("cursor.mode", "navigation");
2282+ addMapperAndConfigure(mapper);
2283+
2284+ setDisplayInfoAndReconfigure(DISPLAY_ID,
2285+ DISPLAY_WIDTH, DISPLAY_HEIGHT,
2286+ DISPLAY_ORIENTATION_90);
2287+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
2288+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
2289+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
2290+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
2291+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
2292+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
2293+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
2294+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
2295+}
2296+
2297+TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) {
2298+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2299+ addConfigurationProperty("cursor.mode", "navigation");
2300+ addConfigurationProperty("cursor.orientationAware", "1");
2301+ addMapperAndConfigure(mapper);
2302+
2303+ setDisplayInfoAndReconfigure(DISPLAY_ID,
2304+ DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0);
2305+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, 1));
2306+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, 1));
2307+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 1, 0));
2308+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, -1));
2309+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, -1));
2310+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
2311+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, -1, 0));
2312+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, 1));
2313+
2314+ setDisplayInfoAndReconfigure(DISPLAY_ID,
2315+ DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_90);
2316+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 1, 0));
2317+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, 1, -1));
2318+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, -1));
2319+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, -1));
2320+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, -1, 0));
2321+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, 1));
2322+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, 1));
2323+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, 1));
2324+
2325+ setDisplayInfoAndReconfigure(DISPLAY_ID,
2326+ DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_180);
2327+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, 0, -1));
2328+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, -1));
2329+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, -1, 0));
2330+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, -1, 1));
2331+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 0, 1));
2332+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, 1));
2333+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 1, 0));
2334+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, 1, -1));
2335+
2336+ setDisplayInfoAndReconfigure(DISPLAY_ID,
2337+ DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_270);
2338+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, 1, -1, 0));
2339+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 1, -1, 1));
2340+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, 0, 0, 1));
2341+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 1, -1, 1, 1));
2342+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, 0, -1, 1, 0));
2343+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, 1, -1));
2344+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 0, 0, -1));
2345+ ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
2346+}
2347+
2348+TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
2349+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2350+ addConfigurationProperty("cursor.mode", "pointer");
2351+ addMapperAndConfigure(mapper);
2352+
2353+ mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
2354+ mFakePointerController->setPosition(100, 200);
2355+ mFakePointerController->setButtonState(0);
2356+
2357+ NotifyMotionArgs motionArgs;
2358+ NotifyKeyArgs keyArgs;
2359+
2360+ // press BTN_LEFT, release BTN_LEFT
2361+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 1);
2362+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2363+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2364+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
2365+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
2366+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
2367+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2368+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2369+
2370+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 0);
2371+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2372+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2373+ ASSERT_EQ(0, motionArgs.buttonState);
2374+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2375+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
2376+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2377+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2378+
2379+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2380+ ASSERT_EQ(0, motionArgs.buttonState);
2381+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2382+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2383+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2384+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2385+
2386+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
2387+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 1);
2388+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 1);
2389+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2390+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2391+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
2392+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
2393+ motionArgs.buttonState);
2394+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
2395+ mFakePointerController->getButtonState());
2396+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2397+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2398+
2399+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 0);
2400+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2401+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2402+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
2403+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
2404+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
2405+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2406+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2407+
2408+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 0);
2409+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2410+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2411+ ASSERT_EQ(0, motionArgs.buttonState);
2412+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2413+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
2414+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2415+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2416+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2417+ ASSERT_EQ(0, motionArgs.buttonState);
2418+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2419+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2420+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2421+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2422+
2423+ // press BTN_BACK, release BTN_BACK
2424+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 1);
2425+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2426+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2427+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
2428+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
2429+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2430+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
2431+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
2432+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2433+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2434+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2435+
2436+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 0);
2437+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2438+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2439+ ASSERT_EQ(0, motionArgs.buttonState);
2440+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2441+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2442+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2443+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2444+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2445+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
2446+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
2447+
2448+ // press BTN_SIDE, release BTN_SIDE
2449+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 1);
2450+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2451+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2452+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
2453+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
2454+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2455+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
2456+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
2457+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2458+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2459+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2460+
2461+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 0);
2462+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2463+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2464+ ASSERT_EQ(0, motionArgs.buttonState);
2465+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2466+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2467+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2468+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2469+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2470+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
2471+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
2472+
2473+ // press BTN_FORWARD, release BTN_FORWARD
2474+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 1);
2475+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2476+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2477+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
2478+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
2479+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2480+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
2481+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
2482+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2483+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2484+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2485+
2486+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 0);
2487+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2488+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2489+ ASSERT_EQ(0, motionArgs.buttonState);
2490+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2491+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2492+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2493+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2494+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2495+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
2496+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
2497+
2498+ // press BTN_EXTRA, release BTN_EXTRA
2499+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 1);
2500+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2501+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2502+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
2503+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
2504+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2505+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
2506+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
2507+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2508+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2509+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2510+
2511+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 0);
2512+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2513+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2514+ ASSERT_EQ(0, motionArgs.buttonState);
2515+ ASSERT_EQ(0, mFakePointerController->getButtonState());
2516+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
2517+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2518+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2519+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2520+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
2521+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
2522+}
2523+
2524+TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
2525+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
2526+ addConfigurationProperty("cursor.mode", "pointer");
2527+ addMapperAndConfigure(mapper);
2528+
2529+ mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
2530+ mFakePointerController->setPosition(100, 200);
2531+ mFakePointerController->setButtonState(0);
2532+
2533+ NotifyMotionArgs args;
2534+
2535+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10);
2536+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20);
2537+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2538+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
2539+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
2540+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2541+ 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
2542+ ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
2543+}
2544+
2545+
2546+// --- TouchInputMapperTest ---
2547+
2548+class TouchInputMapperTest : public InputMapperTest {
2549+protected:
2550+ static const int32_t RAW_X_MIN;
2551+ static const int32_t RAW_X_MAX;
2552+ static const int32_t RAW_Y_MIN;
2553+ static const int32_t RAW_Y_MAX;
2554+ static const int32_t RAW_TOUCH_MIN;
2555+ static const int32_t RAW_TOUCH_MAX;
2556+ static const int32_t RAW_TOOL_MIN;
2557+ static const int32_t RAW_TOOL_MAX;
2558+ static const int32_t RAW_PRESSURE_MIN;
2559+ static const int32_t RAW_PRESSURE_MAX;
2560+ static const int32_t RAW_ORIENTATION_MIN;
2561+ static const int32_t RAW_ORIENTATION_MAX;
2562+ static const int32_t RAW_DISTANCE_MIN;
2563+ static const int32_t RAW_DISTANCE_MAX;
2564+ static const int32_t RAW_TILT_MIN;
2565+ static const int32_t RAW_TILT_MAX;
2566+ static const int32_t RAW_ID_MIN;
2567+ static const int32_t RAW_ID_MAX;
2568+ static const int32_t RAW_SLOT_MIN;
2569+ static const int32_t RAW_SLOT_MAX;
2570+ static const float X_PRECISION;
2571+ static const float Y_PRECISION;
2572+
2573+ static const float GEOMETRIC_SCALE;
2574+
2575+ static const VirtualKeyDefinition VIRTUAL_KEYS[2];
2576+
2577+ enum Axes {
2578+ POSITION = 1 << 0,
2579+ TOUCH = 1 << 1,
2580+ TOOL = 1 << 2,
2581+ PRESSURE = 1 << 3,
2582+ ORIENTATION = 1 << 4,
2583+ MINOR = 1 << 5,
2584+ ID = 1 << 6,
2585+ DISTANCE = 1 << 7,
2586+ TILT = 1 << 8,
2587+ SLOT = 1 << 9,
2588+ TOOL_TYPE = 1 << 10,
2589+ };
2590+
2591+ void prepareDisplay(int32_t orientation);
2592+ void prepareVirtualKeys();
2593+ int32_t toRawX(float displayX);
2594+ int32_t toRawY(float displayY);
2595+ float toDisplayX(int32_t rawX);
2596+ float toDisplayY(int32_t rawY);
2597+};
2598+
2599+const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
2600+const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
2601+const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
2602+const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
2603+const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
2604+const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
2605+const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
2606+const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
2607+const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = RAW_TOUCH_MIN;
2608+const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = RAW_TOUCH_MAX;
2609+const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
2610+const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
2611+const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
2612+const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
2613+const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
2614+const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
2615+const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
2616+const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
2617+const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
2618+const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
2619+const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
2620+const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
2621+
2622+const float TouchInputMapperTest::GEOMETRIC_SCALE =
2623+ avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
2624+ float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
2625+
2626+const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
2627+ { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
2628+ { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
2629+};
2630+
2631+void TouchInputMapperTest::prepareDisplay(int32_t orientation) {
2632+ setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation);
2633+}
2634+
2635+void TouchInputMapperTest::prepareVirtualKeys() {
2636+ mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[0]);
2637+ mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[1]);
2638+ mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
2639+ mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
2640+}
2641+
2642+int32_t TouchInputMapperTest::toRawX(float displayX) {
2643+ return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
2644+}
2645+
2646+int32_t TouchInputMapperTest::toRawY(float displayY) {
2647+ return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
2648+}
2649+
2650+float TouchInputMapperTest::toDisplayX(int32_t rawX) {
2651+ return float(rawX - RAW_X_MIN) * DISPLAY_WIDTH / (RAW_X_MAX - RAW_X_MIN + 1);
2652+}
2653+
2654+float TouchInputMapperTest::toDisplayY(int32_t rawY) {
2655+ return float(rawY - RAW_Y_MIN) * DISPLAY_HEIGHT / (RAW_Y_MAX - RAW_Y_MIN + 1);
2656+}
2657+
2658+
2659+// --- SingleTouchInputMapperTest ---
2660+
2661+class SingleTouchInputMapperTest : public TouchInputMapperTest {
2662+protected:
2663+ void prepareButtons();
2664+ void prepareAxes(int axes);
2665+
2666+ void processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
2667+ void processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
2668+ void processUp(SingleTouchInputMapper* mappery);
2669+ void processPressure(SingleTouchInputMapper* mapper, int32_t pressure);
2670+ void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor);
2671+ void processDistance(SingleTouchInputMapper* mapper, int32_t distance);
2672+ void processTilt(SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY);
2673+ void processKey(SingleTouchInputMapper* mapper, int32_t code, int32_t value);
2674+ void processSync(SingleTouchInputMapper* mapper);
2675+};
2676+
2677+void SingleTouchInputMapperTest::prepareButtons() {
2678+ mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
2679+}
2680+
2681+void SingleTouchInputMapperTest::prepareAxes(int axes) {
2682+ if (axes & POSITION) {
2683+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_X,
2684+ RAW_X_MIN, RAW_X_MAX, 0, 0);
2685+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_Y,
2686+ RAW_Y_MIN, RAW_Y_MAX, 0, 0);
2687+ }
2688+ if (axes & PRESSURE) {
2689+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_PRESSURE,
2690+ RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
2691+ }
2692+ if (axes & TOOL) {
2693+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
2694+ RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
2695+ }
2696+ if (axes & DISTANCE) {
2697+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_DISTANCE,
2698+ RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
2699+ }
2700+ if (axes & TILT) {
2701+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_X,
2702+ RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
2703+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_Y,
2704+ RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
2705+ }
2706+}
2707+
2708+void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
2709+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 1);
2710+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
2711+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
2712+}
2713+
2714+void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
2715+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
2716+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
2717+}
2718+
2719+void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) {
2720+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0);
2721+}
2722+
2723+void SingleTouchInputMapperTest::processPressure(
2724+ SingleTouchInputMapper* mapper, int32_t pressure) {
2725+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_PRESSURE, pressure);
2726+}
2727+
2728+void SingleTouchInputMapperTest::processToolMajor(
2729+ SingleTouchInputMapper* mapper, int32_t toolMajor) {
2730+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
2731+}
2732+
2733+void SingleTouchInputMapperTest::processDistance(
2734+ SingleTouchInputMapper* mapper, int32_t distance) {
2735+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_DISTANCE, distance);
2736+}
2737+
2738+void SingleTouchInputMapperTest::processTilt(
2739+ SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY) {
2740+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_X, tiltX);
2741+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_Y, tiltY);
2742+}
2743+
2744+void SingleTouchInputMapperTest::processKey(
2745+ SingleTouchInputMapper* mapper, int32_t code, int32_t value) {
2746+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
2747+}
2748+
2749+void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
2750+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
2751+}
2752+
2753+
2754+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
2755+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2756+ prepareButtons();
2757+ prepareAxes(POSITION);
2758+ addMapperAndConfigure(mapper);
2759+
2760+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
2761+}
2762+
2763+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndIsACursor_ReturnsTouchPad) {
2764+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2765+ mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_X);
2766+ mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_Y);
2767+ prepareButtons();
2768+ prepareAxes(POSITION);
2769+ addMapperAndConfigure(mapper);
2770+
2771+ ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
2772+}
2773+
2774+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchPad_ReturnsTouchPad) {
2775+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2776+ prepareButtons();
2777+ prepareAxes(POSITION);
2778+ addConfigurationProperty("touch.deviceType", "touchPad");
2779+ addMapperAndConfigure(mapper);
2780+
2781+ ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
2782+}
2783+
2784+TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
2785+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2786+ prepareButtons();
2787+ prepareAxes(POSITION);
2788+ addConfigurationProperty("touch.deviceType", "touchScreen");
2789+ addMapperAndConfigure(mapper);
2790+
2791+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources());
2792+}
2793+
2794+TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
2795+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2796+ addConfigurationProperty("touch.deviceType", "touchScreen");
2797+ prepareDisplay(DISPLAY_ORIENTATION_0);
2798+ prepareButtons();
2799+ prepareAxes(POSITION);
2800+ prepareVirtualKeys();
2801+ addMapperAndConfigure(mapper);
2802+
2803+ // Unknown key.
2804+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
2805+
2806+ // Virtual key is down.
2807+ int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
2808+ int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
2809+ processDown(mapper, x, y);
2810+ processSync(mapper);
2811+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
2812+
2813+ ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
2814+
2815+ // Virtual key is up.
2816+ processUp(mapper);
2817+ processSync(mapper);
2818+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
2819+
2820+ ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
2821+}
2822+
2823+TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
2824+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2825+ addConfigurationProperty("touch.deviceType", "touchScreen");
2826+ prepareDisplay(DISPLAY_ORIENTATION_0);
2827+ prepareButtons();
2828+ prepareAxes(POSITION);
2829+ prepareVirtualKeys();
2830+ addMapperAndConfigure(mapper);
2831+
2832+ // Unknown key.
2833+ ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
2834+
2835+ // Virtual key is down.
2836+ int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
2837+ int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
2838+ processDown(mapper, x, y);
2839+ processSync(mapper);
2840+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
2841+
2842+ ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
2843+
2844+ // Virtual key is up.
2845+ processUp(mapper);
2846+ processSync(mapper);
2847+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
2848+
2849+ ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
2850+}
2851+
2852+TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
2853+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2854+ addConfigurationProperty("touch.deviceType", "touchScreen");
2855+ prepareDisplay(DISPLAY_ORIENTATION_0);
2856+ prepareButtons();
2857+ prepareAxes(POSITION);
2858+ prepareVirtualKeys();
2859+ addMapperAndConfigure(mapper);
2860+
2861+ const int32_t keys[2] = { AKEYCODE_HOME, AKEYCODE_A };
2862+ uint8_t flags[2] = { 0, 0 };
2863+ ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 2, keys, flags));
2864+ ASSERT_TRUE(flags[0]);
2865+ ASSERT_FALSE(flags[1]);
2866+}
2867+
2868+TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
2869+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2870+ addConfigurationProperty("touch.deviceType", "touchScreen");
2871+ prepareDisplay(DISPLAY_ORIENTATION_0);
2872+ prepareButtons();
2873+ prepareAxes(POSITION);
2874+ prepareVirtualKeys();
2875+ addMapperAndConfigure(mapper);
2876+
2877+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
2878+
2879+ NotifyKeyArgs args;
2880+
2881+ // Press virtual key.
2882+ int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
2883+ int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
2884+ processDown(mapper, x, y);
2885+ processSync(mapper);
2886+
2887+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2888+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
2889+ ASSERT_EQ(DEVICE_ID, args.deviceId);
2890+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2891+ ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
2892+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
2893+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
2894+ ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
2895+ ASSERT_EQ(KEY_HOME, args.scanCode);
2896+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
2897+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2898+
2899+ // Release virtual key.
2900+ processUp(mapper);
2901+ processSync(mapper);
2902+
2903+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
2904+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
2905+ ASSERT_EQ(DEVICE_ID, args.deviceId);
2906+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
2907+ ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
2908+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
2909+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
2910+ ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
2911+ ASSERT_EQ(KEY_HOME, args.scanCode);
2912+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
2913+ ASSERT_EQ(ARBITRARY_TIME, args.downTime);
2914+
2915+ // Should not have sent any motions.
2916+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
2917+}
2918+
2919+TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
2920+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
2921+ addConfigurationProperty("touch.deviceType", "touchScreen");
2922+ prepareDisplay(DISPLAY_ORIENTATION_0);
2923+ prepareButtons();
2924+ prepareAxes(POSITION);
2925+ prepareVirtualKeys();
2926+ addMapperAndConfigure(mapper);
2927+
2928+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
2929+
2930+ NotifyKeyArgs keyArgs;
2931+
2932+ // Press virtual key.
2933+ int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
2934+ int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
2935+ processDown(mapper, x, y);
2936+ processSync(mapper);
2937+
2938+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2939+ ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
2940+ ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
2941+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
2942+ ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
2943+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
2944+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
2945+ ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
2946+ ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
2947+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
2948+ ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
2949+
2950+ // Move out of bounds. This should generate a cancel and a pointer down since we moved
2951+ // into the display area.
2952+ y -= 100;
2953+ processMove(mapper, x, y);
2954+ processSync(mapper);
2955+
2956+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
2957+ ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
2958+ ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
2959+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
2960+ ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
2961+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
2962+ ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
2963+ | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
2964+ ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
2965+ ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
2966+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
2967+ ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
2968+
2969+ NotifyMotionArgs motionArgs;
2970+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2971+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
2972+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
2973+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
2974+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
2975+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
2976+ ASSERT_EQ(0, motionArgs.flags);
2977+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
2978+ ASSERT_EQ(0, motionArgs.buttonState);
2979+ ASSERT_EQ(0, motionArgs.edgeFlags);
2980+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
2981+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
2982+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
2983+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
2984+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
2985+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
2986+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
2987+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
2988+
2989+ // Keep moving out of bounds. Should generate a pointer move.
2990+ y -= 50;
2991+ processMove(mapper, x, y);
2992+ processSync(mapper);
2993+
2994+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
2995+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
2996+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
2997+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
2998+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
2999+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3000+ ASSERT_EQ(0, motionArgs.flags);
3001+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3002+ ASSERT_EQ(0, motionArgs.buttonState);
3003+ ASSERT_EQ(0, motionArgs.edgeFlags);
3004+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3005+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3006+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3007+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3008+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3009+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3010+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3011+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3012+
3013+ // Release out of bounds. Should generate a pointer up.
3014+ processUp(mapper);
3015+ processSync(mapper);
3016+
3017+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3018+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3019+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3020+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3021+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3022+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3023+ ASSERT_EQ(0, motionArgs.flags);
3024+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3025+ ASSERT_EQ(0, motionArgs.buttonState);
3026+ ASSERT_EQ(0, motionArgs.edgeFlags);
3027+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3028+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3029+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3030+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3031+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3032+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3033+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3034+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3035+
3036+ // Should not have sent any more keys or motions.
3037+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3038+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3039+}
3040+
3041+TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
3042+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3043+ addConfigurationProperty("touch.deviceType", "touchScreen");
3044+ prepareDisplay(DISPLAY_ORIENTATION_0);
3045+ prepareButtons();
3046+ prepareAxes(POSITION);
3047+ prepareVirtualKeys();
3048+ addMapperAndConfigure(mapper);
3049+
3050+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3051+
3052+ NotifyMotionArgs motionArgs;
3053+
3054+ // Initially go down out of bounds.
3055+ int32_t x = -10;
3056+ int32_t y = -10;
3057+ processDown(mapper, x, y);
3058+ processSync(mapper);
3059+
3060+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3061+
3062+ // Move into the display area. Should generate a pointer down.
3063+ x = 50;
3064+ y = 75;
3065+ processMove(mapper, x, y);
3066+ processSync(mapper);
3067+
3068+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3069+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3070+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3071+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3072+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3073+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3074+ ASSERT_EQ(0, motionArgs.flags);
3075+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3076+ ASSERT_EQ(0, motionArgs.buttonState);
3077+ ASSERT_EQ(0, motionArgs.edgeFlags);
3078+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3079+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3080+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3081+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3082+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3083+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3084+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3085+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3086+
3087+ // Release. Should generate a pointer up.
3088+ processUp(mapper);
3089+ processSync(mapper);
3090+
3091+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3092+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3093+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3094+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3095+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3096+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3097+ ASSERT_EQ(0, motionArgs.flags);
3098+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3099+ ASSERT_EQ(0, motionArgs.buttonState);
3100+ ASSERT_EQ(0, motionArgs.edgeFlags);
3101+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3102+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3103+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3104+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3105+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3106+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3107+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3108+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3109+
3110+ // Should not have sent any more keys or motions.
3111+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3112+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3113+}
3114+
3115+TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
3116+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3117+ addConfigurationProperty("touch.deviceType", "touchScreen");
3118+ prepareDisplay(DISPLAY_ORIENTATION_0);
3119+ prepareButtons();
3120+ prepareAxes(POSITION);
3121+ prepareVirtualKeys();
3122+ addMapperAndConfigure(mapper);
3123+
3124+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3125+
3126+ NotifyMotionArgs motionArgs;
3127+
3128+ // Down.
3129+ int32_t x = 100;
3130+ int32_t y = 125;
3131+ processDown(mapper, x, y);
3132+ processSync(mapper);
3133+
3134+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3135+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3136+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3137+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3138+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3139+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3140+ ASSERT_EQ(0, motionArgs.flags);
3141+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3142+ ASSERT_EQ(0, motionArgs.buttonState);
3143+ ASSERT_EQ(0, motionArgs.edgeFlags);
3144+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3145+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3146+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3147+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3148+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3149+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3150+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3151+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3152+
3153+ // Move.
3154+ x += 50;
3155+ y += 75;
3156+ processMove(mapper, x, y);
3157+ processSync(mapper);
3158+
3159+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3160+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3161+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3162+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3163+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3164+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3165+ ASSERT_EQ(0, motionArgs.flags);
3166+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3167+ ASSERT_EQ(0, motionArgs.buttonState);
3168+ ASSERT_EQ(0, motionArgs.edgeFlags);
3169+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3170+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3171+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3172+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3173+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3174+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3175+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3176+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3177+
3178+ // Up.
3179+ processUp(mapper);
3180+ processSync(mapper);
3181+
3182+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3183+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3184+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3185+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3186+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3187+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3188+ ASSERT_EQ(0, motionArgs.flags);
3189+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3190+ ASSERT_EQ(0, motionArgs.buttonState);
3191+ ASSERT_EQ(0, motionArgs.edgeFlags);
3192+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3193+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3194+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3195+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3196+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3197+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3198+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3199+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3200+
3201+ // Should not have sent any more keys or motions.
3202+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3203+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3204+}
3205+
3206+TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) {
3207+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3208+ addConfigurationProperty("touch.deviceType", "touchScreen");
3209+ prepareButtons();
3210+ prepareAxes(POSITION);
3211+ addConfigurationProperty("touch.orientationAware", "0");
3212+ addMapperAndConfigure(mapper);
3213+
3214+ NotifyMotionArgs args;
3215+
3216+ // Rotation 90.
3217+ prepareDisplay(DISPLAY_ORIENTATION_90);
3218+ processDown(mapper, toRawX(50), toRawY(75));
3219+ processSync(mapper);
3220+
3221+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3222+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
3223+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
3224+
3225+ processUp(mapper);
3226+ processSync(mapper);
3227+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
3228+}
3229+
3230+TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) {
3231+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3232+ addConfigurationProperty("touch.deviceType", "touchScreen");
3233+ prepareButtons();
3234+ prepareAxes(POSITION);
3235+ addMapperAndConfigure(mapper);
3236+
3237+ NotifyMotionArgs args;
3238+
3239+ // Rotation 0.
3240+ prepareDisplay(DISPLAY_ORIENTATION_0);
3241+ processDown(mapper, toRawX(50), toRawY(75));
3242+ processSync(mapper);
3243+
3244+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3245+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
3246+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
3247+
3248+ processUp(mapper);
3249+ processSync(mapper);
3250+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
3251+
3252+ // Rotation 90.
3253+ prepareDisplay(DISPLAY_ORIENTATION_90);
3254+ processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
3255+ processSync(mapper);
3256+
3257+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3258+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
3259+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
3260+
3261+ processUp(mapper);
3262+ processSync(mapper);
3263+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
3264+
3265+ // Rotation 180.
3266+ prepareDisplay(DISPLAY_ORIENTATION_180);
3267+ processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
3268+ processSync(mapper);
3269+
3270+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3271+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
3272+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
3273+
3274+ processUp(mapper);
3275+ processSync(mapper);
3276+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
3277+
3278+ // Rotation 270.
3279+ prepareDisplay(DISPLAY_ORIENTATION_270);
3280+ processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
3281+ processSync(mapper);
3282+
3283+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3284+ ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
3285+ ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
3286+
3287+ processUp(mapper);
3288+ processSync(mapper);
3289+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
3290+}
3291+
3292+TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
3293+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3294+ addConfigurationProperty("touch.deviceType", "touchScreen");
3295+ prepareDisplay(DISPLAY_ORIENTATION_0);
3296+ prepareButtons();
3297+ prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
3298+ addMapperAndConfigure(mapper);
3299+
3300+ // These calculations are based on the input device calibration documentation.
3301+ int32_t rawX = 100;
3302+ int32_t rawY = 200;
3303+ int32_t rawPressure = 10;
3304+ int32_t rawToolMajor = 12;
3305+ int32_t rawDistance = 2;
3306+ int32_t rawTiltX = 30;
3307+ int32_t rawTiltY = 110;
3308+
3309+ float x = toDisplayX(rawX);
3310+ float y = toDisplayY(rawY);
3311+ float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
3312+ float size = float(rawToolMajor) / RAW_TOOL_MAX;
3313+ float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
3314+ float distance = float(rawDistance);
3315+
3316+ float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
3317+ float tiltScale = M_PI / 180;
3318+ float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
3319+ float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
3320+ float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
3321+ float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
3322+
3323+ processDown(mapper, rawX, rawY);
3324+ processPressure(mapper, rawPressure);
3325+ processToolMajor(mapper, rawToolMajor);
3326+ processDistance(mapper, rawDistance);
3327+ processTilt(mapper, rawTiltX, rawTiltY);
3328+ processSync(mapper);
3329+
3330+ NotifyMotionArgs args;
3331+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3332+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
3333+ x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
3334+ ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
3335+}
3336+
3337+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
3338+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3339+ addConfigurationProperty("touch.deviceType", "touchScreen");
3340+ prepareDisplay(DISPLAY_ORIENTATION_0);
3341+ prepareButtons();
3342+ prepareAxes(POSITION);
3343+ addMapperAndConfigure(mapper);
3344+
3345+ NotifyMotionArgs motionArgs;
3346+ NotifyKeyArgs keyArgs;
3347+
3348+ processDown(mapper, 100, 200);
3349+ processSync(mapper);
3350+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3351+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3352+ ASSERT_EQ(0, motionArgs.buttonState);
3353+
3354+ // press BTN_LEFT, release BTN_LEFT
3355+ processKey(mapper, BTN_LEFT, 1);
3356+ processSync(mapper);
3357+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3358+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3359+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
3360+
3361+ processKey(mapper, BTN_LEFT, 0);
3362+ processSync(mapper);
3363+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3364+ ASSERT_EQ(0, motionArgs.buttonState);
3365+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3366+
3367+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
3368+ processKey(mapper, BTN_RIGHT, 1);
3369+ processKey(mapper, BTN_MIDDLE, 1);
3370+ processSync(mapper);
3371+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3372+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3373+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
3374+ motionArgs.buttonState);
3375+
3376+ processKey(mapper, BTN_RIGHT, 0);
3377+ processSync(mapper);
3378+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3379+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
3380+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3381+
3382+ processKey(mapper, BTN_MIDDLE, 0);
3383+ processSync(mapper);
3384+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3385+ ASSERT_EQ(0, motionArgs.buttonState);
3386+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3387+
3388+ // press BTN_BACK, release BTN_BACK
3389+ processKey(mapper, BTN_BACK, 1);
3390+ processSync(mapper);
3391+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3392+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
3393+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
3394+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3395+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
3396+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3397+
3398+ processKey(mapper, BTN_BACK, 0);
3399+ processSync(mapper);
3400+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3401+ ASSERT_EQ(0, motionArgs.buttonState);
3402+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3403+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3404+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
3405+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
3406+
3407+ // press BTN_SIDE, release BTN_SIDE
3408+ processKey(mapper, BTN_SIDE, 1);
3409+ processSync(mapper);
3410+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3411+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
3412+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
3413+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3414+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
3415+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3416+
3417+ processKey(mapper, BTN_SIDE, 0);
3418+ processSync(mapper);
3419+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3420+ ASSERT_EQ(0, motionArgs.buttonState);
3421+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3422+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3423+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
3424+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
3425+
3426+ // press BTN_FORWARD, release BTN_FORWARD
3427+ processKey(mapper, BTN_FORWARD, 1);
3428+ processSync(mapper);
3429+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3430+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
3431+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
3432+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3433+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
3434+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3435+
3436+ processKey(mapper, BTN_FORWARD, 0);
3437+ processSync(mapper);
3438+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3439+ ASSERT_EQ(0, motionArgs.buttonState);
3440+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3441+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3442+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
3443+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
3444+
3445+ // press BTN_EXTRA, release BTN_EXTRA
3446+ processKey(mapper, BTN_EXTRA, 1);
3447+ processSync(mapper);
3448+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3449+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
3450+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
3451+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3452+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
3453+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3454+
3455+ processKey(mapper, BTN_EXTRA, 0);
3456+ processSync(mapper);
3457+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3458+ ASSERT_EQ(0, motionArgs.buttonState);
3459+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3460+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3461+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
3462+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
3463+
3464+ // press BTN_STYLUS, release BTN_STYLUS
3465+ processKey(mapper, BTN_STYLUS, 1);
3466+ processSync(mapper);
3467+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3468+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3469+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
3470+
3471+ processKey(mapper, BTN_STYLUS, 0);
3472+ processSync(mapper);
3473+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3474+ ASSERT_EQ(0, motionArgs.buttonState);
3475+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3476+
3477+ // press BTN_STYLUS2, release BTN_STYLUS2
3478+ processKey(mapper, BTN_STYLUS2, 1);
3479+ processSync(mapper);
3480+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3481+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3482+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
3483+
3484+ processKey(mapper, BTN_STYLUS2, 0);
3485+ processSync(mapper);
3486+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3487+ ASSERT_EQ(0, motionArgs.buttonState);
3488+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3489+
3490+ // release touch
3491+ processUp(mapper);
3492+ processSync(mapper);
3493+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3494+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3495+ ASSERT_EQ(0, motionArgs.buttonState);
3496+}
3497+
3498+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
3499+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3500+ addConfigurationProperty("touch.deviceType", "touchScreen");
3501+ prepareDisplay(DISPLAY_ORIENTATION_0);
3502+ prepareButtons();
3503+ prepareAxes(POSITION);
3504+ addMapperAndConfigure(mapper);
3505+
3506+ NotifyMotionArgs motionArgs;
3507+
3508+ // default tool type is finger
3509+ processDown(mapper, 100, 200);
3510+ processSync(mapper);
3511+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3512+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3513+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3514+
3515+ // eraser
3516+ processKey(mapper, BTN_TOOL_RUBBER, 1);
3517+ processSync(mapper);
3518+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3519+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3520+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
3521+
3522+ // stylus
3523+ processKey(mapper, BTN_TOOL_RUBBER, 0);
3524+ processKey(mapper, BTN_TOOL_PEN, 1);
3525+ processSync(mapper);
3526+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3527+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3528+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
3529+
3530+ // brush
3531+ processKey(mapper, BTN_TOOL_PEN, 0);
3532+ processKey(mapper, BTN_TOOL_BRUSH, 1);
3533+ processSync(mapper);
3534+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3535+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3536+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
3537+
3538+ // pencil
3539+ processKey(mapper, BTN_TOOL_BRUSH, 0);
3540+ processKey(mapper, BTN_TOOL_PENCIL, 1);
3541+ processSync(mapper);
3542+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3543+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3544+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
3545+
3546+ // airbrush
3547+ processKey(mapper, BTN_TOOL_PENCIL, 0);
3548+ processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
3549+ processSync(mapper);
3550+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3551+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3552+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
3553+
3554+ // mouse
3555+ processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
3556+ processKey(mapper, BTN_TOOL_MOUSE, 1);
3557+ processSync(mapper);
3558+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3559+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3560+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
3561+
3562+ // lens
3563+ processKey(mapper, BTN_TOOL_MOUSE, 0);
3564+ processKey(mapper, BTN_TOOL_LENS, 1);
3565+ processSync(mapper);
3566+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3567+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3568+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
3569+
3570+ // double-tap
3571+ processKey(mapper, BTN_TOOL_LENS, 0);
3572+ processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
3573+ processSync(mapper);
3574+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3575+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3576+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3577+
3578+ // triple-tap
3579+ processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
3580+ processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
3581+ processSync(mapper);
3582+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3583+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3584+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3585+
3586+ // quad-tap
3587+ processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
3588+ processKey(mapper, BTN_TOOL_QUADTAP, 1);
3589+ processSync(mapper);
3590+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3591+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3592+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3593+
3594+ // finger
3595+ processKey(mapper, BTN_TOOL_QUADTAP, 0);
3596+ processKey(mapper, BTN_TOOL_FINGER, 1);
3597+ processSync(mapper);
3598+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3599+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3600+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3601+
3602+ // stylus trumps finger
3603+ processKey(mapper, BTN_TOOL_PEN, 1);
3604+ processSync(mapper);
3605+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3606+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3607+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
3608+
3609+ // eraser trumps stylus
3610+ processKey(mapper, BTN_TOOL_RUBBER, 1);
3611+ processSync(mapper);
3612+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3613+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3614+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
3615+
3616+ // mouse trumps eraser
3617+ processKey(mapper, BTN_TOOL_MOUSE, 1);
3618+ processSync(mapper);
3619+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3620+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3621+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
3622+
3623+ // back to default tool type
3624+ processKey(mapper, BTN_TOOL_MOUSE, 0);
3625+ processKey(mapper, BTN_TOOL_RUBBER, 0);
3626+ processKey(mapper, BTN_TOOL_PEN, 0);
3627+ processKey(mapper, BTN_TOOL_FINGER, 0);
3628+ processSync(mapper);
3629+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3630+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3631+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3632+}
3633+
3634+TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
3635+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3636+ addConfigurationProperty("touch.deviceType", "touchScreen");
3637+ prepareDisplay(DISPLAY_ORIENTATION_0);
3638+ prepareButtons();
3639+ prepareAxes(POSITION);
3640+ mFakeEventHub->addKey(DEVICE_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
3641+ addMapperAndConfigure(mapper);
3642+
3643+ NotifyMotionArgs motionArgs;
3644+
3645+ // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
3646+ processKey(mapper, BTN_TOOL_FINGER, 1);
3647+ processMove(mapper, 100, 200);
3648+ processSync(mapper);
3649+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3650+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
3651+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3652+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
3653+
3654+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3655+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
3656+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3657+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
3658+
3659+ // move a little
3660+ processMove(mapper, 150, 250);
3661+ processSync(mapper);
3662+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3663+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
3664+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3665+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3666+
3667+ // down when BTN_TOUCH is pressed, pressure defaults to 1
3668+ processKey(mapper, BTN_TOUCH, 1);
3669+ processSync(mapper);
3670+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3671+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
3672+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3673+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3674+
3675+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3676+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3677+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3678+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
3679+
3680+ // up when BTN_TOUCH is released, hover restored
3681+ processKey(mapper, BTN_TOUCH, 0);
3682+ processSync(mapper);
3683+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3684+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3685+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3686+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
3687+
3688+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3689+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
3690+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3691+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3692+
3693+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3694+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
3695+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3696+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3697+
3698+ // exit hover when pointer goes away
3699+ processKey(mapper, BTN_TOOL_FINGER, 0);
3700+ processSync(mapper);
3701+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3702+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
3703+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3704+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3705+}
3706+
3707+TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
3708+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
3709+ addConfigurationProperty("touch.deviceType", "touchScreen");
3710+ prepareDisplay(DISPLAY_ORIENTATION_0);
3711+ prepareButtons();
3712+ prepareAxes(POSITION | PRESSURE);
3713+ addMapperAndConfigure(mapper);
3714+
3715+ NotifyMotionArgs motionArgs;
3716+
3717+ // initially hovering because pressure is 0
3718+ processDown(mapper, 100, 200);
3719+ processPressure(mapper, 0);
3720+ processSync(mapper);
3721+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3722+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
3723+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3724+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
3725+
3726+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3727+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
3728+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3729+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
3730+
3731+ // move a little
3732+ processMove(mapper, 150, 250);
3733+ processSync(mapper);
3734+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3735+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
3736+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3737+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3738+
3739+ // down when pressure is non-zero
3740+ processPressure(mapper, RAW_PRESSURE_MAX);
3741+ processSync(mapper);
3742+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3743+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
3744+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3745+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3746+
3747+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3748+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3749+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3750+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
3751+
3752+ // up when pressure becomes 0, hover restored
3753+ processPressure(mapper, 0);
3754+ processSync(mapper);
3755+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3756+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3757+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3758+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
3759+
3760+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3761+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
3762+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3763+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3764+
3765+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3766+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
3767+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3768+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3769+
3770+ // exit hover when pointer goes away
3771+ processUp(mapper);
3772+ processSync(mapper);
3773+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3774+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
3775+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3776+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
3777+}
3778+
3779+
3780+// --- MultiTouchInputMapperTest ---
3781+
3782+class MultiTouchInputMapperTest : public TouchInputMapperTest {
3783+protected:
3784+ void prepareAxes(int axes);
3785+
3786+ void processPosition(MultiTouchInputMapper* mapper, int32_t x, int32_t y);
3787+ void processTouchMajor(MultiTouchInputMapper* mapper, int32_t touchMajor);
3788+ void processTouchMinor(MultiTouchInputMapper* mapper, int32_t touchMinor);
3789+ void processToolMajor(MultiTouchInputMapper* mapper, int32_t toolMajor);
3790+ void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor);
3791+ void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation);
3792+ void processPressure(MultiTouchInputMapper* mapper, int32_t pressure);
3793+ void processDistance(MultiTouchInputMapper* mapper, int32_t distance);
3794+ void processId(MultiTouchInputMapper* mapper, int32_t id);
3795+ void processSlot(MultiTouchInputMapper* mapper, int32_t slot);
3796+ void processToolType(MultiTouchInputMapper* mapper, int32_t toolType);
3797+ void processKey(MultiTouchInputMapper* mapper, int32_t code, int32_t value);
3798+ void processMTSync(MultiTouchInputMapper* mapper);
3799+ void processSync(MultiTouchInputMapper* mapper);
3800+ const char *inputSourceToStr(uint32_t source) const;
3801+};
3802+
3803+void MultiTouchInputMapperTest::prepareAxes(int axes) {
3804+ if (axes & POSITION) {
3805+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_X,
3806+ RAW_X_MIN, RAW_X_MAX, 0, 0);
3807+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_Y,
3808+ RAW_Y_MIN, RAW_Y_MAX, 0, 0);
3809+ }
3810+ if (axes & TOUCH) {
3811+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR,
3812+ RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
3813+ if (axes & MINOR) {
3814+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
3815+ RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
3816+ }
3817+ }
3818+ if (axes & TOOL) {
3819+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR,
3820+ RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
3821+ if (axes & MINOR) {
3822+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
3823+ RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
3824+ }
3825+ }
3826+ if (axes & ORIENTATION) {
3827+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_ORIENTATION,
3828+ RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
3829+ }
3830+ if (axes & PRESSURE) {
3831+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
3832+ RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
3833+ }
3834+ if (axes & DISTANCE) {
3835+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_DISTANCE,
3836+ RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
3837+ }
3838+ if (axes & ID) {
3839+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
3840+ RAW_ID_MIN, RAW_ID_MAX, 0, 0);
3841+ }
3842+ if (axes & SLOT) {
3843+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_SLOT,
3844+ RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
3845+ mFakeEventHub->setAbsoluteAxisValue(DEVICE_ID, ABS_MT_SLOT, 0);
3846+ }
3847+ if (axes & TOOL_TYPE) {
3848+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOOL_TYPE,
3849+ 0, MT_TOOL_MAX, 0, 0);
3850+ }
3851+}
3852+
3853+void MultiTouchInputMapperTest::processPosition(
3854+ MultiTouchInputMapper* mapper, int32_t x, int32_t y) {
3855+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_X, x);
3856+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_Y, y);
3857+}
3858+
3859+void MultiTouchInputMapperTest::processTouchMajor(
3860+ MultiTouchInputMapper* mapper, int32_t touchMajor) {
3861+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
3862+}
3863+
3864+void MultiTouchInputMapperTest::processTouchMinor(
3865+ MultiTouchInputMapper* mapper, int32_t touchMinor) {
3866+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
3867+}
3868+
3869+void MultiTouchInputMapperTest::processToolMajor(
3870+ MultiTouchInputMapper* mapper, int32_t toolMajor) {
3871+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
3872+}
3873+
3874+void MultiTouchInputMapperTest::processToolMinor(
3875+ MultiTouchInputMapper* mapper, int32_t toolMinor) {
3876+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
3877+}
3878+
3879+void MultiTouchInputMapperTest::processOrientation(
3880+ MultiTouchInputMapper* mapper, int32_t orientation) {
3881+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_ORIENTATION, orientation);
3882+}
3883+
3884+void MultiTouchInputMapperTest::processPressure(
3885+ MultiTouchInputMapper* mapper, int32_t pressure) {
3886+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, pressure);
3887+}
3888+
3889+void MultiTouchInputMapperTest::processDistance(
3890+ MultiTouchInputMapper* mapper, int32_t distance) {
3891+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_DISTANCE, distance);
3892+}
3893+
3894+void MultiTouchInputMapperTest::processId(
3895+ MultiTouchInputMapper* mapper, int32_t id) {
3896+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, id);
3897+}
3898+
3899+void MultiTouchInputMapperTest::processSlot(
3900+ MultiTouchInputMapper* mapper, int32_t slot) {
3901+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_SLOT, slot);
3902+}
3903+
3904+void MultiTouchInputMapperTest::processToolType(
3905+ MultiTouchInputMapper* mapper, int32_t toolType) {
3906+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
3907+}
3908+
3909+void MultiTouchInputMapperTest::processKey(
3910+ MultiTouchInputMapper* mapper, int32_t code, int32_t value) {
3911+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
3912+}
3913+
3914+void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
3915+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0);
3916+}
3917+
3918+void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) {
3919+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
3920+}
3921+
3922+const char *MultiTouchInputMapperTest::inputSourceToStr(uint32_t source) const {
3923+ switch (source) {
3924+ case AINPUT_SOURCE_UNKNOWN:
3925+ return "AINPUT_SOURCE_UNKNOWN";
3926+ case AINPUT_SOURCE_KEYBOARD:
3927+ return "AINPUT_SOURCE_KEYBOARD";
3928+ case AINPUT_SOURCE_DPAD:
3929+ return "AINPUT_SOURCE_DPAD";
3930+ case AINPUT_SOURCE_GAMEPAD:
3931+ return "AINPUT_SOURCE_GAMEPAD";
3932+ case AINPUT_SOURCE_TOUCHSCREEN:
3933+ return "AINPUT_SOURCE_TOUCHSCREEN";
3934+ case AINPUT_SOURCE_MOUSE:
3935+ return "AINPUT_SOURCE_MOUSE";
3936+ case AINPUT_SOURCE_STYLUS:
3937+ return "AINPUT_SOURCE_STYLUS";
3938+ case AINPUT_SOURCE_TRACKBALL:
3939+ return "AINPUT_SOURCE_TRACKBALL";
3940+ case AINPUT_SOURCE_TOUCHPAD:
3941+ return "AINPUT_SOURCE_TOUCHPAD";
3942+ case AINPUT_SOURCE_JOYSTICK:
3943+ return "AINPUT_SOURCE_JOYSTICK";
3944+ case AINPUT_SOURCE_ANY:
3945+ return "AINPUT_SOURCE_ANY";
3946+ default:
3947+ return "No matching enum value!";
3948+ }
3949+}
3950+
3951+TEST_F(MultiTouchInputMapperTest, DISABLED_Process_NormalMultiTouchGesture_WithoutTrackingIds) {
3952+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
3953+ addConfigurationProperty("touch.deviceType", "touchScreen");
3954+ prepareDisplay(DISPLAY_ORIENTATION_0);
3955+ prepareAxes(POSITION);
3956+ prepareVirtualKeys();
3957+ addMapperAndConfigure(mapper);
3958+
3959+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3960+
3961+ NotifyMotionArgs motionArgs;
3962+
3963+ // Two fingers down at once.
3964+ int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
3965+ processPosition(mapper, x1, y1);
3966+ processMTSync(mapper);
3967+ processPosition(mapper, x2, y2);
3968+ processMTSync(mapper);
3969+ processSync(mapper);
3970+
3971+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3972+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3973+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3974+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source)
3975+ << "motionArgs.source=" << inputSourceToStr(motionArgs.source);
3976+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3977+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3978+ ASSERT_EQ(0, motionArgs.flags);
3979+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3980+ ASSERT_EQ(0, motionArgs.buttonState);
3981+ ASSERT_EQ(0, motionArgs.edgeFlags);
3982+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
3983+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3984+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
3985+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3986+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
3987+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3988+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3989+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3990+
3991+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3992+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3993+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3994+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3995+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3996+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
3997+ motionArgs.action);
3998+ ASSERT_EQ(0, motionArgs.flags);
3999+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4000+ ASSERT_EQ(0, motionArgs.buttonState);
4001+ ASSERT_EQ(0, motionArgs.edgeFlags);
4002+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4003+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4004+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4005+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4006+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4007+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4008+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4009+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4010+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4011+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4012+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4013+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4014+
4015+ // Move.
4016+ x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
4017+ processPosition(mapper, x1, y1);
4018+ processMTSync(mapper);
4019+ processPosition(mapper, x2, y2);
4020+ processMTSync(mapper);
4021+ processSync(mapper);
4022+
4023+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4024+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4025+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4026+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4027+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4028+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4029+ ASSERT_EQ(0, motionArgs.flags);
4030+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4031+ ASSERT_EQ(0, motionArgs.buttonState);
4032+ ASSERT_EQ(0, motionArgs.edgeFlags);
4033+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4034+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4035+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4036+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4037+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4038+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4039+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4040+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4041+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4042+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4043+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4044+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4045+
4046+ // First finger up.
4047+ x2 += 15; y2 -= 20;
4048+ processPosition(mapper, x2, y2);
4049+ processMTSync(mapper);
4050+ processSync(mapper);
4051+
4052+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4053+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4054+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4055+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4056+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4057+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4058+ motionArgs.action);
4059+ ASSERT_EQ(0, motionArgs.flags);
4060+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4061+ ASSERT_EQ(0, motionArgs.buttonState);
4062+ ASSERT_EQ(0, motionArgs.edgeFlags);
4063+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4064+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4065+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4066+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4067+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4068+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4069+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4070+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4071+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4072+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4073+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4074+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4075+
4076+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4077+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4078+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4079+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4080+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4081+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4082+ ASSERT_EQ(0, motionArgs.flags);
4083+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4084+ ASSERT_EQ(0, motionArgs.buttonState);
4085+ ASSERT_EQ(0, motionArgs.edgeFlags);
4086+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4087+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
4088+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4089+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4090+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4091+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4092+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4093+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4094+
4095+ // Move.
4096+ x2 += 20; y2 -= 25;
4097+ processPosition(mapper, x2, y2);
4098+ processMTSync(mapper);
4099+ processSync(mapper);
4100+
4101+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4102+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4103+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4104+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4105+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4106+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4107+ ASSERT_EQ(0, motionArgs.flags);
4108+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4109+ ASSERT_EQ(0, motionArgs.buttonState);
4110+ ASSERT_EQ(0, motionArgs.edgeFlags);
4111+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4112+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
4113+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4114+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4115+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4116+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4117+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4118+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4119+
4120+ // New finger down.
4121+ int32_t x3 = 700, y3 = 300;
4122+ processPosition(mapper, x2, y2);
4123+ processMTSync(mapper);
4124+ processPosition(mapper, x3, y3);
4125+ processMTSync(mapper);
4126+ processSync(mapper);
4127+
4128+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4129+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4130+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4131+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4132+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4133+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4134+ motionArgs.action);
4135+ ASSERT_EQ(0, motionArgs.flags);
4136+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4137+ ASSERT_EQ(0, motionArgs.buttonState);
4138+ ASSERT_EQ(0, motionArgs.edgeFlags);
4139+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4140+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4141+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4142+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4143+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4144+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4145+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4146+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4147+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4148+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4149+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4150+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4151+
4152+ // Second finger up.
4153+ x3 += 30; y3 -= 20;
4154+ processPosition(mapper, x3, y3);
4155+ processMTSync(mapper);
4156+ processSync(mapper);
4157+
4158+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4159+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4160+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4161+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4162+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4163+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4164+ motionArgs.action);
4165+ ASSERT_EQ(0, motionArgs.flags);
4166+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4167+ ASSERT_EQ(0, motionArgs.buttonState);
4168+ ASSERT_EQ(0, motionArgs.edgeFlags);
4169+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4170+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4171+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4172+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4173+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4174+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4175+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4176+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4177+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4178+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4179+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4180+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4181+
4182+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4183+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4184+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4185+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4186+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4187+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4188+ ASSERT_EQ(0, motionArgs.flags);
4189+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4190+ ASSERT_EQ(0, motionArgs.buttonState);
4191+ ASSERT_EQ(0, motionArgs.edgeFlags);
4192+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4193+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4194+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4195+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4196+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4197+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4198+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4199+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4200+
4201+ // Last finger up.
4202+ processMTSync(mapper);
4203+ processSync(mapper);
4204+
4205+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4206+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
4207+ ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
4208+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
4209+ ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
4210+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
4211+ ASSERT_EQ(0, motionArgs.flags);
4212+ ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
4213+ ASSERT_EQ(0, motionArgs.buttonState);
4214+ ASSERT_EQ(0, motionArgs.edgeFlags);
4215+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4216+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4217+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4218+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4219+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4220+ ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
4221+ ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
4222+ ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
4223+
4224+ // Should not have sent any more keys or motions.
4225+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
4226+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
4227+}
4228+
4229+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
4230+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4231+ addConfigurationProperty("touch.deviceType", "touchScreen");
4232+ prepareDisplay(DISPLAY_ORIENTATION_0);
4233+ prepareAxes(POSITION | ID);
4234+ prepareVirtualKeys();
4235+ addMapperAndConfigure(mapper);
4236+
4237+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
4238+
4239+ NotifyMotionArgs motionArgs;
4240+
4241+ // Two fingers down at once.
4242+ int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
4243+ processPosition(mapper, x1, y1);
4244+ processId(mapper, 1);
4245+ processMTSync(mapper);
4246+ processPosition(mapper, x2, y2);
4247+ processId(mapper, 2);
4248+ processMTSync(mapper);
4249+ processSync(mapper);
4250+
4251+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4252+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4253+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4254+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4255+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4256+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4257+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4258+
4259+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4260+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4261+ motionArgs.action);
4262+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4263+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4264+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4265+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4266+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4267+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4268+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4269+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4270+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4271+
4272+ // Move.
4273+ x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
4274+ processPosition(mapper, x1, y1);
4275+ processId(mapper, 1);
4276+ processMTSync(mapper);
4277+ processPosition(mapper, x2, y2);
4278+ processId(mapper, 2);
4279+ processMTSync(mapper);
4280+ processSync(mapper);
4281+
4282+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4283+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4284+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4285+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4286+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4287+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4288+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4289+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4290+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4291+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4292+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4293+
4294+ // First finger up.
4295+ x2 += 15; y2 -= 20;
4296+ processPosition(mapper, x2, y2);
4297+ processId(mapper, 2);
4298+ processMTSync(mapper);
4299+ processSync(mapper);
4300+
4301+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4302+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4303+ motionArgs.action);
4304+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4305+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4306+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4307+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4308+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4309+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4310+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4311+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4312+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4313+
4314+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4315+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4316+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4317+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
4318+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4319+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4320+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4321+
4322+ // Move.
4323+ x2 += 20; y2 -= 25;
4324+ processPosition(mapper, x2, y2);
4325+ processId(mapper, 2);
4326+ processMTSync(mapper);
4327+ processSync(mapper);
4328+
4329+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4330+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4331+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4332+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
4333+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4334+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4335+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4336+
4337+ // New finger down.
4338+ int32_t x3 = 700, y3 = 300;
4339+ processPosition(mapper, x2, y2);
4340+ processId(mapper, 2);
4341+ processMTSync(mapper);
4342+ processPosition(mapper, x3, y3);
4343+ processId(mapper, 3);
4344+ processMTSync(mapper);
4345+ processSync(mapper);
4346+
4347+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4348+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4349+ motionArgs.action);
4350+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4351+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4352+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4353+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4354+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4355+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4356+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4357+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4358+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4359+
4360+ // Second finger up.
4361+ x3 += 30; y3 -= 20;
4362+ processPosition(mapper, x3, y3);
4363+ processId(mapper, 3);
4364+ processMTSync(mapper);
4365+ processSync(mapper);
4366+
4367+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4368+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4369+ motionArgs.action);
4370+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4371+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4372+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4373+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4374+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4375+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4376+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4377+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4378+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4379+
4380+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4381+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4382+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4383+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4384+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4385+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4386+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4387+
4388+ // Last finger up.
4389+ processMTSync(mapper);
4390+ processSync(mapper);
4391+
4392+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4393+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
4394+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4395+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4396+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4397+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4398+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4399+
4400+ // Should not have sent any more keys or motions.
4401+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
4402+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
4403+}
4404+
4405+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
4406+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4407+ addConfigurationProperty("touch.deviceType", "touchScreen");
4408+ prepareDisplay(DISPLAY_ORIENTATION_0);
4409+ prepareAxes(POSITION | ID | SLOT);
4410+ prepareVirtualKeys();
4411+ addMapperAndConfigure(mapper);
4412+
4413+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
4414+
4415+ NotifyMotionArgs motionArgs;
4416+
4417+ // Two fingers down at once.
4418+ int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
4419+ processPosition(mapper, x1, y1);
4420+ processId(mapper, 1);
4421+ processSlot(mapper, 1);
4422+ processPosition(mapper, x2, y2);
4423+ processId(mapper, 2);
4424+ processSync(mapper);
4425+
4426+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4427+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4428+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4429+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4430+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4431+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4432+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4433+
4434+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4435+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4436+ motionArgs.action);
4437+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4438+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4439+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4440+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4441+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4442+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4443+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4444+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4445+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4446+
4447+ // Move.
4448+ x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
4449+ processSlot(mapper, 0);
4450+ processPosition(mapper, x1, y1);
4451+ processSlot(mapper, 1);
4452+ processPosition(mapper, x2, y2);
4453+ processSync(mapper);
4454+
4455+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4456+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4457+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4458+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4459+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4460+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4461+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4462+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4463+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4464+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4465+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4466+
4467+ // First finger up.
4468+ x2 += 15; y2 -= 20;
4469+ processSlot(mapper, 0);
4470+ processId(mapper, -1);
4471+ processSlot(mapper, 1);
4472+ processPosition(mapper, x2, y2);
4473+ processSync(mapper);
4474+
4475+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4476+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4477+ motionArgs.action);
4478+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4479+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4480+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4481+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4482+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4483+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4484+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
4485+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4486+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4487+
4488+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4489+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4490+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4491+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
4492+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4493+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4494+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4495+
4496+ // Move.
4497+ x2 += 20; y2 -= 25;
4498+ processPosition(mapper, x2, y2);
4499+ processSync(mapper);
4500+
4501+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4502+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4503+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4504+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
4505+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4506+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4507+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4508+
4509+ // New finger down.
4510+ int32_t x3 = 700, y3 = 300;
4511+ processPosition(mapper, x2, y2);
4512+ processSlot(mapper, 0);
4513+ processId(mapper, 3);
4514+ processPosition(mapper, x3, y3);
4515+ processSync(mapper);
4516+
4517+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4518+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4519+ motionArgs.action);
4520+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4521+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4522+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4523+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4524+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4525+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4526+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4527+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4528+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4529+
4530+ // Second finger up.
4531+ x3 += 30; y3 -= 20;
4532+ processSlot(mapper, 1);
4533+ processId(mapper, -1);
4534+ processSlot(mapper, 0);
4535+ processPosition(mapper, x3, y3);
4536+ processSync(mapper);
4537+
4538+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4539+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4540+ motionArgs.action);
4541+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
4542+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4543+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4544+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
4545+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
4546+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4547+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4548+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
4549+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
4550+
4551+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4552+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4553+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4554+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4555+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4556+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4557+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4558+
4559+ // Last finger up.
4560+ processId(mapper, -1);
4561+ processSync(mapper);
4562+
4563+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4564+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
4565+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
4566+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
4567+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4568+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4569+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
4570+
4571+ // Should not have sent any more keys or motions.
4572+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
4573+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
4574+}
4575+
4576+TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
4577+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4578+ addConfigurationProperty("touch.deviceType", "touchScreen");
4579+ prepareDisplay(DISPLAY_ORIENTATION_0);
4580+ prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
4581+ addMapperAndConfigure(mapper);
4582+
4583+ // These calculations are based on the input device calibration documentation.
4584+ int32_t rawX = 100;
4585+ int32_t rawY = 200;
4586+ int32_t rawTouchMajor = 7;
4587+ int32_t rawTouchMinor = 6;
4588+ int32_t rawToolMajor = 9;
4589+ int32_t rawToolMinor = 8;
4590+ int32_t rawPressure = 11;
4591+ int32_t rawDistance = 0;
4592+ int32_t rawOrientation = 3;
4593+ int32_t id = 5;
4594+
4595+ float x = toDisplayX(rawX);
4596+ float y = toDisplayY(rawY);
4597+ float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
4598+ float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
4599+ float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
4600+ float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
4601+ float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
4602+ float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
4603+ float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
4604+ float distance = float(rawDistance);
4605+
4606+ processPosition(mapper, rawX, rawY);
4607+ processTouchMajor(mapper, rawTouchMajor);
4608+ processTouchMinor(mapper, rawTouchMinor);
4609+ processToolMajor(mapper, rawToolMajor);
4610+ processToolMinor(mapper, rawToolMinor);
4611+ processPressure(mapper, rawPressure);
4612+ processOrientation(mapper, rawOrientation);
4613+ processDistance(mapper, rawDistance);
4614+ processId(mapper, id);
4615+ processMTSync(mapper);
4616+ processSync(mapper);
4617+
4618+ NotifyMotionArgs args;
4619+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4620+ ASSERT_EQ(0, args.pointerProperties[0].id);
4621+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4622+ x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
4623+ orientation, distance));
4624+}
4625+
4626+TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
4627+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4628+ addConfigurationProperty("touch.deviceType", "touchScreen");
4629+ prepareDisplay(DISPLAY_ORIENTATION_0);
4630+ prepareAxes(POSITION | TOUCH | TOOL | MINOR);
4631+ addConfigurationProperty("touch.size.calibration", "geometric");
4632+ addMapperAndConfigure(mapper);
4633+
4634+ // These calculations are based on the input device calibration documentation.
4635+ int32_t rawX = 100;
4636+ int32_t rawY = 200;
4637+ int32_t rawTouchMajor = 140;
4638+ int32_t rawTouchMinor = 120;
4639+ int32_t rawToolMajor = 180;
4640+ int32_t rawToolMinor = 160;
4641+
4642+ float x = toDisplayX(rawX);
4643+ float y = toDisplayY(rawY);
4644+ float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
4645+ float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
4646+ float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
4647+ float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
4648+ float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
4649+
4650+ processPosition(mapper, rawX, rawY);
4651+ processTouchMajor(mapper, rawTouchMajor);
4652+ processTouchMinor(mapper, rawTouchMinor);
4653+ processToolMajor(mapper, rawToolMajor);
4654+ processToolMinor(mapper, rawToolMinor);
4655+ processMTSync(mapper);
4656+ processSync(mapper);
4657+
4658+ NotifyMotionArgs args;
4659+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4660+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4661+ x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
4662+}
4663+
4664+TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
4665+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4666+ addConfigurationProperty("touch.deviceType", "touchScreen");
4667+ prepareDisplay(DISPLAY_ORIENTATION_0);
4668+ prepareAxes(POSITION | TOUCH | TOOL);
4669+ addConfigurationProperty("touch.size.calibration", "diameter");
4670+ addConfigurationProperty("touch.size.scale", "10");
4671+ addConfigurationProperty("touch.size.bias", "160");
4672+ addConfigurationProperty("touch.size.isSummed", "1");
4673+ addMapperAndConfigure(mapper);
4674+
4675+ // These calculations are based on the input device calibration documentation.
4676+ // Note: We only provide a single common touch/tool value because the device is assumed
4677+ // not to emit separate values for each pointer (isSummed = 1).
4678+ int32_t rawX = 100;
4679+ int32_t rawY = 200;
4680+ int32_t rawX2 = 150;
4681+ int32_t rawY2 = 250;
4682+ int32_t rawTouchMajor = 5;
4683+ int32_t rawToolMajor = 8;
4684+
4685+ float x = toDisplayX(rawX);
4686+ float y = toDisplayY(rawY);
4687+ float x2 = toDisplayX(rawX2);
4688+ float y2 = toDisplayY(rawY2);
4689+ float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
4690+ float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
4691+ float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
4692+
4693+ processPosition(mapper, rawX, rawY);
4694+ processTouchMajor(mapper, rawTouchMajor);
4695+ processToolMajor(mapper, rawToolMajor);
4696+ processMTSync(mapper);
4697+ processPosition(mapper, rawX2, rawY2);
4698+ processTouchMajor(mapper, rawTouchMajor);
4699+ processToolMajor(mapper, rawToolMajor);
4700+ processMTSync(mapper);
4701+ processSync(mapper);
4702+
4703+ NotifyMotionArgs args;
4704+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4705+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4706+
4707+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4708+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
4709+ args.action);
4710+ ASSERT_EQ(size_t(2), args.pointerCount);
4711+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4712+ x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
4713+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
4714+ x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
4715+}
4716+
4717+TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
4718+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4719+ addConfigurationProperty("touch.deviceType", "touchScreen");
4720+ prepareDisplay(DISPLAY_ORIENTATION_0);
4721+ prepareAxes(POSITION | TOUCH | TOOL);
4722+ addConfigurationProperty("touch.size.calibration", "area");
4723+ addConfigurationProperty("touch.size.scale", "43");
4724+ addConfigurationProperty("touch.size.bias", "3");
4725+ addMapperAndConfigure(mapper);
4726+
4727+ // These calculations are based on the input device calibration documentation.
4728+ int32_t rawX = 100;
4729+ int32_t rawY = 200;
4730+ int32_t rawTouchMajor = 5;
4731+ int32_t rawToolMajor = 8;
4732+
4733+ float x = toDisplayX(rawX);
4734+ float y = toDisplayY(rawY);
4735+ float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
4736+ float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
4737+ float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
4738+
4739+ processPosition(mapper, rawX, rawY);
4740+ processTouchMajor(mapper, rawTouchMajor);
4741+ processToolMajor(mapper, rawToolMajor);
4742+ processMTSync(mapper);
4743+ processSync(mapper);
4744+
4745+ NotifyMotionArgs args;
4746+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4747+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4748+ x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
4749+}
4750+
4751+TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
4752+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4753+ addConfigurationProperty("touch.deviceType", "touchScreen");
4754+ prepareDisplay(DISPLAY_ORIENTATION_0);
4755+ prepareAxes(POSITION | PRESSURE);
4756+ addConfigurationProperty("touch.pressure.calibration", "amplitude");
4757+ addConfigurationProperty("touch.pressure.scale", "0.01");
4758+ addMapperAndConfigure(mapper);
4759+
4760+ // These calculations are based on the input device calibration documentation.
4761+ int32_t rawX = 100;
4762+ int32_t rawY = 200;
4763+ int32_t rawPressure = 60;
4764+
4765+ float x = toDisplayX(rawX);
4766+ float y = toDisplayY(rawY);
4767+ float pressure = float(rawPressure) * 0.01f;
4768+
4769+ processPosition(mapper, rawX, rawY);
4770+ processPressure(mapper, rawPressure);
4771+ processMTSync(mapper);
4772+ processSync(mapper);
4773+
4774+ NotifyMotionArgs args;
4775+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4776+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4777+ x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
4778+}
4779+
4780+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
4781+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4782+ addConfigurationProperty("touch.deviceType", "touchScreen");
4783+ prepareDisplay(DISPLAY_ORIENTATION_0);
4784+ prepareAxes(POSITION | ID | SLOT);
4785+ addMapperAndConfigure(mapper);
4786+
4787+ NotifyMotionArgs motionArgs;
4788+ NotifyKeyArgs keyArgs;
4789+
4790+ processId(mapper, 1);
4791+ processPosition(mapper, 100, 200);
4792+ processSync(mapper);
4793+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4794+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4795+ ASSERT_EQ(0, motionArgs.buttonState);
4796+
4797+ // press BTN_LEFT, release BTN_LEFT
4798+ processKey(mapper, BTN_LEFT, 1);
4799+ processSync(mapper);
4800+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4801+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4802+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4803+
4804+ processKey(mapper, BTN_LEFT, 0);
4805+ processSync(mapper);
4806+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4807+ ASSERT_EQ(0, motionArgs.buttonState);
4808+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4809+
4810+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
4811+ processKey(mapper, BTN_RIGHT, 1);
4812+ processKey(mapper, BTN_MIDDLE, 1);
4813+ processSync(mapper);
4814+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4815+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4816+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4817+ motionArgs.buttonState);
4818+
4819+ processKey(mapper, BTN_RIGHT, 0);
4820+ processSync(mapper);
4821+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4822+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4823+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4824+
4825+ processKey(mapper, BTN_MIDDLE, 0);
4826+ processSync(mapper);
4827+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4828+ ASSERT_EQ(0, motionArgs.buttonState);
4829+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4830+
4831+ // press BTN_BACK, release BTN_BACK
4832+ processKey(mapper, BTN_BACK, 1);
4833+ processSync(mapper);
4834+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4835+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4836+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4837+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4838+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4839+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4840+
4841+ processKey(mapper, BTN_BACK, 0);
4842+ processSync(mapper);
4843+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4844+ ASSERT_EQ(0, motionArgs.buttonState);
4845+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4846+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4847+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4848+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4849+
4850+ // press BTN_SIDE, release BTN_SIDE
4851+ processKey(mapper, BTN_SIDE, 1);
4852+ processSync(mapper);
4853+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4854+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4855+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4856+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4857+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4858+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4859+
4860+ processKey(mapper, BTN_SIDE, 0);
4861+ processSync(mapper);
4862+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4863+ ASSERT_EQ(0, motionArgs.buttonState);
4864+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4865+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4866+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4867+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4868+
4869+ // press BTN_FORWARD, release BTN_FORWARD
4870+ processKey(mapper, BTN_FORWARD, 1);
4871+ processSync(mapper);
4872+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4873+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4874+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4875+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4876+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4877+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4878+
4879+ processKey(mapper, BTN_FORWARD, 0);
4880+ processSync(mapper);
4881+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4882+ ASSERT_EQ(0, motionArgs.buttonState);
4883+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4884+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4885+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4886+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4887+
4888+ // press BTN_EXTRA, release BTN_EXTRA
4889+ processKey(mapper, BTN_EXTRA, 1);
4890+ processSync(mapper);
4891+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4892+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4893+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4894+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4895+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4896+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4897+
4898+ processKey(mapper, BTN_EXTRA, 0);
4899+ processSync(mapper);
4900+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4901+ ASSERT_EQ(0, motionArgs.buttonState);
4902+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4903+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4904+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4905+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4906+
4907+ // press BTN_STYLUS, release BTN_STYLUS
4908+ processKey(mapper, BTN_STYLUS, 1);
4909+ processSync(mapper);
4910+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4911+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4912+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
4913+
4914+ processKey(mapper, BTN_STYLUS, 0);
4915+ processSync(mapper);
4916+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4917+ ASSERT_EQ(0, motionArgs.buttonState);
4918+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4919+
4920+ // press BTN_STYLUS2, release BTN_STYLUS2
4921+ processKey(mapper, BTN_STYLUS2, 1);
4922+ processSync(mapper);
4923+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4924+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4925+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4926+
4927+ processKey(mapper, BTN_STYLUS2, 0);
4928+ processSync(mapper);
4929+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4930+ ASSERT_EQ(0, motionArgs.buttonState);
4931+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4932+
4933+ // release touch
4934+ processId(mapper, -1);
4935+ processSync(mapper);
4936+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4937+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
4938+ ASSERT_EQ(0, motionArgs.buttonState);
4939+}
4940+
4941+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
4942+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
4943+ addConfigurationProperty("touch.deviceType", "touchScreen");
4944+ prepareDisplay(DISPLAY_ORIENTATION_0);
4945+ prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
4946+ addMapperAndConfigure(mapper);
4947+
4948+ NotifyMotionArgs motionArgs;
4949+
4950+ // default tool type is finger
4951+ processId(mapper, 1);
4952+ processPosition(mapper, 100, 200);
4953+ processSync(mapper);
4954+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4955+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4956+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
4957+
4958+ // eraser
4959+ processKey(mapper, BTN_TOOL_RUBBER, 1);
4960+ processSync(mapper);
4961+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4962+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4963+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
4964+
4965+ // stylus
4966+ processKey(mapper, BTN_TOOL_RUBBER, 0);
4967+ processKey(mapper, BTN_TOOL_PEN, 1);
4968+ processSync(mapper);
4969+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4970+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4971+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
4972+
4973+ // brush
4974+ processKey(mapper, BTN_TOOL_PEN, 0);
4975+ processKey(mapper, BTN_TOOL_BRUSH, 1);
4976+ processSync(mapper);
4977+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4978+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4979+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
4980+
4981+ // pencil
4982+ processKey(mapper, BTN_TOOL_BRUSH, 0);
4983+ processKey(mapper, BTN_TOOL_PENCIL, 1);
4984+ processSync(mapper);
4985+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4986+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4987+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
4988+
4989+ // airbrush
4990+ processKey(mapper, BTN_TOOL_PENCIL, 0);
4991+ processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
4992+ processSync(mapper);
4993+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4994+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4995+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
4996+
4997+ // mouse
4998+ processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
4999+ processKey(mapper, BTN_TOOL_MOUSE, 1);
5000+ processSync(mapper);
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches