• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cinttypes>
18 #include <memory>
19 #include <optional>
20 
21 #include <CursorInputMapper.h>
22 #include <InputDevice.h>
23 #include <InputMapper.h>
24 #include <InputReader.h>
25 #include <InputReaderBase.h>
26 #include <InputReaderFactory.h>
27 #include <KeyboardInputMapper.h>
28 #include <MultiTouchInputMapper.h>
29 #include <NotifyArgsBuilders.h>
30 #include <PeripheralController.h>
31 #include <ScopedFlagOverride.h>
32 #include <SingleTouchInputMapper.h>
33 #include <TestEventMatchers.h>
34 #include <TestInputListener.h>
35 #include <TouchInputMapper.h>
36 #include <UinputDevice.h>
37 #include <android-base/thread_annotations.h>
38 #include <com_android_input_flags.h>
39 #include <flag_macros.h>
40 #include <ftl/enum.h>
41 #include <gtest/gtest.h>
42 #include <ui/Rotation.h>
43 
44 #include <thread>
45 #include "FakeEventHub.h"
46 #include "FakeInputReaderPolicy.h"
47 #include "InputMapperTest.h"
48 #include "InstrumentedInputReader.h"
49 #include "TestConstants.h"
50 #include "input/DisplayViewport.h"
51 #include "input/Input.h"
52 
53 namespace android {
54 
55 using namespace ftl::flag_operators;
56 using testing::AllOf;
57 using testing::VariantWith;
58 using std::chrono_literals::operator""ms;
59 using std::chrono_literals::operator""s;
60 
61 // Arbitrary display properties.
62 static constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
63 static const std::string DISPLAY_UNIQUE_ID = "local:1";
64 static constexpr ui::LogicalDisplayId SECONDARY_DISPLAY_ID =
65         ui::LogicalDisplayId{DISPLAY_ID.val() + 1};
66 static constexpr int32_t DISPLAY_WIDTH = 480;
67 static constexpr int32_t DISPLAY_HEIGHT = 800;
68 static constexpr ui::LogicalDisplayId VIRTUAL_DISPLAY_ID = ui::LogicalDisplayId{1};
69 static constexpr int32_t VIRTUAL_DISPLAY_WIDTH = 400;
70 static constexpr int32_t VIRTUAL_DISPLAY_HEIGHT = 500;
71 static const char* VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
72 static constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
73 
74 static constexpr int32_t FIRST_SLOT = 0;
75 static constexpr int32_t SECOND_SLOT = 1;
76 static constexpr int32_t THIRD_SLOT = 2;
77 static constexpr int32_t INVALID_TRACKING_ID = -1;
78 static constexpr int32_t FIRST_TRACKING_ID = 0;
79 static constexpr int32_t SECOND_TRACKING_ID = 1;
80 static constexpr int32_t THIRD_TRACKING_ID = 2;
81 static constexpr int32_t LIGHT_BRIGHTNESS = 0x55000000;
82 static constexpr int32_t LIGHT_COLOR = 0x7F448866;
83 static constexpr int32_t LIGHT_PLAYER_ID = 2;
84 
85 static constexpr int32_t ACTION_POINTER_0_DOWN =
86         AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
87 static constexpr int32_t ACTION_POINTER_0_UP =
88         AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
89 static constexpr int32_t ACTION_POINTER_1_DOWN =
90         AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
91 static constexpr int32_t ACTION_POINTER_1_UP =
92         AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
93 
94 static constexpr uint32_t STYLUS_FUSION_SOURCE =
95         AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_BLUETOOTH_STYLUS;
96 
97 // Minimum timestamp separation between subsequent input events from a Bluetooth device.
98 static constexpr nsecs_t MIN_BLUETOOTH_TIMESTAMP_DELTA = ms2ns(4);
99 
100 namespace input_flags = com::android::input::flags;
101 
102 template<typename T>
min(T a,T b)103 static inline T min(T a, T b) {
104     return a < b ? a : b;
105 }
106 
avg(float x,float y)107 static inline float avg(float x, float y) {
108     return (x + y) / 2;
109 }
110 
111 // Mapping for light color name and the light color
112 const std::unordered_map<std::string, LightColor> LIGHT_COLORS = {{"red", LightColor::RED},
113                                                                   {"green", LightColor::GREEN},
114                                                                   {"blue", LightColor::BLUE}};
115 
getInverseRotation(ui::Rotation orientation)116 static ui::Rotation getInverseRotation(ui::Rotation orientation) {
117     switch (orientation) {
118         case ui::ROTATION_90:
119             return ui::ROTATION_270;
120         case ui::ROTATION_270:
121             return ui::ROTATION_90;
122         default:
123             return orientation;
124     }
125 }
126 
assertAxisResolution(MultiTouchInputMapper & mapper,int axis,float resolution)127 static void assertAxisResolution(MultiTouchInputMapper& mapper, int axis, float resolution) {
128     InputDeviceInfo info;
129     mapper.populateDeviceInfo(info);
130 
131     const InputDeviceInfo::MotionRange* motionRange =
132             info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
133     ASSERT_NEAR(motionRange->resolution, resolution, EPSILON);
134 }
135 
assertAxisNotPresent(MultiTouchInputMapper & mapper,int axis)136 static void assertAxisNotPresent(MultiTouchInputMapper& mapper, int axis) {
137     InputDeviceInfo info;
138     mapper.populateDeviceInfo(info);
139 
140     const InputDeviceInfo::MotionRange* motionRange =
141             info.getMotionRange(axis, AINPUT_SOURCE_TOUCHSCREEN);
142     ASSERT_EQ(nullptr, motionRange);
143 }
144 
dumpReader(InputReader & reader)145 [[maybe_unused]] static void dumpReader(InputReader& reader) {
146     std::string dump;
147     reader.dump(dump);
148     std::istringstream iss(dump);
149     for (std::string line; std::getline(iss, line);) {
150         ALOGE("%s", line.c_str());
151         std::this_thread::sleep_for(1ms);
152     }
153 }
154 
155 // --- FakeInputMapper ---
156 
157 class FakeInputMapper : public InputMapper {
158     uint32_t mSources;
159     int32_t mKeyboardType;
160     int32_t mMetaState;
161     KeyedVector<int32_t, int32_t> mKeyCodeStates;
162     KeyedVector<int32_t, int32_t> mScanCodeStates;
163     KeyedVector<int32_t, int32_t> mSwitchStates;
164     // fake mapping which would normally come from keyCharacterMap
165     std::unordered_map<int32_t, int32_t> mKeyCodeMapping;
166     std::vector<int32_t> mSupportedKeyCodes;
167     std::list<NotifyArgs> mProcessResult;
168 
169     std::mutex mLock;
170     std::condition_variable mStateChangedCondition;
171     bool mConfigureWasCalled GUARDED_BY(mLock);
172     bool mResetWasCalled GUARDED_BY(mLock);
173     bool mProcessWasCalled GUARDED_BY(mLock);
174     RawEvent mLastEvent GUARDED_BY(mLock);
175 
176     std::optional<DisplayViewport> mViewport;
177 public:
FakeInputMapper(InputDeviceContext & deviceContext,const InputReaderConfiguration & readerConfig,uint32_t sources)178     FakeInputMapper(InputDeviceContext& deviceContext, const InputReaderConfiguration& readerConfig,
179                     uint32_t sources)
180           : InputMapper(deviceContext, readerConfig),
181             mSources(sources),
182             mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
183             mMetaState(0),
184             mConfigureWasCalled(false),
185             mResetWasCalled(false),
186             mProcessWasCalled(false) {}
187 
~FakeInputMapper()188     virtual ~FakeInputMapper() {}
189 
setKeyboardType(int32_t keyboardType)190     void setKeyboardType(int32_t keyboardType) {
191         mKeyboardType = keyboardType;
192     }
193 
setMetaState(int32_t metaState)194     void setMetaState(int32_t metaState) {
195         mMetaState = metaState;
196     }
197 
198     // Sets the return value for the `process` call.
setProcessResult(std::list<NotifyArgs> notifyArgs)199     void setProcessResult(std::list<NotifyArgs> notifyArgs) {
200         mProcessResult.clear();
201         for (auto notifyArg : notifyArgs) {
202             mProcessResult.push_back(notifyArg);
203         }
204     }
205 
assertConfigureWasCalled()206     void assertConfigureWasCalled() {
207         std::unique_lock<std::mutex> lock(mLock);
208         base::ScopedLockAssertion assumeLocked(mLock);
209         const bool configureCalled =
210                 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
211                     return mConfigureWasCalled;
212                 });
213         if (!configureCalled) {
214             FAIL() << "Expected configure() to have been called.";
215         }
216         mConfigureWasCalled = false;
217     }
218 
assertResetWasCalled()219     void assertResetWasCalled() {
220         std::unique_lock<std::mutex> lock(mLock);
221         base::ScopedLockAssertion assumeLocked(mLock);
222         const bool resetCalled =
223                 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
224                     return mResetWasCalled;
225                 });
226         if (!resetCalled) {
227             FAIL() << "Expected reset() to have been called.";
228         }
229         mResetWasCalled = false;
230     }
231 
assertResetWasNotCalled()232     void assertResetWasNotCalled() {
233         std::scoped_lock lock(mLock);
234         ASSERT_FALSE(mResetWasCalled) << "Expected reset to not have been called.";
235     }
236 
assertProcessWasCalled(RawEvent * outLastEvent=nullptr)237     void assertProcessWasCalled(RawEvent* outLastEvent = nullptr) {
238         std::unique_lock<std::mutex> lock(mLock);
239         base::ScopedLockAssertion assumeLocked(mLock);
240         const bool processCalled =
241                 mStateChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
242                     return mProcessWasCalled;
243                 });
244         if (!processCalled) {
245             FAIL() << "Expected process() to have been called.";
246         }
247         if (outLastEvent) {
248             *outLastEvent = mLastEvent;
249         }
250         mProcessWasCalled = false;
251     }
252 
assertProcessWasNotCalled()253     void assertProcessWasNotCalled() {
254         std::scoped_lock lock(mLock);
255         ASSERT_FALSE(mProcessWasCalled) << "Expected process to not have been called.";
256     }
257 
setKeyCodeState(int32_t keyCode,int32_t state)258     void setKeyCodeState(int32_t keyCode, int32_t state) {
259         mKeyCodeStates.replaceValueFor(keyCode, state);
260     }
261 
setScanCodeState(int32_t scanCode,int32_t state)262     void setScanCodeState(int32_t scanCode, int32_t state) {
263         mScanCodeStates.replaceValueFor(scanCode, state);
264     }
265 
setSwitchState(int32_t switchCode,int32_t state)266     void setSwitchState(int32_t switchCode, int32_t state) {
267         mSwitchStates.replaceValueFor(switchCode, state);
268     }
269 
addSupportedKeyCode(int32_t keyCode)270     void addSupportedKeyCode(int32_t keyCode) {
271         mSupportedKeyCodes.push_back(keyCode);
272     }
273 
addKeyCodeMapping(int32_t fromKeyCode,int32_t toKeyCode)274     void addKeyCodeMapping(int32_t fromKeyCode, int32_t toKeyCode) {
275         mKeyCodeMapping.insert_or_assign(fromKeyCode, toKeyCode);
276     }
277 
278 private:
getSources() const279     uint32_t getSources() const override { return mSources; }
280 
populateDeviceInfo(InputDeviceInfo & deviceInfo)281     void populateDeviceInfo(InputDeviceInfo& deviceInfo) override {
282         InputMapper::populateDeviceInfo(deviceInfo);
283 
284         if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
285             deviceInfo.setKeyboardType(mKeyboardType);
286         }
287     }
288 
reconfigure(nsecs_t,const InputReaderConfiguration & config,ConfigurationChanges changes)289     std::list<NotifyArgs> reconfigure(nsecs_t, const InputReaderConfiguration& config,
290                                       ConfigurationChanges changes) override {
291         std::scoped_lock<std::mutex> lock(mLock);
292         mConfigureWasCalled = true;
293 
294         // Find the associated viewport if exist.
295         const std::optional<uint8_t> displayPort = getDeviceContext().getAssociatedDisplayPort();
296         if (displayPort && changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
297             mViewport = config.getDisplayViewportByPort(*displayPort);
298         }
299 
300         mStateChangedCondition.notify_all();
301         return {};
302     }
303 
reset(nsecs_t)304     std::list<NotifyArgs> reset(nsecs_t) override {
305         std::scoped_lock<std::mutex> lock(mLock);
306         mResetWasCalled = true;
307         mStateChangedCondition.notify_all();
308         return {};
309     }
310 
process(const RawEvent & rawEvent)311     std::list<NotifyArgs> process(const RawEvent& rawEvent) override {
312         std::scoped_lock<std::mutex> lock(mLock);
313         mLastEvent = rawEvent;
314         mProcessWasCalled = true;
315         mStateChangedCondition.notify_all();
316         return mProcessResult;
317     }
318 
getKeyCodeState(uint32_t,int32_t keyCode)319     int32_t getKeyCodeState(uint32_t, int32_t keyCode) override {
320         ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
321         return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
322     }
323 
getKeyCodeForKeyLocation(int32_t locationKeyCode) const324     int32_t getKeyCodeForKeyLocation(int32_t locationKeyCode) const override {
325         auto it = mKeyCodeMapping.find(locationKeyCode);
326         return it != mKeyCodeMapping.end() ? it->second : locationKeyCode;
327     }
328 
getScanCodeState(uint32_t,int32_t scanCode)329     int32_t getScanCodeState(uint32_t, int32_t scanCode) override {
330         ssize_t index = mScanCodeStates.indexOfKey(scanCode);
331         return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
332     }
333 
getSwitchState(uint32_t,int32_t switchCode)334     int32_t getSwitchState(uint32_t, int32_t switchCode) override {
335         ssize_t index = mSwitchStates.indexOfKey(switchCode);
336         return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
337     }
338 
339     // Return true if the device has non-empty key layout.
markSupportedKeyCodes(uint32_t,const std::vector<int32_t> & keyCodes,uint8_t * outFlags)340     bool markSupportedKeyCodes(uint32_t, const std::vector<int32_t>& keyCodes,
341                                uint8_t* outFlags) override {
342         for (size_t i = 0; i < keyCodes.size(); i++) {
343             for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
344                 if (keyCodes[i] == mSupportedKeyCodes[j]) {
345                     outFlags[i] = 1;
346                 }
347             }
348         }
349         bool result = mSupportedKeyCodes.size() > 0;
350         return result;
351     }
352 
getMetaState()353     virtual int32_t getMetaState() {
354         return mMetaState;
355     }
356 
fadePointer()357     virtual void fadePointer() {
358     }
359 
getAssociatedDisplay()360     virtual std::optional<ui::LogicalDisplayId> getAssociatedDisplay() {
361         if (mViewport) {
362             return std::make_optional(mViewport->displayId);
363         }
364         return std::nullopt;
365     }
366 };
367 
368 // --- InputReaderPolicyTest ---
369 class InputReaderPolicyTest : public testing::Test {
370 protected:
371     sp<FakeInputReaderPolicy> mFakePolicy;
372 
SetUp()373     void SetUp() override { mFakePolicy = sp<FakeInputReaderPolicy>::make(); }
TearDown()374     void TearDown() override { mFakePolicy.clear(); }
375 };
376 
377 /**
378  * Check that empty set of viewports is an acceptable configuration.
379  * Also try to get internal viewport two different ways - by type and by uniqueId.
380  *
381  * There will be confusion if two viewports with empty uniqueId and identical type are present.
382  * Such configuration is not currently allowed.
383  */
TEST_F(InputReaderPolicyTest,Viewports_GetCleared)384 TEST_F(InputReaderPolicyTest, Viewports_GetCleared) {
385     static const std::string uniqueId = "local:0";
386 
387     // We didn't add any viewports yet, so there shouldn't be any.
388     ASSERT_FALSE(mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL));
389 
390     // Add an internal viewport, then clear it
391     DisplayViewport internalViewport =
392             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
393                            /*isActive=*/true, uniqueId, NO_PORT, ViewportType::INTERNAL);
394     mFakePolicy->addDisplayViewport(internalViewport);
395     // Check matching by uniqueId
396     std::optional<DisplayViewport> receivedInternalViewport =
397             mFakePolicy->getDisplayViewportByUniqueId(uniqueId);
398     ASSERT_TRUE(receivedInternalViewport.has_value());
399     ASSERT_EQ(internalViewport, *receivedInternalViewport);
400 
401     // Check matching by viewport type
402     receivedInternalViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
403     ASSERT_TRUE(receivedInternalViewport.has_value());
404     ASSERT_EQ(internalViewport, *receivedInternalViewport);
405 
406     mFakePolicy->clearViewports();
407 
408     // Make sure nothing is found after clear
409     ASSERT_FALSE(mFakePolicy->getDisplayViewportByUniqueId(uniqueId));
410     ASSERT_FALSE(mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL));
411 }
412 
TEST_F(InputReaderPolicyTest,Viewports_GetByType)413 TEST_F(InputReaderPolicyTest, Viewports_GetByType) {
414     const std::string internalUniqueId = "local:0";
415     const std::string externalUniqueId = "local:1";
416     const std::string virtualUniqueId1 = "virtual:2";
417     const std::string virtualUniqueId2 = "virtual:3";
418     constexpr ui::LogicalDisplayId virtualDisplayId1 = ui::LogicalDisplayId{2};
419     constexpr ui::LogicalDisplayId virtualDisplayId2 = ui::LogicalDisplayId{3};
420 
421     // Add an internal viewport
422     DisplayViewport internalViewport =
423             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
424                            /*isActive=*/true, internalUniqueId, NO_PORT, ViewportType::INTERNAL);
425     mFakePolicy->addDisplayViewport(internalViewport);
426     // Add an external viewport
427     DisplayViewport externalViewport =
428             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
429                            /*isActive=*/true, externalUniqueId, NO_PORT, ViewportType::EXTERNAL);
430     mFakePolicy->addDisplayViewport(externalViewport);
431     // Add an virtual viewport
432     DisplayViewport virtualViewport1 =
433             createViewport(virtualDisplayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
434                            /*isActive=*/true, virtualUniqueId1, NO_PORT, ViewportType::VIRTUAL);
435     mFakePolicy->addDisplayViewport(virtualViewport1);
436     // Add another virtual viewport
437     DisplayViewport virtualViewport2 =
438             createViewport(virtualDisplayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
439                            /*isActive=*/true, virtualUniqueId2, NO_PORT, ViewportType::VIRTUAL);
440     mFakePolicy->addDisplayViewport(virtualViewport2);
441 
442     // Check matching by type for internal
443     std::optional<DisplayViewport> receivedInternalViewport =
444             mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
445     ASSERT_TRUE(receivedInternalViewport.has_value());
446     ASSERT_EQ(internalViewport, *receivedInternalViewport);
447 
448     // Check matching by type for external
449     std::optional<DisplayViewport> receivedExternalViewport =
450             mFakePolicy->getDisplayViewportByType(ViewportType::EXTERNAL);
451     ASSERT_TRUE(receivedExternalViewport.has_value());
452     ASSERT_EQ(externalViewport, *receivedExternalViewport);
453 
454     // Check matching by uniqueId for virtual viewport #1
455     std::optional<DisplayViewport> receivedVirtualViewport1 =
456             mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId1);
457     ASSERT_TRUE(receivedVirtualViewport1.has_value());
458     ASSERT_EQ(virtualViewport1, *receivedVirtualViewport1);
459 
460     // Check matching by uniqueId for virtual viewport #2
461     std::optional<DisplayViewport> receivedVirtualViewport2 =
462             mFakePolicy->getDisplayViewportByUniqueId(virtualUniqueId2);
463     ASSERT_TRUE(receivedVirtualViewport2.has_value());
464     ASSERT_EQ(virtualViewport2, *receivedVirtualViewport2);
465 }
466 
467 
468 /**
469  * We can have 2 viewports of the same kind. We can distinguish them by uniqueId, and confirm
470  * that lookup works by checking display id.
471  * Check that 2 viewports of each kind is possible, for all existing viewport types.
472  */
TEST_F(InputReaderPolicyTest,Viewports_TwoOfSameType)473 TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
474     const std::string uniqueId1 = "uniqueId1";
475     const std::string uniqueId2 = "uniqueId2";
476     constexpr ui::LogicalDisplayId displayId1 = ui::LogicalDisplayId{2};
477     constexpr ui::LogicalDisplayId displayId2 = ui::LogicalDisplayId{3};
478 
479     std::vector<ViewportType> types = {ViewportType::INTERNAL, ViewportType::EXTERNAL,
480                                        ViewportType::VIRTUAL};
481     for (const ViewportType& type : types) {
482         mFakePolicy->clearViewports();
483         // Add a viewport
484         DisplayViewport viewport1 =
485                 createViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
486                                /*isActive=*/true, uniqueId1, NO_PORT, type);
487         mFakePolicy->addDisplayViewport(viewport1);
488         // Add another viewport
489         DisplayViewport viewport2 =
490                 createViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
491                                /*isActive=*/true, uniqueId2, NO_PORT, type);
492         mFakePolicy->addDisplayViewport(viewport2);
493 
494         // Check that correct display viewport was returned by comparing the display IDs.
495         std::optional<DisplayViewport> receivedViewport1 =
496                 mFakePolicy->getDisplayViewportByUniqueId(uniqueId1);
497         ASSERT_TRUE(receivedViewport1.has_value());
498         ASSERT_EQ(viewport1, *receivedViewport1);
499 
500         std::optional<DisplayViewport> receivedViewport2 =
501                 mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
502         ASSERT_TRUE(receivedViewport2.has_value());
503         ASSERT_EQ(viewport2, *receivedViewport2);
504 
505         // When there are multiple viewports of the same kind, and uniqueId is not specified
506         // in the call to getDisplayViewport, then that situation is not supported.
507         // The viewports can be stored in any order, so we cannot rely on the order, since that
508         // is just implementation detail.
509         // However, we can check that it still returns *a* viewport, we just cannot assert
510         // which one specifically is returned.
511         std::optional<DisplayViewport> someViewport = mFakePolicy->getDisplayViewportByType(type);
512         ASSERT_TRUE(someViewport);
513     }
514 }
515 
516 /**
517  * When we have multiple internal displays make sure we always return the default display when
518  * querying by type.
519  */
TEST_F(InputReaderPolicyTest,Viewports_ByTypeReturnsDefaultForInternal)520 TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
521     const std::string uniqueId1 = "uniqueId1";
522     const std::string uniqueId2 = "uniqueId2";
523     constexpr ui::LogicalDisplayId nonDefaultDisplayId = ui::LogicalDisplayId{2};
524     ASSERT_NE(nonDefaultDisplayId, ui::LogicalDisplayId::DEFAULT)
525             << "Test display ID should not be ui::LogicalDisplayId::DEFAULT ";
526 
527     // Add the default display first and ensure it gets returned.
528     mFakePolicy->clearViewports();
529     DisplayViewport viewport1 = createViewport(ui::LogicalDisplayId::DEFAULT, DISPLAY_WIDTH,
530                                                DISPLAY_HEIGHT, ui::ROTATION_0, /*isActive=*/true,
531                                                uniqueId1, NO_PORT, ViewportType::INTERNAL);
532     mFakePolicy->addDisplayViewport(viewport1);
533     DisplayViewport viewport2 =
534             createViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
535                            /*isActive=*/true, uniqueId2, NO_PORT, ViewportType::INTERNAL);
536     mFakePolicy->addDisplayViewport(viewport2);
537     std::optional<DisplayViewport> receivedViewport =
538             mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
539     ASSERT_TRUE(receivedViewport.has_value());
540     ASSERT_EQ(viewport1, *receivedViewport);
541 
542     // Add the default display second to make sure order doesn't matter.
543     mFakePolicy->clearViewports();
544     mFakePolicy->addDisplayViewport(viewport2);
545     mFakePolicy->addDisplayViewport(viewport1);
546 
547     receivedViewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
548     ASSERT_TRUE(receivedViewport.has_value());
549     ASSERT_EQ(viewport1, *receivedViewport);
550 }
551 
552 /**
553  * Check getDisplayViewportByPort
554  */
TEST_F(InputReaderPolicyTest,Viewports_GetByPort)555 TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {
556     constexpr ViewportType type = ViewportType::EXTERNAL;
557     const std::string uniqueId1 = "uniqueId1";
558     const std::string uniqueId2 = "uniqueId2";
559     constexpr ui::LogicalDisplayId displayId1 = ui::LogicalDisplayId{1};
560     constexpr ui::LogicalDisplayId displayId2 = ui::LogicalDisplayId{2};
561     const uint8_t hdmi1 = 0;
562     const uint8_t hdmi2 = 1;
563     const uint8_t hdmi3 = 2;
564 
565     mFakePolicy->clearViewports();
566     // Add a viewport that's associated with some display port that's not of interest.
567     DisplayViewport viewport1 =
568             createViewport(displayId1, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
569                            /*isActive=*/true, uniqueId1, hdmi3, type);
570     mFakePolicy->addDisplayViewport(viewport1);
571     // Add another viewport, connected to HDMI1 port
572     DisplayViewport viewport2 =
573             createViewport(displayId2, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
574                            /*isActive=*/true, uniqueId2, hdmi1, type);
575     mFakePolicy->addDisplayViewport(viewport2);
576     // Check that correct display viewport was returned by comparing the display ports.
577     std::optional<DisplayViewport> hdmi1Viewport = mFakePolicy->getDisplayViewportByPort(hdmi1);
578     ASSERT_TRUE(hdmi1Viewport.has_value());
579     ASSERT_EQ(viewport2, *hdmi1Viewport);
580 
581     // Check that we can still get the same viewport using the uniqueId
582     hdmi1Viewport = mFakePolicy->getDisplayViewportByUniqueId(uniqueId2);
583     ASSERT_TRUE(hdmi1Viewport.has_value());
584     ASSERT_EQ(viewport2, *hdmi1Viewport);
585 
586     // Check that we cannot find a port with "HDMI2", because we never added one
587     ASSERT_FALSE(mFakePolicy->getDisplayViewportByPort(hdmi2));
588 }
589 
590 // --- InputReaderTest ---
591 
592 class InputReaderTest : public testing::Test {
593 protected:
594     std::unique_ptr<TestInputListener> mFakeListener;
595     sp<FakeInputReaderPolicy> mFakePolicy;
596     std::shared_ptr<FakeEventHub> mFakeEventHub;
597     std::unique_ptr<InstrumentedInputReader> mReader;
598 
SetUp()599     void SetUp() override {
600         mFakeEventHub = std::make_unique<FakeEventHub>();
601         mFakePolicy = sp<FakeInputReaderPolicy>::make();
602         mFakeListener = std::make_unique<TestInputListener>();
603 
604         mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
605                                                             *mFakeListener);
606     }
607 
TearDown()608     void TearDown() override {
609         mFakeListener.reset();
610         mFakePolicy.clear();
611     }
612 
addDevice(int32_t eventHubId,const std::string & name,ftl::Flags<InputDeviceClass> classes,const PropertyMap * configuration,std::string sysfsRootPath="")613     void addDevice(int32_t eventHubId, const std::string& name,
614                    ftl::Flags<InputDeviceClass> classes, const PropertyMap* configuration,
615                    std::string sysfsRootPath = "") {
616         mFakeEventHub->addDevice(eventHubId, name, classes);
617         mFakeEventHub->setSysfsRootPath(eventHubId, sysfsRootPath);
618 
619         if (configuration) {
620             mFakeEventHub->addConfigurationMap(eventHubId, configuration);
621         }
622         mReader->loopOnce();
623         mReader->loopOnce();
624         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
625         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyInputDevicesChangedWasCalled());
626         ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
627     }
628 
disableDevice(int32_t deviceId)629     void disableDevice(int32_t deviceId) {
630         mFakePolicy->addDisabledDevice(deviceId);
631         mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::ENABLED_STATE);
632     }
633 
enableDevice(int32_t deviceId)634     void enableDevice(int32_t deviceId) {
635         mFakePolicy->removeDisabledDevice(deviceId);
636         mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::ENABLED_STATE);
637     }
638 
addDeviceWithFakeInputMapper(int32_t deviceId,int32_t eventHubId,const std::string & name,ftl::Flags<InputDeviceClass> classes,uint32_t sources,const PropertyMap * configuration)639     FakeInputMapper& addDeviceWithFakeInputMapper(int32_t deviceId, int32_t eventHubId,
640                                                   const std::string& name,
641                                                   ftl::Flags<InputDeviceClass> classes,
642                                                   uint32_t sources,
643                                                   const PropertyMap* configuration) {
644         std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, name);
645         FakeInputMapper& mapper =
646                 device->addMapper<FakeInputMapper>(eventHubId,
647                                                    mFakePolicy->getReaderConfiguration(), sources);
648         mReader->pushNextDevice(device);
649         addDevice(eventHubId, name, classes, configuration);
650         return mapper;
651     }
652 };
653 
TEST_F(InputReaderTest,PolicyGetInputDevices)654 TEST_F(InputReaderTest, PolicyGetInputDevices) {
655     ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
656     ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", ftl::Flags<InputDeviceClass>(0),
657                                       nullptr)); // no classes so device will be ignored
658 
659     // Should also have received a notification describing the new input devices.
660     const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
661     ASSERT_EQ(1U, inputDevices.size());
662     ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
663     ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
664     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
665     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
666     ASSERT_EQ(0U, inputDevices[0].getMotionRanges().size());
667 }
668 
TEST_F(InputReaderTest,GetSysfsRootPath)669 TEST_F(InputReaderTest, GetSysfsRootPath) {
670     constexpr std::string SYSFS_ROOT = "xyz";
671     ASSERT_NO_FATAL_FAILURE(
672             addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr, SYSFS_ROOT));
673 
674     // Should also have received a notification describing the new input device.
675     ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
676     InputDeviceInfo inputDevice = mFakePolicy->getInputDevices()[0];
677 
678     ASSERT_EQ(SYSFS_ROOT, mReader->getSysfsRootPath(inputDevice.getId()).string());
679 }
680 
TEST_F(InputReaderTest,InputDeviceRecreatedOnSysfsNodeChanged)681 TEST_F(InputReaderTest, InputDeviceRecreatedOnSysfsNodeChanged) {
682     ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
683     mFakeEventHub->setSysfsRootPath(1, "xyz");
684 
685     // Should also have received a notification describing the new input device.
686     ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
687     InputDeviceInfo inputDevice = mFakePolicy->getInputDevices()[0];
688     ASSERT_EQ(0U, inputDevice.getLights().size());
689 
690     RawLightInfo infoMonolight = {.id = 123,
691                                   .name = "mono_keyboard_backlight",
692                                   .maxBrightness = 255,
693                                   .flags = InputLightClass::BRIGHTNESS,
694                                   .path = ""};
695     mFakeEventHub->addRawLightInfo(/*rawId=*/123, std::move(infoMonolight));
696     mReader->sysfsNodeChanged("xyz");
697     mReader->loopOnce();
698 
699     // Should also have received a notification describing the new recreated input device.
700     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
701     inputDevice = mFakePolicy->getInputDevices()[0];
702     ASSERT_EQ(1U, inputDevice.getLights().size());
703 }
704 
TEST_F(InputReaderTest,GetMergedInputDevices)705 TEST_F(InputReaderTest, GetMergedInputDevices) {
706     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
707     constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
708     // Add two subdevices to device
709     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
710     // Must add at least one mapper or the device will be ignored!
711     device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
712                                        AINPUT_SOURCE_KEYBOARD);
713     device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
714                                        AINPUT_SOURCE_KEYBOARD);
715 
716     // Push same device instance for next device to be added, so they'll have same identifier.
717     mReader->pushNextDevice(device);
718     mReader->pushNextDevice(device);
719     ASSERT_NO_FATAL_FAILURE(
720             addDevice(eventHubIds[0], "fake1", InputDeviceClass::KEYBOARD, nullptr));
721     ASSERT_NO_FATAL_FAILURE(
722             addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
723 
724     // Two devices will be merged to one input device as they have same identifier
725     ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
726 }
727 
TEST_F(InputReaderTest,GetMergedInputDevicesEnabled)728 TEST_F(InputReaderTest, GetMergedInputDevicesEnabled) {
729     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
730     constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
731     // Add two subdevices to device
732     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
733     // Must add at least one mapper or the device will be ignored!
734     device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
735                                        AINPUT_SOURCE_KEYBOARD);
736     device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
737                                        AINPUT_SOURCE_KEYBOARD);
738 
739     // Push same device instance for next device to be added, so they'll have same identifier.
740     mReader->pushNextDevice(device);
741     mReader->pushNextDevice(device);
742     // Sensor device is initially disabled
743     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1",
744                                       InputDeviceClass::KEYBOARD | InputDeviceClass::SENSOR,
745                                       nullptr));
746     // Device is disabled because the only sub device is a sensor device and disabled initially.
747     ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
748     ASSERT_FALSE(device->isEnabled());
749     ASSERT_NO_FATAL_FAILURE(
750             addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
751     // The merged device is enabled if any sub device is enabled
752     ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
753     ASSERT_TRUE(device->isEnabled());
754 }
755 
TEST_F(InputReaderTest,WhenEnabledChanges_SendsDeviceResetNotification)756 TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
757     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
758     constexpr ftl::Flags<InputDeviceClass> deviceClass(InputDeviceClass::KEYBOARD);
759     constexpr int32_t eventHubId = 1;
760     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
761     // Must add at least one mapper or the device will be ignored!
762     device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
763                                        AINPUT_SOURCE_KEYBOARD);
764     mReader->pushNextDevice(device);
765     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
766 
767     NotifyDeviceResetArgs resetArgs;
768     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
769     ASSERT_EQ(deviceId, resetArgs.deviceId);
770 
771     ASSERT_EQ(device->isEnabled(), true);
772     disableDevice(deviceId);
773     mReader->loopOnce();
774 
775     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
776     ASSERT_EQ(deviceId, resetArgs.deviceId);
777     ASSERT_EQ(device->isEnabled(), false);
778 
779     disableDevice(deviceId);
780     mReader->loopOnce();
781     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
782     ASSERT_EQ(device->isEnabled(), false);
783 
784     enableDevice(deviceId);
785     mReader->loopOnce();
786     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
787     ASSERT_EQ(deviceId, resetArgs.deviceId);
788     ASSERT_EQ(device->isEnabled(), true);
789 }
790 
TEST_F(InputReaderTest,GetKeyCodeState_ForwardsRequestsToMappers)791 TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
792     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
793     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
794     constexpr int32_t eventHubId = 1;
795     FakeInputMapper& mapper =
796             addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
797                                          AINPUT_SOURCE_KEYBOARD, nullptr);
798     mapper.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
799 
800     ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
801             AINPUT_SOURCE_ANY, AKEYCODE_A))
802             << "Should return unknown when the device id is >= 0 but unknown.";
803 
804     ASSERT_EQ(AKEY_STATE_UNKNOWN,
805               mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
806             << "Should return unknown when the device id is valid but the sources are not "
807                "supported by the device.";
808 
809     ASSERT_EQ(AKEY_STATE_DOWN,
810               mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
811                                        AKEYCODE_A))
812             << "Should return value provided by mapper when device id is valid and the device "
813                "supports some of the sources.";
814 
815     ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
816             AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
817             << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
818 
819     ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
820             AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
821             << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
822 }
823 
TEST_F(InputReaderTest,GetKeyCodeForKeyLocation_ForwardsRequestsToMappers)824 TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_ForwardsRequestsToMappers) {
825     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
826     constexpr int32_t eventHubId = 1;
827     FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "keyboard",
828                                                            InputDeviceClass::KEYBOARD,
829                                                            AINPUT_SOURCE_KEYBOARD, nullptr);
830     mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
831 
832     ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(0, AKEYCODE_Y))
833             << "Should return unknown when the device with the specified id is not found.";
834 
835     ASSERT_EQ(AKEYCODE_Z, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
836             << "Should return correct mapping when device id is valid and mapping exists.";
837 
838     ASSERT_EQ(AKEYCODE_A, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_A))
839             << "Should return the location key code when device id is valid and there's no "
840                "mapping.";
841 }
842 
TEST_F(InputReaderTest,GetKeyCodeForKeyLocation_NoKeyboardMapper)843 TEST_F(InputReaderTest, GetKeyCodeForKeyLocation_NoKeyboardMapper) {
844     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
845     constexpr int32_t eventHubId = 1;
846     FakeInputMapper& mapper = addDeviceWithFakeInputMapper(deviceId, eventHubId, "joystick",
847                                                            InputDeviceClass::JOYSTICK,
848                                                            AINPUT_SOURCE_GAMEPAD, nullptr);
849     mapper.addKeyCodeMapping(AKEYCODE_Y, AKEYCODE_Z);
850 
851     ASSERT_EQ(AKEYCODE_UNKNOWN, mReader->getKeyCodeForKeyLocation(deviceId, AKEYCODE_Y))
852             << "Should return unknown when the device id is valid but there is no keyboard mapper";
853 }
854 
TEST_F(InputReaderTest,GetScanCodeState_ForwardsRequestsToMappers)855 TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
856     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
857     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
858     constexpr int32_t eventHubId = 1;
859     FakeInputMapper& mapper =
860             addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
861                                          AINPUT_SOURCE_KEYBOARD, nullptr);
862     mapper.setScanCodeState(KEY_A, AKEY_STATE_DOWN);
863 
864     ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
865             AINPUT_SOURCE_ANY, KEY_A))
866             << "Should return unknown when the device id is >= 0 but unknown.";
867 
868     ASSERT_EQ(AKEY_STATE_UNKNOWN,
869               mReader->getScanCodeState(deviceId, AINPUT_SOURCE_TRACKBALL, KEY_A))
870             << "Should return unknown when the device id is valid but the sources are not "
871                "supported by the device.";
872 
873     ASSERT_EQ(AKEY_STATE_DOWN,
874               mReader->getScanCodeState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
875                                         KEY_A))
876             << "Should return value provided by mapper when device id is valid and the device "
877                "supports some of the sources.";
878 
879     ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
880             AINPUT_SOURCE_TRACKBALL, KEY_A))
881             << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
882 
883     ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
884             AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
885             << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
886 }
887 
TEST_F(InputReaderTest,GetSwitchState_ForwardsRequestsToMappers)888 TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
889     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
890     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
891     constexpr int32_t eventHubId = 1;
892     FakeInputMapper& mapper =
893             addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
894                                          AINPUT_SOURCE_KEYBOARD, nullptr);
895     mapper.setSwitchState(SW_LID, AKEY_STATE_DOWN);
896 
897     ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
898             AINPUT_SOURCE_ANY, SW_LID))
899             << "Should return unknown when the device id is >= 0 but unknown.";
900 
901     ASSERT_EQ(AKEY_STATE_UNKNOWN,
902               mReader->getSwitchState(deviceId, AINPUT_SOURCE_TRACKBALL, SW_LID))
903             << "Should return unknown when the device id is valid but the sources are not "
904                "supported by the device.";
905 
906     ASSERT_EQ(AKEY_STATE_DOWN,
907               mReader->getSwitchState(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
908                                       SW_LID))
909             << "Should return value provided by mapper when device id is valid and the device "
910                "supports some of the sources.";
911 
912     ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
913             AINPUT_SOURCE_TRACKBALL, SW_LID))
914             << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
915 
916     ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
917             AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
918             << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
919 }
920 
TEST_F(InputReaderTest,MarkSupportedKeyCodes_ForwardsRequestsToMappers)921 TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
922     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
923     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
924     constexpr int32_t eventHubId = 1;
925     FakeInputMapper& mapper =
926             addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
927                                          AINPUT_SOURCE_KEYBOARD, nullptr);
928 
929     mapper.addSupportedKeyCode(AKEYCODE_A);
930     mapper.addSupportedKeyCode(AKEYCODE_B);
931 
932     const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
933     uint8_t flags[4] = { 0, 0, 0, 1 };
934 
935     ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, keyCodes, flags))
936             << "Should return false when device id is >= 0 but unknown.";
937     ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
938 
939     flags[3] = 1;
940     ASSERT_FALSE(mReader->hasKeys(deviceId, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
941             << "Should return false when device id is valid but the sources are not supported by "
942                "the device.";
943     ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
944 
945     flags[3] = 1;
946     ASSERT_TRUE(mReader->hasKeys(deviceId, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL,
947                                  keyCodes, flags))
948             << "Should return value provided by mapper when device id is valid and the device "
949                "supports some of the sources.";
950     ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
951 
952     flags[3] = 1;
953     ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
954             << "Should return false when the device id is < 0 but the sources are not supported by "
955                "any device.";
956     ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
957 
958     flags[3] = 1;
959     ASSERT_TRUE(
960             mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
961             << "Should return value provided by mapper when device id is < 0 and one of the "
962                "devices supports some of the sources.";
963     ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
964 }
965 
TEST_F(InputReaderTest,LoopOnce_ForwardsRawEventsToMappers)966 TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
967     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
968     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
969     constexpr nsecs_t when = 0;
970     constexpr int32_t eventHubId = 1;
971     constexpr nsecs_t readTime = 2;
972     FakeInputMapper& mapper =
973             addDeviceWithFakeInputMapper(deviceId, eventHubId, "fake", deviceClass,
974                                          AINPUT_SOURCE_KEYBOARD, nullptr);
975 
976     mFakeEventHub->enqueueEvent(when, readTime, eventHubId, EV_KEY, KEY_A, 1);
977     mReader->loopOnce();
978     ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
979 
980     RawEvent event;
981     ASSERT_NO_FATAL_FAILURE(mapper.assertProcessWasCalled(&event));
982     ASSERT_EQ(when, event.when);
983     ASSERT_EQ(readTime, event.readTime);
984     ASSERT_EQ(eventHubId, event.deviceId);
985     ASSERT_EQ(EV_KEY, event.type);
986     ASSERT_EQ(KEY_A, event.code);
987     ASSERT_EQ(1, event.value);
988 }
989 
TEST_F(InputReaderTest,DeviceReset_RandomId)990 TEST_F(InputReaderTest, DeviceReset_RandomId) {
991     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
992     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
993     constexpr int32_t eventHubId = 1;
994     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
995     // Must add at least one mapper or the device will be ignored!
996     device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
997                                        AINPUT_SOURCE_KEYBOARD);
998     mReader->pushNextDevice(device);
999     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1000 
1001     NotifyDeviceResetArgs resetArgs;
1002     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1003     int32_t prevId = resetArgs.id;
1004 
1005     disableDevice(deviceId);
1006     mReader->loopOnce();
1007     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1008     ASSERT_NE(prevId, resetArgs.id);
1009     prevId = resetArgs.id;
1010 
1011     enableDevice(deviceId);
1012     mReader->loopOnce();
1013     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1014     ASSERT_NE(prevId, resetArgs.id);
1015     prevId = resetArgs.id;
1016 
1017     disableDevice(deviceId);
1018     mReader->loopOnce();
1019     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1020     ASSERT_NE(prevId, resetArgs.id);
1021     prevId = resetArgs.id;
1022 }
1023 
TEST_F(InputReaderTest,DeviceReset_GenerateIdWithInputReaderSource)1024 TEST_F(InputReaderTest, DeviceReset_GenerateIdWithInputReaderSource) {
1025     constexpr int32_t deviceId = 1;
1026     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
1027     constexpr int32_t eventHubId = 1;
1028     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1029     // Must add at least one mapper or the device will be ignored!
1030     device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
1031                                        AINPUT_SOURCE_KEYBOARD);
1032     mReader->pushNextDevice(device);
1033     ASSERT_NO_FATAL_FAILURE(addDevice(deviceId, "fake", deviceClass, nullptr));
1034 
1035     NotifyDeviceResetArgs resetArgs;
1036     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1037     ASSERT_EQ(IdGenerator::Source::INPUT_READER, IdGenerator::getSource(resetArgs.id));
1038 }
1039 
TEST_F(InputReaderTest,Device_CanDispatchToDisplay)1040 TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
1041     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1042     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
1043     constexpr int32_t eventHubId = 1;
1044     const char* DEVICE_LOCATION = "USB1";
1045     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1046     FakeInputMapper& mapper =
1047             device->addMapper<FakeInputMapper>(eventHubId, mFakePolicy->getReaderConfiguration(),
1048                                                AINPUT_SOURCE_TOUCHSCREEN);
1049     mReader->pushNextDevice(device);
1050 
1051     const uint8_t hdmi1 = 1;
1052 
1053     // Associated touch screen with second display.
1054     mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
1055 
1056     // Add default and second display.
1057     mFakePolicy->clearViewports();
1058     DisplayViewport internalViewport =
1059             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1060                            /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL);
1061     mFakePolicy->addDisplayViewport(internalViewport);
1062     DisplayViewport externalViewport =
1063             createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1064                            /*isActive=*/true, "local:1", hdmi1, ViewportType::EXTERNAL);
1065     mFakePolicy->addDisplayViewport(externalViewport);
1066     mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO);
1067     mReader->loopOnce();
1068 
1069     // Add the device, and make sure all of the callbacks are triggered.
1070     // The device is added after the input port associations are processed since
1071     // we do not yet support dynamic device-to-display associations.
1072     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1073     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
1074     ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
1075 
1076     // Device should only dispatch to the specified display.
1077     ASSERT_EQ(deviceId, device->getId());
1078     ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
1079     ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
1080 
1081     // Can't dispatch event from a disabled device.
1082     disableDevice(deviceId);
1083     mReader->loopOnce();
1084     ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
1085 }
1086 
TEST_F(InputReaderTest,WhenEnabledChanges_AllSubdevicesAreUpdated)1087 TEST_F(InputReaderTest, WhenEnabledChanges_AllSubdevicesAreUpdated) {
1088     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1089     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
1090     constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1091     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1092     // Must add at least one mapper or the device will be ignored!
1093     device->addMapper<FakeInputMapper>(eventHubIds[0], mFakePolicy->getReaderConfiguration(),
1094                                        AINPUT_SOURCE_KEYBOARD);
1095     device->addMapper<FakeInputMapper>(eventHubIds[1], mFakePolicy->getReaderConfiguration(),
1096                                        AINPUT_SOURCE_KEYBOARD);
1097     mReader->pushNextDevice(device);
1098     mReader->pushNextDevice(device);
1099     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1100     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1101 
1102     NotifyDeviceResetArgs resetArgs;
1103     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1104     ASSERT_EQ(deviceId, resetArgs.deviceId);
1105     ASSERT_TRUE(device->isEnabled());
1106     ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1107     ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1108 
1109     disableDevice(deviceId);
1110     mReader->loopOnce();
1111 
1112     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1113     ASSERT_EQ(deviceId, resetArgs.deviceId);
1114     ASSERT_FALSE(device->isEnabled());
1115     ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1116     ASSERT_FALSE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1117 
1118     enableDevice(deviceId);
1119     mReader->loopOnce();
1120 
1121     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
1122     ASSERT_EQ(deviceId, resetArgs.deviceId);
1123     ASSERT_TRUE(device->isEnabled());
1124     ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[0]));
1125     ASSERT_TRUE(mFakeEventHub->isDeviceEnabled(eventHubIds[1]));
1126 }
1127 
TEST_F(InputReaderTest,GetKeyCodeState_ForwardsRequestsToSubdeviceMappers)1128 TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToSubdeviceMappers) {
1129     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1130     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
1131     constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1132     // Add two subdevices to device
1133     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake");
1134     FakeInputMapper& mapperDevice1 =
1135             device->addMapper<FakeInputMapper>(eventHubIds[0],
1136                                                mFakePolicy->getReaderConfiguration(),
1137                                                AINPUT_SOURCE_KEYBOARD);
1138     FakeInputMapper& mapperDevice2 =
1139             device->addMapper<FakeInputMapper>(eventHubIds[1],
1140                                                mFakePolicy->getReaderConfiguration(),
1141                                                AINPUT_SOURCE_KEYBOARD);
1142     mReader->pushNextDevice(device);
1143     mReader->pushNextDevice(device);
1144     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
1145     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
1146 
1147     mapperDevice1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
1148     mapperDevice2.setKeyCodeState(AKEYCODE_B, AKEY_STATE_DOWN);
1149 
1150     ASSERT_EQ(AKEY_STATE_DOWN,
1151               mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_A));
1152     ASSERT_EQ(AKEY_STATE_DOWN,
1153               mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_B));
1154     ASSERT_EQ(AKEY_STATE_UNKNOWN,
1155               mReader->getKeyCodeState(deviceId, AINPUT_SOURCE_KEYBOARD, AKEYCODE_C));
1156 }
1157 
TEST_F(InputReaderTest,ChangingPointerCaptureNotifiesInputListener)1158 TEST_F(InputReaderTest, ChangingPointerCaptureNotifiesInputListener) {
1159     NotifyPointerCaptureChangedArgs args;
1160 
1161     auto request = mFakePolicy->setPointerCapture(/*window=*/sp<BBinder>::make());
1162     mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
1163     mReader->loopOnce();
1164     mFakeListener->assertNotifyCaptureWasCalled(&args);
1165     ASSERT_TRUE(args.request.isEnable()) << "Pointer Capture should be enabled.";
1166     ASSERT_EQ(args.request, request) << "Pointer Capture sequence number should match.";
1167 
1168     mFakePolicy->setPointerCapture(/*window=*/nullptr);
1169     mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
1170     mReader->loopOnce();
1171     mFakeListener->assertNotifyCaptureWasCalled(&args);
1172     ASSERT_FALSE(args.request.isEnable()) << "Pointer Capture should be disabled.";
1173 
1174     // Verify that the Pointer Capture state is not updated when the configuration value
1175     // does not change.
1176     mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::POINTER_CAPTURE);
1177     mReader->loopOnce();
1178     mFakeListener->assertNotifyCaptureWasNotCalled();
1179 }
1180 
TEST_F(InputReaderTest,GetLastUsedInputDeviceId)1181 TEST_F(InputReaderTest, GetLastUsedInputDeviceId) {
1182     constexpr int32_t FIRST_DEVICE_ID = END_RESERVED_ID + 1000;
1183     constexpr int32_t SECOND_DEVICE_ID = FIRST_DEVICE_ID + 1;
1184     FakeInputMapper& firstMapper =
1185             addDeviceWithFakeInputMapper(FIRST_DEVICE_ID, FIRST_DEVICE_ID, "first",
1186                                          InputDeviceClass::KEYBOARD, AINPUT_SOURCE_KEYBOARD,
1187                                          /*configuration=*/nullptr);
1188     FakeInputMapper& secondMapper =
1189             addDeviceWithFakeInputMapper(SECOND_DEVICE_ID, SECOND_DEVICE_ID, "second",
1190                                          InputDeviceClass::TOUCH_MT, AINPUT_SOURCE_STYLUS,
1191                                          /*configuration=*/nullptr);
1192 
1193     ASSERT_EQ(ReservedInputDeviceId::INVALID_INPUT_DEVICE_ID, mReader->getLastUsedInputDeviceId());
1194 
1195     // Start a new key gesture from the first device
1196     firstMapper.setProcessResult({KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, AINPUT_SOURCE_KEYBOARD)
1197                                           .deviceId(FIRST_DEVICE_ID)
1198                                           .build()});
1199     mFakeEventHub->enqueueEvent(ARBITRARY_TIME, ARBITRARY_TIME, FIRST_DEVICE_ID, 0, 0, 0);
1200     mReader->loopOnce();
1201     ASSERT_EQ(firstMapper.getDeviceId(), mReader->getLastUsedInputDeviceId());
1202 
1203     // Start a new touch gesture from the second device
1204     secondMapper.setProcessResult(
1205             {MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_STYLUS)
1206                      .deviceId(SECOND_DEVICE_ID)
1207                      .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER))
1208                      .build()});
1209     mFakeEventHub->enqueueEvent(ARBITRARY_TIME, ARBITRARY_TIME, SECOND_DEVICE_ID, 0, 0, 0);
1210     mReader->loopOnce();
1211     ASSERT_EQ(SECOND_DEVICE_ID, mReader->getLastUsedInputDeviceId());
1212 
1213     // Releasing the key is not a new gesture, so it does not update the last used device
1214     firstMapper.setProcessResult({KeyArgsBuilder(AKEY_EVENT_ACTION_UP, AINPUT_SOURCE_KEYBOARD)
1215                                           .deviceId(FIRST_DEVICE_ID)
1216                                           .build()});
1217     mFakeEventHub->enqueueEvent(ARBITRARY_TIME, ARBITRARY_TIME, FIRST_DEVICE_ID, 0, 0, 0);
1218     mReader->loopOnce();
1219     ASSERT_EQ(SECOND_DEVICE_ID, mReader->getLastUsedInputDeviceId());
1220 
1221     // But pressing a new key does start a new gesture
1222     firstMapper.setProcessResult({KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, AINPUT_SOURCE_KEYBOARD)
1223                                           .deviceId(FIRST_DEVICE_ID)
1224                                           .build()});
1225     mFakeEventHub->enqueueEvent(ARBITRARY_TIME, ARBITRARY_TIME, FIRST_DEVICE_ID, 0, 0, 0);
1226     mReader->loopOnce();
1227     ASSERT_EQ(FIRST_DEVICE_ID, mReader->getLastUsedInputDeviceId());
1228 
1229     // Moving or ending a touch gesture does not update the last used device
1230     secondMapper.setProcessResult(
1231             {MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_STYLUS)
1232                      .deviceId(SECOND_DEVICE_ID)
1233                      .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS))
1234                      .build()});
1235     mFakeEventHub->enqueueEvent(ARBITRARY_TIME, ARBITRARY_TIME, SECOND_DEVICE_ID, 0, 0, 0);
1236     mReader->loopOnce();
1237     ASSERT_EQ(FIRST_DEVICE_ID, mReader->getLastUsedInputDeviceId());
1238     secondMapper.setProcessResult({MotionArgsBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_STYLUS)
1239                                            .deviceId(SECOND_DEVICE_ID)
1240                                            .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS))
1241                                            .build()});
1242     mFakeEventHub->enqueueEvent(ARBITRARY_TIME, ARBITRARY_TIME, SECOND_DEVICE_ID, 0, 0, 0);
1243     mReader->loopOnce();
1244     ASSERT_EQ(FIRST_DEVICE_ID, mReader->getLastUsedInputDeviceId());
1245 
1246     // Starting a new hover gesture updates the last used device
1247     secondMapper.setProcessResult(
1248             {MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER, AINPUT_SOURCE_STYLUS)
1249                      .deviceId(SECOND_DEVICE_ID)
1250                      .pointer(PointerBuilder(/*id=*/0, ToolType::STYLUS))
1251                      .build()});
1252     mFakeEventHub->enqueueEvent(ARBITRARY_TIME, ARBITRARY_TIME, SECOND_DEVICE_ID, 0, 0, 0);
1253     mReader->loopOnce();
1254     ASSERT_EQ(SECOND_DEVICE_ID, mReader->getLastUsedInputDeviceId());
1255 }
1256 
1257 class FakeVibratorInputMapper : public FakeInputMapper {
1258 public:
FakeVibratorInputMapper(InputDeviceContext & deviceContext,const InputReaderConfiguration & readerConfig,uint32_t sources)1259     FakeVibratorInputMapper(InputDeviceContext& deviceContext,
1260                             const InputReaderConfiguration& readerConfig, uint32_t sources)
1261           : FakeInputMapper(deviceContext, readerConfig, sources) {}
1262 
getVibratorIds()1263     std::vector<int32_t> getVibratorIds() override { return getDeviceContext().getVibratorIds(); }
1264 };
1265 
TEST_F(InputReaderTest,VibratorGetVibratorIds)1266 TEST_F(InputReaderTest, VibratorGetVibratorIds) {
1267     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1268     ftl::Flags<InputDeviceClass> deviceClass =
1269             InputDeviceClass::KEYBOARD | InputDeviceClass::VIBRATOR;
1270     constexpr int32_t eventHubId = 1;
1271     const char* DEVICE_LOCATION = "BLUETOOTH";
1272     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1273     FakeVibratorInputMapper& mapper =
1274             device->addMapper<FakeVibratorInputMapper>(eventHubId,
1275                                                        mFakePolicy->getReaderConfiguration(),
1276                                                        AINPUT_SOURCE_KEYBOARD);
1277     mReader->pushNextDevice(device);
1278 
1279     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1280     ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
1281 
1282     ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
1283     ASSERT_EQ(mReader->getVibratorIds(deviceId).size(), 2U);
1284 }
1285 
1286 // --- FakePeripheralController ---
1287 
1288 class FakePeripheralController : public PeripheralControllerInterface {
1289 public:
FakePeripheralController(InputDeviceContext & deviceContext)1290     FakePeripheralController(InputDeviceContext& deviceContext) : mDeviceContext(deviceContext) {}
1291 
~FakePeripheralController()1292     ~FakePeripheralController() override {}
1293 
getEventHubId() const1294     int32_t getEventHubId() const { return getDeviceContext().getEventHubId(); }
1295 
populateDeviceInfo(InputDeviceInfo * deviceInfo)1296     void populateDeviceInfo(InputDeviceInfo* deviceInfo) override {}
1297 
dump(std::string & dump)1298     void dump(std::string& dump) override {}
1299 
getBatteryCapacity(int32_t batteryId)1300     std::optional<int32_t> getBatteryCapacity(int32_t batteryId) override {
1301         return getDeviceContext().getBatteryCapacity(batteryId);
1302     }
1303 
getBatteryStatus(int32_t batteryId)1304     std::optional<int32_t> getBatteryStatus(int32_t batteryId) override {
1305         return getDeviceContext().getBatteryStatus(batteryId);
1306     }
1307 
setLightColor(int32_t lightId,int32_t color)1308     bool setLightColor(int32_t lightId, int32_t color) override {
1309         getDeviceContext().setLightBrightness(lightId, color >> 24);
1310         return true;
1311     }
1312 
getLightColor(int32_t lightId)1313     std::optional<int32_t> getLightColor(int32_t lightId) override {
1314         std::optional<int32_t> result = getDeviceContext().getLightBrightness(lightId);
1315         if (!result.has_value()) {
1316             return std::nullopt;
1317         }
1318         return result.value() << 24;
1319     }
1320 
setLightPlayerId(int32_t lightId,int32_t playerId)1321     bool setLightPlayerId(int32_t lightId, int32_t playerId) override { return true; }
1322 
getLightPlayerId(int32_t lightId)1323     std::optional<int32_t> getLightPlayerId(int32_t lightId) override { return std::nullopt; }
1324 
1325 private:
1326     InputDeviceContext& mDeviceContext;
getDeviceId()1327     inline int32_t getDeviceId() { return mDeviceContext.getId(); }
getDeviceContext()1328     inline InputDeviceContext& getDeviceContext() { return mDeviceContext; }
getDeviceContext() const1329     inline InputDeviceContext& getDeviceContext() const { return mDeviceContext; }
1330 };
1331 
TEST_F(InputReaderTest,BatteryGetCapacity)1332 TEST_F(InputReaderTest, BatteryGetCapacity) {
1333     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1334     ftl::Flags<InputDeviceClass> deviceClass =
1335             InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1336     constexpr int32_t eventHubId = 1;
1337     const char* DEVICE_LOCATION = "BLUETOOTH";
1338     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1339     FakePeripheralController& controller =
1340             device->addController<FakePeripheralController>(eventHubId);
1341     mReader->pushNextDevice(device);
1342 
1343     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1344 
1345     ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY),
1346               FakeEventHub::BATTERY_CAPACITY);
1347     ASSERT_EQ(mReader->getBatteryCapacity(deviceId), FakeEventHub::BATTERY_CAPACITY);
1348 }
1349 
TEST_F(InputReaderTest,BatteryGetStatus)1350 TEST_F(InputReaderTest, BatteryGetStatus) {
1351     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1352     ftl::Flags<InputDeviceClass> deviceClass =
1353             InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1354     constexpr int32_t eventHubId = 1;
1355     const char* DEVICE_LOCATION = "BLUETOOTH";
1356     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1357     FakePeripheralController& controller =
1358             device->addController<FakePeripheralController>(eventHubId);
1359     mReader->pushNextDevice(device);
1360 
1361     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1362 
1363     ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY),
1364               FakeEventHub::BATTERY_STATUS);
1365     ASSERT_EQ(mReader->getBatteryStatus(deviceId), FakeEventHub::BATTERY_STATUS);
1366 }
1367 
TEST_F(InputReaderTest,BatteryGetDevicePath)1368 TEST_F(InputReaderTest, BatteryGetDevicePath) {
1369     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1370     ftl::Flags<InputDeviceClass> deviceClass =
1371             InputDeviceClass::KEYBOARD | InputDeviceClass::BATTERY;
1372     constexpr int32_t eventHubId = 1;
1373     const char* DEVICE_LOCATION = "BLUETOOTH";
1374     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1375     device->addController<FakePeripheralController>(eventHubId);
1376     mReader->pushNextDevice(device);
1377 
1378     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1379 
1380     ASSERT_EQ(mReader->getBatteryDevicePath(deviceId), FakeEventHub::BATTERY_DEVPATH);
1381 }
1382 
TEST_F(InputReaderTest,LightGetColor)1383 TEST_F(InputReaderTest, LightGetColor) {
1384     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
1385     ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD | InputDeviceClass::LIGHT;
1386     constexpr int32_t eventHubId = 1;
1387     const char* DEVICE_LOCATION = "BLUETOOTH";
1388     std::shared_ptr<InputDevice> device = mReader->newDevice(deviceId, "fake", DEVICE_LOCATION);
1389     FakePeripheralController& controller =
1390             device->addController<FakePeripheralController>(eventHubId);
1391     mReader->pushNextDevice(device);
1392     RawLightInfo info = {.id = 1,
1393                          .name = "Mono",
1394                          .maxBrightness = 255,
1395                          .flags = InputLightClass::BRIGHTNESS,
1396                          .path = ""};
1397     mFakeEventHub->addRawLightInfo(/*rawId=*/1, std::move(info));
1398     mFakeEventHub->fakeLightBrightness(/*rawId=*/1, 0x55);
1399 
1400     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
1401 
1402     ASSERT_TRUE(controller.setLightColor(/*lightId=*/1, LIGHT_BRIGHTNESS));
1403     ASSERT_EQ(controller.getLightColor(/*lightId=*/1), LIGHT_BRIGHTNESS);
1404     ASSERT_TRUE(mReader->setLightColor(deviceId, /*lightId=*/1, LIGHT_BRIGHTNESS));
1405     ASSERT_EQ(mReader->getLightColor(deviceId, /*lightId=*/1), LIGHT_BRIGHTNESS);
1406 }
1407 
TEST_F(InputReaderTest,SetPowerWakeUp)1408 TEST_F(InputReaderTest, SetPowerWakeUp) {
1409     ASSERT_NO_FATAL_FAILURE(addDevice(1, "1st", InputDeviceClass::KEYBOARD, nullptr));
1410     ASSERT_NO_FATAL_FAILURE(addDevice(2, "2nd", InputDeviceClass::KEYBOARD, nullptr));
1411     ASSERT_NO_FATAL_FAILURE(addDevice(3, "3rd", InputDeviceClass::KEYBOARD, nullptr));
1412 
1413     ASSERT_EQ(mFakeEventHub->fakeReadKernelWakeup(1), false);
1414 
1415     ASSERT_TRUE(mFakeEventHub->setKernelWakeEnabled(2, true));
1416     ASSERT_EQ(mFakeEventHub->fakeReadKernelWakeup(2), true);
1417 
1418     ASSERT_TRUE(mFakeEventHub->setKernelWakeEnabled(3, false));
1419     ASSERT_EQ(mFakeEventHub->fakeReadKernelWakeup(3), false);
1420 }
1421 
TEST_F(InputReaderTest,MergeableInputDevices)1422 TEST_F(InputReaderTest, MergeableInputDevices) {
1423     constexpr int32_t eventHubIds[2] = {END_RESERVED_ID, END_RESERVED_ID + 1};
1424 
1425     // By default, all of the default-created eventhub devices will have the same identifier
1426     // (implicitly vid 0, pid 0, etc.), which is why we expect them to be merged.
1427     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::KEYBOARD, nullptr));
1428     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::JOYSTICK, nullptr));
1429 
1430     // The two devices will be merged to one input device as they have same identifier, and none are
1431     // pointer devices.
1432     ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
1433 }
1434 
TEST_F(InputReaderTest,MergeableDevicesWithTouch)1435 TEST_F(InputReaderTest, MergeableDevicesWithTouch) {
1436     constexpr int32_t eventHubIds[3] = {END_RESERVED_ID, END_RESERVED_ID + 1, END_RESERVED_ID + 2};
1437 
1438     // By default, all of the default-created eventhub devices will have the same identifier
1439     // (implicitly vid 0, pid 0, etc.), which is why we expect them to be merged.
1440     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::TOUCH_MT, nullptr));
1441     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::KEYBOARD, nullptr));
1442     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[2], "3rd", InputDeviceClass::GAMEPAD, nullptr));
1443 
1444     // The three devices will be merged to one input device as they have same identifier, and only
1445     // one is a pointer device.
1446     ASSERT_EQ(1U, mFakePolicy->getInputDevices().size());
1447 }
1448 
TEST_F(InputReaderTest,UnmergeableTouchDevices)1449 TEST_F(InputReaderTest, UnmergeableTouchDevices) {
1450     SCOPED_FLAG_OVERRIDE(prevent_merging_input_pointer_devices, true);
1451 
1452     constexpr int32_t eventHubIds[3] = {END_RESERVED_ID, END_RESERVED_ID + 1, END_RESERVED_ID + 2};
1453 
1454     // By default, all of the default-created eventhub devices will have the same identifier
1455     // (implicitly vid 0, pid 0, etc.), which is why they can potentially be merged.
1456     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::TOUCH, nullptr));
1457     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::TOUCH_MT, nullptr));
1458     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[2], "2nd", InputDeviceClass::CURSOR, nullptr));
1459 
1460     // The three devices will not be merged, as they have same identifier, but are all pointer
1461     // devices.
1462     ASSERT_EQ(3U, mFakePolicy->getInputDevices().size());
1463 }
1464 
TEST_F(InputReaderTest,MergeableMixedDevices)1465 TEST_F(InputReaderTest, MergeableMixedDevices) {
1466     SCOPED_FLAG_OVERRIDE(prevent_merging_input_pointer_devices, true);
1467 
1468     constexpr int32_t eventHubIds[4] = {END_RESERVED_ID, END_RESERVED_ID + 1, END_RESERVED_ID + 2,
1469                                         END_RESERVED_ID + 3};
1470 
1471     // By default, all of the default-created eventhub devices will have the same identifier
1472     // (implicitly vid 0, pid 0, etc.), which is why they can potentially be merged.
1473     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "1st", InputDeviceClass::TOUCH, nullptr));
1474     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "2nd", InputDeviceClass::TOUCH_MT, nullptr));
1475     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[2], "3rd", InputDeviceClass::DPAD, nullptr));
1476     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[3], "4th", InputDeviceClass::JOYSTICK, nullptr));
1477 
1478     // Non-touch devices can be merged with one of the touch devices, as they have same identifier,
1479     // but the two touch devices will not combine with each other. It is not specified which touch
1480     // device the non-touch devices merge with.
1481     ASSERT_EQ(2U, mFakePolicy->getInputDevices().size());
1482 }
1483 
1484 // --- InputReaderIntegrationTest ---
1485 
1486 // These tests create and interact with the InputReader only through its interface.
1487 // The InputReader is started during SetUp(), which starts its processing in its own
1488 // thread. The tests use linux uinput to emulate input devices.
1489 // NOTE: Interacting with the physical device while these tests are running may cause
1490 // the tests to fail.
1491 class InputReaderIntegrationTest : public testing::Test {
1492 protected:
1493     std::unique_ptr<TestInputListener> mTestListener;
1494     sp<FakeInputReaderPolicy> mFakePolicy;
1495     std::unique_ptr<InputReaderInterface> mReader;
1496 
1497     constexpr static auto EVENT_HAPPENED_TIMEOUT = 2000ms;
1498     constexpr static auto EVENT_DID_NOT_HAPPEN_TIMEOUT = 30ms;
1499 
SetUp()1500     void SetUp() override {
1501 #if !defined(__ANDROID__)
1502         GTEST_SKIP();
1503 #endif
1504         mFakePolicy = sp<FakeInputReaderPolicy>::make();
1505 
1506         setupInputReader();
1507     }
1508 
TearDown()1509     void TearDown() override {
1510 #if !defined(__ANDROID__)
1511         return;
1512 #endif
1513         ASSERT_EQ(mReader->stop(), OK);
1514         mReader.reset();
1515         mTestListener.reset();
1516         mFakePolicy.clear();
1517     }
1518 
waitForDevice(const std::string & deviceName)1519     std::optional<InputDeviceInfo> waitForDevice(const std::string& deviceName) {
1520         std::chrono::time_point start = std::chrono::steady_clock::now();
1521         while (true) {
1522             const std::vector<InputDeviceInfo> inputDevices = mFakePolicy->getInputDevices();
1523             const auto& it = std::find_if(inputDevices.begin(), inputDevices.end(),
1524                                           [&deviceName](const InputDeviceInfo& info) {
1525                                               return info.getIdentifier().name == deviceName;
1526                                           });
1527             if (it != inputDevices.end()) {
1528                 return std::make_optional(*it);
1529             }
1530             std::this_thread::sleep_for(1ms);
1531             std::chrono::duration elapsed = std::chrono::steady_clock::now() - start;
1532             if (elapsed > 5s) {
1533                 return {};
1534             }
1535         }
1536     }
1537 
setupInputReader()1538     void setupInputReader() {
1539         mTestListener = std::make_unique<TestInputListener>(EVENT_HAPPENED_TIMEOUT,
1540                                                             EVENT_DID_NOT_HAPPEN_TIMEOUT);
1541 
1542         mReader = std::make_unique<InputReader>(std::make_shared<EventHub>(), mFakePolicy,
1543                                                 *mTestListener);
1544         ASSERT_EQ(mReader->start(), OK);
1545 
1546         // Since this test is run on a real device, all the input devices connected
1547         // to the test device will show up in mReader. We wait for those input devices to
1548         // show up before beginning the tests.
1549         ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyInputDevicesChangedWasCalled());
1550         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1551     }
1552 };
1553 
TEST_F(InputReaderIntegrationTest,TestInvalidDevice)1554 TEST_F(InputReaderIntegrationTest, TestInvalidDevice) {
1555     // An invalid input device that is only used for this test.
1556     class InvalidUinputDevice : public UinputDevice {
1557     public:
1558         InvalidUinputDevice() : UinputDevice("Invalid Device", /*productId=*/99) {}
1559 
1560     private:
1561         void configureDevice(int fd, uinput_user_dev* device) override {}
1562     };
1563 
1564     const size_t numDevices = mFakePolicy->getInputDevices().size();
1565 
1566     // UinputDevice does not set any event or key bits, so InputReader should not
1567     // consider it as a valid device.
1568     std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
1569     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1570     ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1571 
1572     invalidDevice.reset();
1573     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
1574     ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
1575 }
1576 
TEST_F(InputReaderIntegrationTest,AddNewDevice)1577 TEST_F(InputReaderIntegrationTest, AddNewDevice) {
1578     const size_t initialNumDevices = mFakePolicy->getInputDevices().size();
1579 
1580     std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1581     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1582     ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
1583 
1584     const auto device = waitForDevice(keyboard->getName());
1585     ASSERT_TRUE(device.has_value());
1586     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1587     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources());
1588     ASSERT_EQ(0U, device->getMotionRanges().size());
1589 
1590     keyboard.reset();
1591     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1592     ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
1593 }
1594 
TEST_F(InputReaderIntegrationTest,SendsEventsToInputListener)1595 TEST_F(InputReaderIntegrationTest, SendsEventsToInputListener) {
1596     std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
1597     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1598 
1599     NotifyKeyArgs keyArgs;
1600     keyboard->pressAndReleaseHomeKey();
1601     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1602     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
1603     ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
1604 
1605     int32_t prevId = keyArgs.id;
1606     nsecs_t prevTimestamp = keyArgs.eventTime;
1607 
1608     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
1609     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
1610     ASSERT_NE(prevId, keyArgs.id);
1611     ASSERT_LE(prevTimestamp, keyArgs.eventTime);
1612     ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
1613 }
1614 
TEST_F(InputReaderIntegrationTest,ExternalStylusesButtons)1615 TEST_F(InputReaderIntegrationTest, ExternalStylusesButtons) {
1616     std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
1617     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1618 
1619     const auto device = waitForDevice(stylus->getName());
1620     ASSERT_TRUE(device.has_value());
1621 
1622     // An external stylus with buttons should also be recognized as a keyboard.
1623     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_STYLUS, device->getSources())
1624             << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1625     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, device->getKeyboardType());
1626 
1627     const auto DOWN =
1628             AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD));
1629     const auto UP = AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD));
1630 
1631     stylus->pressAndReleaseKey(BTN_STYLUS);
1632     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1633             AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1634     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1635             AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY))));
1636 
1637     stylus->pressAndReleaseKey(BTN_STYLUS2);
1638     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1639             AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1640     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1641             AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_SECONDARY))));
1642 
1643     stylus->pressAndReleaseKey(BTN_STYLUS3);
1644     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1645             AllOf(DOWN, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1646     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(
1647             AllOf(UP, WithKeyCode(AKEYCODE_STYLUS_BUTTON_TERTIARY))));
1648 }
1649 
TEST_F(InputReaderIntegrationTest,KeyboardWithStylusButtons)1650 TEST_F(InputReaderIntegrationTest, KeyboardWithStylusButtons) {
1651     std::unique_ptr<UinputKeyboard> keyboard =
1652             createUinputDevice<UinputKeyboard>("KeyboardWithStylusButtons", /*productId=*/99,
1653                                                std::initializer_list<int>{KEY_Q, KEY_W, KEY_E,
1654                                                                           KEY_R, KEY_T, KEY_Y,
1655                                                                           BTN_STYLUS, BTN_STYLUS2,
1656                                                                           BTN_STYLUS3});
1657     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1658 
1659     const auto device = waitForDevice(keyboard->getName());
1660     ASSERT_TRUE(device.has_value());
1661 
1662     // An alphabetical keyboard that reports stylus buttons should not be recognized as a stylus.
1663     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
1664             << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1665     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, device->getKeyboardType());
1666 }
1667 
TEST_F(InputReaderIntegrationTest,HidUsageKeyboardIsNotAStylus)1668 TEST_F(InputReaderIntegrationTest, HidUsageKeyboardIsNotAStylus) {
1669     // Create a Uinput keyboard that simulates a keyboard that can report HID usage codes. The
1670     // hid-input driver reports HID usage codes using the value for EV_MSC MSC_SCAN event.
1671     std::unique_ptr<UinputKeyboardWithHidUsage> keyboard =
1672             createUinputDevice<UinputKeyboardWithHidUsage>(
1673                     std::initializer_list<int>{KEY_VOLUMEUP, KEY_VOLUMEDOWN});
1674     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1675 
1676     const auto device = waitForDevice(keyboard->getName());
1677     ASSERT_TRUE(device.has_value());
1678 
1679     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, device->getSources())
1680             << "Unexpected source " << inputEventSourceToString(device->getSources()).c_str();
1681 
1682     // If a device supports reporting HID usage codes, it shouldn't automatically support
1683     // stylus keys.
1684     const std::vector<int> keycodes{AKEYCODE_STYLUS_BUTTON_PRIMARY};
1685     uint8_t outFlags[] = {0};
1686     ASSERT_TRUE(mReader->hasKeys(device->getId(), AINPUT_SOURCE_KEYBOARD, keycodes, outFlags));
1687     ASSERT_EQ(0, outFlags[0]) << "Keyboard should not have stylus button";
1688 }
1689 
1690 /**
1691  * The Steam controller sends BTN_GEAR_DOWN and BTN_GEAR_UP for the two "paddle" buttons
1692  * on the back. In this test, we make sure that BTN_GEAR_DOWN / BTN_WHEEL and BTN_GEAR_UP
1693  * are passed to the listener.
1694  */
1695 static_assert(BTN_GEAR_DOWN == BTN_WHEEL);
TEST_F(InputReaderIntegrationTest,SendsGearDownAndUpToInputListener)1696 TEST_F(InputReaderIntegrationTest, SendsGearDownAndUpToInputListener) {
1697     std::unique_ptr<UinputSteamController> controller = createUinputDevice<UinputSteamController>();
1698     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1699     NotifyKeyArgs keyArgs;
1700 
1701     controller->pressAndReleaseKey(BTN_GEAR_DOWN);
1702     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1703     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1704     ASSERT_EQ(BTN_GEAR_DOWN, keyArgs.scanCode);
1705 
1706     controller->pressAndReleaseKey(BTN_GEAR_UP);
1707     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_DOWN
1708     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs)); // ACTION_UP
1709     ASSERT_EQ(BTN_GEAR_UP, keyArgs.scanCode);
1710 }
1711 
1712 // --- TouchIntegrationTest ---
1713 
1714 class BaseTouchIntegrationTest : public InputReaderIntegrationTest {
1715 protected:
1716     const std::string UNIQUE_ID = "local:0";
1717 
SetUp()1718     void SetUp() override {
1719 #if !defined(__ANDROID__)
1720         GTEST_SKIP();
1721 #endif
1722         InputReaderIntegrationTest::SetUp();
1723         // At least add an internal display.
1724         setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1725                                      UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
1726 
1727         mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
1728         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1729         const auto info = waitForDevice(mDevice->getName());
1730         ASSERT_TRUE(info.has_value());
1731         mDeviceInfo = *info;
1732     }
1733 
setDisplayInfoAndReconfigure(ui::LogicalDisplayId displayId,int32_t width,int32_t height,ui::Rotation orientation,const std::string & uniqueId,std::optional<uint8_t> physicalPort,ViewportType viewportType)1734     void setDisplayInfoAndReconfigure(ui::LogicalDisplayId displayId, int32_t width, int32_t height,
1735                                       ui::Rotation orientation, const std::string& uniqueId,
1736                                       std::optional<uint8_t> physicalPort,
1737                                       ViewportType viewportType) {
1738         DisplayViewport viewport =
1739                 createViewport(displayId, width, height, orientation, /*isActive=*/true, uniqueId,
1740                                physicalPort, viewportType);
1741         mFakePolicy->addDisplayViewport(viewport);
1742         mReader->requestRefreshConfiguration(InputReaderConfiguration::Change::DISPLAY_INFO);
1743     }
1744 
assertReceivedMotion(int32_t action,const std::vector<Point> & points)1745     void assertReceivedMotion(int32_t action, const std::vector<Point>& points) {
1746         NotifyMotionArgs args;
1747         ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1748         EXPECT_EQ(action, args.action);
1749         ASSERT_EQ(points.size(), args.getPointerCount());
1750         for (size_t i = 0; i < args.getPointerCount(); i++) {
1751             EXPECT_EQ(points[i].x, args.pointerCoords[i].getX());
1752             EXPECT_EQ(points[i].y, args.pointerCoords[i].getY());
1753         }
1754     }
1755 
1756     std::unique_ptr<UinputTouchScreen> mDevice;
1757     InputDeviceInfo mDeviceInfo;
1758 };
1759 
1760 enum class TouchIntegrationTestDisplays { DISPLAY_INTERNAL, DISPLAY_INPUT_PORT, DISPLAY_UNIQUE_ID };
1761 
1762 class TouchIntegrationTest : public BaseTouchIntegrationTest,
1763                              public testing::WithParamInterface<TouchIntegrationTestDisplays> {
1764 protected:
1765     static constexpr std::optional<uint8_t> DISPLAY_PORT = 0;
1766     const std::string INPUT_PORT = "uinput_touch/input0";
1767 
SetUp()1768     void SetUp() override {
1769 #if !defined(__ANDROID__)
1770         GTEST_SKIP();
1771 #endif
1772         if (GetParam() == TouchIntegrationTestDisplays::DISPLAY_INTERNAL) {
1773             BaseTouchIntegrationTest::SetUp();
1774             return;
1775         }
1776 
1777         // setup policy with a input-port or UniqueId association to the display
1778         bool isInputPortAssociation =
1779                 GetParam() == TouchIntegrationTestDisplays::DISPLAY_INPUT_PORT;
1780 
1781         mFakePolicy = sp<FakeInputReaderPolicy>::make();
1782         if (isInputPortAssociation) {
1783             mFakePolicy->addInputPortAssociation(INPUT_PORT, DISPLAY_PORT.value());
1784         } else {
1785             mFakePolicy->addInputUniqueIdAssociation(INPUT_PORT, UNIQUE_ID);
1786         }
1787 
1788         InputReaderIntegrationTest::setupInputReader();
1789 
1790         mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT),
1791                                                         INPUT_PORT);
1792         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1793 
1794         // Add a display linked to a physical port or UniqueId.
1795         setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
1796                                      UNIQUE_ID, isInputPortAssociation ? DISPLAY_PORT : NO_PORT,
1797                                      ViewportType::INTERNAL);
1798         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
1799         const auto info = waitForDevice(mDevice->getName());
1800         ASSERT_TRUE(info.has_value());
1801         mDeviceInfo = *info;
1802     }
1803 };
1804 
TEST_P(TouchIntegrationTest,MultiTouchDeviceSource)1805 TEST_P(TouchIntegrationTest, MultiTouchDeviceSource) {
1806     // The UinputTouchScreen is an MT device that supports MT_TOOL_TYPE and also supports stylus
1807     // buttons. It should show up as a touchscreen, stylus, and keyboard (for reporting button
1808     // presses).
1809     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD,
1810               mDeviceInfo.getSources());
1811 }
1812 
TEST_P(TouchIntegrationTest,InputEvent_ProcessSingleTouch)1813 TEST_P(TouchIntegrationTest, InputEvent_ProcessSingleTouch) {
1814     NotifyMotionArgs args;
1815     const Point centerPoint = mDevice->getCenterPoint();
1816 
1817     // ACTION_DOWN
1818     mDevice->sendTrackingId(FIRST_TRACKING_ID);
1819     mDevice->sendDown(centerPoint);
1820     mDevice->sendSync();
1821     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1822     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1823 
1824     // ACTION_MOVE
1825     mDevice->sendMove(centerPoint + Point(1, 1));
1826     mDevice->sendSync();
1827     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1828     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1829 
1830     // ACTION_UP
1831     mDevice->sendUp();
1832     mDevice->sendSync();
1833     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1834     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1835 }
1836 
TEST_P(TouchIntegrationTest,InputEvent_ProcessMultiTouch)1837 TEST_P(TouchIntegrationTest, InputEvent_ProcessMultiTouch) {
1838     NotifyMotionArgs args;
1839     const Point centerPoint = mDevice->getCenterPoint();
1840 
1841     // ACTION_DOWN
1842     mDevice->sendSlot(FIRST_SLOT);
1843     mDevice->sendTrackingId(FIRST_TRACKING_ID);
1844     mDevice->sendDown(centerPoint);
1845     mDevice->sendSync();
1846     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1847     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1848 
1849     // ACTION_POINTER_DOWN (Second slot)
1850     const Point secondPoint = centerPoint + Point(100, 100);
1851     mDevice->sendSlot(SECOND_SLOT);
1852     mDevice->sendTrackingId(SECOND_TRACKING_ID);
1853     mDevice->sendDown(secondPoint);
1854     mDevice->sendSync();
1855     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1856     ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
1857 
1858     // ACTION_MOVE (Second slot)
1859     mDevice->sendMove(secondPoint + Point(1, 1));
1860     mDevice->sendSync();
1861     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1862     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
1863 
1864     // ACTION_POINTER_UP (Second slot)
1865     mDevice->sendPointerUp();
1866     mDevice->sendSync();
1867     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1868     ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
1869 
1870     // ACTION_UP
1871     mDevice->sendSlot(FIRST_SLOT);
1872     mDevice->sendUp();
1873     mDevice->sendSync();
1874     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1875     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
1876 }
1877 
1878 /**
1879  * What happens when a pointer goes up while another pointer moves in the same frame? Are POINTER_UP
1880  * events guaranteed to contain the same data as a preceding MOVE, or can they contain different
1881  * data?
1882  * In this test, we try to send a change in coordinates in Pointer 0 in the same frame as the
1883  * liftoff of Pointer 1. We check that POINTER_UP event is generated first, and the MOVE event
1884  * for Pointer 0 only is generated after.
1885  * Suppose we are only interested in learning the movement of Pointer 0. If we only observe MOVE
1886  * events, we will not miss any information.
1887  * Even though the Pointer 1 up event contains updated Pointer 0 coordinates, there is another MOVE
1888  * event generated afterwards that contains the newest movement of pointer 0.
1889  * This is important for palm rejection. If there is a subsequent InputListener stage that detects
1890  * palms, and wants to cancel Pointer 1, then it is safe to simply drop POINTER_1_UP event without
1891  * losing information about non-palm pointers.
1892  */
TEST_P(TouchIntegrationTest,MultiTouch_PointerMoveAndSecondPointerUp)1893 TEST_P(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerUp) {
1894     NotifyMotionArgs args;
1895     const Point centerPoint = mDevice->getCenterPoint();
1896 
1897     // ACTION_DOWN
1898     mDevice->sendSlot(FIRST_SLOT);
1899     mDevice->sendTrackingId(FIRST_TRACKING_ID);
1900     mDevice->sendDown(centerPoint);
1901     mDevice->sendSync();
1902     assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1903 
1904     // ACTION_POINTER_DOWN (Second slot)
1905     const Point secondPoint = centerPoint + Point(100, 100);
1906     mDevice->sendSlot(SECOND_SLOT);
1907     mDevice->sendTrackingId(SECOND_TRACKING_ID);
1908     mDevice->sendDown(secondPoint);
1909     mDevice->sendSync();
1910     assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1911 
1912     // ACTION_MOVE (First slot)
1913     mDevice->sendSlot(FIRST_SLOT);
1914     mDevice->sendMove(centerPoint + Point(5, 5));
1915     // ACTION_POINTER_UP (Second slot)
1916     mDevice->sendSlot(SECOND_SLOT);
1917     mDevice->sendPointerUp();
1918     // Send a single sync for the above 2 pointer updates
1919     mDevice->sendSync();
1920 
1921     // First, we should get POINTER_UP for the second pointer
1922     assertReceivedMotion(ACTION_POINTER_1_UP,
1923                          {/*first pointer */ centerPoint + Point(5, 5),
1924                           /*second pointer*/ secondPoint});
1925 
1926     // Next, the MOVE event for the first pointer
1927     assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1928 }
1929 
1930 /**
1931  * Similar scenario as above. The difference is that when the second pointer goes up, it will first
1932  * move, and then it will go up, all in the same frame.
1933  * In this scenario, the movement of the second pointer just prior to liftoff is ignored, and never
1934  * gets sent to the listener.
1935  */
TEST_P(TouchIntegrationTest,MultiTouch_PointerMoveAndSecondPointerMoveAndUp)1936 TEST_P(TouchIntegrationTest, MultiTouch_PointerMoveAndSecondPointerMoveAndUp) {
1937     NotifyMotionArgs args;
1938     const Point centerPoint = mDevice->getCenterPoint();
1939 
1940     // ACTION_DOWN
1941     mDevice->sendSlot(FIRST_SLOT);
1942     mDevice->sendTrackingId(FIRST_TRACKING_ID);
1943     mDevice->sendDown(centerPoint);
1944     mDevice->sendSync();
1945     assertReceivedMotion(AMOTION_EVENT_ACTION_DOWN, {centerPoint});
1946 
1947     // ACTION_POINTER_DOWN (Second slot)
1948     const Point secondPoint = centerPoint + Point(100, 100);
1949     mDevice->sendSlot(SECOND_SLOT);
1950     mDevice->sendTrackingId(SECOND_TRACKING_ID);
1951     mDevice->sendDown(secondPoint);
1952     mDevice->sendSync();
1953     assertReceivedMotion(ACTION_POINTER_1_DOWN, {centerPoint, secondPoint});
1954 
1955     // ACTION_MOVE (First slot)
1956     mDevice->sendSlot(FIRST_SLOT);
1957     mDevice->sendMove(centerPoint + Point(5, 5));
1958     // ACTION_POINTER_UP (Second slot)
1959     mDevice->sendSlot(SECOND_SLOT);
1960     mDevice->sendMove(secondPoint + Point(6, 6));
1961     mDevice->sendPointerUp();
1962     // Send a single sync for the above 2 pointer updates
1963     mDevice->sendSync();
1964 
1965     // First, we should get POINTER_UP for the second pointer
1966     // The movement of the second pointer during the liftoff frame is ignored.
1967     // The coordinates 'secondPoint + Point(6, 6)' are never sent to the listener.
1968     assertReceivedMotion(ACTION_POINTER_1_UP,
1969                          {/*first pointer */ centerPoint + Point(5, 5),
1970                           /*second pointer*/ secondPoint});
1971 
1972     // Next, the MOVE event for the first pointer
1973     assertReceivedMotion(AMOTION_EVENT_ACTION_MOVE, {centerPoint + Point(5, 5)});
1974 }
1975 
TEST_P(TouchIntegrationTest,InputEvent_ProcessPalm)1976 TEST_P(TouchIntegrationTest, InputEvent_ProcessPalm) {
1977     NotifyMotionArgs args;
1978     const Point centerPoint = mDevice->getCenterPoint();
1979 
1980     // ACTION_DOWN
1981     mDevice->sendSlot(FIRST_SLOT);
1982     mDevice->sendTrackingId(FIRST_TRACKING_ID);
1983     mDevice->sendDown(centerPoint);
1984     mDevice->sendSync();
1985     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1986     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
1987 
1988     // ACTION_POINTER_DOWN (second slot)
1989     const Point secondPoint = centerPoint + Point(100, 100);
1990     mDevice->sendSlot(SECOND_SLOT);
1991     mDevice->sendTrackingId(SECOND_TRACKING_ID);
1992     mDevice->sendDown(secondPoint);
1993     mDevice->sendSync();
1994     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
1995     ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
1996 
1997     // ACTION_MOVE (second slot)
1998     mDevice->sendMove(secondPoint + Point(1, 1));
1999     mDevice->sendSync();
2000     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2001     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2002 
2003     // Send MT_TOOL_PALM (second slot), which indicates that the touch IC has determined this to be
2004     // a palm event.
2005     // Expect to receive the ACTION_POINTER_UP with cancel flag.
2006     mDevice->sendToolType(MT_TOOL_PALM);
2007     mDevice->sendSync();
2008     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2009     ASSERT_EQ(ACTION_POINTER_1_UP, args.action);
2010     ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, args.flags);
2011 
2012     // Send up to second slot, expect first slot send moving.
2013     mDevice->sendPointerUp();
2014     mDevice->sendSync();
2015     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2016     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
2017 
2018     // Send ACTION_UP (first slot)
2019     mDevice->sendSlot(FIRST_SLOT);
2020     mDevice->sendUp();
2021     mDevice->sendSync();
2022 
2023     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(&args));
2024     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
2025 }
2026 
2027 /**
2028  * Some drivers historically have reported axis values outside of the range specified in the
2029  * evdev axis info. Ensure we don't crash when this happens. For example, a driver may report a
2030  * pressure value greater than the reported maximum, since it unclear what specific meaning the
2031  * maximum value for pressure has (beyond the maximum value that can be produced by a sensor),
2032  * and no units for pressure (resolution) is specified by the evdev documentation.
2033  */
TEST_P(TouchIntegrationTest,AcceptsAxisValuesOutsideReportedRange)2034 TEST_P(TouchIntegrationTest, AcceptsAxisValuesOutsideReportedRange) {
2035     const Point centerPoint = mDevice->getCenterPoint();
2036 
2037     // Down with pressure outside the reported range
2038     mDevice->sendSlot(FIRST_SLOT);
2039     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2040     mDevice->sendDown(centerPoint);
2041     mDevice->sendPressure(UinputTouchScreen::RAW_PRESSURE_MAX + 2);
2042     mDevice->sendSync();
2043     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2044             WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
2045 
2046     // Move to a point outside the reported range
2047     mDevice->sendMove(Point(DISPLAY_WIDTH, DISPLAY_HEIGHT) + Point(1, 1));
2048     mDevice->sendSync();
2049     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2050             WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
2051 
2052     // Up
2053     mDevice->sendUp();
2054     mDevice->sendSync();
2055     ASSERT_NO_FATAL_FAILURE(
2056             mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
2057 }
2058 
TEST_P(TouchIntegrationTest,NotifiesPolicyWhenStylusGestureStarted)2059 TEST_P(TouchIntegrationTest, NotifiesPolicyWhenStylusGestureStarted) {
2060     const Point centerPoint = mDevice->getCenterPoint();
2061 
2062     // Send down with the pen tool selected. The policy should be notified of the stylus presence.
2063     mDevice->sendSlot(FIRST_SLOT);
2064     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2065     mDevice->sendToolType(MT_TOOL_PEN);
2066     mDevice->sendDown(centerPoint);
2067     mDevice->sendSync();
2068     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2069             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2070                   WithToolType(ToolType::STYLUS))));
2071 
2072     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
2073 
2074     // Release the stylus touch.
2075     mDevice->sendUp();
2076     mDevice->sendSync();
2077     ASSERT_NO_FATAL_FAILURE(
2078             mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
2079 
2080     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
2081 
2082     // Touch down with the finger, without the pen tool selected. The policy is not notified.
2083     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2084     mDevice->sendToolType(MT_TOOL_FINGER);
2085     mDevice->sendDown(centerPoint);
2086     mDevice->sendSync();
2087     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2088             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2089                   WithToolType(ToolType::FINGER))));
2090 
2091     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotNotified());
2092 
2093     mDevice->sendUp();
2094     mDevice->sendSync();
2095     ASSERT_NO_FATAL_FAILURE(
2096             mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
2097 
2098     // Send a move event with the stylus tool without BTN_TOUCH to generate a hover enter.
2099     // The policy should be notified of the stylus presence.
2100     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2101     mDevice->sendToolType(MT_TOOL_PEN);
2102     mDevice->sendMove(centerPoint);
2103     mDevice->sendSync();
2104     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2105             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2106                   WithToolType(ToolType::STYLUS))));
2107 
2108     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertStylusGestureNotified(mDeviceInfo.getId()));
2109 }
2110 
TEST_P(TouchIntegrationTest,ExternalStylusConnectedDuringTouchGesture)2111 TEST_P(TouchIntegrationTest, ExternalStylusConnectedDuringTouchGesture) {
2112     const Point centerPoint = mDevice->getCenterPoint();
2113 
2114     // Down
2115     mDevice->sendSlot(FIRST_SLOT);
2116     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2117     mDevice->sendDown(centerPoint);
2118     mDevice->sendSync();
2119     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2120             WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
2121 
2122     // Move
2123     mDevice->sendMove(centerPoint + Point(1, 1));
2124     mDevice->sendSync();
2125     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2126             WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
2127 
2128     // Connecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
2129     auto externalStylus = createUinputDevice<UinputExternalStylus>();
2130     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2131     const auto stylusInfo = waitForDevice(externalStylus->getName());
2132     ASSERT_TRUE(stylusInfo.has_value());
2133 
2134     // Move
2135     mDevice->sendMove(centerPoint + Point(2, 2));
2136     mDevice->sendSync();
2137     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2138             WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
2139 
2140     // Disconnecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
2141     externalStylus.reset();
2142     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2143     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2144 
2145     // Up
2146     mDevice->sendUp();
2147     mDevice->sendSync();
2148     ASSERT_NO_FATAL_FAILURE(
2149             mTestListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
2150 
2151     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2152 }
2153 
2154 INSTANTIATE_TEST_SUITE_P(TouchIntegrationTestDisplayVariants, TouchIntegrationTest,
2155                          testing::Values(TouchIntegrationTestDisplays::DISPLAY_INTERNAL,
2156                                          TouchIntegrationTestDisplays::DISPLAY_INPUT_PORT,
2157                                          TouchIntegrationTestDisplays::DISPLAY_UNIQUE_ID));
2158 
2159 // --- StylusButtonIntegrationTest ---
2160 
2161 // Verify the behavior of button presses reported by various kinds of styluses, including buttons
2162 // reported by the touchscreen's device, by a fused external stylus, and by an un-fused external
2163 // stylus.
2164 template <typename UinputStylusDevice>
2165 class StylusButtonIntegrationTest : public BaseTouchIntegrationTest {
2166 protected:
SetUp()2167     void SetUp() override {
2168 #if !defined(__ANDROID__)
2169         GTEST_SKIP();
2170 #endif
2171         BaseTouchIntegrationTest::SetUp();
2172         mTouchscreen = mDevice.get();
2173         mTouchscreenInfo = mDeviceInfo;
2174 
2175         setUpStylusDevice();
2176     }
2177 
2178     UinputStylusDevice* mStylus{nullptr};
2179     InputDeviceInfo mStylusInfo{};
2180 
2181     UinputTouchScreen* mTouchscreen{nullptr};
2182     InputDeviceInfo mTouchscreenInfo{};
2183 
2184 private:
2185     // When we are attempting to test stylus button events that are sent from the touchscreen,
2186     // use the same Uinput device for the touchscreen and the stylus.
2187     template <typename T = UinputStylusDevice>
setUpStylusDevice()2188     std::enable_if_t<std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
2189         mStylus = mDevice.get();
2190         mStylusInfo = mDeviceInfo;
2191     }
2192 
2193     // When we are attempting to stylus buttons from an external stylus being merged with touches
2194     // from a touchscreen, create a new Uinput device through which stylus buttons can be injected.
2195     template <typename T = UinputStylusDevice>
setUpStylusDevice()2196     std::enable_if_t<!std::is_same_v<UinputTouchScreen, T>, void> setUpStylusDevice() {
2197         mStylusDeviceLifecycleTracker = createUinputDevice<T>();
2198         mStylus = mStylusDeviceLifecycleTracker.get();
2199         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2200         const auto info = waitForDevice(mStylus->getName());
2201         ASSERT_TRUE(info.has_value());
2202         mStylusInfo = *info;
2203     }
2204 
2205     std::unique_ptr<UinputStylusDevice> mStylusDeviceLifecycleTracker{};
2206 
2207     // Hide the base class's device to expose it with a different name for readability.
2208     using BaseTouchIntegrationTest::mDevice;
2209     using BaseTouchIntegrationTest::mDeviceInfo;
2210 };
2211 
2212 using StylusButtonIntegrationTestTypes =
2213         ::testing::Types<UinputTouchScreen, UinputExternalStylus, UinputExternalStylusWithPressure>;
2214 TYPED_TEST_SUITE(StylusButtonIntegrationTest, StylusButtonIntegrationTestTypes);
2215 
TYPED_TEST(StylusButtonIntegrationTest,StylusButtonsGenerateKeyEvents)2216 TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsGenerateKeyEvents) {
2217     const auto stylusId = TestFixture::mStylusInfo.getId();
2218 
2219     TestFixture::mStylus->pressKey(BTN_STYLUS);
2220     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2221             AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2222                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2223 
2224     TestFixture::mStylus->releaseKey(BTN_STYLUS);
2225     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2226             AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2227                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2228 }
2229 
TYPED_TEST(StylusButtonIntegrationTest,StylusButtonsSurroundingTouchGesture)2230 TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingTouchGesture) {
2231     const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2232     const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2233     const auto stylusId = TestFixture::mStylusInfo.getId();
2234 
2235     // Press the stylus button.
2236     TestFixture::mStylus->pressKey(BTN_STYLUS);
2237     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2238             AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2239                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2240 
2241     // Start and finish a stylus gesture.
2242     TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2243     TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2244     TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2245     TestFixture::mTouchscreen->sendDown(centerPoint);
2246     TestFixture::mTouchscreen->sendSync();
2247     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2248             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2249                   WithToolType(ToolType::STYLUS),
2250                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2251                   WithDeviceId(touchscreenId))));
2252     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2253             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
2254                   WithToolType(ToolType::STYLUS),
2255                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2256                   WithDeviceId(touchscreenId))));
2257 
2258     TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2259     TestFixture::mTouchscreen->sendSync();
2260     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2261             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
2262                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2263                   WithDeviceId(touchscreenId))));
2264     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2265             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
2266                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2267                   WithDeviceId(touchscreenId))));
2268 
2269     // Release the stylus button.
2270     TestFixture::mStylus->releaseKey(BTN_STYLUS);
2271     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2272             AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2273                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2274 }
2275 
TYPED_TEST(StylusButtonIntegrationTest,StylusButtonsSurroundingHoveringTouchGesture)2276 TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsSurroundingHoveringTouchGesture) {
2277     const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2278     const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2279     const auto stylusId = TestFixture::mStylusInfo.getId();
2280     auto toolTypeDevice =
2281             AllOf(WithToolType(ToolType::STYLUS), WithDeviceId(touchscreenId));
2282 
2283     // Press the stylus button.
2284     TestFixture::mStylus->pressKey(BTN_STYLUS);
2285     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2286             AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2287                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2288 
2289     // Start hovering with the stylus.
2290     TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2291     TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2292     TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2293     TestFixture::mTouchscreen->sendMove(centerPoint);
2294     TestFixture::mTouchscreen->sendSync();
2295     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2296             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2297                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2298     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2299             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
2300                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2301     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2302             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
2303                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2304 
2305     // Touch down with the stylus.
2306     TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2307     TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2308     TestFixture::mTouchscreen->sendDown(centerPoint);
2309     TestFixture::mTouchscreen->sendSync();
2310     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2311             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
2312                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2313 
2314     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2315             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2316                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2317 
2318     // Stop touching with the stylus, and start hovering.
2319     TestFixture::mTouchscreen->sendUp();
2320     TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2321     TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2322     TestFixture::mTouchscreen->sendMove(centerPoint);
2323     TestFixture::mTouchscreen->sendSync();
2324     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2325             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_UP),
2326                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2327     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2328             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER),
2329                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2330     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2331             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE),
2332                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2333 
2334     // Stop hovering.
2335     TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2336     TestFixture::mTouchscreen->sendSync();
2337     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2338             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
2339                   WithButtonState(0))));
2340     // TODO(b/257971675): Fix inconsistent button state when exiting hover.
2341     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2342             AllOf(toolTypeDevice, WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT),
2343                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
2344 
2345     // Release the stylus button.
2346     TestFixture::mStylus->releaseKey(BTN_STYLUS);
2347     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2348             AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2349                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2350 }
2351 
TYPED_TEST(StylusButtonIntegrationTest,StylusButtonsWithinTouchGesture)2352 TYPED_TEST(StylusButtonIntegrationTest, StylusButtonsWithinTouchGesture) {
2353     const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2354     const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2355     const auto stylusId = TestFixture::mStylusInfo.getId();
2356 
2357     // Start a stylus gesture.
2358     TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2359     TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2360     TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2361     TestFixture::mTouchscreen->sendDown(centerPoint);
2362     TestFixture::mTouchscreen->sendSync();
2363     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2364             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2365                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2366                   WithDeviceId(touchscreenId))));
2367 
2368     // Press and release a stylus button. Each change in button state also generates a MOVE event.
2369     TestFixture::mStylus->pressKey(BTN_STYLUS);
2370     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2371             AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2372                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2373     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2374             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
2375                   WithToolType(ToolType::STYLUS),
2376                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2377                   WithDeviceId(touchscreenId))));
2378     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2379             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
2380                   WithToolType(ToolType::STYLUS),
2381                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY),
2382                   WithDeviceId(touchscreenId))));
2383 
2384     TestFixture::mStylus->releaseKey(BTN_STYLUS);
2385     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2386             AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2387                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2388     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2389             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
2390                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2391                   WithDeviceId(touchscreenId))));
2392     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2393             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
2394                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2395                   WithDeviceId(touchscreenId))));
2396 
2397     // Finish the stylus gesture.
2398     TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2399     TestFixture::mTouchscreen->sendSync();
2400     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2401             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
2402                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2403                   WithDeviceId(touchscreenId))));
2404 }
2405 
TYPED_TEST(StylusButtonIntegrationTest,StylusButtonMotionEventsDisabled)2406 TYPED_TEST(StylusButtonIntegrationTest, StylusButtonMotionEventsDisabled) {
2407     TestFixture::mFakePolicy->setStylusButtonMotionEventsEnabled(false);
2408     TestFixture::mReader->requestRefreshConfiguration(
2409             InputReaderConfiguration::Change::STYLUS_BUTTON_REPORTING);
2410 
2411     const Point centerPoint = TestFixture::mTouchscreen->getCenterPoint();
2412     const auto touchscreenId = TestFixture::mTouchscreenInfo.getId();
2413     const auto stylusId = TestFixture::mStylusInfo.getId();
2414 
2415     // Start a stylus gesture. By the time this event is processed, the configuration change that
2416     // was requested is guaranteed to be completed.
2417     TestFixture::mTouchscreen->sendSlot(FIRST_SLOT);
2418     TestFixture::mTouchscreen->sendTrackingId(FIRST_TRACKING_ID);
2419     TestFixture::mTouchscreen->sendToolType(MT_TOOL_PEN);
2420     TestFixture::mTouchscreen->sendDown(centerPoint);
2421     TestFixture::mTouchscreen->sendSync();
2422     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2423             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
2424                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2425                   WithDeviceId(touchscreenId))));
2426 
2427     // Press and release a stylus button. Each change only generates a MOVE motion event.
2428     // Key events are unaffected.
2429     TestFixture::mStylus->pressKey(BTN_STYLUS);
2430     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2431             AllOf(WithKeyAction(AKEY_EVENT_ACTION_DOWN), WithSource(AINPUT_SOURCE_KEYBOARD),
2432                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2433     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2434             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
2435                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2436                   WithDeviceId(touchscreenId))));
2437 
2438     TestFixture::mStylus->releaseKey(BTN_STYLUS);
2439     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyKeyWasCalled(
2440             AllOf(WithKeyAction(AKEY_EVENT_ACTION_UP), WithSource(AINPUT_SOURCE_KEYBOARD),
2441                   WithKeyCode(AKEYCODE_STYLUS_BUTTON_PRIMARY), WithDeviceId(stylusId))));
2442     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2443             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
2444                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2445                   WithDeviceId(touchscreenId))));
2446 
2447     // Finish the stylus gesture.
2448     TestFixture::mTouchscreen->sendTrackingId(INVALID_TRACKING_ID);
2449     TestFixture::mTouchscreen->sendSync();
2450     ASSERT_NO_FATAL_FAILURE(TestFixture::mTestListener->assertNotifyMotionWasCalled(
2451             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
2452                   WithToolType(ToolType::STYLUS), WithButtonState(0),
2453                   WithDeviceId(touchscreenId))));
2454 }
2455 
2456 // --- ExternalStylusIntegrationTest ---
2457 
2458 // Verify the behavior of an external stylus. An external stylus can report pressure or button
2459 // data independently of the touchscreen, which is then sent as a MotionEvent as part of an
2460 // ongoing stylus gesture that is being emitted by the touchscreen.
2461 using ExternalStylusIntegrationTest = BaseTouchIntegrationTest;
2462 
TEST_F(ExternalStylusIntegrationTest,ExternalStylusConnectionChangesTouchscreenSource)2463 TEST_F(ExternalStylusIntegrationTest, ExternalStylusConnectionChangesTouchscreenSource) {
2464     // Create an external stylus capable of reporting pressure data that
2465     // should be fused with a touch pointer.
2466     std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2467             createUinputDevice<UinputExternalStylusWithPressure>();
2468     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2469     const auto stylusInfo = waitForDevice(stylus->getName());
2470     ASSERT_TRUE(stylusInfo);
2471 
2472     // Connecting an external stylus changes the source of the touchscreen.
2473     const auto deviceInfo = waitForDevice(mDevice->getName());
2474     ASSERT_TRUE(deviceInfo.has_value());
2475     ASSERT_TRUE(isFromSource(deviceInfo->getSources(), STYLUS_FUSION_SOURCE));
2476 }
2477 
TEST_F(ExternalStylusIntegrationTest,FusedExternalStylusPressureReported)2478 TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureReported) {
2479     const Point centerPoint = mDevice->getCenterPoint();
2480 
2481     // Create an external stylus capable of reporting pressure data that
2482     // should be fused with a touch pointer.
2483     std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2484             createUinputDevice<UinputExternalStylusWithPressure>();
2485     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2486     const auto stylusInfo = waitForDevice(stylus->getName());
2487     ASSERT_TRUE(stylusInfo.has_value());
2488 
2489     ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2490 
2491     const auto touchscreenId = mDeviceInfo.getId();
2492 
2493     // Set a pressure value on the stylus. It doesn't generate any events.
2494     const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
2495     stylus->setPressure(100);
2496     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2497 
2498     // Start a finger gesture, and ensure it shows up as stylus gesture
2499     // with the pressure set by the external stylus.
2500     mDevice->sendSlot(FIRST_SLOT);
2501     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2502     mDevice->sendToolType(MT_TOOL_FINGER);
2503     mDevice->sendDown(centerPoint);
2504     mDevice->sendSync();
2505     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2506             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithToolType(ToolType::STYLUS),
2507                   WithButtonState(0), WithSource(STYLUS_FUSION_SOURCE), WithDeviceId(touchscreenId),
2508                   WithPressure(100.f / RAW_PRESSURE_MAX))));
2509 
2510     // Change the pressure on the external stylus, and ensure the touchscreen generates a MOVE
2511     // event with the updated pressure.
2512     stylus->setPressure(200);
2513     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2514             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithToolType(ToolType::STYLUS),
2515                   WithButtonState(0), WithSource(STYLUS_FUSION_SOURCE), WithDeviceId(touchscreenId),
2516                   WithPressure(200.f / RAW_PRESSURE_MAX))));
2517 
2518     // The external stylus did not generate any events.
2519     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2520     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2521 }
2522 
TEST_F(ExternalStylusIntegrationTest,FusedExternalStylusPressureNotReported)2523 TEST_F(ExternalStylusIntegrationTest, FusedExternalStylusPressureNotReported) {
2524     const Point centerPoint = mDevice->getCenterPoint();
2525 
2526     // Create an external stylus capable of reporting pressure data that
2527     // should be fused with a touch pointer.
2528     std::unique_ptr<UinputExternalStylusWithPressure> stylus =
2529             createUinputDevice<UinputExternalStylusWithPressure>();
2530     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2531     const auto stylusInfo = waitForDevice(stylus->getName());
2532     ASSERT_TRUE(stylusInfo.has_value());
2533 
2534     ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2535 
2536     const auto touchscreenId = mDeviceInfo.getId();
2537 
2538     // Set a pressure value of 0 on the stylus. It doesn't generate any events.
2539     const auto& RAW_PRESSURE_MAX = UinputExternalStylusWithPressure::RAW_PRESSURE_MAX;
2540     // Send a non-zero value first to prevent the kernel from consuming the zero event.
2541     stylus->setPressure(100);
2542     stylus->setPressure(0);
2543     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2544 
2545     // Start a finger gesture. The touch device will withhold generating any touches for
2546     // up to 72 milliseconds while waiting for pressure data from the external stylus.
2547     mDevice->sendSlot(FIRST_SLOT);
2548     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2549     mDevice->sendToolType(MT_TOOL_FINGER);
2550     mDevice->sendDown(centerPoint);
2551     const auto syncTime = std::chrono::system_clock::now();
2552     // After 72 ms, the event *will* be generated. If we wait the full 72 ms to check that NO event
2553     // is generated in that period, there will be a race condition between the event being generated
2554     // and the test's wait timeout expiring. Thus, we wait for a shorter duration in the test to
2555     // ensure the event is not immediately generated, which should reduce the liklihood of the race
2556     // condition occurring.
2557     const auto waitUntilTimeForNoEvent = syncTime + std::chrono::milliseconds(1);
2558     mDevice->sendSync();
2559     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled(waitUntilTimeForNoEvent));
2560 
2561     // Since the external stylus did not report a pressure value within the timeout,
2562     // it shows up as a finger pointer.
2563     const auto waitUntilTimeForEvent = syncTime +
2564             std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT)) + EVENT_HAPPENED_TIMEOUT;
2565     ASSERT_NO_FATAL_FAILURE(
2566             mTestListener->assertNotifyMotionWasCalled(AllOf(WithMotionAction(
2567                                                                      AMOTION_EVENT_ACTION_DOWN),
2568                                                              WithSource(AINPUT_SOURCE_TOUCHSCREEN |
2569                                                                         AINPUT_SOURCE_STYLUS),
2570                                                              WithToolType(ToolType::FINGER),
2571                                                              WithDeviceId(touchscreenId),
2572                                                              WithPressure(1.f)),
2573                                                        waitUntilTimeForEvent));
2574 
2575     // Change the pressure on the external stylus. Since the pressure was not present at the start
2576     // of the gesture, it is ignored for now.
2577     stylus->setPressure(200);
2578     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2579 
2580     // Finish the finger gesture.
2581     mDevice->sendTrackingId(INVALID_TRACKING_ID);
2582     mDevice->sendSync();
2583     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2584             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
2585                   WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
2586                   WithToolType(ToolType::FINGER))));
2587 
2588     // Start a new gesture. Since we have a valid pressure value, it shows up as a stylus.
2589     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2590     mDevice->sendToolType(MT_TOOL_FINGER);
2591     mDevice->sendDown(centerPoint);
2592     mDevice->sendSync();
2593     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasCalled(
2594             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithSource(STYLUS_FUSION_SOURCE),
2595                   WithToolType(ToolType::STYLUS), WithButtonState(0), WithDeviceId(touchscreenId),
2596                   WithPressure(200.f / RAW_PRESSURE_MAX))));
2597 
2598     // The external stylus did not generate any events.
2599     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2600     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2601 }
2602 
TEST_F(ExternalStylusIntegrationTest,UnfusedExternalStylus)2603 TEST_F(ExternalStylusIntegrationTest, UnfusedExternalStylus) {
2604     const Point centerPoint = mDevice->getCenterPoint();
2605 
2606     // Create an external stylus device that does not support pressure. It should not affect any
2607     // touch pointers.
2608     std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
2609     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
2610     const auto stylusInfo = waitForDevice(stylus->getName());
2611     ASSERT_TRUE(stylusInfo);
2612 
2613     ASSERT_EQ(AINPUT_SOURCE_STYLUS | AINPUT_SOURCE_KEYBOARD, stylusInfo->getSources());
2614 
2615     const auto touchscreenId = mDeviceInfo.getId();
2616 
2617     // Start a finger gesture and ensure a finger pointer is generated for it, without waiting for
2618     // pressure data from the external stylus.
2619     mDevice->sendSlot(FIRST_SLOT);
2620     mDevice->sendTrackingId(FIRST_TRACKING_ID);
2621     mDevice->sendToolType(MT_TOOL_FINGER);
2622     mDevice->sendDown(centerPoint);
2623     auto waitUntil = std::chrono::system_clock::now() +
2624             std::chrono::milliseconds(ns2ms(EXTERNAL_STYLUS_DATA_TIMEOUT));
2625     mDevice->sendSync();
2626     ASSERT_NO_FATAL_FAILURE(
2627             mTestListener->assertNotifyMotionWasCalled(AllOf(WithMotionAction(
2628                                                                      AMOTION_EVENT_ACTION_DOWN),
2629                                                              WithToolType(ToolType::FINGER),
2630                                                              WithSource(AINPUT_SOURCE_TOUCHSCREEN |
2631                                                                         AINPUT_SOURCE_STYLUS),
2632                                                              WithButtonState(0),
2633                                                              WithDeviceId(touchscreenId),
2634                                                              WithPressure(1.f)),
2635                                                        waitUntil));
2636 
2637     // The external stylus did not generate any events.
2638     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
2639     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasNotCalled());
2640 }
2641 
2642 // --- InputDeviceTest ---
2643 class InputDeviceTest : public testing::Test {
2644 protected:
2645     static const char* DEVICE_NAME;
2646     static const char* DEVICE_LOCATION;
2647     static const int32_t DEVICE_ID;
2648     static const int32_t DEVICE_GENERATION;
2649     static const int32_t DEVICE_CONTROLLER_NUMBER;
2650     static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
2651     static const int32_t EVENTHUB_ID;
2652     static const std::string DEVICE_BLUETOOTH_ADDRESS;
2653 
2654     std::shared_ptr<FakeEventHub> mFakeEventHub;
2655     sp<FakeInputReaderPolicy> mFakePolicy;
2656     std::unique_ptr<TestInputListener> mFakeListener;
2657     std::unique_ptr<InstrumentedInputReader> mReader;
2658     std::shared_ptr<InputDevice> mDevice;
2659 
SetUp()2660     void SetUp() override {
2661         mFakeEventHub = std::make_unique<FakeEventHub>();
2662         mFakePolicy = sp<FakeInputReaderPolicy>::make();
2663         mFakeListener = std::make_unique<TestInputListener>();
2664         mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
2665                                                             *mFakeListener);
2666         InputDeviceIdentifier identifier;
2667         identifier.name = DEVICE_NAME;
2668         identifier.location = DEVICE_LOCATION;
2669         identifier.bluetoothAddress = DEVICE_BLUETOOTH_ADDRESS;
2670         mDevice = std::make_shared<InputDevice>(mReader->getContext(), DEVICE_ID, DEVICE_GENERATION,
2671                                                 identifier);
2672         mReader->pushNextDevice(mDevice);
2673         mFakeEventHub->addDevice(EVENTHUB_ID, DEVICE_NAME, ftl::Flags<InputDeviceClass>(0));
2674         mReader->loopOnce();
2675     }
2676 
TearDown()2677     void TearDown() override {
2678         mFakeListener.reset();
2679         mFakePolicy.clear();
2680     }
2681 };
2682 
2683 const char* InputDeviceTest::DEVICE_NAME = "device";
2684 const char* InputDeviceTest::DEVICE_LOCATION = "USB1";
2685 const int32_t InputDeviceTest::DEVICE_ID = END_RESERVED_ID + 1000;
2686 const int32_t InputDeviceTest::DEVICE_GENERATION = 2;
2687 const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0;
2688 const ftl::Flags<InputDeviceClass> InputDeviceTest::DEVICE_CLASSES =
2689         InputDeviceClass::KEYBOARD | InputDeviceClass::TOUCH | InputDeviceClass::JOYSTICK;
2690 const int32_t InputDeviceTest::EVENTHUB_ID = 1;
2691 const std::string InputDeviceTest::DEVICE_BLUETOOTH_ADDRESS = "11:AA:22:BB:33:CC";
2692 
TEST_F(InputDeviceTest,ImmutableProperties)2693 TEST_F(InputDeviceTest, ImmutableProperties) {
2694     ASSERT_EQ(DEVICE_ID, mDevice->getId());
2695     ASSERT_STREQ(DEVICE_NAME, mDevice->getName().c_str());
2696     ASSERT_EQ(ftl::Flags<InputDeviceClass>(0), mDevice->getClasses());
2697 }
2698 
TEST_F(InputDeviceTest,WhenDeviceCreated_EnabledIsFalse)2699 TEST_F(InputDeviceTest, WhenDeviceCreated_EnabledIsFalse) {
2700     ASSERT_EQ(mDevice->isEnabled(), false);
2701 }
2702 
TEST_F(InputDeviceTest,WhenNoMappersAreRegistered_DeviceIsIgnored)2703 TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
2704     // Configuration.
2705     InputReaderConfiguration config;
2706     std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2707 
2708     // Reset.
2709     unused += mDevice->reset(ARBITRARY_TIME);
2710 
2711     NotifyDeviceResetArgs resetArgs;
2712     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2713     ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2714     ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2715 
2716     // Metadata.
2717     ASSERT_TRUE(mDevice->isIgnored());
2718     ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
2719 
2720     InputDeviceInfo info = mDevice->getDeviceInfo();
2721     ASSERT_EQ(DEVICE_ID, info.getId());
2722     ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2723     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
2724     ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
2725 
2726     // State queries.
2727     ASSERT_EQ(0, mDevice->getMetaState());
2728 
2729     ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2730             << "Ignored device should return unknown key code state.";
2731     ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
2732             << "Ignored device should return unknown scan code state.";
2733     ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
2734             << "Ignored device should return unknown switch state.";
2735 
2736     const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B};
2737     uint8_t flags[2] = { 0, 1 };
2738     ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
2739             << "Ignored device should never mark any key codes.";
2740     ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
2741     ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
2742 }
2743 
TEST_F(InputDeviceTest,WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers)2744 TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
2745     // Configuration.
2746     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "key", "value");
2747 
2748     FakeInputMapper& mapper1 =
2749             mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2750                                                 AINPUT_SOURCE_KEYBOARD);
2751     mapper1.setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
2752     mapper1.setMetaState(AMETA_ALT_ON);
2753     mapper1.addSupportedKeyCode(AKEYCODE_A);
2754     mapper1.addSupportedKeyCode(AKEYCODE_B);
2755     mapper1.setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
2756     mapper1.setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
2757     mapper1.setScanCodeState(2, AKEY_STATE_DOWN);
2758     mapper1.setScanCodeState(3, AKEY_STATE_UP);
2759     mapper1.setSwitchState(4, AKEY_STATE_DOWN);
2760 
2761     FakeInputMapper& mapper2 =
2762             mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2763                                                 AINPUT_SOURCE_TOUCHSCREEN);
2764     mapper2.setMetaState(AMETA_SHIFT_ON);
2765 
2766     InputReaderConfiguration config;
2767     std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2768 
2769     std::optional<std::string> propertyValue = mDevice->getConfiguration().getString("key");
2770     ASSERT_TRUE(propertyValue.has_value())
2771             << "Device should have read configuration during configuration phase.";
2772     ASSERT_EQ("value", *propertyValue);
2773 
2774     ASSERT_NO_FATAL_FAILURE(mapper1.assertConfigureWasCalled());
2775     ASSERT_NO_FATAL_FAILURE(mapper2.assertConfigureWasCalled());
2776 
2777     // Reset
2778     unused += mDevice->reset(ARBITRARY_TIME);
2779     ASSERT_NO_FATAL_FAILURE(mapper1.assertResetWasCalled());
2780     ASSERT_NO_FATAL_FAILURE(mapper2.assertResetWasCalled());
2781 
2782     NotifyDeviceResetArgs resetArgs;
2783     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
2784     ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
2785     ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
2786 
2787     // Metadata.
2788     ASSERT_FALSE(mDevice->isIgnored());
2789     ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
2790 
2791     InputDeviceInfo info = mDevice->getDeviceInfo();
2792     ASSERT_EQ(DEVICE_ID, info.getId());
2793     ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.c_str());
2794     ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
2795     ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
2796 
2797     // State queries.
2798     ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
2799             << "Should query mappers and combine meta states.";
2800 
2801     ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2802             << "Should return unknown key code state when source not supported.";
2803     ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2804             << "Should return unknown scan code state when source not supported.";
2805     ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
2806             << "Should return unknown switch state when source not supported.";
2807 
2808     ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
2809             << "Should query mapper when source is supported.";
2810     ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
2811             << "Should query mapper when source is supported.";
2812     ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
2813             << "Should query mapper when source is supported.";
2814 
2815     const std::vector<int32_t> keyCodes{AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2};
2816     uint8_t flags[4] = { 0, 0, 0, 1 };
2817     ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, keyCodes, flags))
2818             << "Should do nothing when source is unsupported.";
2819     ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
2820     ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
2821     ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
2822     ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
2823 
2824     ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, keyCodes, flags))
2825             << "Should query mapper when source is supported.";
2826     ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
2827     ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
2828     ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
2829     ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
2830 
2831     // Event handling.
2832     RawEvent event;
2833     event.deviceId = EVENTHUB_ID;
2834     unused += mDevice->process(&event, 1);
2835 
2836     ASSERT_NO_FATAL_FAILURE(mapper1.assertProcessWasCalled());
2837     ASSERT_NO_FATAL_FAILURE(mapper2.assertProcessWasCalled());
2838 }
2839 
TEST_F(InputDeviceTest,Configure_SmoothScrollViewBehaviorNotSet)2840 TEST_F(InputDeviceTest, Configure_SmoothScrollViewBehaviorNotSet) {
2841     // Set some behavior to force the configuration to be update.
2842     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "1");
2843     mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2844                                         AINPUT_SOURCE_KEYBOARD);
2845 
2846     std::list<NotifyArgs> unused =
2847             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2848                                /*changes=*/{});
2849 
2850     ASSERT_FALSE(mDevice->getDeviceInfo().getViewBehavior().shouldSmoothScroll.has_value());
2851 }
2852 
TEST_F(InputDeviceTest,Configure_SmoothScrollViewBehaviorEnabled)2853 TEST_F(InputDeviceTest, Configure_SmoothScrollViewBehaviorEnabled) {
2854     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.viewBehavior_smoothScroll", "1");
2855     mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2856                                         AINPUT_SOURCE_KEYBOARD);
2857 
2858     std::list<NotifyArgs> unused =
2859             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2860                                /*changes=*/{});
2861 
2862     ASSERT_TRUE(mDevice->getDeviceInfo().getViewBehavior().shouldSmoothScroll.value_or(false));
2863 }
2864 
TEST_F(InputDeviceTest,WakeDevice_AddsWakeFlagToProcessNotifyArgs)2865 TEST_F(InputDeviceTest, WakeDevice_AddsWakeFlagToProcessNotifyArgs) {
2866     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "1");
2867     FakeInputMapper& mapper =
2868             mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2869                                                 AINPUT_SOURCE_KEYBOARD);
2870     NotifyMotionArgs args1;
2871     NotifySwitchArgs args2;
2872     NotifyKeyArgs args3;
2873     mapper.setProcessResult({args1, args2, args3});
2874 
2875     InputReaderConfiguration config;
2876     std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2877 
2878     RawEvent event;
2879     event.deviceId = EVENTHUB_ID;
2880     std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2881 
2882     for (auto& arg : notifyArgs) {
2883         if (const auto notifyMotionArgs = std::get_if<NotifyMotionArgs>(&arg)) {
2884             ASSERT_EQ(POLICY_FLAG_WAKE, notifyMotionArgs->policyFlags);
2885         } else if (const auto notifySwitchArgs = std::get_if<NotifySwitchArgs>(&arg)) {
2886             ASSERT_EQ(POLICY_FLAG_WAKE, notifySwitchArgs->policyFlags);
2887         } else if (const auto notifyKeyArgs = std::get_if<NotifyKeyArgs>(&arg)) {
2888             ASSERT_EQ(POLICY_FLAG_WAKE, notifyKeyArgs->policyFlags);
2889         }
2890     }
2891 }
2892 
TEST_F(InputDeviceTest,NotWakeDevice_DoesNotAddWakeFlagToProcessNotifyArgs)2893 TEST_F(InputDeviceTest, NotWakeDevice_DoesNotAddWakeFlagToProcessNotifyArgs) {
2894     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0");
2895     FakeInputMapper& mapper =
2896             mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2897                                                 AINPUT_SOURCE_KEYBOARD);
2898     NotifyMotionArgs args;
2899     mapper.setProcessResult({args});
2900 
2901     InputReaderConfiguration config;
2902     std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2903 
2904     RawEvent event;
2905     event.deviceId = EVENTHUB_ID;
2906     std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2907 
2908     // POLICY_FLAG_WAKE is not added to the NotifyArgs.
2909     ASSERT_EQ(0u, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags);
2910 }
2911 
TEST_F(InputDeviceTest,NotWakeDevice_DoesNotRemoveExistingWakeFlagFromProcessNotifyArgs)2912 TEST_F(InputDeviceTest, NotWakeDevice_DoesNotRemoveExistingWakeFlagFromProcessNotifyArgs) {
2913     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "device.wake", "0");
2914     FakeInputMapper& mapper =
2915             mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2916                                                 AINPUT_SOURCE_KEYBOARD);
2917     NotifyMotionArgs args;
2918     args.policyFlags = POLICY_FLAG_WAKE;
2919     mapper.setProcessResult({args});
2920 
2921     InputReaderConfiguration config;
2922     std::list<NotifyArgs> unused = mDevice->configure(ARBITRARY_TIME, config, /*changes=*/{});
2923 
2924     RawEvent event;
2925     event.deviceId = EVENTHUB_ID;
2926     std::list<NotifyArgs> notifyArgs = mDevice->process(&event, 1);
2927 
2928     // The POLICY_FLAG_WAKE is preserved, despite the device being a non-wake device.
2929     ASSERT_EQ(POLICY_FLAG_WAKE, std::get<NotifyMotionArgs>(notifyArgs.front()).policyFlags);
2930 }
2931 
2932 // A single input device is associated with a specific display. Check that:
2933 // 1. Device is disabled if the viewport corresponding to the associated display is not found
2934 // 2. Device is disabled when configure API is called
TEST_F(InputDeviceTest,Configure_AssignsDisplayPort)2935 TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) {
2936     mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2937                                         AINPUT_SOURCE_TOUCHSCREEN);
2938 
2939     // First Configuration.
2940     std::list<NotifyArgs> unused =
2941             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2942                                /*changes=*/{});
2943 
2944     // Device should be enabled by default.
2945     ASSERT_TRUE(mDevice->isEnabled());
2946 
2947     // Prepare associated info.
2948     constexpr uint8_t hdmi = 1;
2949     const std::string UNIQUE_ID = "local:1";
2950 
2951     mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi);
2952     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2953                                  InputReaderConfiguration::Change::DISPLAY_INFO);
2954     // Device should be disabled because it is associated with a specific display via
2955     // input port <-> display port association, but the corresponding display is not found
2956     ASSERT_FALSE(mDevice->isEnabled());
2957 
2958     // Prepare displays.
2959     DisplayViewport viewport =
2960             createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
2961                            /*isActive=*/true, UNIQUE_ID, hdmi, ViewportType::INTERNAL);
2962     mFakePolicy->addDisplayViewport(viewport);
2963     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2964                                  InputReaderConfiguration::Change::DISPLAY_INFO);
2965     ASSERT_TRUE(mDevice->isEnabled());
2966 
2967     // Device should be disabled after set disable.
2968     mFakePolicy->addDisabledDevice(mDevice->getId());
2969     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2970                                  InputReaderConfiguration::Change::ENABLED_STATE);
2971     ASSERT_FALSE(mDevice->isEnabled());
2972 
2973     // Device should still be disabled even found the associated display.
2974     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2975                                  InputReaderConfiguration::Change::DISPLAY_INFO);
2976     ASSERT_FALSE(mDevice->isEnabled());
2977 }
2978 
TEST_F(InputDeviceTest,Configure_AssignsDisplayUniqueId)2979 TEST_F(InputDeviceTest, Configure_AssignsDisplayUniqueId) {
2980     // Device should be enabled by default.
2981     mFakePolicy->clearViewports();
2982     mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
2983                                         AINPUT_SOURCE_KEYBOARD);
2984     std::list<NotifyArgs> unused =
2985             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2986                                /*changes=*/{});
2987     ASSERT_TRUE(mDevice->isEnabled());
2988 
2989     // Device should be disabled because it is associated with a specific display, but the
2990     // corresponding display is not found.
2991     mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
2992     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
2993                                  InputReaderConfiguration::Change::DISPLAY_INFO);
2994     ASSERT_FALSE(mDevice->isEnabled());
2995 
2996     // Device should be enabled when a display is found.
2997 
2998     DisplayViewport secondViewport =
2999             createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
3000                            /* isActive= */ true, DISPLAY_UNIQUE_ID, NO_PORT,
3001                            ViewportType::INTERNAL);
3002     mFakePolicy->addDisplayViewport(secondViewport);
3003     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3004                                  InputReaderConfiguration::Change::DISPLAY_INFO);
3005     ASSERT_TRUE(mDevice->isEnabled());
3006 
3007     // Device should be disabled after set disable.
3008     mFakePolicy->addDisabledDevice(mDevice->getId());
3009     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3010                                  InputReaderConfiguration::Change::ENABLED_STATE);
3011     ASSERT_FALSE(mDevice->isEnabled());
3012 
3013     // Device should still be disabled even found the associated display.
3014     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3015                                  InputReaderConfiguration::Change::DISPLAY_INFO);
3016     ASSERT_FALSE(mDevice->isEnabled());
3017 }
3018 
TEST_F(InputDeviceTest,Configure_UniqueId_CorrectlyMatches)3019 TEST_F(InputDeviceTest, Configure_UniqueId_CorrectlyMatches) {
3020     mFakePolicy->clearViewports();
3021     mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
3022                                         AINPUT_SOURCE_KEYBOARD);
3023     std::list<NotifyArgs> unused =
3024             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3025                                /*changes=*/{});
3026 
3027     mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, DISPLAY_UNIQUE_ID);
3028 
3029     DisplayViewport secondViewport =
3030             createViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
3031                            /* isActive= */ true, DISPLAY_UNIQUE_ID, NO_PORT,
3032                            ViewportType::INTERNAL);
3033     mFakePolicy->addDisplayViewport(secondViewport);
3034     const auto initialGeneration = mDevice->getGeneration();
3035     unused += mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3036                                  InputReaderConfiguration::Change::DISPLAY_INFO);
3037     ASSERT_EQ(DISPLAY_UNIQUE_ID, mDevice->getAssociatedDisplayUniqueIdByPort());
3038     ASSERT_GT(mDevice->getGeneration(), initialGeneration);
3039     ASSERT_EQ(mDevice->getDeviceInfo().getAssociatedDisplayId(), SECONDARY_DISPLAY_ID);
3040 }
3041 
3042 /**
3043  * This test reproduces a crash caused by a dangling reference that remains after device is added
3044  * and removed. The reference is accessed in InputDevice::dump(..);
3045  */
TEST_F(InputDeviceTest,DumpDoesNotCrash)3046 TEST_F(InputDeviceTest, DumpDoesNotCrash) {
3047     constexpr int32_t TEST_EVENTHUB_ID = 10;
3048     mFakeEventHub->addDevice(TEST_EVENTHUB_ID, "Test EventHub device", InputDeviceClass::BATTERY);
3049 
3050     InputDevice device(mReader->getContext(), /*id=*/1, /*generation=*/2, /*identifier=*/{});
3051     auto _ = device.addEventHubDevice(ARBITRARY_TIME, TEST_EVENTHUB_ID,
3052                                       mFakePolicy->getReaderConfiguration());
3053     device.removeEventHubDevice(TEST_EVENTHUB_ID);
3054     std::string dumpStr, eventHubDevStr;
3055     device.dump(dumpStr, eventHubDevStr);
3056 }
3057 
TEST_F(InputDeviceTest,GetBluetoothAddress)3058 TEST_F(InputDeviceTest, GetBluetoothAddress) {
3059     const auto& address = mReader->getBluetoothAddress(DEVICE_ID);
3060     ASSERT_TRUE(address);
3061     ASSERT_EQ(DEVICE_BLUETOOTH_ADDRESS, *address);
3062 }
3063 
TEST_F(InputDeviceTest,KernelBufferOverflowResetsMappers)3064 TEST_F(InputDeviceTest, KernelBufferOverflowResetsMappers) {
3065     mFakePolicy->clearViewports();
3066     FakeInputMapper& mapper =
3067             mDevice->addMapper<FakeInputMapper>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
3068                                                 AINPUT_SOURCE_KEYBOARD);
3069     std::list<NotifyArgs> unused =
3070             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3071                                /*changes=*/{});
3072 
3073     mapper.assertConfigureWasCalled();
3074     mapper.assertResetWasNotCalled();
3075 
3076     RawEvent event{.when = ARBITRARY_TIME,
3077                    .readTime = ARBITRARY_TIME,
3078                    .deviceId = EVENTHUB_ID,
3079                    .type = EV_SYN,
3080                    .code = SYN_REPORT,
3081                    .value = 0};
3082 
3083     // Events are processed normally.
3084     unused = mDevice->process(&event, /*count=*/1);
3085     mapper.assertProcessWasCalled();
3086 
3087     // Simulate a kernel buffer overflow, which generates a SYN_DROPPED event.
3088     event.type = EV_SYN;
3089     event.code = SYN_DROPPED;
3090     event.value = 0;
3091     unused = mDevice->process(&event, /*count=*/1);
3092     mapper.assertProcessWasNotCalled();
3093 
3094     // All events until the next SYN_REPORT should be dropped.
3095     event.type = EV_KEY;
3096     event.code = KEY_A;
3097     event.value = 1;
3098     unused = mDevice->process(&event, /*count=*/1);
3099     mapper.assertProcessWasNotCalled();
3100 
3101     // We get the SYN_REPORT event now, which is not forwarded to mappers.
3102     // This should reset the mapper.
3103     event.type = EV_SYN;
3104     event.code = SYN_REPORT;
3105     event.value = 0;
3106     unused = mDevice->process(&event, /*count=*/1);
3107     mapper.assertProcessWasNotCalled();
3108     mapper.assertResetWasCalled();
3109 
3110     // The mapper receives events normally now.
3111     event.type = EV_KEY;
3112     event.code = KEY_B;
3113     event.value = 1;
3114     unused = mDevice->process(&event, /*count=*/1);
3115     mapper.assertProcessWasCalled();
3116 }
3117 
3118 // --- TouchInputMapperTest ---
3119 
3120 class TouchInputMapperTest : public InputMapperTest {
3121 protected:
3122     static const int32_t RAW_X_MIN;
3123     static const int32_t RAW_X_MAX;
3124     static const int32_t RAW_Y_MIN;
3125     static const int32_t RAW_Y_MAX;
3126     static const int32_t RAW_TOUCH_MIN;
3127     static const int32_t RAW_TOUCH_MAX;
3128     static const int32_t RAW_TOOL_MIN;
3129     static const int32_t RAW_TOOL_MAX;
3130     static const int32_t RAW_PRESSURE_MIN;
3131     static const int32_t RAW_PRESSURE_MAX;
3132     static const int32_t RAW_ORIENTATION_MIN;
3133     static const int32_t RAW_ORIENTATION_MAX;
3134     static const int32_t RAW_DISTANCE_MIN;
3135     static const int32_t RAW_DISTANCE_MAX;
3136     static const int32_t RAW_TILT_MIN;
3137     static const int32_t RAW_TILT_MAX;
3138     static const int32_t RAW_ID_MIN;
3139     static const int32_t RAW_ID_MAX;
3140     static const int32_t RAW_SLOT_MIN;
3141     static const int32_t RAW_SLOT_MAX;
3142     static const float X_PRECISION;
3143     static const float Y_PRECISION;
3144     static const float X_PRECISION_VIRTUAL;
3145     static const float Y_PRECISION_VIRTUAL;
3146 
3147     static const float GEOMETRIC_SCALE;
3148     static const TouchAffineTransformation AFFINE_TRANSFORM;
3149 
3150     static const VirtualKeyDefinition VIRTUAL_KEYS[2];
3151 
3152     const std::string UNIQUE_ID = "local:0";
3153     const std::string SECONDARY_UNIQUE_ID = "local:1";
3154 
3155     enum Axes {
3156         POSITION = 1 << 0,
3157         TOUCH = 1 << 1,
3158         TOOL = 1 << 2,
3159         PRESSURE = 1 << 3,
3160         ORIENTATION = 1 << 4,
3161         MINOR = 1 << 5,
3162         ID = 1 << 6,
3163         DISTANCE = 1 << 7,
3164         TILT = 1 << 8,
3165         SLOT = 1 << 9,
3166         TOOL_TYPE = 1 << 10,
3167     };
3168 
3169     void prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port = NO_PORT);
3170     void prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port = NO_PORT);
3171     void prepareVirtualDisplay(ui::Rotation orientation);
3172     void prepareVirtualKeys();
3173     void prepareLocationCalibration();
3174     int32_t toRawX(float displayX);
3175     int32_t toRawY(float displayY);
3176     int32_t toRotatedRawX(float displayX);
3177     int32_t toRotatedRawY(float displayY);
3178     float toCookedX(float rawX, float rawY);
3179     float toCookedY(float rawX, float rawY);
3180     float toDisplayX(int32_t rawX);
3181     float toDisplayX(int32_t rawX, int32_t displayWidth);
3182     float toDisplayY(int32_t rawY);
3183     float toDisplayY(int32_t rawY, int32_t displayHeight);
3184 
3185 };
3186 
3187 const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
3188 const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
3189 const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
3190 const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
3191 const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
3192 const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
3193 const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
3194 const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
3195 const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = 0;
3196 const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = 255;
3197 const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
3198 const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
3199 const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
3200 const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
3201 const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
3202 const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
3203 const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
3204 const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
3205 const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
3206 const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
3207 const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
3208 const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
3209 const float TouchInputMapperTest::X_PRECISION_VIRTUAL =
3210         float(RAW_X_MAX - RAW_X_MIN + 1) / VIRTUAL_DISPLAY_WIDTH;
3211 const float TouchInputMapperTest::Y_PRECISION_VIRTUAL =
3212         float(RAW_Y_MAX - RAW_Y_MIN + 1) / VIRTUAL_DISPLAY_HEIGHT;
3213 const TouchAffineTransformation TouchInputMapperTest::AFFINE_TRANSFORM =
3214         TouchAffineTransformation(1, -2, 3, -4, 5, -6);
3215 
3216 const float TouchInputMapperTest::GEOMETRIC_SCALE =
3217         avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
3218                 float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
3219 
3220 const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
3221         { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
3222         { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
3223 };
3224 
prepareDisplay(ui::Rotation orientation,std::optional<uint8_t> port)3225 void TouchInputMapperTest::prepareDisplay(ui::Rotation orientation, std::optional<uint8_t> port) {
3226     setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation, UNIQUE_ID,
3227                                  port, ViewportType::INTERNAL);
3228 }
3229 
prepareSecondaryDisplay(ViewportType type,std::optional<uint8_t> port)3230 void TouchInputMapperTest::prepareSecondaryDisplay(ViewportType type, std::optional<uint8_t> port) {
3231     setDisplayInfoAndReconfigure(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
3232                                  ui::ROTATION_0, SECONDARY_UNIQUE_ID, port, type);
3233 }
3234 
prepareVirtualDisplay(ui::Rotation orientation)3235 void TouchInputMapperTest::prepareVirtualDisplay(ui::Rotation orientation) {
3236     setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH, VIRTUAL_DISPLAY_HEIGHT,
3237                                  orientation, VIRTUAL_DISPLAY_UNIQUE_ID, NO_PORT,
3238                                  ViewportType::VIRTUAL);
3239 }
3240 
prepareVirtualKeys()3241 void TouchInputMapperTest::prepareVirtualKeys() {
3242     mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[0]);
3243     mFakeEventHub->addVirtualKeyDefinition(EVENTHUB_ID, VIRTUAL_KEYS[1]);
3244     mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
3245     mFakeEventHub->addKey(EVENTHUB_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
3246 }
3247 
prepareLocationCalibration()3248 void TouchInputMapperTest::prepareLocationCalibration() {
3249     mFakePolicy->setTouchAffineTransformation(AFFINE_TRANSFORM);
3250 }
3251 
toRawX(float displayX)3252 int32_t TouchInputMapperTest::toRawX(float displayX) {
3253     return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
3254 }
3255 
toRawY(float displayY)3256 int32_t TouchInputMapperTest::toRawY(float displayY) {
3257     return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
3258 }
3259 
toRotatedRawX(float displayX)3260 int32_t TouchInputMapperTest::toRotatedRawX(float displayX) {
3261     return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_HEIGHT + RAW_X_MIN);
3262 }
3263 
toRotatedRawY(float displayY)3264 int32_t TouchInputMapperTest::toRotatedRawY(float displayY) {
3265     return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_WIDTH + RAW_Y_MIN);
3266 }
3267 
toCookedX(float rawX,float rawY)3268 float TouchInputMapperTest::toCookedX(float rawX, float rawY) {
3269     AFFINE_TRANSFORM.applyTo(rawX, rawY);
3270     return rawX;
3271 }
3272 
toCookedY(float rawX,float rawY)3273 float TouchInputMapperTest::toCookedY(float rawX, float rawY) {
3274     AFFINE_TRANSFORM.applyTo(rawX, rawY);
3275     return rawY;
3276 }
3277 
toDisplayX(int32_t rawX)3278 float TouchInputMapperTest::toDisplayX(int32_t rawX) {
3279     return toDisplayX(rawX, DISPLAY_WIDTH);
3280 }
3281 
toDisplayX(int32_t rawX,int32_t displayWidth)3282 float TouchInputMapperTest::toDisplayX(int32_t rawX, int32_t displayWidth) {
3283     return float(rawX - RAW_X_MIN) * displayWidth / (RAW_X_MAX - RAW_X_MIN + 1);
3284 }
3285 
toDisplayY(int32_t rawY)3286 float TouchInputMapperTest::toDisplayY(int32_t rawY) {
3287     return toDisplayY(rawY, DISPLAY_HEIGHT);
3288 }
3289 
toDisplayY(int32_t rawY,int32_t displayHeight)3290 float TouchInputMapperTest::toDisplayY(int32_t rawY, int32_t displayHeight) {
3291     return float(rawY - RAW_Y_MIN) * displayHeight / (RAW_Y_MAX - RAW_Y_MIN + 1);
3292 }
3293 
3294 
3295 // --- SingleTouchInputMapperTest ---
3296 
3297 class SingleTouchInputMapperTest : public TouchInputMapperTest {
3298 protected:
3299     void prepareButtons();
3300     void prepareAxes(int axes);
3301 
3302     std::list<NotifyArgs> processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
3303     std::list<NotifyArgs> processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
3304     std::list<NotifyArgs> processUp(SingleTouchInputMapper& mappery);
3305     std::list<NotifyArgs> processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
3306     std::list<NotifyArgs> processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
3307     std::list<NotifyArgs> processDistance(SingleTouchInputMapper& mapper, int32_t distance);
3308     std::list<NotifyArgs> processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
3309     std::list<NotifyArgs> processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
3310     std::list<NotifyArgs> processSync(SingleTouchInputMapper& mapper);
3311 };
3312 
prepareButtons()3313 void SingleTouchInputMapperTest::prepareButtons() {
3314     mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
3315 }
3316 
prepareAxes(int axes)3317 void SingleTouchInputMapperTest::prepareAxes(int axes) {
3318     if (axes & POSITION) {
3319         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
3320         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
3321     }
3322     if (axes & PRESSURE) {
3323         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MIN,
3324                                        RAW_PRESSURE_MAX, 0, 0);
3325     }
3326     if (axes & TOOL) {
3327         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0,
3328                                        0);
3329     }
3330     if (axes & DISTANCE) {
3331         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_DISTANCE, RAW_DISTANCE_MIN,
3332                                        RAW_DISTANCE_MAX, 0, 0);
3333     }
3334     if (axes & TILT) {
3335         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_X, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
3336         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_TILT_Y, RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
3337     }
3338 }
3339 
processDown(SingleTouchInputMapper & mapper,int32_t x,int32_t y)3340 std::list<NotifyArgs> SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper,
3341                                                               int32_t x, int32_t y) {
3342     std::list<NotifyArgs> args;
3343     args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
3344     args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
3345     args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
3346     return args;
3347 }
3348 
processMove(SingleTouchInputMapper & mapper,int32_t x,int32_t y)3349 std::list<NotifyArgs> SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper,
3350                                                               int32_t x, int32_t y) {
3351     std::list<NotifyArgs> args;
3352     args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
3353     args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
3354     return args;
3355 }
3356 
processUp(SingleTouchInputMapper & mapper)3357 std::list<NotifyArgs> SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
3358     return process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
3359 }
3360 
processPressure(SingleTouchInputMapper & mapper,int32_t pressure)3361 std::list<NotifyArgs> SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper,
3362                                                                   int32_t pressure) {
3363     return process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
3364 }
3365 
processToolMajor(SingleTouchInputMapper & mapper,int32_t toolMajor)3366 std::list<NotifyArgs> SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
3367                                                                    int32_t toolMajor) {
3368     return process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
3369 }
3370 
processDistance(SingleTouchInputMapper & mapper,int32_t distance)3371 std::list<NotifyArgs> SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper,
3372                                                                   int32_t distance) {
3373     return process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
3374 }
3375 
processTilt(SingleTouchInputMapper & mapper,int32_t tiltX,int32_t tiltY)3376 std::list<NotifyArgs> SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper,
3377                                                               int32_t tiltX, int32_t tiltY) {
3378     std::list<NotifyArgs> args;
3379     args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
3380     args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
3381     return args;
3382 }
3383 
processKey(SingleTouchInputMapper & mapper,int32_t code,int32_t value)3384 std::list<NotifyArgs> SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper,
3385                                                              int32_t code, int32_t value) {
3386     return process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
3387 }
3388 
processSync(SingleTouchInputMapper & mapper)3389 std::list<NotifyArgs> SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
3390     return process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
3391 }
3392 
TEST_F(SingleTouchInputMapperTest,GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer)3393 TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
3394     prepareButtons();
3395     prepareAxes(POSITION);
3396     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3397 
3398     ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
3399 }
3400 
TEST_F(SingleTouchInputMapperTest,GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen)3401 TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
3402     prepareButtons();
3403     prepareAxes(POSITION);
3404     addConfigurationProperty("touch.deviceType", "touchScreen");
3405     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3406 
3407     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
3408 }
3409 
TEST_F(SingleTouchInputMapperTest,GetKeyCodeState)3410 TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
3411     addConfigurationProperty("touch.deviceType", "touchScreen");
3412     prepareDisplay(ui::ROTATION_0);
3413     prepareButtons();
3414     prepareAxes(POSITION);
3415     prepareVirtualKeys();
3416     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3417 
3418     // Unknown key.
3419     ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
3420 
3421     // Virtual key is down.
3422     int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
3423     int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
3424     processDown(mapper, x, y);
3425     processSync(mapper);
3426     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
3427 
3428     ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
3429 
3430     // Virtual key is up.
3431     processUp(mapper);
3432     processSync(mapper);
3433     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
3434 
3435     ASSERT_EQ(AKEY_STATE_UP, mapper.getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
3436 }
3437 
TEST_F(SingleTouchInputMapperTest,GetScanCodeState)3438 TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
3439     addConfigurationProperty("touch.deviceType", "touchScreen");
3440     prepareDisplay(ui::ROTATION_0);
3441     prepareButtons();
3442     prepareAxes(POSITION);
3443     prepareVirtualKeys();
3444     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3445 
3446     // Unknown key.
3447     ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
3448 
3449     // Virtual key is down.
3450     int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
3451     int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
3452     processDown(mapper, x, y);
3453     processSync(mapper);
3454     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
3455 
3456     ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
3457 
3458     // Virtual key is up.
3459     processUp(mapper);
3460     processSync(mapper);
3461     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
3462 
3463     ASSERT_EQ(AKEY_STATE_UP, mapper.getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
3464 }
3465 
TEST_F(SingleTouchInputMapperTest,MarkSupportedKeyCodes)3466 TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
3467     addConfigurationProperty("touch.deviceType", "touchScreen");
3468     prepareDisplay(ui::ROTATION_0);
3469     prepareButtons();
3470     prepareAxes(POSITION);
3471     prepareVirtualKeys();
3472     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3473 
3474     uint8_t flags[2] = { 0, 0 };
3475     ASSERT_TRUE(
3476             mapper.markSupportedKeyCodes(AINPUT_SOURCE_ANY, {AKEYCODE_HOME, AKEYCODE_A}, flags));
3477     ASSERT_TRUE(flags[0]);
3478     ASSERT_FALSE(flags[1]);
3479 }
3480 
TEST_F(SingleTouchInputMapperTest,DeviceTypeChange_RecalculatesRawToDisplayTransform)3481 TEST_F(SingleTouchInputMapperTest, DeviceTypeChange_RecalculatesRawToDisplayTransform) {
3482     prepareDisplay(ui::ROTATION_0);
3483     prepareAxes(POSITION);
3484     addConfigurationProperty("touch.deviceType", "touchScreen");
3485     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3486 
3487     const int32_t x = 900;
3488     const int32_t y = 75;
3489     std::list<NotifyArgs> args;
3490     args += processDown(mapper, x, y);
3491     args += processSync(mapper);
3492 
3493     // Assert that motion event is received in display coordinate space for deviceType touchScreen.
3494     ASSERT_THAT(args,
3495                 ElementsAre(VariantWith<NotifyMotionArgs>(
3496                         AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
3497                               WithCoords(toDisplayX(x), toDisplayY(y))))));
3498 
3499     // Add device type association after the device was created.
3500     mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
3501     // Send update to the mapper.
3502     std::list<NotifyArgs> unused =
3503             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
3504                                InputReaderConfiguration::Change::DEVICE_TYPE /*changes*/);
3505 
3506     args.clear();
3507     args += processDown(mapper, x, y);
3508     args += processSync(mapper);
3509 
3510     // Assert that motion event is received in raw coordinate space for deviceType touchNavigation.
3511     ASSERT_THAT(args,
3512                 ElementsAre(VariantWith<NotifyMotionArgs>(
3513                         AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
3514                               WithCoords(x - RAW_X_MIN, y - RAW_Y_MIN)))));
3515 }
3516 
TEST_F(SingleTouchInputMapperTest,Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp)3517 TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
3518     addConfigurationProperty("touch.deviceType", "touchScreen");
3519     prepareDisplay(ui::ROTATION_0);
3520     prepareButtons();
3521     prepareAxes(POSITION);
3522     prepareVirtualKeys();
3523     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3524 
3525     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3526 
3527     NotifyKeyArgs args;
3528 
3529     // Press virtual key.
3530     int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
3531     int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
3532     processDown(mapper, x, y);
3533     processSync(mapper);
3534 
3535     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3536     ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3537     ASSERT_EQ(DEVICE_ID, args.deviceId);
3538     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3539     ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
3540     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
3541     ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
3542     ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3543     ASSERT_EQ(KEY_HOME, args.scanCode);
3544     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3545     ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3546 
3547     // Release virtual key.
3548     processUp(mapper);
3549     processSync(mapper);
3550 
3551     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
3552     ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
3553     ASSERT_EQ(DEVICE_ID, args.deviceId);
3554     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
3555     ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
3556     ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
3557     ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
3558     ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
3559     ASSERT_EQ(KEY_HOME, args.scanCode);
3560     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
3561     ASSERT_EQ(ARBITRARY_TIME, args.downTime);
3562 
3563     // Should not have sent any motions.
3564     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3565 }
3566 
TEST_F(SingleTouchInputMapperTest,Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel)3567 TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
3568     addConfigurationProperty("touch.deviceType", "touchScreen");
3569     prepareDisplay(ui::ROTATION_0);
3570     prepareButtons();
3571     prepareAxes(POSITION);
3572     prepareVirtualKeys();
3573     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3574 
3575     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3576 
3577     NotifyKeyArgs keyArgs;
3578 
3579     // Press virtual key.
3580     int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
3581     int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
3582     processDown(mapper, x, y);
3583     processSync(mapper);
3584 
3585     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3586     ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
3587     ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
3588     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
3589     ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
3590     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
3591     ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
3592     ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
3593     ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
3594     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
3595     ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
3596 
3597     // Move out of bounds.  This should generate a cancel and a pointer down since we moved
3598     // into the display area.
3599     y -= 100;
3600     processMove(mapper, x, y);
3601     processSync(mapper);
3602 
3603     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
3604     ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
3605     ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
3606     ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
3607     ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
3608     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
3609     ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
3610             | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
3611     ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
3612     ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
3613     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
3614     ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
3615 
3616     NotifyMotionArgs motionArgs;
3617     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3618     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3619     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3620     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3621     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3622     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3623     ASSERT_EQ(0, motionArgs.flags);
3624     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3625     ASSERT_EQ(0, motionArgs.buttonState);
3626     ASSERT_EQ(0, motionArgs.edgeFlags);
3627     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3628     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3629     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3630     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3631             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3632     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3633     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3634     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3635 
3636     // Keep moving out of bounds.  Should generate a pointer move.
3637     y -= 50;
3638     processMove(mapper, x, y);
3639     processSync(mapper);
3640 
3641     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3642     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3643     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3644     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3645     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3646     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3647     ASSERT_EQ(0, motionArgs.flags);
3648     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3649     ASSERT_EQ(0, motionArgs.buttonState);
3650     ASSERT_EQ(0, motionArgs.edgeFlags);
3651     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3652     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3653     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3654     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3655             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3656     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3657     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3658     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3659 
3660     // Release out of bounds.  Should generate a pointer up.
3661     processUp(mapper);
3662     processSync(mapper);
3663 
3664     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3665     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3666     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3667     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3668     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3669     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3670     ASSERT_EQ(0, motionArgs.flags);
3671     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3672     ASSERT_EQ(0, motionArgs.buttonState);
3673     ASSERT_EQ(0, motionArgs.edgeFlags);
3674     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3675     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3676     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3677     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3678             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3679     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3680     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3681     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3682 
3683     // Should not have sent any more keys or motions.
3684     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3685     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3686 }
3687 
TEST_F(SingleTouchInputMapperTest,Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay)3688 TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
3689     addConfigurationProperty("touch.deviceType", "touchScreen");
3690     prepareDisplay(ui::ROTATION_0);
3691     prepareButtons();
3692     prepareAxes(POSITION);
3693     prepareVirtualKeys();
3694     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3695 
3696     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3697 
3698     NotifyMotionArgs motionArgs;
3699 
3700     // Initially go down out of bounds.
3701     int32_t x = -10;
3702     int32_t y = -10;
3703     processDown(mapper, x, y);
3704     processSync(mapper);
3705 
3706     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3707 
3708     // Move into the display area.  Should generate a pointer down.
3709     x = 50;
3710     y = 75;
3711     processMove(mapper, x, y);
3712     processSync(mapper);
3713 
3714     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3715     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3716     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3717     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3718     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3719     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3720     ASSERT_EQ(0, motionArgs.flags);
3721     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3722     ASSERT_EQ(0, motionArgs.buttonState);
3723     ASSERT_EQ(0, motionArgs.edgeFlags);
3724     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3725     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3726     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3727     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3728             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3729     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3730     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3731     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3732 
3733     // Release.  Should generate a pointer up.
3734     processUp(mapper);
3735     processSync(mapper);
3736 
3737     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3738     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3739     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3740     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3741     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3742     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3743     ASSERT_EQ(0, motionArgs.flags);
3744     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3745     ASSERT_EQ(0, motionArgs.buttonState);
3746     ASSERT_EQ(0, motionArgs.edgeFlags);
3747     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3748     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3749     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3750     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3751             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3752     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3753     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3754     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3755 
3756     // Should not have sent any more keys or motions.
3757     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3758     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3759 }
3760 
TEST_F(SingleTouchInputMapperTest,Process_NormalSingleTouchGesture_VirtualDisplay)3761 TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture_VirtualDisplay) {
3762     addConfigurationProperty("touch.deviceType", "touchScreen");
3763     addConfigurationProperty("touch.displayId", VIRTUAL_DISPLAY_UNIQUE_ID);
3764 
3765     prepareVirtualDisplay(ui::ROTATION_0);
3766     prepareButtons();
3767     prepareAxes(POSITION);
3768     prepareVirtualKeys();
3769     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3770 
3771     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3772 
3773     NotifyMotionArgs motionArgs;
3774 
3775     // Down.
3776     int32_t x = 100;
3777     int32_t y = 125;
3778     processDown(mapper, x, y);
3779     processSync(mapper);
3780 
3781     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3782     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3783     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3784     ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
3785     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3786     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3787     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3788     ASSERT_EQ(0, motionArgs.flags);
3789     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3790     ASSERT_EQ(0, motionArgs.buttonState);
3791     ASSERT_EQ(0, motionArgs.edgeFlags);
3792     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3793     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3794     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3795     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3796             toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
3797             1, 0, 0, 0, 0, 0, 0, 0));
3798     ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
3799     ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
3800     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3801 
3802     // Move.
3803     x += 50;
3804     y += 75;
3805     processMove(mapper, x, y);
3806     processSync(mapper);
3807 
3808     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3809     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3810     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3811     ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
3812     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3813     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3814     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3815     ASSERT_EQ(0, motionArgs.flags);
3816     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3817     ASSERT_EQ(0, motionArgs.buttonState);
3818     ASSERT_EQ(0, motionArgs.edgeFlags);
3819     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3820     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3821     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3822     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3823             toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
3824             1, 0, 0, 0, 0, 0, 0, 0));
3825     ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
3826     ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
3827     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3828 
3829     // Up.
3830     processUp(mapper);
3831     processSync(mapper);
3832 
3833     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3834     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3835     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3836     ASSERT_EQ(VIRTUAL_DISPLAY_ID, motionArgs.displayId);
3837     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3838     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3839     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3840     ASSERT_EQ(0, motionArgs.flags);
3841     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3842     ASSERT_EQ(0, motionArgs.buttonState);
3843     ASSERT_EQ(0, motionArgs.edgeFlags);
3844     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3845     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3846     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3847     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3848             toDisplayX(x, VIRTUAL_DISPLAY_WIDTH), toDisplayY(y, VIRTUAL_DISPLAY_HEIGHT),
3849             1, 0, 0, 0, 0, 0, 0, 0));
3850     ASSERT_NEAR(X_PRECISION_VIRTUAL, motionArgs.xPrecision, EPSILON);
3851     ASSERT_NEAR(Y_PRECISION_VIRTUAL, motionArgs.yPrecision, EPSILON);
3852     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3853 
3854     // Should not have sent any more keys or motions.
3855     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3856     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3857 }
3858 
TEST_F(SingleTouchInputMapperTest,Process_NormalSingleTouchGesture)3859 TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
3860     addConfigurationProperty("touch.deviceType", "touchScreen");
3861     prepareDisplay(ui::ROTATION_0);
3862     prepareButtons();
3863     prepareAxes(POSITION);
3864     prepareVirtualKeys();
3865     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3866 
3867     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
3868 
3869     NotifyMotionArgs motionArgs;
3870 
3871     // Down.
3872     int32_t x = 100;
3873     int32_t y = 125;
3874     processDown(mapper, x, y);
3875     processSync(mapper);
3876 
3877     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3878     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3879     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3880     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3881     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3882     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
3883     ASSERT_EQ(0, motionArgs.flags);
3884     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3885     ASSERT_EQ(0, motionArgs.buttonState);
3886     ASSERT_EQ(0, motionArgs.edgeFlags);
3887     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3888     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3889     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3890     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3891             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3892     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3893     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3894     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3895 
3896     // Move.
3897     x += 50;
3898     y += 75;
3899     processMove(mapper, x, y);
3900     processSync(mapper);
3901 
3902     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3903     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3904     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3905     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3906     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3907     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
3908     ASSERT_EQ(0, motionArgs.flags);
3909     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3910     ASSERT_EQ(0, motionArgs.buttonState);
3911     ASSERT_EQ(0, motionArgs.edgeFlags);
3912     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3913     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3914     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3915     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3916             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3917     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3918     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3919     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3920 
3921     // Up.
3922     processUp(mapper);
3923     processSync(mapper);
3924 
3925     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
3926     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
3927     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
3928     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
3929     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
3930     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
3931     ASSERT_EQ(0, motionArgs.flags);
3932     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
3933     ASSERT_EQ(0, motionArgs.buttonState);
3934     ASSERT_EQ(0, motionArgs.edgeFlags);
3935     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
3936     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
3937     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
3938     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
3939             toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
3940     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
3941     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
3942     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
3943 
3944     // Should not have sent any more keys or motions.
3945     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
3946     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
3947 }
3948 
TEST_F(SingleTouchInputMapperTest,Process_WhenOrientationAware_DoesNotRotateMotions)3949 TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_DoesNotRotateMotions) {
3950     addConfigurationProperty("touch.deviceType", "touchScreen");
3951     prepareButtons();
3952     prepareAxes(POSITION);
3953     // InputReader works in the un-rotated coordinate space, so orientation-aware devices do not
3954     // need to be rotated. Touchscreens are orientation-aware by default.
3955     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3956 
3957     NotifyMotionArgs args;
3958 
3959     // Rotation 90.
3960     prepareDisplay(ui::ROTATION_90);
3961     processDown(mapper, toRawX(50), toRawY(75));
3962     processSync(mapper);
3963 
3964     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3965     ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
3966     ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
3967 
3968     processUp(mapper);
3969     processSync(mapper);
3970     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
3971 }
3972 
TEST_F(SingleTouchInputMapperTest,Process_WhenNotOrientationAware_RotatesMotions)3973 TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_RotatesMotions) {
3974     addConfigurationProperty("touch.deviceType", "touchScreen");
3975     prepareButtons();
3976     prepareAxes(POSITION);
3977     // Since InputReader works in the un-rotated coordinate space, only devices that are not
3978     // orientation-aware are affected by display rotation.
3979     addConfigurationProperty("touch.orientationAware", "0");
3980     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
3981 
3982     NotifyMotionArgs args;
3983 
3984     // Rotation 0.
3985     clearViewports();
3986     prepareDisplay(ui::ROTATION_0);
3987     processDown(mapper, toRawX(50), toRawY(75));
3988     processSync(mapper);
3989 
3990     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
3991     ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
3992     ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
3993 
3994     processUp(mapper);
3995     processSync(mapper);
3996     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
3997 
3998     // Rotation 90.
3999     clearViewports();
4000     prepareDisplay(ui::ROTATION_90);
4001     processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
4002     processSync(mapper);
4003 
4004     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4005     ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4006     ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4007 
4008     processUp(mapper);
4009     processSync(mapper);
4010     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4011 
4012     // Rotation 180.
4013     clearViewports();
4014     prepareDisplay(ui::ROTATION_180);
4015     processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
4016     processSync(mapper);
4017 
4018     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4019     ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4020     ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4021 
4022     processUp(mapper);
4023     processSync(mapper);
4024     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4025 
4026     // Rotation 270.
4027     clearViewports();
4028     prepareDisplay(ui::ROTATION_270);
4029     processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
4030     processSync(mapper);
4031 
4032     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4033     ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4034     ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4035 
4036     processUp(mapper);
4037     processSync(mapper);
4038     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4039 }
4040 
TEST_F(SingleTouchInputMapperTest,Process_WhenOrientation0_RotatesMotions)4041 TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation0_RotatesMotions) {
4042     addConfigurationProperty("touch.deviceType", "touchScreen");
4043     prepareButtons();
4044     prepareAxes(POSITION);
4045     addConfigurationProperty("touch.orientationAware", "1");
4046     addConfigurationProperty("touch.orientation", "ORIENTATION_0");
4047     clearViewports();
4048     prepareDisplay(ui::ROTATION_0);
4049     auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4050     NotifyMotionArgs args;
4051 
4052     // Orientation 0.
4053     processDown(mapper, toRawX(50), toRawY(75));
4054     processSync(mapper);
4055 
4056     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4057     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4058     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4059 
4060     processUp(mapper);
4061     processSync(mapper);
4062     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4063 }
4064 
TEST_F(SingleTouchInputMapperTest,Process_WhenOrientation90_RotatesMotions)4065 TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation90_RotatesMotions) {
4066     addConfigurationProperty("touch.deviceType", "touchScreen");
4067     prepareButtons();
4068     prepareAxes(POSITION);
4069     addConfigurationProperty("touch.orientationAware", "1");
4070     addConfigurationProperty("touch.orientation", "ORIENTATION_90");
4071     clearViewports();
4072     prepareDisplay(ui::ROTATION_0);
4073     auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4074     NotifyMotionArgs args;
4075 
4076     // Orientation 90.
4077     processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
4078     processSync(mapper);
4079 
4080     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4081     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4082     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4083 
4084     processUp(mapper);
4085     processSync(mapper);
4086     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4087 }
4088 
TEST_F(SingleTouchInputMapperTest,Process_WhenOrientation180_RotatesMotions)4089 TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation180_RotatesMotions) {
4090     addConfigurationProperty("touch.deviceType", "touchScreen");
4091     prepareButtons();
4092     prepareAxes(POSITION);
4093     addConfigurationProperty("touch.orientationAware", "1");
4094     addConfigurationProperty("touch.orientation", "ORIENTATION_180");
4095     clearViewports();
4096     prepareDisplay(ui::ROTATION_0);
4097     auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4098     NotifyMotionArgs args;
4099 
4100     // Orientation 180.
4101     processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
4102     processSync(mapper);
4103 
4104     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4105     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4106     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4107 
4108     processUp(mapper);
4109     processSync(mapper);
4110     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4111 }
4112 
TEST_F(SingleTouchInputMapperTest,Process_WhenOrientation270_RotatesMotions)4113 TEST_F(SingleTouchInputMapperTest, Process_WhenOrientation270_RotatesMotions) {
4114     addConfigurationProperty("touch.deviceType", "touchScreen");
4115     prepareButtons();
4116     prepareAxes(POSITION);
4117     addConfigurationProperty("touch.orientationAware", "1");
4118     addConfigurationProperty("touch.orientation", "ORIENTATION_270");
4119     clearViewports();
4120     prepareDisplay(ui::ROTATION_0);
4121     auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4122     NotifyMotionArgs args;
4123 
4124     // Orientation 270.
4125     processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
4126     processSync(mapper);
4127 
4128     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4129     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4130     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4131 
4132     processUp(mapper);
4133     processSync(mapper);
4134     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4135 }
4136 
TEST_F(SingleTouchInputMapperTest,Process_WhenOrientationSpecified_RotatesMotionWithDisplay)4137 TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationSpecified_RotatesMotionWithDisplay) {
4138     addConfigurationProperty("touch.deviceType", "touchScreen");
4139     prepareButtons();
4140     prepareAxes(POSITION);
4141     // Since InputReader works in the un-rotated coordinate space, only devices that are not
4142     // orientation-aware are affected by display rotation.
4143     addConfigurationProperty("touch.orientationAware", "0");
4144     addConfigurationProperty("touch.orientation", "ORIENTATION_90");
4145     auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4146 
4147     NotifyMotionArgs args;
4148 
4149     // Orientation 90, Rotation 0.
4150     clearViewports();
4151     prepareDisplay(ui::ROTATION_0);
4152     processDown(mapper, RAW_X_MAX - toRotatedRawX(75) + RAW_X_MIN, toRotatedRawY(50));
4153     processSync(mapper);
4154 
4155     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4156     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4157     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4158 
4159     processUp(mapper);
4160     processSync(mapper);
4161     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4162 
4163     // Orientation 90, Rotation 90.
4164     clearViewports();
4165     prepareDisplay(ui::ROTATION_90);
4166     processDown(mapper, toRawX(50), toRawY(75));
4167     processSync(mapper);
4168 
4169     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4170     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4171     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4172 
4173     processUp(mapper);
4174     processSync(mapper);
4175     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4176 
4177     // Orientation 90, Rotation 180.
4178     clearViewports();
4179     prepareDisplay(ui::ROTATION_180);
4180     processDown(mapper, toRotatedRawX(75), RAW_Y_MAX - toRotatedRawY(50) + RAW_Y_MIN);
4181     processSync(mapper);
4182 
4183     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4184     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4185     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4186 
4187     processUp(mapper);
4188     processSync(mapper);
4189     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4190 
4191     // Orientation 90, Rotation 270.
4192     clearViewports();
4193     prepareDisplay(ui::ROTATION_270);
4194     processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
4195     processSync(mapper);
4196 
4197     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4198     EXPECT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4199     EXPECT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4200 
4201     processUp(mapper);
4202     processSync(mapper);
4203     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4204 }
4205 
TEST_F(SingleTouchInputMapperTest,Process_IgnoresTouchesOutsidePhysicalFrame)4206 TEST_F(SingleTouchInputMapperTest, Process_IgnoresTouchesOutsidePhysicalFrame) {
4207     addConfigurationProperty("touch.deviceType", "touchScreen");
4208     prepareButtons();
4209     prepareAxes(POSITION);
4210     addConfigurationProperty("touch.orientationAware", "1");
4211     prepareDisplay(ui::ROTATION_0);
4212     auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4213 
4214     // Set a physical frame in the display viewport.
4215     auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
4216     viewport->physicalLeft = 20;
4217     viewport->physicalTop = 600;
4218     viewport->physicalRight = 30;
4219     viewport->physicalBottom = 610;
4220     mFakePolicy->updateViewport(*viewport);
4221     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
4222 
4223     // Start the touch.
4224     process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
4225     processSync(mapper);
4226 
4227     // Expect all input starting outside the physical frame to be ignored.
4228     const std::array<Point, 6> outsidePoints = {
4229             {{0, 0}, {19, 605}, {31, 605}, {25, 599}, {25, 611}, {DISPLAY_WIDTH, DISPLAY_HEIGHT}}};
4230     for (const auto& p : outsidePoints) {
4231         processMove(mapper, toRawX(p.x), toRawY(p.y));
4232         processSync(mapper);
4233         EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
4234     }
4235 
4236     // Move the touch into the physical frame.
4237     processMove(mapper, toRawX(25), toRawY(605));
4238     processSync(mapper);
4239     NotifyMotionArgs args;
4240     EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4241     EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
4242     EXPECT_NEAR(25, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4243     EXPECT_NEAR(605, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4244 
4245     // Once the touch down is reported, continue reporting input, even if it is outside the frame.
4246     for (const auto& p : outsidePoints) {
4247         processMove(mapper, toRawX(p.x), toRawY(p.y));
4248         processSync(mapper);
4249         EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4250         EXPECT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
4251         EXPECT_NEAR(p.x, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
4252         EXPECT_NEAR(p.y, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
4253     }
4254 
4255     processUp(mapper);
4256     processSync(mapper);
4257     EXPECT_NO_FATAL_FAILURE(
4258             mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
4259 }
4260 
TEST_F(SingleTouchInputMapperTest,Process_DoesntCheckPhysicalFrameForTouchpads)4261 TEST_F(SingleTouchInputMapperTest, Process_DoesntCheckPhysicalFrameForTouchpads) {
4262     addConfigurationProperty("touch.deviceType", "pointer");
4263     prepareAxes(POSITION);
4264     prepareDisplay(ui::ROTATION_0);
4265     auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4266 
4267     // Set a physical frame in the display viewport.
4268     auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
4269     viewport->physicalLeft = 20;
4270     viewport->physicalTop = 600;
4271     viewport->physicalRight = 30;
4272     viewport->physicalBottom = 610;
4273     mFakePolicy->updateViewport(*viewport);
4274     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
4275 
4276     // Start the touch.
4277     process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
4278     processSync(mapper);
4279 
4280     // Expect all input starting outside the physical frame to result in NotifyMotionArgs being
4281     // produced.
4282     const std::array<Point, 6> outsidePoints = {
4283             {{0, 0}, {19, 605}, {31, 605}, {25, 599}, {25, 611}, {DISPLAY_WIDTH, DISPLAY_HEIGHT}}};
4284     for (const auto& p : outsidePoints) {
4285         processMove(mapper, toRawX(p.x), toRawY(p.y));
4286         processSync(mapper);
4287         EXPECT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
4288     }
4289 }
4290 
TEST_F(SingleTouchInputMapperTest,Process_AllAxes_DefaultCalibration)4291 TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
4292     addConfigurationProperty("touch.deviceType", "touchScreen");
4293     prepareDisplay(ui::ROTATION_0);
4294     prepareButtons();
4295     prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
4296     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4297 
4298     // These calculations are based on the input device calibration documentation.
4299     int32_t rawX = 100;
4300     int32_t rawY = 200;
4301     int32_t rawPressure = 10;
4302     int32_t rawToolMajor = 12;
4303     int32_t rawDistance = 2;
4304     int32_t rawTiltX = 30;
4305     int32_t rawTiltY = 110;
4306 
4307     float x = toDisplayX(rawX);
4308     float y = toDisplayY(rawY);
4309     float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
4310     float size = float(rawToolMajor) / RAW_TOOL_MAX;
4311     float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
4312     float distance = float(rawDistance);
4313 
4314     float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
4315     float tiltScale = M_PI / 180;
4316     float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
4317     float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
4318     float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
4319     float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
4320 
4321     processDown(mapper, rawX, rawY);
4322     processPressure(mapper, rawPressure);
4323     processToolMajor(mapper, rawToolMajor);
4324     processDistance(mapper, rawDistance);
4325     processTilt(mapper, rawTiltX, rawTiltY);
4326     processSync(mapper);
4327 
4328     NotifyMotionArgs args;
4329     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4330     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4331             x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
4332     ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
4333     ASSERT_EQ(args.flags,
4334               AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
4335                       AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION);
4336 }
4337 
TEST_F(SingleTouchInputMapperTest,Process_XYAxes_AffineCalibration)4338 TEST_F(SingleTouchInputMapperTest, Process_XYAxes_AffineCalibration) {
4339     addConfigurationProperty("touch.deviceType", "touchScreen");
4340     prepareDisplay(ui::ROTATION_0);
4341     prepareLocationCalibration();
4342     prepareButtons();
4343     prepareAxes(POSITION);
4344     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4345 
4346     int32_t rawX = 100;
4347     int32_t rawY = 200;
4348 
4349     float x = toDisplayX(toCookedX(rawX, rawY));
4350     float y = toDisplayY(toCookedY(rawX, rawY));
4351 
4352     processDown(mapper, rawX, rawY);
4353     processSync(mapper);
4354 
4355     NotifyMotionArgs args;
4356     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
4357     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
4358             x, y, 1, 0, 0, 0, 0, 0, 0, 0));
4359 }
4360 
TEST_F(SingleTouchInputMapperTest,Process_ShouldHandleAllButtons)4361 TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
4362     addConfigurationProperty("touch.deviceType", "touchScreen");
4363     prepareDisplay(ui::ROTATION_0);
4364     prepareButtons();
4365     prepareAxes(POSITION);
4366     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4367 
4368     NotifyMotionArgs motionArgs;
4369     NotifyKeyArgs keyArgs;
4370 
4371     processDown(mapper, 100, 200);
4372     processSync(mapper);
4373     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4374     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4375     ASSERT_EQ(0, motionArgs.buttonState);
4376 
4377     // press BTN_LEFT, release BTN_LEFT
4378     processKey(mapper, BTN_LEFT, 1);
4379     processSync(mapper);
4380     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4381     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4382     ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4383 
4384     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4385     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4386     ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
4387 
4388     processKey(mapper, BTN_LEFT, 0);
4389     processSync(mapper);
4390     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4391     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4392     ASSERT_EQ(0, motionArgs.buttonState);
4393 
4394     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4395     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4396     ASSERT_EQ(0, motionArgs.buttonState);
4397 
4398     // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
4399     processKey(mapper, BTN_RIGHT, 1);
4400     processKey(mapper, BTN_MIDDLE, 1);
4401     processSync(mapper);
4402     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4403     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4404     ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4405             motionArgs.buttonState);
4406 
4407     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4408     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4409     ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4410 
4411     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4412     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4413     ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
4414             motionArgs.buttonState);
4415 
4416     processKey(mapper, BTN_RIGHT, 0);
4417     processSync(mapper);
4418     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4419     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4420     ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4421 
4422     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4423     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4424     ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
4425 
4426     processKey(mapper, BTN_MIDDLE, 0);
4427     processSync(mapper);
4428     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4429     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4430     ASSERT_EQ(0, motionArgs.buttonState);
4431 
4432     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4433     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4434     ASSERT_EQ(0, motionArgs.buttonState);
4435 
4436     // press BTN_BACK, release BTN_BACK
4437     processKey(mapper, BTN_BACK, 1);
4438     processSync(mapper);
4439     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4440     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4441     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4442 
4443     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4444     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4445     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4446 
4447     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4448     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4449     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4450 
4451     processKey(mapper, BTN_BACK, 0);
4452     processSync(mapper);
4453     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4454     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4455     ASSERT_EQ(0, motionArgs.buttonState);
4456 
4457     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4458     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4459     ASSERT_EQ(0, motionArgs.buttonState);
4460 
4461     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4462     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4463     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4464 
4465     // press BTN_SIDE, release BTN_SIDE
4466     processKey(mapper, BTN_SIDE, 1);
4467     processSync(mapper);
4468     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4469     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4470     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4471 
4472     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4473     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4474     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4475 
4476     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4477     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4478     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
4479 
4480     processKey(mapper, BTN_SIDE, 0);
4481     processSync(mapper);
4482     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4483     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4484     ASSERT_EQ(0, motionArgs.buttonState);
4485 
4486     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4487     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4488     ASSERT_EQ(0, motionArgs.buttonState);
4489 
4490     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4491     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4492     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
4493 
4494     // press BTN_FORWARD, release BTN_FORWARD
4495     processKey(mapper, BTN_FORWARD, 1);
4496     processSync(mapper);
4497     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4498     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4499     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4500 
4501     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4502     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4503     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4504 
4505     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4506     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4507     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4508 
4509     processKey(mapper, BTN_FORWARD, 0);
4510     processSync(mapper);
4511     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4512     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4513     ASSERT_EQ(0, motionArgs.buttonState);
4514 
4515     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4516     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4517     ASSERT_EQ(0, motionArgs.buttonState);
4518 
4519     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4520     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4521     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4522 
4523     // press BTN_EXTRA, release BTN_EXTRA
4524     processKey(mapper, BTN_EXTRA, 1);
4525     processSync(mapper);
4526     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4527     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
4528     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4529 
4530     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4531     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4532     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4533 
4534     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4535     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4536     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
4537 
4538     processKey(mapper, BTN_EXTRA, 0);
4539     processSync(mapper);
4540     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4541     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4542     ASSERT_EQ(0, motionArgs.buttonState);
4543 
4544     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4545     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4546     ASSERT_EQ(0, motionArgs.buttonState);
4547 
4548     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
4549     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
4550     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
4551 
4552     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
4553 
4554     // press BTN_STYLUS, release BTN_STYLUS
4555     processKey(mapper, BTN_STYLUS, 1);
4556     processSync(mapper);
4557     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4558     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4559     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
4560 
4561     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4562     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4563     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
4564 
4565     processKey(mapper, BTN_STYLUS, 0);
4566     processSync(mapper);
4567     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4568     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4569     ASSERT_EQ(0, motionArgs.buttonState);
4570 
4571     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4572     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4573     ASSERT_EQ(0, motionArgs.buttonState);
4574 
4575     // press BTN_STYLUS2, release BTN_STYLUS2
4576     processKey(mapper, BTN_STYLUS2, 1);
4577     processSync(mapper);
4578     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4579     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4580     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
4581 
4582     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4583     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
4584     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
4585 
4586     processKey(mapper, BTN_STYLUS2, 0);
4587     processSync(mapper);
4588     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4589     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
4590     ASSERT_EQ(0, motionArgs.buttonState);
4591 
4592     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4593     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4594     ASSERT_EQ(0, motionArgs.buttonState);
4595 
4596     // release touch
4597     processUp(mapper);
4598     processSync(mapper);
4599     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4600     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
4601     ASSERT_EQ(0, motionArgs.buttonState);
4602 }
4603 
TEST_F(SingleTouchInputMapperTest,Process_ShouldHandleAllToolTypes)4604 TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
4605     addConfigurationProperty("touch.deviceType", "touchScreen");
4606     prepareDisplay(ui::ROTATION_0);
4607     prepareButtons();
4608     prepareAxes(POSITION);
4609     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4610 
4611     NotifyMotionArgs motionArgs;
4612 
4613     // Hold down the mouse button for the duration of the test, since the mouse tools require
4614     // the button to be pressed to make sure they are not hovering.
4615     processKey(mapper, BTN_MOUSE, 1);
4616 
4617     // default tool type is finger
4618     processDown(mapper, 100, 200);
4619     processSync(mapper);
4620     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4621     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4622     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
4623 
4624     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4625             WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS)));
4626 
4627     // eraser
4628     processKey(mapper, BTN_TOOL_RUBBER, 1);
4629     processSync(mapper);
4630     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4631     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4632     ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
4633 
4634     // stylus
4635     processKey(mapper, BTN_TOOL_RUBBER, 0);
4636     processKey(mapper, BTN_TOOL_PEN, 1);
4637     processSync(mapper);
4638     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4639     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4640     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
4641 
4642     // brush
4643     processKey(mapper, BTN_TOOL_PEN, 0);
4644     processKey(mapper, BTN_TOOL_BRUSH, 1);
4645     processSync(mapper);
4646     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4647     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4648     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
4649 
4650     // pencil
4651     processKey(mapper, BTN_TOOL_BRUSH, 0);
4652     processKey(mapper, BTN_TOOL_PENCIL, 1);
4653     processSync(mapper);
4654     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4655     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4656     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
4657 
4658     // air-brush
4659     processKey(mapper, BTN_TOOL_PENCIL, 0);
4660     processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
4661     processSync(mapper);
4662     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4663     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4664     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
4665 
4666     // mouse
4667     processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
4668     processKey(mapper, BTN_TOOL_MOUSE, 1);
4669     processSync(mapper);
4670     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4671     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4672     ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
4673 
4674     // lens
4675     processKey(mapper, BTN_TOOL_MOUSE, 0);
4676     processKey(mapper, BTN_TOOL_LENS, 1);
4677     processSync(mapper);
4678     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4679     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4680     ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
4681 
4682     // double-tap
4683     processKey(mapper, BTN_TOOL_LENS, 0);
4684     processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
4685     processSync(mapper);
4686     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4687     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4688     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
4689 
4690     // triple-tap
4691     processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
4692     processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
4693     processSync(mapper);
4694     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4695     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4696     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
4697 
4698     // quad-tap
4699     processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
4700     processKey(mapper, BTN_TOOL_QUADTAP, 1);
4701     processSync(mapper);
4702     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4703     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4704     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
4705 
4706     // finger
4707     processKey(mapper, BTN_TOOL_QUADTAP, 0);
4708     processKey(mapper, BTN_TOOL_FINGER, 1);
4709     processSync(mapper);
4710     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4711     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4712     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
4713 
4714     // stylus trumps finger
4715     processKey(mapper, BTN_TOOL_PEN, 1);
4716     processSync(mapper);
4717     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4718     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4719     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
4720 
4721     // eraser trumps stylus
4722     processKey(mapper, BTN_TOOL_RUBBER, 1);
4723     processSync(mapper);
4724     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4725     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4726     ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
4727 
4728     // mouse trumps eraser
4729     processKey(mapper, BTN_TOOL_MOUSE, 1);
4730     processSync(mapper);
4731     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4732     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4733     ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
4734 
4735     // back to default tool type
4736     processKey(mapper, BTN_TOOL_MOUSE, 0);
4737     processKey(mapper, BTN_TOOL_RUBBER, 0);
4738     processKey(mapper, BTN_TOOL_PEN, 0);
4739     processKey(mapper, BTN_TOOL_FINGER, 0);
4740     processSync(mapper);
4741     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4742     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
4743     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
4744 }
4745 
TEST_F(SingleTouchInputMapperTest,Process_WhenBtnTouchPresent_HoversIfItsValueIsZero)4746 TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
4747     addConfigurationProperty("touch.deviceType", "touchScreen");
4748     prepareDisplay(ui::ROTATION_0);
4749     prepareButtons();
4750     prepareAxes(POSITION);
4751     mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
4752     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4753 
4754     NotifyMotionArgs motionArgs;
4755 
4756     // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
4757     processKey(mapper, BTN_TOOL_FINGER, 1);
4758     processMove(mapper, 100, 200);
4759     processSync(mapper);
4760     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4761     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
4762     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4763             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
4764 
4765     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4766     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4767     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4768             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
4769 
4770     // move a little
4771     processMove(mapper, 150, 250);
4772     processSync(mapper);
4773     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4774     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4775     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4776             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4777 
4778     // down when BTN_TOUCH is pressed, pressure defaults to 1
4779     processKey(mapper, BTN_TOUCH, 1);
4780     processSync(mapper);
4781     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4782     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
4783     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4784             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4785 
4786     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4787     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4788     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4789             toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
4790 
4791     // up when BTN_TOUCH is released, hover restored
4792     processKey(mapper, BTN_TOUCH, 0);
4793     processSync(mapper);
4794     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4795     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
4796     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4797             toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
4798 
4799     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4800     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
4801     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4802             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4803 
4804     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4805     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4806     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4807             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4808 
4809     // exit hover when pointer goes away
4810     processKey(mapper, BTN_TOOL_FINGER, 0);
4811     processSync(mapper);
4812     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4813     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
4814     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4815             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4816 }
4817 
TEST_F(SingleTouchInputMapperTest,Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero)4818 TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
4819     addConfigurationProperty("touch.deviceType", "touchScreen");
4820     prepareDisplay(ui::ROTATION_0);
4821     prepareButtons();
4822     prepareAxes(POSITION | PRESSURE);
4823     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4824 
4825     NotifyMotionArgs motionArgs;
4826 
4827     // initially hovering because pressure is 0
4828     processDown(mapper, 100, 200);
4829     processPressure(mapper, 0);
4830     processSync(mapper);
4831     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4832     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
4833     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4834             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
4835 
4836     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4837     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4838     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4839             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
4840 
4841     // move a little
4842     processMove(mapper, 150, 250);
4843     processSync(mapper);
4844     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4845     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4846     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4847             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4848 
4849     // down when pressure is non-zero
4850     processPressure(mapper, RAW_PRESSURE_MAX);
4851     processSync(mapper);
4852     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4853     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
4854     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4855             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4856 
4857     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4858     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4859     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4860             toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
4861 
4862     // up when pressure becomes 0, hover restored
4863     processPressure(mapper, 0);
4864     processSync(mapper);
4865     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4866     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
4867     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4868             toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
4869 
4870     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4871     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
4872     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4873             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4874 
4875     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4876     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
4877     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4878             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4879 
4880     // exit hover when pointer goes away
4881     processUp(mapper);
4882     processSync(mapper);
4883     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4884     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
4885     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
4886             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
4887 }
4888 
TEST_F(SingleTouchInputMapperTest,Reset_CancelsOngoingGesture)4889 TEST_F(SingleTouchInputMapperTest, Reset_CancelsOngoingGesture) {
4890     addConfigurationProperty("touch.deviceType", "touchScreen");
4891     prepareDisplay(ui::ROTATION_0);
4892     prepareButtons();
4893     prepareAxes(POSITION | PRESSURE);
4894     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4895 
4896     // Touch down.
4897     processDown(mapper, 100, 200);
4898     processPressure(mapper, 1);
4899     processSync(mapper);
4900     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4901             WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
4902 
4903     // Reset the mapper. This should cancel the ongoing gesture.
4904     resetMapper(mapper, ARBITRARY_TIME);
4905     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4906             WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
4907 
4908     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
4909 }
4910 
TEST_F(SingleTouchInputMapperTest,Reset_RecreatesTouchState)4911 TEST_F(SingleTouchInputMapperTest, Reset_RecreatesTouchState) {
4912     addConfigurationProperty("touch.deviceType", "touchScreen");
4913     prepareDisplay(ui::ROTATION_0);
4914     prepareButtons();
4915     prepareAxes(POSITION | PRESSURE);
4916     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4917 
4918     // Set the initial state for the touch pointer.
4919     mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 100);
4920     mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 200);
4921     mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_PRESSURE, RAW_PRESSURE_MAX);
4922     mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
4923 
4924     // Reset the mapper. When the mapper is reset, we expect it to attempt to recreate the touch
4925     // state by reading the current axis values. Since there was no ongoing gesture, calling reset
4926     // does not generate any events.
4927     resetMapper(mapper, ARBITRARY_TIME);
4928 
4929     // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
4930     // the recreated touch state to generate a down event.
4931     processSync(mapper);
4932     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
4933             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
4934 
4935     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
4936 }
4937 
TEST_F(SingleTouchInputMapperTest,Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset)4938 TEST_F(SingleTouchInputMapperTest,
4939        Process_WhenViewportDisplayIdChanged_TouchIsCanceledAndDeviceIsReset) {
4940     addConfigurationProperty("touch.deviceType", "touchScreen");
4941     prepareDisplay(ui::ROTATION_0);
4942     prepareButtons();
4943     prepareAxes(POSITION);
4944     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4945     NotifyMotionArgs motionArgs;
4946 
4947     // Down.
4948     processDown(mapper, 100, 200);
4949     processSync(mapper);
4950 
4951     // We should receive a down event
4952     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4953     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4954 
4955     // Change display id
4956     clearViewports();
4957     prepareSecondaryDisplay(ViewportType::INTERNAL);
4958 
4959     // We should receive a cancel event
4960     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4961     ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
4962     // Then receive reset called
4963     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
4964 }
4965 
TEST_F(SingleTouchInputMapperTest,Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset)4966 TEST_F(SingleTouchInputMapperTest,
4967        Process_WhenViewportActiveStatusChanged_TouchIsCanceledAndDeviceIsReset) {
4968     addConfigurationProperty("touch.deviceType", "touchScreen");
4969     prepareDisplay(ui::ROTATION_0);
4970     prepareButtons();
4971     prepareAxes(POSITION);
4972     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
4973     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
4974     NotifyMotionArgs motionArgs;
4975 
4976     // Start a new gesture.
4977     processDown(mapper, 100, 200);
4978     processSync(mapper);
4979     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4980     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
4981 
4982     // Make the viewport inactive. This will put the device in disabled mode.
4983     auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
4984     viewport->isActive = false;
4985     mFakePolicy->updateViewport(*viewport);
4986     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
4987 
4988     // We should receive a cancel event for the ongoing gesture.
4989     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
4990     ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
4991     // Then we should be notified that the device was reset.
4992     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
4993 
4994     // No events are generated while the viewport is inactive.
4995     processMove(mapper, 101, 201);
4996     processSync(mapper);
4997     processUp(mapper);
4998     processSync(mapper);
4999     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5000 
5001     // Start a new gesture while the viewport is still inactive.
5002     processDown(mapper, 300, 400);
5003     mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_X, 300);
5004     mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_Y, 400);
5005     mFakeEventHub->setScanCodeState(EVENTHUB_ID, BTN_TOUCH, 1);
5006     processSync(mapper);
5007 
5008     // Make the viewport active again. The device should resume processing events.
5009     viewport->isActive = true;
5010     mFakePolicy->updateViewport(*viewport);
5011     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5012 
5013     // The device is reset because it changes back to direct mode, without generating any events.
5014     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
5015     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5016 
5017     // In the next sync, the touch state that was recreated when the device was reset is reported.
5018     processSync(mapper);
5019     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5020             WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
5021 
5022     // No more events.
5023     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5024     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
5025 }
5026 
TEST_F(SingleTouchInputMapperTest,ButtonIsReleasedOnTouchUp)5027 TEST_F(SingleTouchInputMapperTest, ButtonIsReleasedOnTouchUp) {
5028     addConfigurationProperty("touch.deviceType", "touchScreen");
5029     prepareDisplay(ui::ROTATION_0);
5030     prepareButtons();
5031     prepareAxes(POSITION);
5032     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5033     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
5034 
5035     // Press a stylus button.
5036     processKey(mapper, BTN_STYLUS, 1);
5037     processSync(mapper);
5038 
5039     // Start a touch gesture and ensure the BUTTON_PRESS event is generated.
5040     processDown(mapper, 100, 200);
5041     processSync(mapper);
5042     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5043             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
5044                   WithCoords(toDisplayX(100), toDisplayY(200)),
5045                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
5046     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5047             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
5048                   WithCoords(toDisplayX(100), toDisplayY(200)),
5049                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
5050 
5051     // Release the touch gesture. Ensure that the BUTTON_RELEASE event is generated even though
5052     // the button has not actually been released, since there will be no pointers through which the
5053     // button state can be reported. The event is generated at the location of the pointer before
5054     // it went up.
5055     processUp(mapper);
5056     processSync(mapper);
5057     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5058             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
5059                   WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
5060     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5061             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
5062                   WithCoords(toDisplayX(100), toDisplayY(200)), WithButtonState(0))));
5063 }
5064 
TEST_F(SingleTouchInputMapperTest,StylusButtonMotionEventsDisabled)5065 TEST_F(SingleTouchInputMapperTest, StylusButtonMotionEventsDisabled) {
5066     addConfigurationProperty("touch.deviceType", "touchScreen");
5067     prepareDisplay(ui::ROTATION_0);
5068     prepareButtons();
5069     prepareAxes(POSITION);
5070 
5071     mFakePolicy->setStylusButtonMotionEventsEnabled(false);
5072 
5073     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5074     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
5075 
5076     // Press a stylus button.
5077     processKey(mapper, BTN_STYLUS, 1);
5078     processSync(mapper);
5079 
5080     // Start a touch gesture and ensure that the stylus button is not reported.
5081     processDown(mapper, 100, 200);
5082     processSync(mapper);
5083     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5084             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
5085 
5086     // Release and press the stylus button again.
5087     processKey(mapper, BTN_STYLUS, 0);
5088     processSync(mapper);
5089     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5090             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
5091     processKey(mapper, BTN_STYLUS, 1);
5092     processSync(mapper);
5093     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5094             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
5095 
5096     // Release the touch gesture.
5097     processUp(mapper);
5098     processSync(mapper);
5099     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5100             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
5101 
5102     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5103 }
5104 
TEST_F(SingleTouchInputMapperTest,WhenDeviceTypeIsSetToTouchNavigation_setsCorrectType)5105 TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsSetToTouchNavigation_setsCorrectType) {
5106     mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
5107     prepareDisplay(ui::ROTATION_0);
5108     prepareButtons();
5109     prepareAxes(POSITION);
5110     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5111     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
5112 
5113     ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
5114 }
5115 
TEST_F(SingleTouchInputMapperTest,WhenDeviceTypeIsChangedToTouchNavigation_updatesDeviceType)5116 TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsChangedToTouchNavigation_updatesDeviceType) {
5117     // Initialize the device without setting device source to touch navigation.
5118     addConfigurationProperty("touch.deviceType", "touchScreen");
5119     prepareDisplay(ui::ROTATION_0);
5120     prepareButtons();
5121     prepareAxes(POSITION);
5122     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5123 
5124     // Ensure that the device is created as a touchscreen, not touch navigation.
5125     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
5126 
5127     // Add device type association after the device was created.
5128     mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
5129 
5130     // Send update to the mapper.
5131     std::list<NotifyArgs> unused2 =
5132             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
5133                                InputReaderConfiguration::Change::DEVICE_TYPE /*changes*/);
5134 
5135     // Check whether device type update was successful.
5136     ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION | AINPUT_SOURCE_TOUCHPAD, mDevice->getSources());
5137 }
5138 
TEST_F(SingleTouchInputMapperTest,HoverEventsOutsidePhysicalFrameAreIgnored)5139 TEST_F(SingleTouchInputMapperTest, HoverEventsOutsidePhysicalFrameAreIgnored) {
5140     // Initialize the device without setting device source to touch navigation.
5141     addConfigurationProperty("touch.deviceType", "touchScreen");
5142     prepareDisplay(ui::ROTATION_0);
5143     prepareButtons();
5144     prepareAxes(POSITION);
5145     mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
5146 
5147     // Set a physical frame in the display viewport.
5148     auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
5149     viewport->physicalLeft = 0;
5150     viewport->physicalTop = 0;
5151     viewport->physicalRight = DISPLAY_WIDTH / 2;
5152     viewport->physicalBottom = DISPLAY_HEIGHT / 2;
5153     mFakePolicy->updateViewport(*viewport);
5154     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5155 
5156     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5157 
5158     // Hovering inside the physical frame produces events.
5159     processKey(mapper, BTN_TOOL_PEN, 1);
5160     processMove(mapper, RAW_X_MIN + 1, RAW_Y_MIN + 1);
5161     processSync(mapper);
5162     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5163             WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)));
5164     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5165             WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)));
5166 
5167     // Leaving the physical frame ends the hovering gesture.
5168     processMove(mapper, RAW_X_MAX - 1, RAW_Y_MAX - 1);
5169     processSync(mapper);
5170     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5171             WithMotionAction(AMOTION_EVENT_ACTION_HOVER_EXIT)));
5172 
5173     // Moving outside the physical frame does not produce events.
5174     processMove(mapper, RAW_X_MAX - 2, RAW_Y_MAX - 2);
5175     processSync(mapper);
5176     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5177 
5178     // Re-entering the physical frame produces events.
5179     processMove(mapper, RAW_X_MIN, RAW_Y_MIN);
5180     processSync(mapper);
5181     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5182             WithMotionAction(AMOTION_EVENT_ACTION_HOVER_ENTER)));
5183     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5184             WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE)));
5185 }
5186 
5187 // --- TouchDisplayProjectionTest ---
5188 
5189 class TouchDisplayProjectionTest : public SingleTouchInputMapperTest {
5190 public:
5191     // The values inside DisplayViewport are expected to be pre-rotated. This updates the current
5192     // DisplayViewport to pre-rotate the values. The viewport's physical display will be set to the
5193     // rotated equivalent of the given un-rotated physical display bounds.
configurePhysicalDisplay(ui::Rotation orientation,Rect naturalPhysicalDisplay,int32_t naturalDisplayWidth=DISPLAY_WIDTH,int32_t naturalDisplayHeight=DISPLAY_HEIGHT)5194     void configurePhysicalDisplay(ui::Rotation orientation, Rect naturalPhysicalDisplay,
5195                                   int32_t naturalDisplayWidth = DISPLAY_WIDTH,
5196                                   int32_t naturalDisplayHeight = DISPLAY_HEIGHT) {
5197         uint32_t inverseRotationFlags;
5198         auto rotatedWidth = naturalDisplayWidth;
5199         auto rotatedHeight = naturalDisplayHeight;
5200         switch (orientation) {
5201             case ui::ROTATION_90:
5202                 inverseRotationFlags = ui::Transform::ROT_270;
5203                 std::swap(rotatedWidth, rotatedHeight);
5204                 break;
5205             case ui::ROTATION_180:
5206                 inverseRotationFlags = ui::Transform::ROT_180;
5207                 break;
5208             case ui::ROTATION_270:
5209                 inverseRotationFlags = ui::Transform::ROT_90;
5210                 std::swap(rotatedWidth, rotatedHeight);
5211                 break;
5212             case ui::ROTATION_0:
5213                 inverseRotationFlags = ui::Transform::ROT_0;
5214                 break;
5215         }
5216 
5217         const ui::Transform rotation(inverseRotationFlags, rotatedWidth, rotatedHeight);
5218         const Rect rotatedPhysicalDisplay = rotation.transform(naturalPhysicalDisplay);
5219 
5220         std::optional<DisplayViewport> internalViewport =
5221                 *mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
5222         DisplayViewport& v = *internalViewport;
5223         v.displayId = DISPLAY_ID;
5224         v.orientation = orientation;
5225 
5226         v.logicalLeft = 0;
5227         v.logicalTop = 0;
5228         v.logicalRight = 100;
5229         v.logicalBottom = 100;
5230 
5231         v.physicalLeft = rotatedPhysicalDisplay.left;
5232         v.physicalTop = rotatedPhysicalDisplay.top;
5233         v.physicalRight = rotatedPhysicalDisplay.right;
5234         v.physicalBottom = rotatedPhysicalDisplay.bottom;
5235 
5236         v.deviceWidth = rotatedWidth;
5237         v.deviceHeight = rotatedHeight;
5238 
5239         v.isActive = true;
5240         v.uniqueId = UNIQUE_ID;
5241         v.type = ViewportType::INTERNAL;
5242         mFakePolicy->updateViewport(v);
5243         configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
5244     }
5245 
assertReceivedMove(const Point & point)5246     void assertReceivedMove(const Point& point) {
5247         NotifyMotionArgs motionArgs;
5248         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5249         ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
5250         ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
5251         ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], point.x, point.y,
5252                                                     1, 0, 0, 0, 0, 0, 0, 0));
5253     }
5254 };
5255 
TEST_F(TouchDisplayProjectionTest,IgnoresTouchesOutsidePhysicalDisplay)5256 TEST_F(TouchDisplayProjectionTest, IgnoresTouchesOutsidePhysicalDisplay) {
5257     addConfigurationProperty("touch.deviceType", "touchScreen");
5258     prepareDisplay(ui::ROTATION_0);
5259 
5260     prepareButtons();
5261     prepareAxes(POSITION);
5262     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5263 
5264     NotifyMotionArgs motionArgs;
5265 
5266     // Configure the DisplayViewport such that the logical display maps to a subsection of
5267     // the display panel called the physical display. Here, the physical display is bounded by the
5268     // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
5269     static const Rect kPhysicalDisplay{10, 20, 70, 160};
5270     static const std::array<Point, 6> kPointsOutsidePhysicalDisplay{
5271             {{-10, -10}, {0, 0}, {5, 100}, {50, 15}, {75, 100}, {50, 165}}};
5272 
5273     for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
5274         configurePhysicalDisplay(orientation, kPhysicalDisplay);
5275 
5276         // Touches outside the physical display should be ignored, and should not generate any
5277         // events. Ensure touches at the following points that lie outside of the physical display
5278         // area do not generate any events.
5279         for (const auto& point : kPointsOutsidePhysicalDisplay) {
5280             processDown(mapper, toRawX(point.x), toRawY(point.y));
5281             processSync(mapper);
5282             processUp(mapper);
5283             processSync(mapper);
5284             ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled())
5285                     << "Unexpected event generated for touch outside physical display at point: "
5286                     << point.x << ", " << point.y;
5287         }
5288     }
5289 }
5290 
TEST_F(TouchDisplayProjectionTest,EmitsTouchDownAfterEnteringPhysicalDisplay)5291 TEST_F(TouchDisplayProjectionTest, EmitsTouchDownAfterEnteringPhysicalDisplay) {
5292     addConfigurationProperty("touch.deviceType", "touchScreen");
5293     prepareDisplay(ui::ROTATION_0);
5294 
5295     prepareButtons();
5296     prepareAxes(POSITION);
5297     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5298 
5299     NotifyMotionArgs motionArgs;
5300 
5301     // Configure the DisplayViewport such that the logical display maps to a subsection of
5302     // the display panel called the physical display. Here, the physical display is bounded by the
5303     // points (10, 20) and (70, 160) inside the display space, which is of the size 400 x 800.
5304     static const Rect kPhysicalDisplay{10, 20, 70, 160};
5305 
5306     for (auto orientation : {ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180, ui::ROTATION_270}) {
5307         configurePhysicalDisplay(orientation, kPhysicalDisplay);
5308 
5309         // Touches that start outside the physical display should be ignored until it enters the
5310         // physical display bounds, at which point it should generate a down event. Start a touch at
5311         // the point (5, 100), which is outside the physical display bounds.
5312         static const Point kOutsidePoint{5, 100};
5313         processDown(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
5314         processSync(mapper);
5315         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5316 
5317         // Move the touch into the physical display area. This should generate a pointer down.
5318         processMove(mapper, toRawX(11), toRawY(21));
5319         processSync(mapper);
5320         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5321         ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
5322         ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
5323         ASSERT_NO_FATAL_FAILURE(
5324                 assertPointerCoords(motionArgs.pointerCoords[0], 11, 21, 1, 0, 0, 0, 0, 0, 0, 0));
5325 
5326         // Move the touch inside the physical display area. This should generate a pointer move.
5327         processMove(mapper, toRawX(69), toRawY(159));
5328         processSync(mapper);
5329         assertReceivedMove({69, 159});
5330 
5331         // Move outside the physical display area. Since the pointer is already down, this should
5332         // now continue generating events.
5333         processMove(mapper, toRawX(kOutsidePoint.x), toRawY(kOutsidePoint.y));
5334         processSync(mapper);
5335         assertReceivedMove(kOutsidePoint);
5336 
5337         // Release. This should generate a pointer up.
5338         processUp(mapper);
5339         processSync(mapper);
5340         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
5341         ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
5342         ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], kOutsidePoint.x,
5343                                                     kOutsidePoint.y, 1, 0, 0, 0, 0, 0, 0, 0));
5344 
5345         // Ensure no more events were generated.
5346         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
5347         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5348     }
5349 }
5350 
5351 // --- TouchscreenPrecisionTests ---
5352 
5353 // This test suite is used to ensure that touchscreen devices are scaled and configured correctly
5354 // in various orientations and with different display rotations. We configure the touchscreen to
5355 // have a higher resolution than that of the display by an integer scale factor in each axis so that
5356 // we can enforce that coordinates match precisely as expected.
5357 class TouchscreenPrecisionTestsFixture : public TouchDisplayProjectionTest,
5358                                          public ::testing::WithParamInterface<ui::Rotation> {
5359 public:
SetUp()5360     void SetUp() override {
5361         SingleTouchInputMapperTest::SetUp();
5362 
5363         // Prepare the raw axes to have twice the resolution of the display in the X axis and
5364         // four times the resolution of the display in the Y axis.
5365         prepareButtons();
5366         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, PRECISION_RAW_X_MIN, PRECISION_RAW_X_MAX,
5367                                        PRECISION_RAW_X_FLAT, PRECISION_RAW_X_FUZZ,
5368                                        PRECISION_RAW_X_RES);
5369         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, PRECISION_RAW_Y_MIN, PRECISION_RAW_Y_MAX,
5370                                        PRECISION_RAW_Y_FLAT, PRECISION_RAW_Y_FUZZ,
5371                                        PRECISION_RAW_Y_RES);
5372     }
5373 
5374     static const int32_t PRECISION_RAW_X_MIN = TouchInputMapperTest::RAW_X_MIN;
5375     static const int32_t PRECISION_RAW_X_MAX = PRECISION_RAW_X_MIN + DISPLAY_WIDTH * 2 - 1;
5376     static const int32_t PRECISION_RAW_Y_MIN = TouchInputMapperTest::RAW_Y_MIN;
5377     static const int32_t PRECISION_RAW_Y_MAX = PRECISION_RAW_Y_MIN + DISPLAY_HEIGHT * 4 - 1;
5378 
5379     static const int32_t PRECISION_RAW_X_RES = 50;  // units per millimeter
5380     static const int32_t PRECISION_RAW_Y_RES = 100; // units per millimeter
5381 
5382     static const int32_t PRECISION_RAW_X_FLAT = 16;
5383     static const int32_t PRECISION_RAW_Y_FLAT = 32;
5384 
5385     static const int32_t PRECISION_RAW_X_FUZZ = 4;
5386     static const int32_t PRECISION_RAW_Y_FUZZ = 8;
5387 
5388     static const std::array<Point, 4> kRawCorners;
5389 };
5390 
5391 const std::array<Point, 4> TouchscreenPrecisionTestsFixture::kRawCorners = {{
5392         {PRECISION_RAW_X_MIN, PRECISION_RAW_Y_MIN}, // left-top
5393         {PRECISION_RAW_X_MAX, PRECISION_RAW_Y_MIN}, // right-top
5394         {PRECISION_RAW_X_MAX, PRECISION_RAW_Y_MAX}, // right-bottom
5395         {PRECISION_RAW_X_MIN, PRECISION_RAW_Y_MAX}, // left-bottom
5396 }};
5397 
5398 // Tests for how the touchscreen is oriented relative to the natural orientation of the display.
5399 // For example, if a touchscreen is configured with an orientation of 90 degrees, it is a portrait
5400 // touchscreen panel that is used on a device whose natural display orientation is in landscape.
TEST_P(TouchscreenPrecisionTestsFixture,OrientationPrecision)5401 TEST_P(TouchscreenPrecisionTestsFixture, OrientationPrecision) {
5402     enum class Orientation {
5403         ORIENTATION_0 = ui::toRotationInt(ui::ROTATION_0),
5404         ORIENTATION_90 = ui::toRotationInt(ui::ROTATION_90),
5405         ORIENTATION_180 = ui::toRotationInt(ui::ROTATION_180),
5406         ORIENTATION_270 = ui::toRotationInt(ui::ROTATION_270),
5407         ftl_last = ORIENTATION_270,
5408     };
5409     using Orientation::ORIENTATION_0, Orientation::ORIENTATION_90, Orientation::ORIENTATION_180,
5410             Orientation::ORIENTATION_270;
5411     static const std::map<Orientation, std::array<vec2, 4> /*mappedCorners*/> kMappedCorners = {
5412             {ORIENTATION_0, {{{0, 0}, {479.5, 0}, {479.5, 799.75}, {0, 799.75}}}},
5413             {ORIENTATION_90, {{{0, 479.5}, {0, 0}, {799.75, 0}, {799.75, 479.5}}}},
5414             {ORIENTATION_180, {{{479.5, 799.75}, {0, 799.75}, {0, 0}, {479.5, 0}}}},
5415             {ORIENTATION_270, {{{799.75, 0}, {799.75, 479.5}, {0, 479.5}, {0, 0}}}},
5416     };
5417 
5418     const auto touchscreenOrientation = static_cast<Orientation>(ui::toRotationInt(GetParam()));
5419 
5420     // Configure the touchscreen as being installed in the one of the four different orientations
5421     // relative to the display.
5422     addConfigurationProperty("touch.deviceType", "touchScreen");
5423     addConfigurationProperty("touch.orientation", ftl::enum_string(touchscreenOrientation).c_str());
5424     prepareDisplay(ui::ROTATION_0);
5425 
5426     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5427 
5428     // If the touchscreen is installed in a rotated orientation relative to the display (i.e. in
5429     // orientations of either 90 or 270) this means the display's natural resolution will be
5430     // flipped.
5431     const bool displayRotated =
5432             touchscreenOrientation == ORIENTATION_90 || touchscreenOrientation == ORIENTATION_270;
5433     const int32_t width = displayRotated ? DISPLAY_HEIGHT : DISPLAY_WIDTH;
5434     const int32_t height = displayRotated ? DISPLAY_WIDTH : DISPLAY_HEIGHT;
5435     const Rect physicalFrame{0, 0, width, height};
5436     configurePhysicalDisplay(ui::ROTATION_0, physicalFrame, width, height);
5437 
5438     const auto& expectedPoints = kMappedCorners.at(touchscreenOrientation);
5439     const float expectedPrecisionX = displayRotated ? 4 : 2;
5440     const float expectedPrecisionY = displayRotated ? 2 : 4;
5441 
5442     // Test all four corners.
5443     for (int i = 0; i < 4; i++) {
5444         const auto& raw = kRawCorners[i];
5445         processDown(mapper, raw.x, raw.y);
5446         processSync(mapper);
5447         const auto& expected = expectedPoints[i];
5448         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5449                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
5450                       WithCoords(expected.x, expected.y),
5451                       WithPrecision(expectedPrecisionX, expectedPrecisionY))))
5452                 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
5453                 << "with touchscreen orientation "
5454                 << ftl::enum_string(touchscreenOrientation).c_str() << ", expected point ("
5455                 << expected.x << ", " << expected.y << ").";
5456         processUp(mapper);
5457         processSync(mapper);
5458         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5459                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
5460                       WithCoords(expected.x, expected.y))));
5461     }
5462 }
5463 
TEST_P(TouchscreenPrecisionTestsFixture,RotationPrecisionWhenOrientationAware)5464 TEST_P(TouchscreenPrecisionTestsFixture, RotationPrecisionWhenOrientationAware) {
5465     static const std::map<ui::Rotation /*rotation*/, std::array<vec2, 4> /*mappedCorners*/>
5466             kMappedCorners = {
5467                     {ui::ROTATION_0, {{{0, 0}, {479.5, 0}, {479.5, 799.75}, {0, 799.75}}}},
5468                     {ui::ROTATION_90, {{{0.5, 0}, {480, 0}, {480, 799.75}, {0.5, 799.75}}}},
5469                     {ui::ROTATION_180, {{{0.5, 0.25}, {480, 0.25}, {480, 800}, {0.5, 800}}}},
5470                     {ui::ROTATION_270, {{{0, 0.25}, {479.5, 0.25}, {479.5, 800}, {0, 800}}}},
5471             };
5472 
5473     const ui::Rotation displayRotation = GetParam();
5474 
5475     addConfigurationProperty("touch.deviceType", "touchScreen");
5476     prepareDisplay(displayRotation);
5477 
5478     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5479 
5480     const auto& expectedPoints = kMappedCorners.at(displayRotation);
5481 
5482     // Test all four corners.
5483     for (int i = 0; i < 4; i++) {
5484         const auto& expected = expectedPoints[i];
5485         const auto& raw = kRawCorners[i];
5486         processDown(mapper, raw.x, raw.y);
5487         processSync(mapper);
5488         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5489                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
5490                       WithCoords(expected.x, expected.y), WithPrecision(2, 4))))
5491                 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
5492                 << "with display rotation " << ui::toCString(displayRotation)
5493                 << ", expected point (" << expected.x << ", " << expected.y << ").";
5494         processUp(mapper);
5495         processSync(mapper);
5496         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5497                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
5498                       WithCoords(expected.x, expected.y))));
5499     }
5500 }
5501 
TEST_P(TouchscreenPrecisionTestsFixture,RotationPrecisionOrientationAwareInOri270)5502 TEST_P(TouchscreenPrecisionTestsFixture, RotationPrecisionOrientationAwareInOri270) {
5503     static const std::map<ui::Rotation /*orientation*/, std::array<vec2, 4> /*mappedCorners*/>
5504             kMappedCorners = {
5505                     {ui::ROTATION_0, {{{799.75, 0}, {799.75, 479.5}, {0, 479.5}, {0, 0}}}},
5506                     {ui::ROTATION_90, {{{800, 0}, {800, 479.5}, {0.25, 479.5}, {0.25, 0}}}},
5507                     {ui::ROTATION_180, {{{800, 0.5}, {800, 480}, {0.25, 480}, {0.25, 0.5}}}},
5508                     {ui::ROTATION_270, {{{799.75, 0.5}, {799.75, 480}, {0, 480}, {0, 0.5}}}},
5509             };
5510 
5511     const ui::Rotation displayRotation = GetParam();
5512 
5513     addConfigurationProperty("touch.deviceType", "touchScreen");
5514     addConfigurationProperty("touch.orientation", "ORIENTATION_270");
5515 
5516     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5517 
5518     // Ori 270, so width and height swapped
5519     const Rect physicalFrame{0, 0, DISPLAY_HEIGHT, DISPLAY_WIDTH};
5520     prepareDisplay(displayRotation);
5521     configurePhysicalDisplay(displayRotation, physicalFrame, DISPLAY_HEIGHT, DISPLAY_WIDTH);
5522 
5523     const auto& expectedPoints = kMappedCorners.at(displayRotation);
5524 
5525     // Test all four corners.
5526     for (int i = 0; i < 4; i++) {
5527         const auto& expected = expectedPoints[i];
5528         const auto& raw = kRawCorners[i];
5529         processDown(mapper, raw.x, raw.y);
5530         processSync(mapper);
5531         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5532                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
5533                       WithCoords(expected.x, expected.y), WithPrecision(4, 2))))
5534                 << "Failed to process raw point (" << raw.x << ", " << raw.y << ") "
5535                 << "with display rotation " << ui::toCString(displayRotation)
5536                 << ", expected point (" << expected.x << ", " << expected.y << ").";
5537         processUp(mapper);
5538         processSync(mapper);
5539         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5540                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
5541                       WithCoords(expected.x, expected.y))));
5542     }
5543 }
5544 
TEST_P(TouchscreenPrecisionTestsFixture,MotionRangesAreOrientedInRotatedDisplay)5545 TEST_P(TouchscreenPrecisionTestsFixture, MotionRangesAreOrientedInRotatedDisplay) {
5546     const ui::Rotation displayRotation = GetParam();
5547 
5548     addConfigurationProperty("touch.deviceType", "touchScreen");
5549     prepareDisplay(displayRotation);
5550 
5551     __attribute__((unused)) SingleTouchInputMapper& mapper =
5552             constructAndAddMapper<SingleTouchInputMapper>();
5553 
5554     const InputDeviceInfo deviceInfo = mDevice->getDeviceInfo();
5555     // MotionRanges use display pixels as their units
5556     const auto* xRange = deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_X, AINPUT_SOURCE_TOUCHSCREEN);
5557     const auto* yRange = deviceInfo.getMotionRange(AMOTION_EVENT_AXIS_Y, AINPUT_SOURCE_TOUCHSCREEN);
5558 
5559     // The MotionRanges should be oriented in the rotated display's coordinate space
5560     const bool displayRotated =
5561             displayRotation == ui::ROTATION_90 || displayRotation == ui::ROTATION_270;
5562 
5563     constexpr float MAX_X = 479.5;
5564     constexpr float MAX_Y = 799.75;
5565     EXPECT_EQ(xRange->min, 0.f);
5566     EXPECT_EQ(yRange->min, 0.f);
5567     EXPECT_EQ(xRange->max, displayRotated ? MAX_Y : MAX_X);
5568     EXPECT_EQ(yRange->max, displayRotated ? MAX_X : MAX_Y);
5569 
5570     EXPECT_EQ(xRange->flat, 8.f);
5571     EXPECT_EQ(yRange->flat, 8.f);
5572 
5573     EXPECT_EQ(xRange->fuzz, 2.f);
5574     EXPECT_EQ(yRange->fuzz, 2.f);
5575 
5576     EXPECT_EQ(xRange->resolution, 25.f); // pixels per millimeter
5577     EXPECT_EQ(yRange->resolution, 25.f); // pixels per millimeter
5578 }
5579 
5580 // Run the precision tests for all rotations.
5581 INSTANTIATE_TEST_SUITE_P(TouchscreenPrecisionTests, TouchscreenPrecisionTestsFixture,
5582                          ::testing::Values(ui::ROTATION_0, ui::ROTATION_90, ui::ROTATION_180,
5583                                            ui::ROTATION_270),
__anon1196b7490202(const testing::TestParamInfo<ui::Rotation>& testParamInfo) 5584                          [](const testing::TestParamInfo<ui::Rotation>& testParamInfo) {
5585                              return ftl::enum_string(testParamInfo.param);
5586                          });
5587 
5588 // --- ExternalStylusFusionTest ---
5589 
5590 class ExternalStylusFusionTest : public SingleTouchInputMapperTest {
5591 public:
SetUp()5592     void SetUp() override {
5593         SingleTouchInputMapperTest::SetUp();
5594         mExternalStylusDeviceInfo = {};
5595         mStylusState = {};
5596     }
5597 
initializeInputMapperWithExternalStylus(bool supportsPressure=true)5598     SingleTouchInputMapper& initializeInputMapperWithExternalStylus(bool supportsPressure = true) {
5599         addConfigurationProperty("touch.deviceType", "touchScreen");
5600         prepareDisplay(ui::ROTATION_0);
5601         prepareButtons();
5602         prepareAxes(POSITION);
5603         auto& mapper = constructAndAddMapper<SingleTouchInputMapper>();
5604 
5605         if (supportsPressure) {
5606             mExternalStylusDeviceInfo.addMotionRange(AMOTION_EVENT_AXIS_PRESSURE,
5607                                                      AINPUT_SOURCE_STYLUS, 0.0f, 1.0f, 0.0f, 0.0f,
5608                                                      0.0f);
5609             mStylusState.pressure = 0.f;
5610         }
5611 
5612         mStylusState.when = ARBITRARY_TIME;
5613         mStylusState.toolType = ToolType::STYLUS;
5614         mReader->getContext()->setExternalStylusDevices({mExternalStylusDeviceInfo});
5615         configureDevice(InputReaderConfiguration::Change::EXTERNAL_STYLUS_PRESENCE);
5616         processExternalStylusState(mapper);
5617         return mapper;
5618     }
5619 
processExternalStylusState(InputMapper & mapper)5620     std::list<NotifyArgs> processExternalStylusState(InputMapper& mapper) {
5621         std::list<NotifyArgs> generatedArgs = mapper.updateExternalStylusState(mStylusState);
5622         for (const NotifyArgs& args : generatedArgs) {
5623             mFakeListener->notify(args);
5624         }
5625         // Loop the reader to flush the input listener queue.
5626         mReader->loopOnce();
5627         return generatedArgs;
5628     }
5629 
5630 protected:
5631     StylusState mStylusState{};
5632 
testStartFusedStylusGesture(SingleTouchInputMapper & mapper)5633     void testStartFusedStylusGesture(SingleTouchInputMapper& mapper) {
5634         auto toolTypeSource =
5635                 AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
5636 
5637         // The first pointer is withheld.
5638         processDown(mapper, 100, 200);
5639         processSync(mapper);
5640         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5641         ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
5642                 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
5643 
5644         // The external stylus reports pressure. The withheld finger pointer is released as a
5645         // stylus.
5646         mStylusState.pressure = 1.f;
5647         processExternalStylusState(mapper);
5648         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5649                 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
5650         ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5651 
5652         // Subsequent pointer events are not withheld.
5653         processMove(mapper, 101, 201);
5654         processSync(mapper);
5655         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5656                 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
5657 
5658         ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5659         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5660     }
5661 
testSuccessfulFusionGesture(SingleTouchInputMapper & mapper)5662     void testSuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
5663         ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
5664 
5665         // Releasing the touch pointer ends the gesture.
5666         processUp(mapper);
5667         processSync(mapper);
5668         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5669                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(STYLUS_FUSION_SOURCE),
5670                       WithToolType(ToolType::STYLUS))));
5671 
5672         mStylusState.pressure = 0.f;
5673         processExternalStylusState(mapper);
5674         ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5675         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5676     }
5677 
testUnsuccessfulFusionGesture(SingleTouchInputMapper & mapper)5678     void testUnsuccessfulFusionGesture(SingleTouchInputMapper& mapper) {
5679         // When stylus fusion is not successful, events should be reported with the original source.
5680         // In this case, it is from a touchscreen.
5681         auto toolTypeSource =
5682                 AllOf(WithSource(AINPUT_SOURCE_TOUCHSCREEN), WithToolType(ToolType::FINGER));
5683 
5684         // The first pointer is withheld when an external stylus is connected,
5685         // and a timeout is requested.
5686         processDown(mapper, 100, 200);
5687         processSync(mapper);
5688         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5689         ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
5690                 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
5691 
5692         // If the timeout expires early, it is requested again.
5693         handleTimeout(mapper, ARBITRARY_TIME + 1);
5694         ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasRequested(
5695                 ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT));
5696 
5697         // When the timeout expires, the withheld touch is released as a finger pointer.
5698         handleTimeout(mapper, ARBITRARY_TIME + EXTERNAL_STYLUS_DATA_TIMEOUT);
5699         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5700                 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
5701 
5702         // Subsequent pointer events are not withheld.
5703         processMove(mapper, 101, 201);
5704         processSync(mapper);
5705         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5706                 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
5707         processUp(mapper);
5708         processSync(mapper);
5709         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5710                 AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
5711 
5712         ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5713         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5714     }
5715 
5716 private:
5717     InputDeviceInfo mExternalStylusDeviceInfo{};
5718 };
5719 
TEST_F(ExternalStylusFusionTest,UsesBluetoothStylusSourceWithPressure)5720 TEST_F(ExternalStylusFusionTest, UsesBluetoothStylusSourceWithPressure) {
5721     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5722     ASSERT_EQ(STYLUS_FUSION_SOURCE, mapper.getSources());
5723 }
5724 
TEST_F(ExternalStylusFusionTest,DoesNotUseBluetoothStylusSourceWithoutPressure)5725 TEST_F(ExternalStylusFusionTest, DoesNotUseBluetoothStylusSourceWithoutPressure) {
5726     SingleTouchInputMapper& mapper =
5727             initializeInputMapperWithExternalStylus(/*supportsPressure=*/false);
5728     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
5729 }
5730 
TEST_F(ExternalStylusFusionTest,UnsuccessfulFusion)5731 TEST_F(ExternalStylusFusionTest, UnsuccessfulFusion) {
5732     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5733     ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
5734 }
5735 
TEST_F(ExternalStylusFusionTest,SuccessfulFusion_TouchFirst)5736 TEST_F(ExternalStylusFusionTest, SuccessfulFusion_TouchFirst) {
5737     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5738     ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
5739 }
5740 
5741 // Test a successful stylus fusion gesture where the pressure is reported by the external
5742 // before the touch is reported by the touchscreen.
TEST_F(ExternalStylusFusionTest,SuccessfulFusion_PressureFirst)5743 TEST_F(ExternalStylusFusionTest, SuccessfulFusion_PressureFirst) {
5744     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5745     auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
5746 
5747     // The external stylus reports pressure first. It is ignored for now.
5748     mStylusState.pressure = 1.f;
5749     processExternalStylusState(mapper);
5750     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5751     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5752 
5753     // When the touch goes down afterwards, it is reported as a stylus pointer.
5754     processDown(mapper, 100, 200);
5755     processSync(mapper);
5756     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5757             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN))));
5758     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5759 
5760     processMove(mapper, 101, 201);
5761     processSync(mapper);
5762     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5763             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE))));
5764     processUp(mapper);
5765     processSync(mapper);
5766     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5767             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP))));
5768 
5769     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5770     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5771 }
5772 
TEST_F(ExternalStylusFusionTest,FusionIsRepeatedForEachNewGesture)5773 TEST_F(ExternalStylusFusionTest, FusionIsRepeatedForEachNewGesture) {
5774     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5775 
5776     ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
5777     ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
5778 
5779     ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
5780     ASSERT_NO_FATAL_FAILURE(testSuccessfulFusionGesture(mapper));
5781     ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
5782     ASSERT_NO_FATAL_FAILURE(testUnsuccessfulFusionGesture(mapper));
5783 }
5784 
TEST_F(ExternalStylusFusionTest,FusedPointerReportsPressureChanges)5785 TEST_F(ExternalStylusFusionTest, FusedPointerReportsPressureChanges) {
5786     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5787     auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
5788 
5789     mStylusState.pressure = 0.8f;
5790     processExternalStylusState(mapper);
5791     processDown(mapper, 100, 200);
5792     processSync(mapper);
5793     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5794             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
5795                   WithPressure(0.8f))));
5796     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5797 
5798     // The external stylus reports a pressure change. We wait for some time for a touch event.
5799     mStylusState.pressure = 0.6f;
5800     processExternalStylusState(mapper);
5801     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5802     ASSERT_NO_FATAL_FAILURE(
5803             mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
5804 
5805     // If a touch is reported within the timeout, it reports the updated pressure.
5806     processMove(mapper, 101, 201);
5807     processSync(mapper);
5808     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5809             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5810                   WithPressure(0.6f))));
5811     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5812 
5813     // There is another pressure change.
5814     mStylusState.pressure = 0.5f;
5815     processExternalStylusState(mapper);
5816     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5817     ASSERT_NO_FATAL_FAILURE(
5818             mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
5819 
5820     // If a touch is not reported within the timeout, a move event is generated to report
5821     // the new pressure.
5822     handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
5823     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5824             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5825                   WithPressure(0.5f))));
5826 
5827     // If a zero pressure is reported before the touch goes up, the previous pressure value is
5828     // repeated indefinitely.
5829     mStylusState.pressure = 0.0f;
5830     processExternalStylusState(mapper);
5831     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5832     ASSERT_NO_FATAL_FAILURE(
5833             mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
5834     processMove(mapper, 102, 202);
5835     processSync(mapper);
5836     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5837             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5838                   WithPressure(0.5f))));
5839     processMove(mapper, 103, 203);
5840     processSync(mapper);
5841     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5842             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5843                   WithPressure(0.5f))));
5844 
5845     processUp(mapper);
5846     processSync(mapper);
5847     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5848             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSource(STYLUS_FUSION_SOURCE),
5849                   WithToolType(ToolType::STYLUS))));
5850 
5851     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5852     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5853 }
5854 
TEST_F(ExternalStylusFusionTest,FusedPointerReportsToolTypeChanges)5855 TEST_F(ExternalStylusFusionTest, FusedPointerReportsToolTypeChanges) {
5856     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5857     auto source = WithSource(STYLUS_FUSION_SOURCE);
5858 
5859     mStylusState.pressure = 1.f;
5860     mStylusState.toolType = ToolType::ERASER;
5861     processExternalStylusState(mapper);
5862     processDown(mapper, 100, 200);
5863     processSync(mapper);
5864     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5865             AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
5866                   WithToolType(ToolType::ERASER))));
5867     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5868 
5869     // The external stylus reports a tool change. We wait for some time for a touch event.
5870     mStylusState.toolType = ToolType::STYLUS;
5871     processExternalStylusState(mapper);
5872     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5873     ASSERT_NO_FATAL_FAILURE(
5874             mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
5875 
5876     // If a touch is reported within the timeout, it reports the updated pressure.
5877     processMove(mapper, 101, 201);
5878     processSync(mapper);
5879     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5880             AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5881                   WithToolType(ToolType::STYLUS))));
5882     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5883 
5884     // There is another tool type change.
5885     mStylusState.toolType = ToolType::FINGER;
5886     processExternalStylusState(mapper);
5887     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5888     ASSERT_NO_FATAL_FAILURE(
5889             mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
5890 
5891     // If a touch is not reported within the timeout, a move event is generated to report
5892     // the new tool type.
5893     handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
5894     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5895             AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5896                   WithToolType(ToolType::FINGER))));
5897 
5898     processUp(mapper);
5899     processSync(mapper);
5900     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5901             AllOf(source, WithMotionAction(AMOTION_EVENT_ACTION_UP),
5902                   WithToolType(ToolType::FINGER))));
5903 
5904     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5905     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5906 }
5907 
TEST_F(ExternalStylusFusionTest,FusedPointerReportsButtons)5908 TEST_F(ExternalStylusFusionTest, FusedPointerReportsButtons) {
5909     SingleTouchInputMapper& mapper = initializeInputMapperWithExternalStylus();
5910     auto toolTypeSource = AllOf(WithSource(STYLUS_FUSION_SOURCE), WithToolType(ToolType::STYLUS));
5911 
5912     ASSERT_NO_FATAL_FAILURE(testStartFusedStylusGesture(mapper));
5913 
5914     // The external stylus reports a button change. We wait for some time for a touch event.
5915     mStylusState.buttons = AMOTION_EVENT_BUTTON_STYLUS_PRIMARY;
5916     processExternalStylusState(mapper);
5917     ASSERT_NO_FATAL_FAILURE(
5918             mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
5919 
5920     // If a touch is reported within the timeout, it reports the updated button state.
5921     processMove(mapper, 101, 201);
5922     processSync(mapper);
5923     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5924             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5925                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
5926     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5927             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
5928                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
5929     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5930 
5931     // The button is now released.
5932     mStylusState.buttons = 0;
5933     processExternalStylusState(mapper);
5934     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5935     ASSERT_NO_FATAL_FAILURE(
5936             mReader->getContext()->assertTimeoutWasRequested(ARBITRARY_TIME + TOUCH_DATA_TIMEOUT));
5937 
5938     // If a touch is not reported within the timeout, a move event is generated to report
5939     // the new button state.
5940     handleTimeout(mapper, ARBITRARY_TIME + TOUCH_DATA_TIMEOUT);
5941     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5942             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE),
5943                   WithButtonState(0))));
5944     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5945             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
5946                   WithButtonState(0))));
5947 
5948     processUp(mapper);
5949     processSync(mapper);
5950     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
5951             AllOf(toolTypeSource, WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
5952 
5953     ASSERT_NO_FATAL_FAILURE(mReader->getContext()->assertTimeoutWasNotRequested());
5954     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
5955 }
5956 
5957 // --- MultiTouchInputMapperTest ---
5958 
5959 class MultiTouchInputMapperTest : public TouchInputMapperTest {
5960 protected:
5961     void prepareAxes(int axes);
5962 
5963     void processPosition(MultiTouchInputMapper& mapper, int32_t x, int32_t y);
5964     void processTouchMajor(MultiTouchInputMapper& mapper, int32_t touchMajor);
5965     void processTouchMinor(MultiTouchInputMapper& mapper, int32_t touchMinor);
5966     void processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor);
5967     void processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor);
5968     void processOrientation(MultiTouchInputMapper& mapper, int32_t orientation);
5969     void processPressure(MultiTouchInputMapper& mapper, int32_t pressure);
5970     void processDistance(MultiTouchInputMapper& mapper, int32_t distance);
5971     void processId(MultiTouchInputMapper& mapper, int32_t id);
5972     void processSlot(MultiTouchInputMapper& mapper, int32_t slot);
5973     void processToolType(MultiTouchInputMapper& mapper, int32_t toolType);
5974     void processKey(MultiTouchInputMapper& mapper, int32_t code, int32_t value);
5975     void processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode, int32_t value);
5976     void processMTSync(MultiTouchInputMapper& mapper);
5977     void processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime = ARBITRARY_TIME,
5978                      nsecs_t readTime = READ_TIME);
5979 };
5980 
prepareAxes(int axes)5981 void MultiTouchInputMapperTest::prepareAxes(int axes) {
5982     if (axes & POSITION) {
5983         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
5984         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
5985     }
5986     if (axes & TOUCH) {
5987         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN,
5988                                        RAW_TOUCH_MAX, 0, 0);
5989         if (axes & MINOR) {
5990             mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN,
5991                                            RAW_TOUCH_MAX, 0, 0);
5992         }
5993     }
5994     if (axes & TOOL) {
5995         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
5996                                        0, 0);
5997         if (axes & MINOR) {
5998             mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN,
5999                                            RAW_TOOL_MAX, 0, 0);
6000         }
6001     }
6002     if (axes & ORIENTATION) {
6003         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_ORIENTATION, RAW_ORIENTATION_MIN,
6004                                        RAW_ORIENTATION_MAX, 0, 0);
6005     }
6006     if (axes & PRESSURE) {
6007         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_PRESSURE, RAW_PRESSURE_MIN,
6008                                        RAW_PRESSURE_MAX, 0, 0);
6009     }
6010     if (axes & DISTANCE) {
6011         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_DISTANCE, RAW_DISTANCE_MIN,
6012                                        RAW_DISTANCE_MAX, 0, 0);
6013     }
6014     if (axes & ID) {
6015         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX, 0,
6016                                        0);
6017     }
6018     if (axes & SLOT) {
6019         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
6020         mFakeEventHub->setAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, 0);
6021     }
6022     if (axes & TOOL_TYPE) {
6023         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
6024     }
6025 }
6026 
processPosition(MultiTouchInputMapper & mapper,int32_t x,int32_t y)6027 void MultiTouchInputMapperTest::processPosition(MultiTouchInputMapper& mapper, int32_t x,
6028                                                 int32_t y) {
6029     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_X, x);
6030     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
6031 }
6032 
processTouchMajor(MultiTouchInputMapper & mapper,int32_t touchMajor)6033 void MultiTouchInputMapperTest::processTouchMajor(MultiTouchInputMapper& mapper,
6034                                                   int32_t touchMajor) {
6035     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
6036 }
6037 
processTouchMinor(MultiTouchInputMapper & mapper,int32_t touchMinor)6038 void MultiTouchInputMapperTest::processTouchMinor(MultiTouchInputMapper& mapper,
6039                                                   int32_t touchMinor) {
6040     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
6041 }
6042 
processToolMajor(MultiTouchInputMapper & mapper,int32_t toolMajor)6043 void MultiTouchInputMapperTest::processToolMajor(MultiTouchInputMapper& mapper, int32_t toolMajor) {
6044     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
6045 }
6046 
processToolMinor(MultiTouchInputMapper & mapper,int32_t toolMinor)6047 void MultiTouchInputMapperTest::processToolMinor(MultiTouchInputMapper& mapper, int32_t toolMinor) {
6048     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
6049 }
6050 
processOrientation(MultiTouchInputMapper & mapper,int32_t orientation)6051 void MultiTouchInputMapperTest::processOrientation(MultiTouchInputMapper& mapper,
6052                                                    int32_t orientation) {
6053     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
6054 }
6055 
processPressure(MultiTouchInputMapper & mapper,int32_t pressure)6056 void MultiTouchInputMapperTest::processPressure(MultiTouchInputMapper& mapper, int32_t pressure) {
6057     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
6058 }
6059 
processDistance(MultiTouchInputMapper & mapper,int32_t distance)6060 void MultiTouchInputMapperTest::processDistance(MultiTouchInputMapper& mapper, int32_t distance) {
6061     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
6062 }
6063 
processId(MultiTouchInputMapper & mapper,int32_t id)6064 void MultiTouchInputMapperTest::processId(MultiTouchInputMapper& mapper, int32_t id) {
6065     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
6066 }
6067 
processSlot(MultiTouchInputMapper & mapper,int32_t slot)6068 void MultiTouchInputMapperTest::processSlot(MultiTouchInputMapper& mapper, int32_t slot) {
6069     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_SLOT, slot);
6070 }
6071 
processToolType(MultiTouchInputMapper & mapper,int32_t toolType)6072 void MultiTouchInputMapperTest::processToolType(MultiTouchInputMapper& mapper, int32_t toolType) {
6073     process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
6074 }
6075 
processKey(MultiTouchInputMapper & mapper,int32_t code,int32_t value)6076 void MultiTouchInputMapperTest::processKey(MultiTouchInputMapper& mapper, int32_t code,
6077                                            int32_t value) {
6078     process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
6079 }
6080 
processHidUsage(MultiTouchInputMapper & mapper,int32_t usageCode,int32_t value)6081 void MultiTouchInputMapperTest::processHidUsage(MultiTouchInputMapper& mapper, int32_t usageCode,
6082                                                 int32_t value) {
6083     process(mapper, ARBITRARY_TIME, READ_TIME, EV_MSC, MSC_SCAN, usageCode);
6084     process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_UNKNOWN, value);
6085 }
6086 
processMTSync(MultiTouchInputMapper & mapper)6087 void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper& mapper) {
6088     process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_MT_REPORT, 0);
6089 }
6090 
processSync(MultiTouchInputMapper & mapper,nsecs_t eventTime,nsecs_t readTime)6091 void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper& mapper, nsecs_t eventTime,
6092                                             nsecs_t readTime) {
6093     process(mapper, eventTime, readTime, EV_SYN, SYN_REPORT, 0);
6094 }
6095 
TEST_F(MultiTouchInputMapperTest,Process_NormalMultiTouchGesture_WithoutTrackingIds)6096 TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
6097     addConfigurationProperty("touch.deviceType", "touchScreen");
6098     prepareDisplay(ui::ROTATION_0);
6099     prepareAxes(POSITION);
6100     prepareVirtualKeys();
6101     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6102 
6103     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
6104 
6105     NotifyMotionArgs motionArgs;
6106 
6107     // Two fingers down at once.
6108     int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
6109     processPosition(mapper, x1, y1);
6110     processMTSync(mapper);
6111     processPosition(mapper, x2, y2);
6112     processMTSync(mapper);
6113     processSync(mapper);
6114 
6115     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6116     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6117     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6118     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6119     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6120     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6121     ASSERT_EQ(0, motionArgs.flags);
6122     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6123     ASSERT_EQ(0, motionArgs.buttonState);
6124     ASSERT_EQ(0, motionArgs.edgeFlags);
6125     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6126     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6127     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6128     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6129             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6130     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6131     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6132     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6133 
6134     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6135     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6136     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6137     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6138     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6139     ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
6140     ASSERT_EQ(0, motionArgs.flags);
6141     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6142     ASSERT_EQ(0, motionArgs.buttonState);
6143     ASSERT_EQ(0, motionArgs.edgeFlags);
6144     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6145     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6146     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6147     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6148     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6149     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6150             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6151     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6152             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6153     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6154     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6155     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6156 
6157     // Move.
6158     x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
6159     processPosition(mapper, x1, y1);
6160     processMTSync(mapper);
6161     processPosition(mapper, x2, y2);
6162     processMTSync(mapper);
6163     processSync(mapper);
6164 
6165     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6166     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6167     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6168     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6169     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6170     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6171     ASSERT_EQ(0, motionArgs.flags);
6172     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6173     ASSERT_EQ(0, motionArgs.buttonState);
6174     ASSERT_EQ(0, motionArgs.edgeFlags);
6175     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6176     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6177     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6178     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6179     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6180     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6181             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6182     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6183             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6184     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6185     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6186     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6187 
6188     // First finger up.
6189     x2 += 15; y2 -= 20;
6190     processPosition(mapper, x2, y2);
6191     processMTSync(mapper);
6192     processSync(mapper);
6193 
6194     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6195     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6196     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6197     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6198     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6199     ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
6200     ASSERT_EQ(0, motionArgs.flags);
6201     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6202     ASSERT_EQ(0, motionArgs.buttonState);
6203     ASSERT_EQ(0, motionArgs.edgeFlags);
6204     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6205     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6206     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6207     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6208     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6209     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6210             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6211     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6212             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6213     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6214     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6215     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6216 
6217     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6218     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6219     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6220     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6221     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6222     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6223     ASSERT_EQ(0, motionArgs.flags);
6224     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6225     ASSERT_EQ(0, motionArgs.buttonState);
6226     ASSERT_EQ(0, motionArgs.edgeFlags);
6227     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6228     ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6229     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6230     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6231             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6232     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6233     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6234     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6235 
6236     // Move.
6237     x2 += 20; y2 -= 25;
6238     processPosition(mapper, x2, y2);
6239     processMTSync(mapper);
6240     processSync(mapper);
6241 
6242     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6243     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6244     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6245     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6246     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6247     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6248     ASSERT_EQ(0, motionArgs.flags);
6249     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6250     ASSERT_EQ(0, motionArgs.buttonState);
6251     ASSERT_EQ(0, motionArgs.edgeFlags);
6252     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6253     ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6254     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6255     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6256             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6257     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6258     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6259     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6260 
6261     // New finger down.
6262     int32_t x3 = 700, y3 = 300;
6263     processPosition(mapper, x2, y2);
6264     processMTSync(mapper);
6265     processPosition(mapper, x3, y3);
6266     processMTSync(mapper);
6267     processSync(mapper);
6268 
6269     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6270     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6271     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6272     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6273     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6274     ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
6275     ASSERT_EQ(0, motionArgs.flags);
6276     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6277     ASSERT_EQ(0, motionArgs.buttonState);
6278     ASSERT_EQ(0, motionArgs.edgeFlags);
6279     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6280     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6281     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6282     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6283     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6284     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6285             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6286     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6287             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6288     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6289     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6290     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6291 
6292     // Second finger up.
6293     x3 += 30; y3 -= 20;
6294     processPosition(mapper, x3, y3);
6295     processMTSync(mapper);
6296     processSync(mapper);
6297 
6298     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6299     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6300     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6301     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6302     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6303     ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
6304     ASSERT_EQ(0, motionArgs.flags);
6305     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6306     ASSERT_EQ(0, motionArgs.buttonState);
6307     ASSERT_EQ(0, motionArgs.edgeFlags);
6308     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6309     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6310     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6311     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6312     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6313     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6314             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6315     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6316             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6317     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6318     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6319     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6320 
6321     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6322     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6323     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6324     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6325     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6326     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6327     ASSERT_EQ(0, motionArgs.flags);
6328     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6329     ASSERT_EQ(0, motionArgs.buttonState);
6330     ASSERT_EQ(0, motionArgs.edgeFlags);
6331     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6332     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6333     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6334     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6335             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6336     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6337     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6338     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6339 
6340     // Last finger up.
6341     processMTSync(mapper);
6342     processSync(mapper);
6343 
6344     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6345     ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
6346     ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
6347     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
6348     ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
6349     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6350     ASSERT_EQ(0, motionArgs.flags);
6351     ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
6352     ASSERT_EQ(0, motionArgs.buttonState);
6353     ASSERT_EQ(0, motionArgs.edgeFlags);
6354     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6355     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6356     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6357     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6358             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6359     ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
6360     ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
6361     ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
6362 
6363     // Should not have sent any more keys or motions.
6364     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6365     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6366 }
6367 
TEST_F(MultiTouchInputMapperTest,AxisResolution_IsPopulated)6368 TEST_F(MultiTouchInputMapperTest, AxisResolution_IsPopulated) {
6369     addConfigurationProperty("touch.deviceType", "touchScreen");
6370     prepareDisplay(ui::ROTATION_0);
6371 
6372     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
6373                                    /*fuzz*/ 0, /*resolution*/ 10);
6374     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
6375                                    /*fuzz*/ 0, /*resolution*/ 11);
6376     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
6377                                    /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 12);
6378     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_TOUCH_MINOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX,
6379                                    /*flat*/ 0, /*fuzz*/ 0, /*resolution*/ 13);
6380     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
6381                                    /*flat*/ 0, /*flat*/ 0, /*resolution*/ 14);
6382     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_WIDTH_MINOR, RAW_TOOL_MIN, RAW_TOOL_MAX,
6383                                    /*flat*/ 0, /*flat*/ 0, /*resolution*/ 15);
6384 
6385     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6386 
6387     // X and Y axes
6388     assertAxisResolution(mapper, AMOTION_EVENT_AXIS_X, 10 / X_PRECISION);
6389     assertAxisResolution(mapper, AMOTION_EVENT_AXIS_Y, 11 / Y_PRECISION);
6390     // Touch major and minor
6391     assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR, 12 * GEOMETRIC_SCALE);
6392     assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR, 13 * GEOMETRIC_SCALE);
6393     // Tool major and minor
6394     assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR, 14 * GEOMETRIC_SCALE);
6395     assertAxisResolution(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR, 15 * GEOMETRIC_SCALE);
6396 }
6397 
TEST_F(MultiTouchInputMapperTest,TouchMajorAndMinorAxes_DoNotAppearIfNotSupported)6398 TEST_F(MultiTouchInputMapperTest, TouchMajorAndMinorAxes_DoNotAppearIfNotSupported) {
6399     addConfigurationProperty("touch.deviceType", "touchScreen");
6400     prepareDisplay(ui::ROTATION_0);
6401 
6402     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, /*flat*/ 0,
6403                                    /*fuzz*/ 0, /*resolution*/ 10);
6404     mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, /*flat*/ 0,
6405                                    /*fuzz*/ 0, /*resolution*/ 11);
6406 
6407     // We do not add ABS_MT_TOUCH_MAJOR / MINOR or ABS_MT_WIDTH_MAJOR / MINOR axes
6408 
6409     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6410 
6411     // Touch major and minor
6412     assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MAJOR);
6413     assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOUCH_MINOR);
6414     // Tool major and minor
6415     assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MAJOR);
6416     assertAxisNotPresent(mapper, AMOTION_EVENT_AXIS_TOOL_MINOR);
6417 }
6418 
TEST_F(MultiTouchInputMapperTest,Process_NormalMultiTouchGesture_WithTrackingIds)6419 TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
6420     addConfigurationProperty("touch.deviceType", "touchScreen");
6421     prepareDisplay(ui::ROTATION_0);
6422     prepareAxes(POSITION | ID);
6423     prepareVirtualKeys();
6424     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6425 
6426     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
6427 
6428     NotifyMotionArgs motionArgs;
6429 
6430     // Two fingers down at once.
6431     int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
6432     processPosition(mapper, x1, y1);
6433     processId(mapper, 1);
6434     processMTSync(mapper);
6435     processPosition(mapper, x2, y2);
6436     processId(mapper, 2);
6437     processMTSync(mapper);
6438     processSync(mapper);
6439 
6440     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6441     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6442     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6443     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6444     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6445     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6446             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6447 
6448     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6449     ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
6450     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6451     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6452     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6453     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6454     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6455     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6456             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6457     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6458             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6459 
6460     // Move.
6461     x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
6462     processPosition(mapper, x1, y1);
6463     processId(mapper, 1);
6464     processMTSync(mapper);
6465     processPosition(mapper, x2, y2);
6466     processId(mapper, 2);
6467     processMTSync(mapper);
6468     processSync(mapper);
6469 
6470     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6471     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6472     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6473     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6474     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6475     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6476     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6477     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6478             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6479     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6480             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6481 
6482     // First finger up.
6483     x2 += 15; y2 -= 20;
6484     processPosition(mapper, x2, y2);
6485     processId(mapper, 2);
6486     processMTSync(mapper);
6487     processSync(mapper);
6488 
6489     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6490     ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
6491     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6492     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6493     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6494     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6495     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6496     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6497             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6498     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6499             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6500 
6501     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6502     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6503     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6504     ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6505     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6506     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6507             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6508 
6509     // Move.
6510     x2 += 20; y2 -= 25;
6511     processPosition(mapper, x2, y2);
6512     processId(mapper, 2);
6513     processMTSync(mapper);
6514     processSync(mapper);
6515 
6516     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6517     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6518     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6519     ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6520     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6521     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6522             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6523 
6524     // New finger down.
6525     int32_t x3 = 700, y3 = 300;
6526     processPosition(mapper, x2, y2);
6527     processId(mapper, 2);
6528     processMTSync(mapper);
6529     processPosition(mapper, x3, y3);
6530     processId(mapper, 3);
6531     processMTSync(mapper);
6532     processSync(mapper);
6533 
6534     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6535     ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
6536     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6537     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6538     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6539     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6540     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6541     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6542             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6543     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6544             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6545 
6546     // Second finger up.
6547     x3 += 30; y3 -= 20;
6548     processPosition(mapper, x3, y3);
6549     processId(mapper, 3);
6550     processMTSync(mapper);
6551     processSync(mapper);
6552 
6553     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6554     ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
6555     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6556     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6557     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6558     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6559     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6560     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6561             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6562     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6563             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6564 
6565     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6566     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6567     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6568     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6569     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6570     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6571             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6572 
6573     // Last finger up.
6574     processMTSync(mapper);
6575     processSync(mapper);
6576 
6577     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6578     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6579     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6580     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6581     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6582     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6583             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6584 
6585     // Should not have sent any more keys or motions.
6586     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6587     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6588 }
6589 
TEST_F(MultiTouchInputMapperTest,Process_NormalMultiTouchGesture_WithSlots)6590 TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
6591     addConfigurationProperty("touch.deviceType", "touchScreen");
6592     prepareDisplay(ui::ROTATION_0);
6593     prepareAxes(POSITION | ID | SLOT);
6594     prepareVirtualKeys();
6595     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6596 
6597     mReader->getContext()->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
6598 
6599     NotifyMotionArgs motionArgs;
6600 
6601     // Two fingers down at once.
6602     int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
6603     processPosition(mapper, x1, y1);
6604     processId(mapper, 1);
6605     processSlot(mapper, 1);
6606     processPosition(mapper, x2, y2);
6607     processId(mapper, 2);
6608     processSync(mapper);
6609 
6610     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6611     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6612     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6613     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6614     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6615     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6616             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6617 
6618     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6619     ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
6620     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6621     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6622     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6623     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6624     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6625     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6626             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6627     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6628             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6629 
6630     // Move.
6631     x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
6632     processSlot(mapper, 0);
6633     processPosition(mapper, x1, y1);
6634     processSlot(mapper, 1);
6635     processPosition(mapper, x2, y2);
6636     processSync(mapper);
6637 
6638     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6639     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6640     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6641     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6642     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6643     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6644     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6645     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6646             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6647     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6648             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6649 
6650     // First finger up.
6651     x2 += 15; y2 -= 20;
6652     processSlot(mapper, 0);
6653     processId(mapper, -1);
6654     processSlot(mapper, 1);
6655     processPosition(mapper, x2, y2);
6656     processSync(mapper);
6657 
6658     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6659     ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
6660     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6661     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6662     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6663     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6664     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6665     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6666             toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
6667     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6668             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6669 
6670     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6671     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6672     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6673     ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6674     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6675     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6676             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6677 
6678     // Move.
6679     x2 += 20; y2 -= 25;
6680     processPosition(mapper, x2, y2);
6681     processSync(mapper);
6682 
6683     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6684     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6685     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6686     ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
6687     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6688     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6689             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6690 
6691     // New finger down.
6692     int32_t x3 = 700, y3 = 300;
6693     processPosition(mapper, x2, y2);
6694     processSlot(mapper, 0);
6695     processId(mapper, 3);
6696     processPosition(mapper, x3, y3);
6697     processSync(mapper);
6698 
6699     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6700     ASSERT_EQ(ACTION_POINTER_0_DOWN, motionArgs.action);
6701     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6702     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6703     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6704     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6705     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6706     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6707             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6708     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6709             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6710 
6711     // Second finger up.
6712     x3 += 30; y3 -= 20;
6713     processSlot(mapper, 1);
6714     processId(mapper, -1);
6715     processSlot(mapper, 0);
6716     processPosition(mapper, x3, y3);
6717     processSync(mapper);
6718 
6719     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6720     ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
6721     ASSERT_EQ(size_t(2), motionArgs.getPointerCount());
6722     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6723     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6724     ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
6725     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
6726     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6727             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6728     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
6729             toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
6730 
6731     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6732     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6733     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6734     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6735     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6736     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6737             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6738 
6739     // Last finger up.
6740     processId(mapper, -1);
6741     processSync(mapper);
6742 
6743     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6744     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
6745     ASSERT_EQ(size_t(1), motionArgs.getPointerCount());
6746     ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
6747     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
6748     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
6749             toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
6750 
6751     // Should not have sent any more keys or motions.
6752     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
6753     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
6754 }
6755 
TEST_F(MultiTouchInputMapperTest,Process_AllAxes_WithDefaultCalibration)6756 TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
6757     addConfigurationProperty("touch.deviceType", "touchScreen");
6758     prepareDisplay(ui::ROTATION_0);
6759     prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
6760     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6761 
6762     // These calculations are based on the input device calibration documentation.
6763     int32_t rawX = 100;
6764     int32_t rawY = 200;
6765     int32_t rawTouchMajor = 7;
6766     int32_t rawTouchMinor = 6;
6767     int32_t rawToolMajor = 9;
6768     int32_t rawToolMinor = 8;
6769     int32_t rawPressure = 11;
6770     int32_t rawDistance = 0;
6771     int32_t rawOrientation = 3;
6772     int32_t id = 5;
6773 
6774     float x = toDisplayX(rawX);
6775     float y = toDisplayY(rawY);
6776     float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
6777     float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
6778     float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
6779     float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
6780     float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
6781     float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
6782     float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
6783     float distance = float(rawDistance);
6784 
6785     processPosition(mapper, rawX, rawY);
6786     processTouchMajor(mapper, rawTouchMajor);
6787     processTouchMinor(mapper, rawTouchMinor);
6788     processToolMajor(mapper, rawToolMajor);
6789     processToolMinor(mapper, rawToolMinor);
6790     processPressure(mapper, rawPressure);
6791     processOrientation(mapper, rawOrientation);
6792     processDistance(mapper, rawDistance);
6793     processId(mapper, id);
6794     processMTSync(mapper);
6795     processSync(mapper);
6796 
6797     NotifyMotionArgs args;
6798     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6799     ASSERT_EQ(0, args.pointerProperties[0].id);
6800     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6801             x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
6802             orientation, distance));
6803     ASSERT_EQ(args.flags, AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION);
6804 }
6805 
TEST_F(MultiTouchInputMapperTest,Process_TouchAndToolAxes_GeometricCalibration)6806 TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
6807     addConfigurationProperty("touch.deviceType", "touchScreen");
6808     prepareDisplay(ui::ROTATION_0);
6809     prepareAxes(POSITION | TOUCH | TOOL | MINOR);
6810     addConfigurationProperty("touch.size.calibration", "geometric");
6811     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6812 
6813     // These calculations are based on the input device calibration documentation.
6814     int32_t rawX = 100;
6815     int32_t rawY = 200;
6816     int32_t rawTouchMajor = 140;
6817     int32_t rawTouchMinor = 120;
6818     int32_t rawToolMajor = 180;
6819     int32_t rawToolMinor = 160;
6820 
6821     float x = toDisplayX(rawX);
6822     float y = toDisplayY(rawY);
6823     float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
6824     float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
6825     float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
6826     float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
6827     float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
6828 
6829     processPosition(mapper, rawX, rawY);
6830     processTouchMajor(mapper, rawTouchMajor);
6831     processTouchMinor(mapper, rawTouchMinor);
6832     processToolMajor(mapper, rawToolMajor);
6833     processToolMinor(mapper, rawToolMinor);
6834     processMTSync(mapper);
6835     processSync(mapper);
6836 
6837     NotifyMotionArgs args;
6838     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6839     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6840             x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
6841 }
6842 
TEST_F(MultiTouchInputMapperTest,Process_TouchAndToolAxes_SummedLinearCalibration)6843 TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
6844     addConfigurationProperty("touch.deviceType", "touchScreen");
6845     prepareDisplay(ui::ROTATION_0);
6846     prepareAxes(POSITION | TOUCH | TOOL);
6847     addConfigurationProperty("touch.size.calibration", "diameter");
6848     addConfigurationProperty("touch.size.scale", "10");
6849     addConfigurationProperty("touch.size.bias", "160");
6850     addConfigurationProperty("touch.size.isSummed", "1");
6851     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6852 
6853     // These calculations are based on the input device calibration documentation.
6854     // Note: We only provide a single common touch/tool value because the device is assumed
6855     //       not to emit separate values for each pointer (isSummed = 1).
6856     int32_t rawX = 100;
6857     int32_t rawY = 200;
6858     int32_t rawX2 = 150;
6859     int32_t rawY2 = 250;
6860     int32_t rawTouchMajor = 5;
6861     int32_t rawToolMajor = 8;
6862 
6863     float x = toDisplayX(rawX);
6864     float y = toDisplayY(rawY);
6865     float x2 = toDisplayX(rawX2);
6866     float y2 = toDisplayY(rawY2);
6867     float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
6868     float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
6869     float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
6870 
6871     processPosition(mapper, rawX, rawY);
6872     processTouchMajor(mapper, rawTouchMajor);
6873     processToolMajor(mapper, rawToolMajor);
6874     processMTSync(mapper);
6875     processPosition(mapper, rawX2, rawY2);
6876     processTouchMajor(mapper, rawTouchMajor);
6877     processToolMajor(mapper, rawToolMajor);
6878     processMTSync(mapper);
6879     processSync(mapper);
6880 
6881     NotifyMotionArgs args;
6882     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6883     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
6884 
6885     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6886     ASSERT_EQ(ACTION_POINTER_1_DOWN, args.action);
6887     ASSERT_EQ(size_t(2), args.getPointerCount());
6888     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6889             x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
6890     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
6891             x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
6892 }
6893 
TEST_F(MultiTouchInputMapperTest,Process_TouchAndToolAxes_AreaCalibration)6894 TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
6895     addConfigurationProperty("touch.deviceType", "touchScreen");
6896     prepareDisplay(ui::ROTATION_0);
6897     prepareAxes(POSITION | TOUCH | TOOL);
6898     addConfigurationProperty("touch.size.calibration", "area");
6899     addConfigurationProperty("touch.size.scale", "43");
6900     addConfigurationProperty("touch.size.bias", "3");
6901     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6902 
6903     // These calculations are based on the input device calibration documentation.
6904     int32_t rawX = 100;
6905     int32_t rawY = 200;
6906     int32_t rawTouchMajor = 5;
6907     int32_t rawToolMajor = 8;
6908 
6909     float x = toDisplayX(rawX);
6910     float y = toDisplayY(rawY);
6911     float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
6912     float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
6913     float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
6914 
6915     processPosition(mapper, rawX, rawY);
6916     processTouchMajor(mapper, rawTouchMajor);
6917     processToolMajor(mapper, rawToolMajor);
6918     processMTSync(mapper);
6919     processSync(mapper);
6920 
6921     NotifyMotionArgs args;
6922     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6923     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6924             x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
6925 }
6926 
TEST_F(MultiTouchInputMapperTest,Process_PressureAxis_AmplitudeCalibration)6927 TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
6928     addConfigurationProperty("touch.deviceType", "touchScreen");
6929     prepareDisplay(ui::ROTATION_0);
6930     prepareAxes(POSITION | PRESSURE);
6931     addConfigurationProperty("touch.pressure.calibration", "amplitude");
6932     addConfigurationProperty("touch.pressure.scale", "0.01");
6933     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6934 
6935     InputDeviceInfo info;
6936     mapper.populateDeviceInfo(info);
6937     ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
6938             AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TOUCHSCREEN,
6939             0.0f, RAW_PRESSURE_MAX * 0.01, 0.0f, 0.0f));
6940 
6941     // These calculations are based on the input device calibration documentation.
6942     int32_t rawX = 100;
6943     int32_t rawY = 200;
6944     int32_t rawPressure = 60;
6945 
6946     float x = toDisplayX(rawX);
6947     float y = toDisplayY(rawY);
6948     float pressure = float(rawPressure) * 0.01f;
6949 
6950     processPosition(mapper, rawX, rawY);
6951     processPressure(mapper, rawPressure);
6952     processMTSync(mapper);
6953     processSync(mapper);
6954 
6955     NotifyMotionArgs args;
6956     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
6957     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
6958             x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
6959 }
6960 
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandleAllButtons)6961 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
6962     addConfigurationProperty("touch.deviceType", "touchScreen");
6963     prepareDisplay(ui::ROTATION_0);
6964     prepareAxes(POSITION | ID | SLOT);
6965     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
6966 
6967     NotifyMotionArgs motionArgs;
6968     NotifyKeyArgs keyArgs;
6969 
6970     processId(mapper, 1);
6971     processPosition(mapper, 100, 200);
6972     processSync(mapper);
6973     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6974     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
6975     ASSERT_EQ(0, motionArgs.buttonState);
6976 
6977     // press BTN_LEFT, release BTN_LEFT
6978     processKey(mapper, BTN_LEFT, 1);
6979     processSync(mapper);
6980     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6981     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6982     ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6983 
6984     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6985     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
6986     ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
6987 
6988     processKey(mapper, BTN_LEFT, 0);
6989     processSync(mapper);
6990     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6991     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
6992     ASSERT_EQ(0, motionArgs.buttonState);
6993 
6994     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
6995     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
6996     ASSERT_EQ(0, motionArgs.buttonState);
6997 
6998     // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
6999     processKey(mapper, BTN_RIGHT, 1);
7000     processKey(mapper, BTN_MIDDLE, 1);
7001     processSync(mapper);
7002     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7003     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7004     ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
7005             motionArgs.buttonState);
7006 
7007     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7008     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7009     ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
7010 
7011     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7012     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7013     ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
7014             motionArgs.buttonState);
7015 
7016     processKey(mapper, BTN_RIGHT, 0);
7017     processSync(mapper);
7018     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7019     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7020     ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
7021 
7022     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7023     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7024     ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
7025 
7026     processKey(mapper, BTN_MIDDLE, 0);
7027     processSync(mapper);
7028     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7029     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7030     ASSERT_EQ(0, motionArgs.buttonState);
7031 
7032     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7033     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7034     ASSERT_EQ(0, motionArgs.buttonState);
7035 
7036     // press BTN_BACK, release BTN_BACK
7037     processKey(mapper, BTN_BACK, 1);
7038     processSync(mapper);
7039     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7040     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7041     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
7042 
7043     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7044     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7045     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
7046 
7047     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7048     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7049     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
7050 
7051     processKey(mapper, BTN_BACK, 0);
7052     processSync(mapper);
7053     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7054     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7055     ASSERT_EQ(0, motionArgs.buttonState);
7056 
7057     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7058     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7059     ASSERT_EQ(0, motionArgs.buttonState);
7060 
7061     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7062     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7063     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
7064 
7065     // press BTN_SIDE, release BTN_SIDE
7066     processKey(mapper, BTN_SIDE, 1);
7067     processSync(mapper);
7068     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7069     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7070     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
7071 
7072     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7073     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7074     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
7075 
7076     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7077     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7078     ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
7079 
7080     processKey(mapper, BTN_SIDE, 0);
7081     processSync(mapper);
7082     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7083     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7084     ASSERT_EQ(0, motionArgs.buttonState);
7085 
7086     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7087     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7088     ASSERT_EQ(0, motionArgs.buttonState);
7089 
7090     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7091     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7092     ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
7093 
7094     // press BTN_FORWARD, release BTN_FORWARD
7095     processKey(mapper, BTN_FORWARD, 1);
7096     processSync(mapper);
7097     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7098     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7099     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7100 
7101     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7102     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7103     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
7104 
7105     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7106     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7107     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
7108 
7109     processKey(mapper, BTN_FORWARD, 0);
7110     processSync(mapper);
7111     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7112     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7113     ASSERT_EQ(0, motionArgs.buttonState);
7114 
7115     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7116     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7117     ASSERT_EQ(0, motionArgs.buttonState);
7118 
7119     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7120     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7121     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7122 
7123     // press BTN_EXTRA, release BTN_EXTRA
7124     processKey(mapper, BTN_EXTRA, 1);
7125     processSync(mapper);
7126     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7127     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
7128     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7129 
7130     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7131     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7132     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
7133 
7134     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7135     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7136     ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
7137 
7138     processKey(mapper, BTN_EXTRA, 0);
7139     processSync(mapper);
7140     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7141     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7142     ASSERT_EQ(0, motionArgs.buttonState);
7143 
7144     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7145     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7146     ASSERT_EQ(0, motionArgs.buttonState);
7147 
7148     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
7149     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
7150     ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
7151 
7152     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
7153 
7154     // press BTN_STYLUS, release BTN_STYLUS
7155     processKey(mapper, BTN_STYLUS, 1);
7156     processSync(mapper);
7157     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7158     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7159     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
7160 
7161     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7162     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7163     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY, motionArgs.buttonState);
7164 
7165     processKey(mapper, BTN_STYLUS, 0);
7166     processSync(mapper);
7167     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7168     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7169     ASSERT_EQ(0, motionArgs.buttonState);
7170 
7171     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7172     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7173     ASSERT_EQ(0, motionArgs.buttonState);
7174 
7175     // press BTN_STYLUS2, release BTN_STYLUS2
7176     processKey(mapper, BTN_STYLUS2, 1);
7177     processSync(mapper);
7178     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7179     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7180     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
7181 
7182     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7183     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, motionArgs.action);
7184     ASSERT_EQ(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY, motionArgs.buttonState);
7185 
7186     processKey(mapper, BTN_STYLUS2, 0);
7187     processSync(mapper);
7188     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7189     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
7190     ASSERT_EQ(0, motionArgs.buttonState);
7191 
7192     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7193     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7194     ASSERT_EQ(0, motionArgs.buttonState);
7195 
7196     // release touch
7197     processId(mapper, -1);
7198     processSync(mapper);
7199     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7200     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7201     ASSERT_EQ(0, motionArgs.buttonState);
7202 }
7203 
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandleMappedStylusButtons)7204 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleMappedStylusButtons) {
7205     addConfigurationProperty("touch.deviceType", "touchScreen");
7206     prepareDisplay(ui::ROTATION_0);
7207     prepareAxes(POSITION | ID | SLOT);
7208     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7209 
7210     mFakeEventHub->addKey(EVENTHUB_ID, BTN_A, 0, AKEYCODE_STYLUS_BUTTON_PRIMARY, 0);
7211     mFakeEventHub->addKey(EVENTHUB_ID, 0, 0xabcd, AKEYCODE_STYLUS_BUTTON_SECONDARY, 0);
7212 
7213     // Touch down.
7214     processId(mapper, 1);
7215     processPosition(mapper, 100, 200);
7216     processSync(mapper);
7217     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7218             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithButtonState(0))));
7219 
7220     // Press and release button mapped to the primary stylus button.
7221     processKey(mapper, BTN_A, 1);
7222     processSync(mapper);
7223     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7224             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7225                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7226     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7227             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7228                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_PRIMARY))));
7229 
7230     processKey(mapper, BTN_A, 0);
7231     processSync(mapper);
7232     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7233             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
7234     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7235             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
7236 
7237     // Press and release the HID usage mapped to the secondary stylus button.
7238     processHidUsage(mapper, 0xabcd, 1);
7239     processSync(mapper);
7240     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7241             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
7242                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
7243     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7244             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS),
7245                   WithButtonState(AMOTION_EVENT_BUTTON_STYLUS_SECONDARY))));
7246 
7247     processHidUsage(mapper, 0xabcd, 0);
7248     processSync(mapper);
7249     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7250             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_RELEASE), WithButtonState(0))));
7251     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7252             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithButtonState(0))));
7253 
7254     // Release touch.
7255     processId(mapper, -1);
7256     processSync(mapper);
7257     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7258             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithButtonState(0))));
7259 }
7260 
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandleAllToolTypes)7261 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
7262     addConfigurationProperty("touch.deviceType", "touchScreen");
7263     prepareDisplay(ui::ROTATION_0);
7264     prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
7265     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7266 
7267     NotifyMotionArgs motionArgs;
7268 
7269     // Hold down the mouse button for the duration of the test, since the mouse tools require
7270     // the button to be pressed to make sure they are not hovering.
7271     processKey(mapper, BTN_MOUSE, 1);
7272 
7273     // default tool type is finger
7274     processId(mapper, 1);
7275     processPosition(mapper, 100, 200);
7276     processSync(mapper);
7277     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7278     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7279     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
7280 
7281     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7282             WithMotionAction(AMOTION_EVENT_ACTION_BUTTON_PRESS)));
7283 
7284     // eraser
7285     processKey(mapper, BTN_TOOL_RUBBER, 1);
7286     processSync(mapper);
7287     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7288     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7289     ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
7290 
7291     // stylus
7292     processKey(mapper, BTN_TOOL_RUBBER, 0);
7293     processKey(mapper, BTN_TOOL_PEN, 1);
7294     processSync(mapper);
7295     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7296     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7297     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
7298 
7299     // brush
7300     processKey(mapper, BTN_TOOL_PEN, 0);
7301     processKey(mapper, BTN_TOOL_BRUSH, 1);
7302     processSync(mapper);
7303     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7304     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7305     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
7306 
7307     // pencil
7308     processKey(mapper, BTN_TOOL_BRUSH, 0);
7309     processKey(mapper, BTN_TOOL_PENCIL, 1);
7310     processSync(mapper);
7311     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7312     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7313     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
7314 
7315     // air-brush
7316     processKey(mapper, BTN_TOOL_PENCIL, 0);
7317     processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
7318     processSync(mapper);
7319     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7320     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7321     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
7322 
7323     // mouse
7324     processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
7325     processKey(mapper, BTN_TOOL_MOUSE, 1);
7326     processSync(mapper);
7327     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7328     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7329     ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
7330 
7331     // lens
7332     processKey(mapper, BTN_TOOL_MOUSE, 0);
7333     processKey(mapper, BTN_TOOL_LENS, 1);
7334     processSync(mapper);
7335     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7336     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7337     ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
7338 
7339     // double-tap
7340     processKey(mapper, BTN_TOOL_LENS, 0);
7341     processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
7342     processSync(mapper);
7343     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7344     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7345     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
7346 
7347     // triple-tap
7348     processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
7349     processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
7350     processSync(mapper);
7351     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7352     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7353     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
7354 
7355     // quad-tap
7356     processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
7357     processKey(mapper, BTN_TOOL_QUADTAP, 1);
7358     processSync(mapper);
7359     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7360     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7361     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
7362 
7363     // finger
7364     processKey(mapper, BTN_TOOL_QUADTAP, 0);
7365     processKey(mapper, BTN_TOOL_FINGER, 1);
7366     processSync(mapper);
7367     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7368     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7369     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
7370 
7371     // stylus trumps finger
7372     processKey(mapper, BTN_TOOL_PEN, 1);
7373     processSync(mapper);
7374     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7375     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7376     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
7377 
7378     // eraser trumps stylus
7379     processKey(mapper, BTN_TOOL_RUBBER, 1);
7380     processSync(mapper);
7381     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7382     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7383     ASSERT_EQ(ToolType::ERASER, motionArgs.pointerProperties[0].toolType);
7384 
7385     // mouse trumps eraser
7386     processKey(mapper, BTN_TOOL_MOUSE, 1);
7387     processSync(mapper);
7388     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7389     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7390     ASSERT_EQ(ToolType::MOUSE, motionArgs.pointerProperties[0].toolType);
7391 
7392     // MT tool type trumps BTN tool types: MT_TOOL_FINGER
7393     processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
7394     processSync(mapper);
7395     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7396     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7397     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
7398 
7399     // MT tool type trumps BTN tool types: MT_TOOL_PEN
7400     processToolType(mapper, MT_TOOL_PEN);
7401     processSync(mapper);
7402     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7403     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7404     ASSERT_EQ(ToolType::STYLUS, motionArgs.pointerProperties[0].toolType);
7405 
7406     // back to default tool type
7407     processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
7408     processKey(mapper, BTN_TOOL_MOUSE, 0);
7409     processKey(mapper, BTN_TOOL_RUBBER, 0);
7410     processKey(mapper, BTN_TOOL_PEN, 0);
7411     processKey(mapper, BTN_TOOL_FINGER, 0);
7412     processSync(mapper);
7413     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7414     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
7415     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
7416 }
7417 
TEST_F(MultiTouchInputMapperTest,Process_WhenBtnTouchPresent_HoversIfItsValueIsZero)7418 TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
7419     addConfigurationProperty("touch.deviceType", "touchScreen");
7420     prepareDisplay(ui::ROTATION_0);
7421     prepareAxes(POSITION | ID | SLOT);
7422     mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
7423     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7424 
7425     NotifyMotionArgs motionArgs;
7426 
7427     // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
7428     processId(mapper, 1);
7429     processPosition(mapper, 100, 200);
7430     processSync(mapper);
7431     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7432     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7433     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7434             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7435 
7436     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7437     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7438     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7439             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7440 
7441     // move a little
7442     processPosition(mapper, 150, 250);
7443     processSync(mapper);
7444     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7445     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7446     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7447             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7448 
7449     // down when BTN_TOUCH is pressed, pressure defaults to 1
7450     processPosition(mapper, 151, 251);
7451     processKey(mapper, BTN_TOUCH, 1);
7452     processSync(mapper);
7453     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7454     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7455     // HOVER_EXIT should have the same coordinates as the previous HOVER_MOVE
7456     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7457             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7458     // down at the new position
7459     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7460     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7461     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7462             toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0));
7463 
7464     // up when BTN_TOUCH is released, hover restored
7465     processPosition(mapper, 152, 252);
7466     processKey(mapper, BTN_TOUCH, 0);
7467     processSync(mapper);
7468     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7469     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7470     // UP should have the same coordinates as the previous event
7471     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7472             toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0));
7473     // HOVER_ENTER at the new position
7474     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7475     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7476     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7477             toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0));
7478 
7479     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7480     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7481     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7482             toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0));
7483 
7484     // exit hover when pointer goes away
7485     processId(mapper, -1);
7486     processSync(mapper);
7487     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7488     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7489     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7490             toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0));
7491 }
7492 
TEST_F(MultiTouchInputMapperTest,Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero)7493 TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
7494     addConfigurationProperty("touch.deviceType", "touchScreen");
7495     prepareDisplay(ui::ROTATION_0);
7496     prepareAxes(POSITION | ID | SLOT | PRESSURE);
7497     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7498 
7499     NotifyMotionArgs motionArgs;
7500 
7501     // initially hovering because pressure is 0
7502     processId(mapper, 1);
7503     processPosition(mapper, 100, 200);
7504     processPressure(mapper, 0);
7505     processSync(mapper);
7506     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7507     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7508     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7509             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7510 
7511     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7512     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7513     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7514             toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
7515 
7516     // move a little
7517     processPosition(mapper, 150, 250);
7518     processSync(mapper);
7519     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7520     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7521     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7522             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7523 
7524     // down when pressure becomes non-zero
7525     processPosition(mapper, 151, 251);
7526     processPressure(mapper, RAW_PRESSURE_MAX);
7527     processSync(mapper);
7528     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7529     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7530     // HOVER_EXIT should have the same coordinates as the previous HOVER_MOVE
7531     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7532             toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
7533     // down at the new position
7534     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7535     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7536     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7537             toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0));
7538 
7539     // up when pressure becomes 0, hover restored
7540     processPosition(mapper, 152, 252);
7541     processPressure(mapper, 0);
7542     processSync(mapper);
7543     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7544     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
7545     // UP should have the same coordinates as the previous event
7546     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7547             toDisplayX(151), toDisplayY(251), 1, 0, 0, 0, 0, 0, 0, 0));
7548     // HOVER_ENTER at the new position
7549     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7550     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
7551     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7552             toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0));
7553 
7554     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7555     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
7556     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7557             toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0));
7558 
7559     // exit hover when pointer goes away
7560     processId(mapper, -1);
7561     processSync(mapper);
7562     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7563     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
7564     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
7565             toDisplayX(152), toDisplayY(252), 0, 0, 0, 0, 0, 0, 0, 0));
7566 }
7567 
7568 /**
7569  * Set the input device port <--> display port associations, and check that the
7570  * events are routed to the display that matches the display port.
7571  * This can be checked by looking at the displayId of the resulting NotifyMotionArgs.
7572  */
TEST_F(MultiTouchInputMapperTest,Configure_AssignsDisplayPort)7573 TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayPort) {
7574     const std::string usb2 = "USB2";
7575     const uint8_t hdmi1 = 0;
7576     const uint8_t hdmi2 = 1;
7577     const std::string secondaryUniqueId = "uniqueId2";
7578     constexpr ViewportType type = ViewportType::EXTERNAL;
7579 
7580     addConfigurationProperty("touch.deviceType", "touchScreen");
7581     prepareAxes(POSITION);
7582     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7583 
7584     mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
7585     mFakePolicy->addInputPortAssociation(usb2, hdmi2);
7586 
7587     // We are intentionally not adding the viewport for display 1 yet. Since the port association
7588     // for this input device is specified, and the matching viewport is not present,
7589     // the input device should be disabled (at the mapper level).
7590 
7591     // Add viewport for display 2 on hdmi2
7592     prepareSecondaryDisplay(type, hdmi2);
7593     // Send a touch event
7594     processPosition(mapper, 100, 100);
7595     processSync(mapper);
7596     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7597 
7598     // Add viewport for display 1 on hdmi1
7599     prepareDisplay(ui::ROTATION_0, hdmi1);
7600     // Send a touch event again
7601     processPosition(mapper, 100, 100);
7602     processSync(mapper);
7603 
7604     NotifyMotionArgs args;
7605     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7606     ASSERT_EQ(DISPLAY_ID, args.displayId);
7607 }
7608 
TEST_F(MultiTouchInputMapperTest,Configure_AssignsDisplayUniqueId)7609 TEST_F(MultiTouchInputMapperTest, Configure_AssignsDisplayUniqueId) {
7610     addConfigurationProperty("touch.deviceType", "touchScreen");
7611     prepareAxes(POSITION);
7612     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7613 
7614     mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
7615 
7616     prepareDisplay(ui::ROTATION_0);
7617     prepareVirtualDisplay(ui::ROTATION_0);
7618 
7619     // Send a touch event
7620     processPosition(mapper, 100, 100);
7621     processSync(mapper);
7622 
7623     NotifyMotionArgs args;
7624     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7625     ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
7626 }
7627 
TEST_F(MultiTouchInputMapperTest,Process_Pointer_ShouldHandleDisplayId)7628 TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShouldHandleDisplayId) {
7629     SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, true);
7630     prepareSecondaryDisplay(ViewportType::EXTERNAL);
7631 
7632     prepareDisplay(ui::ROTATION_0);
7633     prepareAxes(POSITION);
7634     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7635 
7636     ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
7637 
7638     NotifyMotionArgs motionArgs;
7639     processPosition(mapper, 100, 100);
7640     processSync(mapper);
7641 
7642     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7643             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithDisplayId(DISPLAY_ID),
7644                   WithSource(AINPUT_SOURCE_MOUSE), WithToolType(ToolType::FINGER))));
7645 }
7646 
7647 /**
7648  * Ensure that the readTime is set to the SYN_REPORT value when processing touch events.
7649  */
TEST_F(MultiTouchInputMapperTest,Process_SendsReadTime)7650 TEST_F(MultiTouchInputMapperTest, Process_SendsReadTime) {
7651     addConfigurationProperty("touch.deviceType", "touchScreen");
7652     prepareAxes(POSITION);
7653     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7654 
7655     prepareDisplay(ui::ROTATION_0);
7656     process(mapper, 10, /*readTime=*/11, EV_ABS, ABS_MT_TRACKING_ID, 1);
7657     process(mapper, 15, /*readTime=*/16, EV_ABS, ABS_MT_POSITION_X, 100);
7658     process(mapper, 20, /*readTime=*/21, EV_ABS, ABS_MT_POSITION_Y, 100);
7659     process(mapper, 25, /*readTime=*/26, EV_SYN, SYN_REPORT, 0);
7660 
7661     NotifyMotionArgs args;
7662     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7663     ASSERT_EQ(26, args.readTime);
7664 
7665     process(mapper, 30, /*readTime=*/31, EV_ABS, ABS_MT_POSITION_X, 110);
7666     process(mapper, 30, /*readTime=*/32, EV_ABS, ABS_MT_POSITION_Y, 220);
7667     process(mapper, 30, /*readTime=*/33, EV_SYN, SYN_REPORT, 0);
7668 
7669     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7670     ASSERT_EQ(33, args.readTime);
7671 }
7672 
7673 /**
7674  * When the viewport is not active (isActive=false), the touch mapper should be disabled and the
7675  * events should not be delivered to the listener.
7676  */
TEST_F(MultiTouchInputMapperTest,WhenViewportIsNotActive_TouchesAreDropped)7677 TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreDropped) {
7678     addConfigurationProperty("touch.deviceType", "touchScreen");
7679     // Don't set touch.enableForInactiveViewport to verify the default behavior.
7680     DisplayViewport viewport =
7681             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
7682                            /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
7683     mFakePolicy->addDisplayViewport(viewport);
7684     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7685     prepareAxes(POSITION);
7686     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7687 
7688     NotifyMotionArgs motionArgs;
7689     processPosition(mapper, 100, 100);
7690     processSync(mapper);
7691 
7692     mFakeListener->assertNotifyMotionWasNotCalled();
7693 }
7694 
7695 /**
7696  * When the viewport is not active (isActive=false) and touch.enableForInactiveViewport is true,
7697  * the touch mapper can process the events and the events can be delivered to the listener.
7698  */
TEST_F(MultiTouchInputMapperTest,WhenViewportIsNotActive_TouchesAreProcessed)7699 TEST_F(MultiTouchInputMapperTest, WhenViewportIsNotActive_TouchesAreProcessed) {
7700     addConfigurationProperty("touch.deviceType", "touchScreen");
7701     addConfigurationProperty("touch.enableForInactiveViewport", "1");
7702     DisplayViewport viewport =
7703             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
7704                            /*isActive=*/false, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
7705     mFakePolicy->addDisplayViewport(viewport);
7706     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7707     prepareAxes(POSITION);
7708     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7709 
7710     NotifyMotionArgs motionArgs;
7711     processPosition(mapper, 100, 100);
7712     processSync(mapper);
7713 
7714     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7715     EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7716 }
7717 
7718 /**
7719  * When the viewport is deactivated (isActive transitions from true to false),
7720  * and touch.enableForInactiveViewport is false, touches prior to the transition
7721  * should be cancelled.
7722  */
TEST_F(MultiTouchInputMapperTest,Process_DeactivateViewport_AbortTouches)7723 TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_AbortTouches) {
7724     addConfigurationProperty("touch.deviceType", "touchScreen");
7725     addConfigurationProperty("touch.enableForInactiveViewport", "0");
7726     DisplayViewport viewport =
7727             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
7728                            /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
7729     mFakePolicy->addDisplayViewport(viewport);
7730     std::optional<DisplayViewport> optionalDisplayViewport =
7731             mFakePolicy->getDisplayViewportByUniqueId(UNIQUE_ID);
7732     ASSERT_TRUE(optionalDisplayViewport.has_value());
7733     DisplayViewport displayViewport = *optionalDisplayViewport;
7734 
7735     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7736     prepareAxes(POSITION);
7737     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7738 
7739     // Finger down
7740     int32_t x = 100, y = 100;
7741     processPosition(mapper, x, y);
7742     processSync(mapper);
7743 
7744     NotifyMotionArgs motionArgs;
7745     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7746     EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7747 
7748     // Deactivate display viewport
7749     displayViewport.isActive = false;
7750     ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
7751     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7752 
7753     // The ongoing touch should be canceled immediately
7754     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7755     EXPECT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
7756 
7757     // Finger move is ignored
7758     x += 10, y += 10;
7759     processPosition(mapper, x, y);
7760     processSync(mapper);
7761     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7762 
7763     // Reactivate display viewport
7764     displayViewport.isActive = true;
7765     ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
7766     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7767 
7768     // Finger move again starts new gesture
7769     x += 10, y += 10;
7770     processPosition(mapper, x, y);
7771     processSync(mapper);
7772     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7773     EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
7774 }
7775 
7776 /**
7777  * When the viewport is deactivated (isActive transitions from true to false),
7778  * and touch.enableForInactiveViewport is true, touches prior to the transition
7779  * should not be cancelled.
7780  */
TEST_F(MultiTouchInputMapperTest,Process_DeactivateViewport_TouchesNotAborted)7781 TEST_F(MultiTouchInputMapperTest, Process_DeactivateViewport_TouchesNotAborted) {
7782     addConfigurationProperty("touch.deviceType", "touchScreen");
7783     addConfigurationProperty("touch.enableForInactiveViewport", "1");
7784     DisplayViewport displayViewport =
7785             createViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
7786                            /*isActive=*/true, UNIQUE_ID, NO_PORT, ViewportType::INTERNAL);
7787     mFakePolicy->addDisplayViewport(displayViewport);
7788 
7789     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7790     prepareAxes(POSITION);
7791     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7792 
7793     // Finger down
7794     int32_t x = 100, y = 100;
7795     processPosition(mapper, x, y);
7796     processSync(mapper);
7797     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7798             WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
7799 
7800     // Deactivate display viewport
7801     displayViewport.isActive = false;
7802     ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
7803     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7804 
7805     // The ongoing touch should not be canceled
7806     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
7807 
7808     // Finger move is not ignored
7809     x += 10, y += 10;
7810     processPosition(mapper, x, y);
7811     processSync(mapper);
7812     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7813             WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
7814 
7815     // Reactivate display viewport
7816     displayViewport.isActive = true;
7817     ASSERT_TRUE(mFakePolicy->updateViewport(displayViewport));
7818     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
7819 
7820     // Finger move continues and does not start new gesture
7821     x += 10, y += 10;
7822     processPosition(mapper, x, y);
7823     processSync(mapper);
7824     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
7825             WithMotionAction(AMOTION_EVENT_ACTION_MOVE)));
7826 }
7827 
TEST_F(MultiTouchInputMapperTest,VideoFrames_ReceivedByListener)7828 TEST_F(MultiTouchInputMapperTest, VideoFrames_ReceivedByListener) {
7829     prepareAxes(POSITION);
7830     addConfigurationProperty("touch.deviceType", "touchScreen");
7831     prepareDisplay(ui::ROTATION_0);
7832     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7833 
7834     NotifyMotionArgs motionArgs;
7835     // Unrotated video frame
7836     TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
7837     std::vector<TouchVideoFrame> frames{frame};
7838     mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
7839     processPosition(mapper, 100, 200);
7840     processSync(mapper);
7841     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7842     ASSERT_EQ(frames, motionArgs.videoFrames);
7843 
7844     // Subsequent touch events should not have any videoframes
7845     // This is implemented separately in FakeEventHub,
7846     // but that should match the behaviour of TouchVideoDevice.
7847     processPosition(mapper, 200, 200);
7848     processSync(mapper);
7849     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7850     ASSERT_EQ(std::vector<TouchVideoFrame>(), motionArgs.videoFrames);
7851 }
7852 
TEST_F(MultiTouchInputMapperTest,VideoFrames_AreNotRotated)7853 TEST_F(MultiTouchInputMapperTest, VideoFrames_AreNotRotated) {
7854     prepareAxes(POSITION);
7855     addConfigurationProperty("touch.deviceType", "touchScreen");
7856     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7857     // Unrotated video frame
7858     TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
7859     NotifyMotionArgs motionArgs;
7860 
7861     // Test all 4 orientations
7862     for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
7863         SCOPED_TRACE(StringPrintf("Orientation %s", ftl::enum_string(orientation).c_str()));
7864         clearViewports();
7865         prepareDisplay(orientation);
7866         std::vector<TouchVideoFrame> frames{frame};
7867         mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
7868         processPosition(mapper, 100, 200);
7869         processSync(mapper);
7870         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7871         ASSERT_EQ(frames, motionArgs.videoFrames);
7872     }
7873 }
7874 
TEST_F(MultiTouchInputMapperTest,VideoFrames_WhenNotOrientationAware_AreRotated)7875 TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_AreRotated) {
7876     prepareAxes(POSITION);
7877     addConfigurationProperty("touch.deviceType", "touchScreen");
7878     // Since InputReader works in the un-rotated coordinate space, only devices that are not
7879     // orientation-aware are affected by display rotation.
7880     addConfigurationProperty("touch.orientationAware", "0");
7881     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7882     // Unrotated video frame
7883     TouchVideoFrame frame(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
7884     NotifyMotionArgs motionArgs;
7885 
7886     // Test all 4 orientations
7887     for (ui::Rotation orientation : ftl::enum_range<ui::Rotation>()) {
7888         SCOPED_TRACE(StringPrintf("Orientation %s", ftl::enum_string(orientation).c_str()));
7889         clearViewports();
7890         prepareDisplay(orientation);
7891         std::vector<TouchVideoFrame> frames{frame};
7892         mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
7893         processPosition(mapper, 100, 200);
7894         processSync(mapper);
7895         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7896         // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
7897         // compared to the display. This is so that when the window transform (which contains the
7898         // display rotation) is applied later by InputDispatcher, the coordinates end up in the
7899         // window's coordinate space.
7900         frames[0].rotate(getInverseRotation(orientation));
7901         ASSERT_EQ(frames, motionArgs.videoFrames);
7902 
7903         // Release finger.
7904         processSync(mapper);
7905         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7906     }
7907 }
7908 
TEST_F(MultiTouchInputMapperTest,VideoFrames_MultipleFramesAreNotRotated)7909 TEST_F(MultiTouchInputMapperTest, VideoFrames_MultipleFramesAreNotRotated) {
7910     prepareAxes(POSITION);
7911     addConfigurationProperty("touch.deviceType", "touchScreen");
7912     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7913     // Unrotated video frames. There's no rule that they must all have the same dimensions,
7914     // so mix these.
7915     TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
7916     TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
7917     TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
7918     std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
7919     NotifyMotionArgs motionArgs;
7920 
7921     prepareDisplay(ui::ROTATION_90);
7922     mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
7923     processPosition(mapper, 100, 200);
7924     processSync(mapper);
7925     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7926     ASSERT_EQ(frames, motionArgs.videoFrames);
7927 }
7928 
TEST_F(MultiTouchInputMapperTest,VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated)7929 TEST_F(MultiTouchInputMapperTest, VideoFrames_WhenNotOrientationAware_MultipleFramesAreRotated) {
7930     prepareAxes(POSITION);
7931     addConfigurationProperty("touch.deviceType", "touchScreen");
7932     // Since InputReader works in the un-rotated coordinate space, only devices that are not
7933     // orientation-aware are affected by display rotation.
7934     addConfigurationProperty("touch.orientationAware", "0");
7935     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7936     // Unrotated video frames. There's no rule that they must all have the same dimensions,
7937     // so mix these.
7938     TouchVideoFrame frame1(3, 2, {1, 2, 3, 4, 5, 6}, {1, 2});
7939     TouchVideoFrame frame2(3, 3, {0, 1, 2, 3, 4, 5, 6, 7, 8}, {1, 3});
7940     TouchVideoFrame frame3(2, 2, {10, 20, 10, 0}, {1, 4});
7941     std::vector<TouchVideoFrame> frames{frame1, frame2, frame3};
7942     NotifyMotionArgs motionArgs;
7943 
7944     prepareDisplay(ui::ROTATION_90);
7945     mFakeEventHub->setVideoFrames({{EVENTHUB_ID, frames}});
7946     processPosition(mapper, 100, 200);
7947     processSync(mapper);
7948     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
7949     std::for_each(frames.begin(), frames.end(), [](TouchVideoFrame& frame) {
7950         // We expect the raw coordinates of the MotionEvent to be rotated in the inverse direction
7951         // compared to the display. This is so that when the window transform (which contains the
7952         // display rotation) is applied later by InputDispatcher, the coordinates end up in the
7953         // window's coordinate space.
7954         frame.rotate(getInverseRotation(ui::ROTATION_90));
7955     });
7956     ASSERT_EQ(frames, motionArgs.videoFrames);
7957 }
7958 
7959 /**
7960  * If we had defined port associations, but the viewport is not ready, the touch device would be
7961  * expected to be disabled, and it should be enabled after the viewport has found.
7962  */
TEST_F(MultiTouchInputMapperTest,Configure_EnabledForAssociatedDisplay)7963 TEST_F(MultiTouchInputMapperTest, Configure_EnabledForAssociatedDisplay) {
7964     constexpr uint8_t hdmi2 = 1;
7965     const std::string secondaryUniqueId = "uniqueId2";
7966     constexpr ViewportType type = ViewportType::EXTERNAL;
7967 
7968     mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi2);
7969 
7970     addConfigurationProperty("touch.deviceType", "touchScreen");
7971     prepareAxes(POSITION);
7972     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7973 
7974     ASSERT_EQ(mDevice->isEnabled(), false);
7975 
7976     // Add display on hdmi2, the device should be enabled and can receive touch event.
7977     prepareSecondaryDisplay(type, hdmi2);
7978     ASSERT_EQ(mDevice->isEnabled(), true);
7979 
7980     // Send a touch event.
7981     processPosition(mapper, 100, 100);
7982     processSync(mapper);
7983 
7984     NotifyMotionArgs args;
7985     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
7986     ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
7987 }
7988 
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandleSingleTouch)7989 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
7990     addConfigurationProperty("touch.deviceType", "touchScreen");
7991     prepareDisplay(ui::ROTATION_0);
7992     prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
7993     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
7994 
7995     NotifyMotionArgs motionArgs;
7996 
7997     constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
7998     // finger down
7999     processId(mapper, 1);
8000     processPosition(mapper, x1, y1);
8001     processSync(mapper);
8002     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8003     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8004     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8005 
8006     // finger move
8007     processId(mapper, 1);
8008     processPosition(mapper, x2, y2);
8009     processSync(mapper);
8010     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8011     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8012     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8013 
8014     // finger up.
8015     processId(mapper, -1);
8016     processSync(mapper);
8017     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8018     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8019     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8020 
8021     // new finger down
8022     processId(mapper, 1);
8023     processPosition(mapper, x3, y3);
8024     processSync(mapper);
8025     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8026     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8027     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8028 }
8029 
8030 /**
8031  * Test single touch should be canceled when received the MT_TOOL_PALM event, and the following
8032  * MOVE and UP events should be ignored.
8033  */
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandlePalmToolType_SinglePointer)8034 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_SinglePointer) {
8035     addConfigurationProperty("touch.deviceType", "touchScreen");
8036     prepareDisplay(ui::ROTATION_0);
8037     prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
8038     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8039 
8040     NotifyMotionArgs motionArgs;
8041 
8042     // default tool type is finger
8043     constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
8044     processId(mapper, FIRST_TRACKING_ID);
8045     processPosition(mapper, x1, y1);
8046     processSync(mapper);
8047     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8048     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8049     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8050 
8051     // Tool changed to MT_TOOL_PALM expect sending the cancel event.
8052     processToolType(mapper, MT_TOOL_PALM);
8053     processSync(mapper);
8054     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8055     ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8056 
8057     // Ignore the following MOVE and UP events if had detect a palm event.
8058     processId(mapper, FIRST_TRACKING_ID);
8059     processPosition(mapper, x2, y2);
8060     processSync(mapper);
8061     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8062 
8063     // finger up.
8064     processId(mapper, INVALID_TRACKING_ID);
8065     processSync(mapper);
8066     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8067 
8068     // new finger down
8069     processId(mapper, FIRST_TRACKING_ID);
8070     processToolType(mapper, MT_TOOL_FINGER);
8071     processPosition(mapper, x3, y3);
8072     processSync(mapper);
8073     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8074     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8075     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8076 }
8077 
8078 /**
8079  * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
8080  * and the rest active fingers could still be allowed to receive the events
8081  */
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandlePalmToolType_TwoPointers)8082 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_TwoPointers) {
8083     addConfigurationProperty("touch.deviceType", "touchScreen");
8084     prepareDisplay(ui::ROTATION_0);
8085     prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
8086     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8087 
8088     NotifyMotionArgs motionArgs;
8089 
8090     // default tool type is finger
8091     constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
8092     processId(mapper, FIRST_TRACKING_ID);
8093     processPosition(mapper, x1, y1);
8094     processSync(mapper);
8095     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8096     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8097     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8098 
8099     // Second finger down.
8100     processSlot(mapper, SECOND_SLOT);
8101     processId(mapper, SECOND_TRACKING_ID);
8102     processPosition(mapper, x2, y2);
8103     processSync(mapper);
8104     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8105     ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
8106     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[1].toolType);
8107 
8108     // If the tool type of the first finger changes to MT_TOOL_PALM,
8109     // we expect to receive ACTION_POINTER_UP with cancel flag.
8110     processSlot(mapper, FIRST_SLOT);
8111     processId(mapper, FIRST_TRACKING_ID);
8112     processToolType(mapper, MT_TOOL_PALM);
8113     processSync(mapper);
8114     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8115     ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
8116     ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8117 
8118     // The following MOVE events of second finger should be processed.
8119     processSlot(mapper, SECOND_SLOT);
8120     processId(mapper, SECOND_TRACKING_ID);
8121     processPosition(mapper, x2 + 1, y2 + 1);
8122     processSync(mapper);
8123     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8124     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8125     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8126 
8127     // First finger up. It used to be in palm mode, and we already generated ACTION_POINTER_UP for
8128     // it. Second finger receive move.
8129     processSlot(mapper, FIRST_SLOT);
8130     processId(mapper, INVALID_TRACKING_ID);
8131     processSync(mapper);
8132     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8133     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8134     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8135 
8136     // Second finger keeps moving.
8137     processSlot(mapper, SECOND_SLOT);
8138     processId(mapper, SECOND_TRACKING_ID);
8139     processPosition(mapper, x2 + 2, y2 + 2);
8140     processSync(mapper);
8141     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8142     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8143     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8144 
8145     // Second finger up.
8146     processId(mapper, INVALID_TRACKING_ID);
8147     processSync(mapper);
8148     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8149     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8150     ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8151 }
8152 
8153 /**
8154  * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event, if only 1 finger
8155  * is active, it should send CANCEL after receiving the MT_TOOL_PALM event.
8156  */
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm)8157 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_ShouldCancelWhenAllTouchIsPalm) {
8158     addConfigurationProperty("touch.deviceType", "touchScreen");
8159     prepareDisplay(ui::ROTATION_0);
8160     prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
8161     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8162 
8163     NotifyMotionArgs motionArgs;
8164 
8165     constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
8166     // First finger down.
8167     processId(mapper, FIRST_TRACKING_ID);
8168     processPosition(mapper, x1, y1);
8169     processSync(mapper);
8170     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8171     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8172     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8173 
8174     // Second finger down.
8175     processSlot(mapper, SECOND_SLOT);
8176     processId(mapper, SECOND_TRACKING_ID);
8177     processPosition(mapper, x2, y2);
8178     processSync(mapper);
8179     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8180     ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
8181     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8182 
8183     // If the tool type of the first finger changes to MT_TOOL_PALM,
8184     // we expect to receive ACTION_POINTER_UP with cancel flag.
8185     processSlot(mapper, FIRST_SLOT);
8186     processId(mapper, FIRST_TRACKING_ID);
8187     processToolType(mapper, MT_TOOL_PALM);
8188     processSync(mapper);
8189     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8190     ASSERT_EQ(ACTION_POINTER_0_UP, motionArgs.action);
8191     ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8192 
8193     // Second finger keeps moving.
8194     processSlot(mapper, SECOND_SLOT);
8195     processId(mapper, SECOND_TRACKING_ID);
8196     processPosition(mapper, x2 + 1, y2 + 1);
8197     processSync(mapper);
8198     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8199     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8200 
8201     // second finger becomes palm, receive cancel due to only 1 finger is active.
8202     processId(mapper, SECOND_TRACKING_ID);
8203     processToolType(mapper, MT_TOOL_PALM);
8204     processSync(mapper);
8205     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8206     ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8207 
8208     // third finger down.
8209     processSlot(mapper, THIRD_SLOT);
8210     processId(mapper, THIRD_TRACKING_ID);
8211     processToolType(mapper, MT_TOOL_FINGER);
8212     processPosition(mapper, x3, y3);
8213     processSync(mapper);
8214     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8215     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8216     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8217     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8218 
8219     // third finger move
8220     processId(mapper, THIRD_TRACKING_ID);
8221     processPosition(mapper, x3 + 1, y3 + 1);
8222     processSync(mapper);
8223     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8224     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8225 
8226     // first finger up, third finger receive move.
8227     processSlot(mapper, FIRST_SLOT);
8228     processId(mapper, INVALID_TRACKING_ID);
8229     processSync(mapper);
8230     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8231     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8232     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8233 
8234     // second finger up, third finger receive move.
8235     processSlot(mapper, SECOND_SLOT);
8236     processId(mapper, INVALID_TRACKING_ID);
8237     processSync(mapper);
8238     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8239     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8240     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8241 
8242     // third finger up.
8243     processSlot(mapper, THIRD_SLOT);
8244     processId(mapper, INVALID_TRACKING_ID);
8245     processSync(mapper);
8246     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8247     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8248     ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8249 }
8250 
8251 /**
8252  * Test multi-touch should sent POINTER_UP when received the MT_TOOL_PALM event from some finger,
8253  * and the active finger could still be allowed to receive the events
8254  */
TEST_F(MultiTouchInputMapperTest,Process_ShouldHandlePalmToolType_KeepFirstPointer)8255 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType_KeepFirstPointer) {
8256     addConfigurationProperty("touch.deviceType", "touchScreen");
8257     prepareDisplay(ui::ROTATION_0);
8258     prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
8259     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8260 
8261     NotifyMotionArgs motionArgs;
8262 
8263     // default tool type is finger
8264     constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220;
8265     processId(mapper, FIRST_TRACKING_ID);
8266     processPosition(mapper, x1, y1);
8267     processSync(mapper);
8268     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8269     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8270     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8271 
8272     // Second finger down.
8273     processSlot(mapper, SECOND_SLOT);
8274     processId(mapper, SECOND_TRACKING_ID);
8275     processPosition(mapper, x2, y2);
8276     processSync(mapper);
8277     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8278     ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
8279     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8280 
8281     // If the tool type of the second finger changes to MT_TOOL_PALM,
8282     // we expect to receive ACTION_POINTER_UP with cancel flag.
8283     processId(mapper, SECOND_TRACKING_ID);
8284     processToolType(mapper, MT_TOOL_PALM);
8285     processSync(mapper);
8286     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8287     ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
8288     ASSERT_EQ(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8289 
8290     // The following MOVE event should be processed.
8291     processSlot(mapper, FIRST_SLOT);
8292     processId(mapper, FIRST_TRACKING_ID);
8293     processPosition(mapper, x1 + 1, y1 + 1);
8294     processSync(mapper);
8295     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8296     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8297     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8298 
8299     // second finger up.
8300     processSlot(mapper, SECOND_SLOT);
8301     processId(mapper, INVALID_TRACKING_ID);
8302     processSync(mapper);
8303     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8304     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8305 
8306     // first finger keep moving
8307     processSlot(mapper, FIRST_SLOT);
8308     processId(mapper, FIRST_TRACKING_ID);
8309     processPosition(mapper, x1 + 2, y1 + 2);
8310     processSync(mapper);
8311     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8312     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8313 
8314     // first finger up.
8315     processId(mapper, INVALID_TRACKING_ID);
8316     processSync(mapper);
8317     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8318     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8319     ASSERT_NE(AMOTION_EVENT_FLAG_CANCELED, motionArgs.flags);
8320 }
8321 
8322 /**
8323  * Test multi-touch should sent ACTION_POINTER_UP/ACTION_UP when received the INVALID_TRACKING_ID,
8324  * to prevent the driver side may send unexpected data after set tracking id as INVALID_TRACKING_ID
8325  * cause slot be valid again.
8326  */
TEST_F(MultiTouchInputMapperTest,Process_MultiTouch_WithInvalidTrackingId)8327 TEST_F(MultiTouchInputMapperTest, Process_MultiTouch_WithInvalidTrackingId) {
8328     addConfigurationProperty("touch.deviceType", "touchScreen");
8329     prepareDisplay(ui::ROTATION_0);
8330     prepareAxes(POSITION | ID | SLOT | PRESSURE);
8331     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8332 
8333     NotifyMotionArgs motionArgs;
8334 
8335     constexpr int32_t x1 = 100, y1 = 200, x2 = 0, y2 = 0;
8336     // First finger down.
8337     processId(mapper, FIRST_TRACKING_ID);
8338     processPosition(mapper, x1, y1);
8339     processPressure(mapper, RAW_PRESSURE_MAX);
8340     processSync(mapper);
8341     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8342     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8343     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8344 
8345     // First finger move.
8346     processId(mapper, FIRST_TRACKING_ID);
8347     processPosition(mapper, x1 + 1, y1 + 1);
8348     processPressure(mapper, RAW_PRESSURE_MAX);
8349     processSync(mapper);
8350     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8351     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8352     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8353 
8354     // Second finger down.
8355     processSlot(mapper, SECOND_SLOT);
8356     processId(mapper, SECOND_TRACKING_ID);
8357     processPosition(mapper, x2, y2);
8358     processPressure(mapper, RAW_PRESSURE_MAX);
8359     processSync(mapper);
8360     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8361     ASSERT_EQ(ACTION_POINTER_1_DOWN, motionArgs.action);
8362     ASSERT_EQ(uint32_t(2), motionArgs.getPointerCount());
8363 
8364     // second finger up with some unexpected data.
8365     processSlot(mapper, SECOND_SLOT);
8366     processId(mapper, INVALID_TRACKING_ID);
8367     processPosition(mapper, x2, y2);
8368     processSync(mapper);
8369     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8370     ASSERT_EQ(ACTION_POINTER_1_UP, motionArgs.action);
8371     ASSERT_EQ(uint32_t(2), motionArgs.getPointerCount());
8372 
8373     // first finger up with some unexpected data.
8374     processSlot(mapper, FIRST_SLOT);
8375     processId(mapper, INVALID_TRACKING_ID);
8376     processPosition(mapper, x2, y2);
8377     processPressure(mapper, RAW_PRESSURE_MAX);
8378     processSync(mapper);
8379     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8380     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
8381     ASSERT_EQ(uint32_t(1), motionArgs.getPointerCount());
8382 }
8383 
TEST_F(MultiTouchInputMapperTest,Reset_RepopulatesMultiTouchState)8384 TEST_F(MultiTouchInputMapperTest, Reset_RepopulatesMultiTouchState) {
8385     addConfigurationProperty("touch.deviceType", "touchScreen");
8386     prepareDisplay(ui::ROTATION_0);
8387     prepareAxes(POSITION | ID | SLOT | PRESSURE);
8388     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8389 
8390     // First finger down.
8391     constexpr int32_t x1 = 100, y1 = 200, x2 = 300, y2 = 400;
8392     processId(mapper, FIRST_TRACKING_ID);
8393     processPosition(mapper, x1, y1);
8394     processPressure(mapper, RAW_PRESSURE_MAX);
8395     processSync(mapper);
8396     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8397             WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
8398 
8399     // Second finger down.
8400     processSlot(mapper, SECOND_SLOT);
8401     processId(mapper, SECOND_TRACKING_ID);
8402     processPosition(mapper, x2, y2);
8403     processPressure(mapper, RAW_PRESSURE_MAX);
8404     processSync(mapper);
8405     ASSERT_NO_FATAL_FAILURE(
8406             mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(ACTION_POINTER_1_DOWN)));
8407 
8408     // Set MT Slot state to be repopulated for the required slots
8409     std::vector<int32_t> mtSlotValues(RAW_SLOT_MAX + 1, -1);
8410     mtSlotValues[0] = FIRST_TRACKING_ID;
8411     mtSlotValues[1] = SECOND_TRACKING_ID;
8412     mFakeEventHub->setMtSlotValues(EVENTHUB_ID, ABS_MT_TRACKING_ID, mtSlotValues);
8413 
8414     mtSlotValues[0] = x1;
8415     mtSlotValues[1] = x2;
8416     mFakeEventHub->setMtSlotValues(EVENTHUB_ID, ABS_MT_POSITION_X, mtSlotValues);
8417 
8418     mtSlotValues[0] = y1;
8419     mtSlotValues[1] = y2;
8420     mFakeEventHub->setMtSlotValues(EVENTHUB_ID, ABS_MT_POSITION_Y, mtSlotValues);
8421 
8422     mtSlotValues[0] = RAW_PRESSURE_MAX;
8423     mtSlotValues[1] = RAW_PRESSURE_MAX;
8424     mFakeEventHub->setMtSlotValues(EVENTHUB_ID, ABS_MT_PRESSURE, mtSlotValues);
8425 
8426     // Reset the mapper. When the mapper is reset, we expect the current multi-touch state to be
8427     // repopulated. Resetting should cancel the ongoing gesture.
8428     resetMapper(mapper, ARBITRARY_TIME);
8429     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8430             WithMotionAction(AMOTION_EVENT_ACTION_CANCEL)));
8431 
8432     // Send a sync to simulate an empty touch frame where nothing changes. The mapper should use
8433     // the existing touch state to generate a down event.
8434     processPosition(mapper, 301, 302);
8435     processSync(mapper);
8436     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8437             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithPressure(1.f))));
8438     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8439             AllOf(WithMotionAction(ACTION_POINTER_1_DOWN), WithPressure(1.f))));
8440 
8441     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8442 }
8443 
TEST_F(MultiTouchInputMapperTest,Reset_PreservesLastTouchState_NoPointersDown)8444 TEST_F(MultiTouchInputMapperTest, Reset_PreservesLastTouchState_NoPointersDown) {
8445     addConfigurationProperty("touch.deviceType", "touchScreen");
8446     prepareDisplay(ui::ROTATION_0);
8447     prepareAxes(POSITION | ID | SLOT | PRESSURE);
8448     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8449 
8450     // First finger touches down and releases.
8451     processId(mapper, FIRST_TRACKING_ID);
8452     processPosition(mapper, 100, 200);
8453     processPressure(mapper, RAW_PRESSURE_MAX);
8454     processSync(mapper);
8455     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8456             WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
8457     processId(mapper, INVALID_TRACKING_ID);
8458     processSync(mapper);
8459     ASSERT_NO_FATAL_FAILURE(
8460             mFakeListener->assertNotifyMotionWasCalled(WithMotionAction(AMOTION_EVENT_ACTION_UP)));
8461 
8462     // Reset the mapper. When the mapper is reset, we expect it to restore the latest
8463     // raw state where no pointers are down.
8464     resetMapper(mapper, ARBITRARY_TIME);
8465     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8466 
8467     // Send an empty sync frame. Since there are no pointers, no events are generated.
8468     processSync(mapper);
8469     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8470 }
8471 
TEST_F(MultiTouchInputMapperTest,StylusSourceIsAddedDynamicallyFromToolType)8472 TEST_F(MultiTouchInputMapperTest, StylusSourceIsAddedDynamicallyFromToolType) {
8473     addConfigurationProperty("touch.deviceType", "touchScreen");
8474     prepareDisplay(ui::ROTATION_0);
8475     prepareAxes(POSITION | ID | SLOT | PRESSURE | TOOL_TYPE);
8476     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8477     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
8478 
8479     // Even if the device supports reporting the ABS_MT_TOOL_TYPE axis, which could give it the
8480     // ability to report MT_TOOL_PEN, we do not report the device as coming from a stylus source.
8481     // Due to limitations in the evdev protocol, we cannot say for certain that a device is capable
8482     // of reporting stylus events just because it supports ABS_MT_TOOL_TYPE.
8483     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper.getSources());
8484 
8485     // However, if the device ever ends up reporting an event with MT_TOOL_PEN, it should be
8486     // reported with the stylus source.
8487     processId(mapper, FIRST_TRACKING_ID);
8488     processToolType(mapper, MT_TOOL_PEN);
8489     processPosition(mapper, 100, 200);
8490     processPressure(mapper, RAW_PRESSURE_MAX);
8491     processSync(mapper);
8492     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8493             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
8494                   WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
8495                   WithToolType(ToolType::STYLUS))));
8496 
8497     // Now that we know the device supports styluses, ensure that the device is re-configured with
8498     // the stylus source.
8499     ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, mapper.getSources());
8500     {
8501         const auto& devices = mReader->getInputDevices();
8502         auto deviceInfo =
8503                 std::find_if(devices.begin(), devices.end(),
8504                              [](const InputDeviceInfo& info) { return info.getId() == DEVICE_ID; });
8505         LOG_ALWAYS_FATAL_IF(deviceInfo == devices.end(), "Cannot find InputDevice");
8506         ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS, deviceInfo->getSources());
8507     }
8508 
8509     // Ensure the device was not reset to prevent interruptions of any ongoing gestures.
8510     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
8511 
8512     processId(mapper, INVALID_TRACKING_ID);
8513     processSync(mapper);
8514     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8515             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
8516                   WithSource(AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS),
8517                   WithToolType(ToolType::STYLUS))));
8518 }
8519 
8520 // TODO(b/281840344): Remove the test when the old touchpad stack is removed. It is currently
8521 //  unclear what the behavior of the touchpad logic in TouchInputMapper should do after the
8522 //  PointerChoreographer refactor.
TEST_F(MultiTouchInputMapperTest,DISABLED_Process_TouchpadPointer)8523 TEST_F(MultiTouchInputMapperTest, DISABLED_Process_TouchpadPointer) {
8524     // prepare device
8525     prepareDisplay(ui::ROTATION_0);
8526     prepareAxes(POSITION | ID | SLOT);
8527     mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
8528     mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
8529     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8530     // run uncaptured pointer tests - pushes out generic events
8531     // FINGER 0 DOWN
8532     processId(mapper, 3);
8533     processPosition(mapper, 100, 100);
8534     processKey(mapper, BTN_TOUCH, 1);
8535     processSync(mapper);
8536 
8537     // start at (100,100), cursor should be at (0,0) * scale
8538     NotifyMotionArgs args;
8539     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8540     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
8541     ASSERT_NO_FATAL_FAILURE(
8542             assertPointerCoords(args.pointerCoords[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
8543 
8544     // FINGER 0 MOVE
8545     processPosition(mapper, 200, 200);
8546     processSync(mapper);
8547 
8548     // compute scaling to help with touch position checking
8549     float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
8550     float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
8551     float scale =
8552             mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
8553 
8554     // translate from (100,100) -> (200,200), cursor should have changed to (100,100) * scale)
8555     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8556     ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
8557     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], 100 * scale, 100 * scale, 0,
8558                                                 0, 0, 0, 0, 0, 0, 0));
8559 
8560     // BUTTON DOWN
8561     processKey(mapper, BTN_LEFT, 1);
8562     processSync(mapper);
8563 
8564     // touchinputmapper design sends a move before button press
8565     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8566     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
8567     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8568     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_PRESS, args.action);
8569 
8570     // BUTTON UP
8571     processKey(mapper, BTN_LEFT, 0);
8572     processSync(mapper);
8573 
8574     // touchinputmapper design sends a move after button release
8575     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8576     ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
8577     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
8578     ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
8579 }
8580 
TEST_F(MultiTouchInputMapperTest,Touchpad_GetSources)8581 TEST_F(MultiTouchInputMapperTest, Touchpad_GetSources) {
8582     prepareDisplay(ui::ROTATION_0);
8583     prepareAxes(POSITION | ID | SLOT);
8584     mFakeEventHub->addKey(EVENTHUB_ID, BTN_LEFT, 0, AKEYCODE_UNKNOWN, 0);
8585     mFakePolicy->setPointerCapture(/*window=*/nullptr);
8586     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8587 
8588     // uncaptured touchpad should be a pointer device
8589     ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper.getSources());
8590 }
8591 
8592 // --- BluetoothMultiTouchInputMapperTest ---
8593 
8594 class BluetoothMultiTouchInputMapperTest : public MultiTouchInputMapperTest {
8595 protected:
SetUp()8596     void SetUp() override {
8597         InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::EXTERNAL, BUS_BLUETOOTH);
8598     }
8599 };
8600 
TEST_F(BluetoothMultiTouchInputMapperTest,TimestampSmoothening)8601 TEST_F(BluetoothMultiTouchInputMapperTest, TimestampSmoothening) {
8602     addConfigurationProperty("touch.deviceType", "touchScreen");
8603     prepareDisplay(ui::ROTATION_0);
8604     prepareAxes(POSITION | ID | SLOT | PRESSURE);
8605     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8606 
8607     nsecs_t kernelEventTime = ARBITRARY_TIME;
8608     nsecs_t expectedEventTime = ARBITRARY_TIME;
8609     // Touch down.
8610     processId(mapper, FIRST_TRACKING_ID);
8611     processPosition(mapper, 100, 200);
8612     processPressure(mapper, RAW_PRESSURE_MAX);
8613     processSync(mapper, ARBITRARY_TIME);
8614     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8615             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithEventTime(ARBITRARY_TIME))));
8616 
8617     // Process several events that come in quick succession, according to their timestamps.
8618     for (int i = 0; i < 3; i++) {
8619         constexpr static nsecs_t delta = ms2ns(1);
8620         static_assert(delta < MIN_BLUETOOTH_TIMESTAMP_DELTA);
8621         kernelEventTime += delta;
8622         expectedEventTime += MIN_BLUETOOTH_TIMESTAMP_DELTA;
8623 
8624         processPosition(mapper, 101 + i, 201 + i);
8625         processSync(mapper, kernelEventTime);
8626         ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8627                 AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8628                       WithEventTime(expectedEventTime))));
8629     }
8630 
8631     // Release the touch.
8632     processId(mapper, INVALID_TRACKING_ID);
8633     processPressure(mapper, RAW_PRESSURE_MIN);
8634     processSync(mapper, ARBITRARY_TIME + ms2ns(50));
8635     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8636             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP),
8637                   WithEventTime(ARBITRARY_TIME + ms2ns(50)))));
8638 }
8639 
8640 // --- MultiTouchPointerModeTest ---
8641 
8642 class MultiTouchPointerModeTest : public MultiTouchInputMapperTest {
8643 protected:
8644     float mPointerMovementScale;
8645     float mPointerXZoomScale;
preparePointerMode(int xAxisResolution,int yAxisResolution)8646     void preparePointerMode(int xAxisResolution, int yAxisResolution) {
8647         addConfigurationProperty("touch.deviceType", "pointer");
8648         prepareDisplay(ui::ROTATION_0);
8649 
8650         prepareAxes(POSITION);
8651         prepareAbsoluteAxisResolution(xAxisResolution, yAxisResolution);
8652         // In order to enable swipe and freeform gesture in pointer mode, pointer capture
8653         // needs to be disabled, and the pointer gesture needs to be enabled.
8654         mFakePolicy->setPointerCapture(/*window=*/nullptr);
8655         mFakePolicy->setPointerGestureEnabled(true);
8656 
8657         float rawDiagonal = hypotf(RAW_X_MAX - RAW_X_MIN, RAW_Y_MAX - RAW_Y_MIN);
8658         float displayDiagonal = hypotf(DISPLAY_WIDTH, DISPLAY_HEIGHT);
8659         mPointerMovementScale =
8660                 mFakePolicy->getPointerGestureMovementSpeedRatio() * displayDiagonal / rawDiagonal;
8661         mPointerXZoomScale =
8662                 mFakePolicy->getPointerGestureZoomSpeedRatio() * displayDiagonal / rawDiagonal;
8663     }
8664 
prepareAbsoluteAxisResolution(int xAxisResolution,int yAxisResolution)8665     void prepareAbsoluteAxisResolution(int xAxisResolution, int yAxisResolution) {
8666         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
8667                                        /*flat*/ 0,
8668                                        /*fuzz*/ 0, /*resolution*/ xAxisResolution);
8669         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
8670                                        /*flat*/ 0,
8671                                        /*fuzz*/ 0, /*resolution*/ yAxisResolution);
8672     }
8673 };
8674 
8675 /**
8676  * Two fingers down on a pointer mode touch pad. The width
8677  * of the two finger is larger than 1/4 of the touch pack diagnal length. However, it
8678  * is smaller than the fixed min physical length 30mm. Two fingers' distance must
8679  * be greater than the both value to be freeform gesture, so that after two
8680  * fingers start to move downwards, the gesture should be swipe.
8681  */
TEST_F(MultiTouchPointerModeTest,PointerGestureMaxSwipeWidthSwipe)8682 TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthSwipe) {
8683     SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8684 
8685     // The min freeform gesture width is 25units/mm x 30mm = 750
8686     // which is greater than fraction of the diagnal length of the touchpad (349).
8687     // Thus, MaxSwipWidth is 750.
8688     preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
8689     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8690     NotifyMotionArgs motionArgs;
8691 
8692     // Two fingers down at once.
8693     // The two fingers are 450 units apart, expects the current gesture to be PRESS
8694     // Pointer's initial position is used the [0,0] coordinate.
8695     int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
8696 
8697     processId(mapper, FIRST_TRACKING_ID);
8698     processPosition(mapper, x1, y1);
8699     processMTSync(mapper);
8700     processId(mapper, SECOND_TRACKING_ID);
8701     processPosition(mapper, x2, y2);
8702     processMTSync(mapper);
8703     processSync(mapper);
8704 
8705     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8706     ASSERT_EQ(1U, motionArgs.getPointerCount());
8707     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8708     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8709     ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
8710     ASSERT_NO_FATAL_FAILURE(
8711             assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
8712 
8713     // It should be recognized as a SWIPE gesture when two fingers start to move down,
8714     // that there should be 1 pointer.
8715     int32_t movingDistance = 200;
8716     y1 += movingDistance;
8717     y2 += movingDistance;
8718 
8719     processId(mapper, FIRST_TRACKING_ID);
8720     processPosition(mapper, x1, y1);
8721     processMTSync(mapper);
8722     processId(mapper, SECOND_TRACKING_ID);
8723     processPosition(mapper, x2, y2);
8724     processMTSync(mapper);
8725     processSync(mapper);
8726 
8727     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8728     ASSERT_EQ(1U, motionArgs.getPointerCount());
8729     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8730     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8731     ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
8732     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
8733                                                 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
8734                                                 0, 0, 0, 0));
8735 }
8736 
8737 /**
8738  * Two fingers down on a pointer mode touch pad. The width of the two finger is larger
8739  * than the minimum freeform gesture width, 30mm. However, it is smaller than 1/4 of
8740  * the touch pack diagnal length. Two fingers' distance must be greater than the both
8741  * value to be freeform gesture, so that after two fingers start to move downwards,
8742  * the gesture should be swipe.
8743  */
TEST_F(MultiTouchPointerModeTest,PointerGestureMaxSwipeWidthLowResolutionSwipe)8744 TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthLowResolutionSwipe) {
8745     SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8746 
8747     // The min freeform gesture width is 5units/mm x 30mm = 150
8748     // which is greater than fraction of the diagnal length of the touchpad (349).
8749     // Thus, MaxSwipWidth is the fraction of the diagnal length, 349.
8750     preparePointerMode(/*xResolution=*/5, /*yResolution=*/5);
8751     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8752     NotifyMotionArgs motionArgs;
8753 
8754     // Two fingers down at once.
8755     // The two fingers are 250 units apart, expects the current gesture to be PRESS
8756     // Pointer's initial position is used the [0,0] coordinate.
8757     int32_t x1 = 100, y1 = 125, x2 = 350, y2 = 125;
8758 
8759     processId(mapper, FIRST_TRACKING_ID);
8760     processPosition(mapper, x1, y1);
8761     processMTSync(mapper);
8762     processId(mapper, SECOND_TRACKING_ID);
8763     processPosition(mapper, x2, y2);
8764     processMTSync(mapper);
8765     processSync(mapper);
8766 
8767     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8768     ASSERT_EQ(1U, motionArgs.getPointerCount());
8769     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8770     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8771     ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
8772     ASSERT_NO_FATAL_FAILURE(
8773             assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
8774 
8775     // It should be recognized as a SWIPE gesture when two fingers start to move down,
8776     // and there should be 1 pointer.
8777     int32_t movingDistance = 200;
8778     y1 += movingDistance;
8779     y2 += movingDistance;
8780 
8781     processId(mapper, FIRST_TRACKING_ID);
8782     processPosition(mapper, x1, y1);
8783     processMTSync(mapper);
8784     processId(mapper, SECOND_TRACKING_ID);
8785     processPosition(mapper, x2, y2);
8786     processMTSync(mapper);
8787     processSync(mapper);
8788 
8789     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8790     ASSERT_EQ(1U, motionArgs.getPointerCount());
8791     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8792     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8793     ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
8794     // New coordinate is the scaled relative coordinate from the initial coordinate.
8795     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], 0,
8796                                                 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
8797                                                 0, 0, 0, 0));
8798 }
8799 
8800 /**
8801  * Touch the touch pad with two fingers with a distance wider than the minimum freeform
8802  * gesture width and 1/4 of the diagnal length of the touchpad. Expect to receive
8803  * freeform gestures after two fingers start to move downwards.
8804  */
TEST_F(MultiTouchPointerModeTest,PointerGestureMaxSwipeWidthFreeform)8805 TEST_F(MultiTouchPointerModeTest, PointerGestureMaxSwipeWidthFreeform) {
8806     SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8807 
8808     preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
8809     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8810 
8811     NotifyMotionArgs motionArgs;
8812 
8813     // Two fingers down at once. Wider than the max swipe width.
8814     // The gesture is expected to be PRESS, then transformed to FREEFORM
8815     int32_t x1 = 100, y1 = 125, x2 = 900, y2 = 125;
8816 
8817     processId(mapper, FIRST_TRACKING_ID);
8818     processPosition(mapper, x1, y1);
8819     processMTSync(mapper);
8820     processId(mapper, SECOND_TRACKING_ID);
8821     processPosition(mapper, x2, y2);
8822     processMTSync(mapper);
8823     processSync(mapper);
8824 
8825     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8826     ASSERT_EQ(1U, motionArgs.getPointerCount());
8827     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8828     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8829     ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
8830     // One pointer for PRESS, and its coordinate is used as the origin for pointer coordinates.
8831     ASSERT_NO_FATAL_FAILURE(
8832             assertPointerCoords(motionArgs.pointerCoords[0], 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
8833 
8834     int32_t movingDistance = 200;
8835 
8836     // Move two fingers down, expect a cancel event because gesture is changing to freeform,
8837     // then two down events for two pointers.
8838     y1 += movingDistance;
8839     y2 += movingDistance;
8840 
8841     processId(mapper, FIRST_TRACKING_ID);
8842     processPosition(mapper, x1, y1);
8843     processMTSync(mapper);
8844     processId(mapper, SECOND_TRACKING_ID);
8845     processPosition(mapper, x2, y2);
8846     processMTSync(mapper);
8847     processSync(mapper);
8848 
8849     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8850     // The previous PRESS gesture is cancelled, because it is transformed to freeform
8851     ASSERT_EQ(1U, motionArgs.getPointerCount());
8852     ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
8853     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8854     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8855     ASSERT_EQ(1U, motionArgs.getPointerCount());
8856     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8857     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8858     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8859     ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
8860     ASSERT_EQ(2U, motionArgs.getPointerCount());
8861     ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN, motionArgs.action & AMOTION_EVENT_ACTION_MASK);
8862     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8863     ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
8864     // Two pointers' scaled relative coordinates from their initial centroid.
8865     // Initial y coordinates are 0 as y1 and y2 have the same value.
8866     float cookedX1 = (x1 - x2) / 2 * mPointerXZoomScale;
8867     float cookedX2 = (x2 - x1) / 2 * mPointerXZoomScale;
8868     // When pointers move,  the new coordinates equal to the initial coordinates plus
8869     // scaled moving distance.
8870     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
8871                                                 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
8872                                                 0, 0, 0, 0));
8873     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
8874                                                 movingDistance * mPointerMovementScale, 1, 0, 0, 0,
8875                                                 0, 0, 0, 0));
8876 
8877     // Move two fingers down again, expect one MOVE motion event.
8878     y1 += movingDistance;
8879     y2 += movingDistance;
8880 
8881     processId(mapper, FIRST_TRACKING_ID);
8882     processPosition(mapper, x1, y1);
8883     processMTSync(mapper);
8884     processId(mapper, SECOND_TRACKING_ID);
8885     processPosition(mapper, x2, y2);
8886     processMTSync(mapper);
8887     processSync(mapper);
8888 
8889     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8890     ASSERT_EQ(2U, motionArgs.getPointerCount());
8891     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8892     ASSERT_EQ(ToolType::FINGER, motionArgs.pointerProperties[0].toolType);
8893     ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
8894     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0], cookedX1,
8895                                                 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
8896                                                 0, 0, 0, 0, 0));
8897     ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1], cookedX2,
8898                                                 movingDistance * 2 * mPointerMovementScale, 1, 0, 0,
8899                                                 0, 0, 0, 0, 0));
8900 }
8901 
TEST_F(MultiTouchPointerModeTest,TwoFingerSwipeOffsets)8902 TEST_F(MultiTouchPointerModeTest, TwoFingerSwipeOffsets) {
8903     SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8904 
8905     preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
8906     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8907     NotifyMotionArgs motionArgs;
8908 
8909     // Place two fingers down.
8910     int32_t x1 = 100, y1 = 125, x2 = 550, y2 = 125;
8911 
8912     processId(mapper, FIRST_TRACKING_ID);
8913     processPosition(mapper, x1, y1);
8914     processMTSync(mapper);
8915     processId(mapper, SECOND_TRACKING_ID);
8916     processPosition(mapper, x2, y2);
8917     processMTSync(mapper);
8918     processSync(mapper);
8919 
8920     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8921     ASSERT_EQ(1U, motionArgs.getPointerCount());
8922     ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
8923     ASSERT_EQ(MotionClassification::NONE, motionArgs.classification);
8924     ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET));
8925     ASSERT_EQ(0, motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET));
8926 
8927     // Move the two fingers down and to the left.
8928     int32_t movingDistance = 200;
8929     x1 -= movingDistance;
8930     y1 += movingDistance;
8931     x2 -= movingDistance;
8932     y2 += movingDistance;
8933 
8934     processId(mapper, FIRST_TRACKING_ID);
8935     processPosition(mapper, x1, y1);
8936     processMTSync(mapper);
8937     processId(mapper, SECOND_TRACKING_ID);
8938     processPosition(mapper, x2, y2);
8939     processMTSync(mapper);
8940     processSync(mapper);
8941 
8942     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
8943     ASSERT_EQ(1U, motionArgs.getPointerCount());
8944     ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
8945     ASSERT_EQ(MotionClassification::TWO_FINGER_SWIPE, motionArgs.classification);
8946     ASSERT_LT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET), 0);
8947     ASSERT_GT(motionArgs.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET), 0);
8948 }
8949 
TEST_F(MultiTouchPointerModeTest,WhenViewportActiveStatusChanged_PointerGestureIsReset)8950 TEST_F(MultiTouchPointerModeTest, WhenViewportActiveStatusChanged_PointerGestureIsReset) {
8951     SCOPED_FLAG_OVERRIDE(disable_touch_input_mapper_pointer_usage, false);
8952 
8953     preparePointerMode(/*xResolution=*/25, /*yResolution=*/25);
8954     mFakeEventHub->addKey(EVENTHUB_ID, BTN_TOOL_PEN, 0, AKEYCODE_UNKNOWN, 0);
8955     MultiTouchInputMapper& mapper = constructAndAddMapper<MultiTouchInputMapper>();
8956     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
8957 
8958     // Start a stylus gesture.
8959     processKey(mapper, BTN_TOOL_PEN, 1);
8960     processId(mapper, FIRST_TRACKING_ID);
8961     processPosition(mapper, 100, 200);
8962     processSync(mapper);
8963     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8964             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
8965                   WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
8966                   WithToolType(ToolType::STYLUS))));
8967     // TODO(b/257078296): Pointer mode generates extra event.
8968     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8969             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
8970                   WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
8971                   WithToolType(ToolType::STYLUS))));
8972     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8973 
8974     // Make the viewport inactive. This will put the device in disabled mode, and the ongoing stylus
8975     // gesture should be disabled.
8976     auto viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
8977     viewport->isActive = false;
8978     mFakePolicy->updateViewport(*viewport);
8979     configureDevice(InputReaderConfiguration::Change::DISPLAY_INFO);
8980     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8981             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
8982                   WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
8983                   WithToolType(ToolType::STYLUS))));
8984     // TODO(b/257078296): Pointer mode generates extra event.
8985     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(
8986             AllOf(WithMotionAction(AMOTION_EVENT_ACTION_CANCEL),
8987                   WithSource(AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_STYLUS),
8988                   WithToolType(ToolType::STYLUS))));
8989     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
8990 }
8991 
8992 // --- PeripheralControllerTest ---
8993 
8994 class PeripheralControllerTest : public testing::Test {
8995 protected:
8996     static const char* DEVICE_NAME;
8997     static const char* DEVICE_LOCATION;
8998     static const int32_t DEVICE_ID;
8999     static const int32_t DEVICE_GENERATION;
9000     static const int32_t DEVICE_CONTROLLER_NUMBER;
9001     static const ftl::Flags<InputDeviceClass> DEVICE_CLASSES;
9002     static const int32_t EVENTHUB_ID;
9003 
9004     std::shared_ptr<FakeEventHub> mFakeEventHub;
9005     sp<FakeInputReaderPolicy> mFakePolicy;
9006     std::unique_ptr<TestInputListener> mFakeListener;
9007     std::unique_ptr<InstrumentedInputReader> mReader;
9008     std::shared_ptr<InputDevice> mDevice;
9009 
SetUp(ftl::Flags<InputDeviceClass> classes)9010     virtual void SetUp(ftl::Flags<InputDeviceClass> classes) {
9011         mFakeEventHub = std::make_unique<FakeEventHub>();
9012         mFakePolicy = sp<FakeInputReaderPolicy>::make();
9013         mFakeListener = std::make_unique<TestInputListener>();
9014         mReader = std::make_unique<InstrumentedInputReader>(mFakeEventHub, mFakePolicy,
9015                                                             *mFakeListener);
9016         mDevice = newDevice(DEVICE_ID, DEVICE_NAME, DEVICE_LOCATION, EVENTHUB_ID, classes);
9017     }
9018 
SetUp()9019     void SetUp() override { SetUp(DEVICE_CLASSES); }
9020 
TearDown()9021     void TearDown() override {
9022         mFakeListener.reset();
9023         mFakePolicy.clear();
9024     }
9025 
newDevice(int32_t deviceId,const std::string & name,const std::string & location,int32_t eventHubId,ftl::Flags<InputDeviceClass> classes)9026     std::shared_ptr<InputDevice> newDevice(int32_t deviceId, const std::string& name,
9027                                            const std::string& location, int32_t eventHubId,
9028                                            ftl::Flags<InputDeviceClass> classes) {
9029         InputDeviceIdentifier identifier;
9030         identifier.name = name;
9031         identifier.location = location;
9032         std::shared_ptr<InputDevice> device =
9033                 std::make_shared<InputDevice>(mReader->getContext(), deviceId, DEVICE_GENERATION,
9034                                               identifier);
9035         mReader->pushNextDevice(device);
9036         mFakeEventHub->addDevice(eventHubId, name, classes);
9037         mReader->loopOnce();
9038         return device;
9039     }
9040 
9041     template <class T, typename... Args>
addControllerAndConfigure(Args...args)9042     T& addControllerAndConfigure(Args... args) {
9043         T& controller = mDevice->addController<T>(EVENTHUB_ID, args...);
9044 
9045         return controller;
9046     }
9047 };
9048 
9049 const char* PeripheralControllerTest::DEVICE_NAME = "device";
9050 const char* PeripheralControllerTest::DEVICE_LOCATION = "BLUETOOTH";
9051 const int32_t PeripheralControllerTest::DEVICE_ID = END_RESERVED_ID + 1000;
9052 const int32_t PeripheralControllerTest::DEVICE_GENERATION = 2;
9053 const int32_t PeripheralControllerTest::DEVICE_CONTROLLER_NUMBER = 0;
9054 const ftl::Flags<InputDeviceClass> PeripheralControllerTest::DEVICE_CLASSES =
9055         ftl::Flags<InputDeviceClass>(0); // not needed for current tests
9056 const int32_t PeripheralControllerTest::EVENTHUB_ID = 1;
9057 
9058 // --- BatteryControllerTest ---
9059 class BatteryControllerTest : public PeripheralControllerTest {
9060 protected:
SetUp()9061     void SetUp() override {
9062         PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::BATTERY);
9063     }
9064 };
9065 
TEST_F(BatteryControllerTest,GetBatteryCapacity)9066 TEST_F(BatteryControllerTest, GetBatteryCapacity) {
9067     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9068 
9069     ASSERT_TRUE(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY));
9070     ASSERT_EQ(controller.getBatteryCapacity(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
9071               FakeEventHub::BATTERY_CAPACITY);
9072 }
9073 
TEST_F(BatteryControllerTest,GetBatteryStatus)9074 TEST_F(BatteryControllerTest, GetBatteryStatus) {
9075     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9076 
9077     ASSERT_TRUE(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY));
9078     ASSERT_EQ(controller.getBatteryStatus(FakeEventHub::DEFAULT_BATTERY).value_or(-1),
9079               FakeEventHub::BATTERY_STATUS);
9080 }
9081 
9082 // --- LightControllerTest ---
9083 class LightControllerTest : public PeripheralControllerTest {
9084 protected:
SetUp()9085     void SetUp() override {
9086         PeripheralControllerTest::SetUp(DEVICE_CLASSES | InputDeviceClass::LIGHT);
9087     }
9088 };
9089 
TEST_F(LightControllerTest,MonoLight)9090 TEST_F(LightControllerTest, MonoLight) {
9091     RawLightInfo infoMono = {.id = 1,
9092                              .name = "mono_light",
9093                              .maxBrightness = 255,
9094                              .flags = InputLightClass::BRIGHTNESS,
9095                              .path = ""};
9096     mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9097 
9098     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9099     InputDeviceInfo info;
9100     controller.populateDeviceInfo(&info);
9101     std::vector<InputDeviceLightInfo> lights = info.getLights();
9102     ASSERT_EQ(1U, lights.size());
9103     ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
9104     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9105 
9106     ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
9107     ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
9108 }
9109 
TEST_F(LightControllerTest,MonoKeyboardMuteLight)9110 TEST_F(LightControllerTest, MonoKeyboardMuteLight) {
9111     RawLightInfo infoMono = {.id = 1,
9112                              .name = "mono_keyboard_mute",
9113                              .maxBrightness = 255,
9114                              .flags = InputLightClass::BRIGHTNESS |
9115                                      InputLightClass::KEYBOARD_MIC_MUTE,
9116                              .path = ""};
9117     mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9118 
9119     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9120     std::list<NotifyArgs> unused =
9121             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9122                                /*changes=*/{});
9123 
9124     InputDeviceInfo info;
9125     controller.populateDeviceInfo(&info);
9126     std::vector<InputDeviceLightInfo> lights = info.getLights();
9127     ASSERT_EQ(1U, lights.size());
9128     ASSERT_EQ(InputDeviceLightType::KEYBOARD_MIC_MUTE, lights[0].type);
9129     ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
9130 }
9131 
TEST_F(LightControllerTest,MonoKeyboardBacklight)9132 TEST_F(LightControllerTest, MonoKeyboardBacklight) {
9133     RawLightInfo infoMono = {.id = 1,
9134                              .name = "mono_keyboard_backlight",
9135                              .maxBrightness = 255,
9136                              .flags = InputLightClass::BRIGHTNESS |
9137                                      InputLightClass::KEYBOARD_BACKLIGHT,
9138                              .path = ""};
9139     mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9140 
9141     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9142     InputDeviceInfo info;
9143     controller.populateDeviceInfo(&info);
9144     std::vector<InputDeviceLightInfo> lights = info.getLights();
9145     ASSERT_EQ(1U, lights.size());
9146     ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
9147     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9148 
9149     ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_BRIGHTNESS));
9150     ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_BRIGHTNESS);
9151 }
9152 
TEST_F(LightControllerTest,Ignore_MonoLight_WithPreferredBacklightLevels)9153 TEST_F(LightControllerTest, Ignore_MonoLight_WithPreferredBacklightLevels) {
9154     RawLightInfo infoMono = {.id = 1,
9155                              .name = "mono_light",
9156                              .maxBrightness = 255,
9157                              .flags = InputLightClass::BRIGHTNESS,
9158                              .path = ""};
9159     mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9160     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
9161                                             "0,100,200");
9162 
9163     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9164     std::list<NotifyArgs> unused =
9165             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9166                                /*changes=*/{});
9167 
9168     InputDeviceInfo info;
9169     controller.populateDeviceInfo(&info);
9170     std::vector<InputDeviceLightInfo> lights = info.getLights();
9171     ASSERT_EQ(1U, lights.size());
9172     ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
9173 }
9174 
TEST_F(LightControllerTest,KeyboardBacklight_WithNoPreferredBacklightLevels)9175 TEST_F(LightControllerTest, KeyboardBacklight_WithNoPreferredBacklightLevels) {
9176     RawLightInfo infoMono = {.id = 1,
9177                              .name = "mono_keyboard_backlight",
9178                              .maxBrightness = 255,
9179                              .flags = InputLightClass::BRIGHTNESS |
9180                                      InputLightClass::KEYBOARD_BACKLIGHT,
9181                              .path = ""};
9182     mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9183 
9184     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9185     std::list<NotifyArgs> unused =
9186             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9187                                /*changes=*/{});
9188 
9189     InputDeviceInfo info;
9190     controller.populateDeviceInfo(&info);
9191     std::vector<InputDeviceLightInfo> lights = info.getLights();
9192     ASSERT_EQ(1U, lights.size());
9193     ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
9194 }
9195 
TEST_F(LightControllerTest,KeyboardBacklight_WithPreferredBacklightLevels)9196 TEST_F(LightControllerTest, KeyboardBacklight_WithPreferredBacklightLevels) {
9197     RawLightInfo infoMono = {.id = 1,
9198                              .name = "mono_keyboard_backlight",
9199                              .maxBrightness = 255,
9200                              .flags = InputLightClass::BRIGHTNESS |
9201                                      InputLightClass::KEYBOARD_BACKLIGHT,
9202                              .path = ""};
9203     mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9204     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
9205                                             "0,100,200");
9206 
9207     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9208     std::list<NotifyArgs> unused =
9209             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9210                                /*changes=*/{});
9211 
9212     InputDeviceInfo info;
9213     controller.populateDeviceInfo(&info);
9214     std::vector<InputDeviceLightInfo> lights = info.getLights();
9215     ASSERT_EQ(1U, lights.size());
9216     ASSERT_EQ(3U, lights[0].preferredBrightnessLevels.size());
9217     std::set<BrightnessLevel>::iterator it = lights[0].preferredBrightnessLevels.begin();
9218     ASSERT_EQ(BrightnessLevel(0), *it);
9219     std::advance(it, 1);
9220     ASSERT_EQ(BrightnessLevel(100), *it);
9221     std::advance(it, 1);
9222     ASSERT_EQ(BrightnessLevel(200), *it);
9223 }
9224 
TEST_F(LightControllerTest,KeyboardBacklight_WithWrongPreferredBacklightLevels)9225 TEST_F(LightControllerTest, KeyboardBacklight_WithWrongPreferredBacklightLevels) {
9226     RawLightInfo infoMono = {.id = 1,
9227                              .name = "mono_keyboard_backlight",
9228                              .maxBrightness = 255,
9229                              .flags = InputLightClass::BRIGHTNESS |
9230                                      InputLightClass::KEYBOARD_BACKLIGHT,
9231                              .path = ""};
9232     mFakeEventHub->addRawLightInfo(infoMono.id, std::move(infoMono));
9233     mFakeEventHub->addConfigurationProperty(EVENTHUB_ID, "keyboard.backlight.brightnessLevels",
9234                                             "0,100,200,300,400,500");
9235 
9236     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9237     std::list<NotifyArgs> unused =
9238             mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
9239                                /*changes=*/{});
9240 
9241     InputDeviceInfo info;
9242     controller.populateDeviceInfo(&info);
9243     std::vector<InputDeviceLightInfo> lights = info.getLights();
9244     ASSERT_EQ(1U, lights.size());
9245     ASSERT_EQ(0U, lights[0].preferredBrightnessLevels.size());
9246 }
9247 
TEST_F(LightControllerTest,RGBLight)9248 TEST_F(LightControllerTest, RGBLight) {
9249     RawLightInfo infoRed = {.id = 1,
9250                             .name = "red",
9251                             .maxBrightness = 255,
9252                             .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
9253                             .path = ""};
9254     RawLightInfo infoGreen = {.id = 2,
9255                               .name = "green",
9256                               .maxBrightness = 255,
9257                               .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
9258                               .path = ""};
9259     RawLightInfo infoBlue = {.id = 3,
9260                              .name = "blue",
9261                              .maxBrightness = 255,
9262                              .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
9263                              .path = ""};
9264     mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
9265     mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
9266     mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
9267 
9268     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9269     InputDeviceInfo info;
9270     controller.populateDeviceInfo(&info);
9271     std::vector<InputDeviceLightInfo> lights = info.getLights();
9272     ASSERT_EQ(1U, lights.size());
9273     ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
9274     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9275     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
9276 
9277     ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
9278     ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
9279 }
9280 
TEST_F(LightControllerTest,CorrectRGBKeyboardBacklight)9281 TEST_F(LightControllerTest, CorrectRGBKeyboardBacklight) {
9282     RawLightInfo infoRed = {.id = 1,
9283                             .name = "red_keyboard_backlight",
9284                             .maxBrightness = 255,
9285                             .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED |
9286                                     InputLightClass::KEYBOARD_BACKLIGHT,
9287                             .path = ""};
9288     RawLightInfo infoGreen = {.id = 2,
9289                               .name = "green_keyboard_backlight",
9290                               .maxBrightness = 255,
9291                               .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN |
9292                                       InputLightClass::KEYBOARD_BACKLIGHT,
9293                               .path = ""};
9294     RawLightInfo infoBlue = {.id = 3,
9295                              .name = "blue_keyboard_backlight",
9296                              .maxBrightness = 255,
9297                              .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE |
9298                                      InputLightClass::KEYBOARD_BACKLIGHT,
9299                              .path = ""};
9300     mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
9301     mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
9302     mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
9303 
9304     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9305     InputDeviceInfo info;
9306     controller.populateDeviceInfo(&info);
9307     std::vector<InputDeviceLightInfo> lights = info.getLights();
9308     ASSERT_EQ(1U, lights.size());
9309     ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
9310     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9311     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
9312 
9313     ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
9314     ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
9315 }
9316 
TEST_F(LightControllerTest,IncorrectRGBKeyboardBacklight)9317 TEST_F(LightControllerTest, IncorrectRGBKeyboardBacklight) {
9318     RawLightInfo infoRed = {.id = 1,
9319                             .name = "red",
9320                             .maxBrightness = 255,
9321                             .flags = InputLightClass::BRIGHTNESS | InputLightClass::RED,
9322                             .path = ""};
9323     RawLightInfo infoGreen = {.id = 2,
9324                               .name = "green",
9325                               .maxBrightness = 255,
9326                               .flags = InputLightClass::BRIGHTNESS | InputLightClass::GREEN,
9327                               .path = ""};
9328     RawLightInfo infoBlue = {.id = 3,
9329                              .name = "blue",
9330                              .maxBrightness = 255,
9331                              .flags = InputLightClass::BRIGHTNESS | InputLightClass::BLUE,
9332                              .path = ""};
9333     RawLightInfo infoGlobal = {.id = 3,
9334                                .name = "global_keyboard_backlight",
9335                                .maxBrightness = 255,
9336                                .flags = InputLightClass::BRIGHTNESS | InputLightClass::GLOBAL |
9337                                        InputLightClass::KEYBOARD_BACKLIGHT,
9338                                .path = ""};
9339     mFakeEventHub->addRawLightInfo(infoRed.id, std::move(infoRed));
9340     mFakeEventHub->addRawLightInfo(infoGreen.id, std::move(infoGreen));
9341     mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoBlue));
9342     mFakeEventHub->addRawLightInfo(infoBlue.id, std::move(infoGlobal));
9343 
9344     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9345     InputDeviceInfo info;
9346     controller.populateDeviceInfo(&info);
9347     std::vector<InputDeviceLightInfo> lights = info.getLights();
9348     ASSERT_EQ(1U, lights.size());
9349     ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
9350     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9351     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
9352 
9353     ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
9354     ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
9355 }
9356 
TEST_F(LightControllerTest,MultiColorRGBLight)9357 TEST_F(LightControllerTest, MultiColorRGBLight) {
9358     RawLightInfo infoColor = {.id = 1,
9359                               .name = "multi_color",
9360                               .maxBrightness = 255,
9361                               .flags = InputLightClass::BRIGHTNESS |
9362                                       InputLightClass::MULTI_INTENSITY |
9363                                       InputLightClass::MULTI_INDEX,
9364                               .path = ""};
9365 
9366     mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
9367 
9368     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9369     InputDeviceInfo info;
9370     controller.populateDeviceInfo(&info);
9371     std::vector<InputDeviceLightInfo> lights = info.getLights();
9372     ASSERT_EQ(1U, lights.size());
9373     ASSERT_EQ(InputDeviceLightType::INPUT, lights[0].type);
9374     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9375     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
9376 
9377     ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
9378     ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
9379 }
9380 
TEST_F(LightControllerTest,MultiColorRGBKeyboardBacklight)9381 TEST_F(LightControllerTest, MultiColorRGBKeyboardBacklight) {
9382     RawLightInfo infoColor = {.id = 1,
9383                               .name = "multi_color_keyboard_backlight",
9384                               .maxBrightness = 255,
9385                               .flags = InputLightClass::BRIGHTNESS |
9386                                       InputLightClass::MULTI_INTENSITY |
9387                                       InputLightClass::MULTI_INDEX |
9388                                       InputLightClass::KEYBOARD_BACKLIGHT,
9389                               .path = ""};
9390 
9391     mFakeEventHub->addRawLightInfo(infoColor.id, std::move(infoColor));
9392 
9393     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9394     InputDeviceInfo info;
9395     controller.populateDeviceInfo(&info);
9396     std::vector<InputDeviceLightInfo> lights = info.getLights();
9397     ASSERT_EQ(1U, lights.size());
9398     ASSERT_EQ(InputDeviceLightType::KEYBOARD_BACKLIGHT, lights[0].type);
9399     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9400     ASSERT_TRUE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
9401 
9402     ASSERT_TRUE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
9403     ASSERT_EQ(controller.getLightColor(lights[0].id).value_or(-1), LIGHT_COLOR);
9404 }
9405 
TEST_F(LightControllerTest,SonyPlayerIdLight)9406 TEST_F(LightControllerTest, SonyPlayerIdLight) {
9407     RawLightInfo info1 = {.id = 1,
9408                           .name = "sony1",
9409                           .maxBrightness = 255,
9410                           .flags = InputLightClass::BRIGHTNESS,
9411                           .path = ""};
9412     RawLightInfo info2 = {.id = 2,
9413                           .name = "sony2",
9414                           .maxBrightness = 255,
9415                           .flags = InputLightClass::BRIGHTNESS,
9416                           .path = ""};
9417     RawLightInfo info3 = {.id = 3,
9418                           .name = "sony3",
9419                           .maxBrightness = 255,
9420                           .flags = InputLightClass::BRIGHTNESS,
9421                           .path = ""};
9422     RawLightInfo info4 = {.id = 4,
9423                           .name = "sony4",
9424                           .maxBrightness = 255,
9425                           .flags = InputLightClass::BRIGHTNESS,
9426                           .path = ""};
9427     mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
9428     mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
9429     mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
9430     mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
9431 
9432     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9433     InputDeviceInfo info;
9434     controller.populateDeviceInfo(&info);
9435     std::vector<InputDeviceLightInfo> lights = info.getLights();
9436     ASSERT_EQ(1U, lights.size());
9437     ASSERT_STREQ("sony", lights[0].name.c_str());
9438     ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
9439     ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9440     ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
9441 
9442     ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
9443     ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
9444     ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
9445     ASSERT_STREQ("sony", lights[0].name.c_str());
9446 }
9447 
TEST_F(LightControllerTest,PlayerIdLight)9448 TEST_F(LightControllerTest, PlayerIdLight) {
9449     RawLightInfo info1 = {.id = 1,
9450                           .name = "player-1",
9451                           .maxBrightness = 255,
9452                           .flags = InputLightClass::BRIGHTNESS,
9453                           .path = ""};
9454     RawLightInfo info2 = {.id = 2,
9455                           .name = "player-2",
9456                           .maxBrightness = 255,
9457                           .flags = InputLightClass::BRIGHTNESS,
9458                           .path = ""};
9459     RawLightInfo info3 = {.id = 3,
9460                           .name = "player-3",
9461                           .maxBrightness = 255,
9462                           .flags = InputLightClass::BRIGHTNESS,
9463                           .path = ""};
9464     RawLightInfo info4 = {.id = 4,
9465                           .name = "player-4",
9466                           .maxBrightness = 255,
9467                           .flags = InputLightClass::BRIGHTNESS,
9468                           .path = ""};
9469     mFakeEventHub->addRawLightInfo(info1.id, std::move(info1));
9470     mFakeEventHub->addRawLightInfo(info2.id, std::move(info2));
9471     mFakeEventHub->addRawLightInfo(info3.id, std::move(info3));
9472     mFakeEventHub->addRawLightInfo(info4.id, std::move(info4));
9473 
9474     PeripheralController& controller = addControllerAndConfigure<PeripheralController>();
9475     InputDeviceInfo info;
9476     controller.populateDeviceInfo(&info);
9477     std::vector<InputDeviceLightInfo> lights = info.getLights();
9478     ASSERT_EQ(1U, lights.size());
9479     ASSERT_STREQ("player", lights[0].name.c_str());
9480     ASSERT_EQ(InputDeviceLightType::PLAYER_ID, lights[0].type);
9481     ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS));
9482     ASSERT_FALSE(lights[0].capabilityFlags.test(InputDeviceLightCapability::RGB));
9483 
9484     ASSERT_FALSE(controller.setLightColor(lights[0].id, LIGHT_COLOR));
9485     ASSERT_TRUE(controller.setLightPlayerId(lights[0].id, LIGHT_PLAYER_ID));
9486     ASSERT_EQ(controller.getLightPlayerId(lights[0].id).value_or(-1), LIGHT_PLAYER_ID);
9487 }
9488 
9489 } // namespace android
9490