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