• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 #include <gestures/HardwareStateConverter.h>
17 
18 #include <memory>
19 
20 #include <EventHub.h>
21 #include <com_android_input_flags.h>
22 #include <flag_macros.h>
23 #include <gtest/gtest.h>
24 #include <linux/input-event-codes.h>
25 #include <utils/StrongPointer.h>
26 
27 #include "FakeEventHub.h"
28 #include "FakeInputReaderPolicy.h"
29 #include "InstrumentedInputReader.h"
30 #include "MultiTouchMotionAccumulator.h"
31 #include "TestConstants.h"
32 #include "TestInputListener.h"
33 
34 namespace android {
35 
36 namespace {
37 
38 const auto REPORT_PALMS =
39         ACONFIG_FLAG(com::android::input::flags, report_palms_to_gestures_library);
40 
41 } // namespace
42 
43 class HardwareStateConverterTest : public testing::Test {
44 public:
HardwareStateConverterTest()45     HardwareStateConverterTest()
46           : mFakeEventHub(std::make_shared<FakeEventHub>()),
47             mFakePolicy(sp<FakeInputReaderPolicy>::make()),
48             mReader(mFakeEventHub, mFakePolicy, mFakeListener),
49             mDevice(newDevice()),
50             mDeviceContext(*mDevice, EVENTHUB_ID) {
51         const size_t slotCount = 8;
52         mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, 0, slotCount - 1, 0, 0, 0);
53         mAccumulator.configure(mDeviceContext, slotCount, /*usingSlotsProtocol=*/true);
54         mConverter = std::make_unique<HardwareStateConverter>(mDeviceContext, mAccumulator);
55     }
56 
57 protected:
58     static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
59     static constexpr int32_t EVENTHUB_ID = 1;
60 
newDevice()61     std::shared_ptr<InputDevice> newDevice() {
62         InputDeviceIdentifier identifier;
63         identifier.name = "device";
64         identifier.location = "USB1";
65         identifier.bus = 0;
66         std::shared_ptr<InputDevice> device =
67                 std::make_shared<InputDevice>(mReader.getContext(), DEVICE_ID, /*generation=*/2,
68                                               identifier);
69         mReader.pushNextDevice(device);
70         mFakeEventHub->addDevice(EVENTHUB_ID, identifier.name, InputDeviceClass::TOUCHPAD,
71                                  identifier.bus);
72         mReader.loopOnce();
73         return device;
74     }
75 
processAxis(nsecs_t when,int32_t type,int32_t code,int32_t value)76     void processAxis(nsecs_t when, int32_t type, int32_t code, int32_t value) {
77         RawEvent event;
78         event.when = when;
79         event.readTime = READ_TIME;
80         event.deviceId = EVENTHUB_ID;
81         event.type = type;
82         event.code = code;
83         event.value = value;
84         std::optional<SelfContainedHardwareState> schs = mConverter->processRawEvent(event);
85         EXPECT_FALSE(schs.has_value());
86     }
87 
processSync(nsecs_t when)88     std::optional<SelfContainedHardwareState> processSync(nsecs_t when) {
89         RawEvent event;
90         event.when = when;
91         event.readTime = READ_TIME;
92         event.deviceId = EVENTHUB_ID;
93         event.type = EV_SYN;
94         event.code = SYN_REPORT;
95         event.value = 0;
96         return mConverter->processRawEvent(event);
97     }
98 
99     std::shared_ptr<FakeEventHub> mFakeEventHub;
100     sp<FakeInputReaderPolicy> mFakePolicy;
101     TestInputListener mFakeListener;
102     InstrumentedInputReader mReader;
103     std::shared_ptr<InputDevice> mDevice;
104     InputDeviceContext mDeviceContext;
105     MultiTouchMotionAccumulator mAccumulator;
106     std::unique_ptr<HardwareStateConverter> mConverter;
107 };
108 
TEST_F(HardwareStateConverterTest,OneFinger)109 TEST_F(HardwareStateConverterTest, OneFinger) {
110     const nsecs_t time = 1500000000;
111 
112     processAxis(time, EV_ABS, ABS_MT_SLOT, 0);
113     processAxis(time, EV_ABS, ABS_MT_TRACKING_ID, 123);
114     processAxis(time, EV_ABS, ABS_MT_POSITION_X, 50);
115     processAxis(time, EV_ABS, ABS_MT_POSITION_Y, 100);
116     processAxis(time, EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
117     processAxis(time, EV_ABS, ABS_MT_TOUCH_MINOR, 4);
118     processAxis(time, EV_ABS, ABS_MT_PRESSURE, 42);
119     processAxis(time, EV_ABS, ABS_MT_ORIENTATION, 2);
120 
121     processAxis(time, EV_ABS, ABS_X, 50);
122     processAxis(time, EV_ABS, ABS_Y, 100);
123     processAxis(time, EV_ABS, ABS_PRESSURE, 42);
124 
125     processAxis(time, EV_KEY, BTN_TOUCH, 1);
126     processAxis(time, EV_KEY, BTN_TOOL_FINGER, 1);
127     std::optional<SelfContainedHardwareState> schs = processSync(time);
128 
129     ASSERT_TRUE(schs.has_value());
130     const HardwareState& state = schs->state;
131     EXPECT_NEAR(1.5, state.timestamp, EPSILON);
132     EXPECT_EQ(0, state.buttons_down);
133     EXPECT_EQ(1, state.touch_cnt);
134 
135     ASSERT_EQ(1, state.finger_cnt);
136     const FingerState& finger = state.fingers[0];
137     EXPECT_EQ(123, finger.tracking_id);
138     EXPECT_NEAR(50, finger.position_x, EPSILON);
139     EXPECT_NEAR(100, finger.position_y, EPSILON);
140     EXPECT_NEAR(5, finger.touch_major, EPSILON);
141     EXPECT_NEAR(4, finger.touch_minor, EPSILON);
142     EXPECT_NEAR(42, finger.pressure, EPSILON);
143     EXPECT_NEAR(2, finger.orientation, EPSILON);
144     EXPECT_EQ(0u, finger.flags);
145 
146     EXPECT_EQ(0, state.rel_x);
147     EXPECT_EQ(0, state.rel_y);
148     EXPECT_EQ(0, state.rel_wheel);
149     EXPECT_EQ(0, state.rel_wheel_hi_res);
150     EXPECT_EQ(0, state.rel_hwheel);
151     EXPECT_NEAR(0.0, state.msc_timestamp, EPSILON);
152 }
153 
TEST_F(HardwareStateConverterTest,TwoFingers)154 TEST_F(HardwareStateConverterTest, TwoFingers) {
155     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
156     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
157     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
158     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
159     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
160     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, 4);
161     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, 42);
162     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, 2);
163 
164     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 1);
165     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 456);
166     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, -20);
167     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 40);
168     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, 8);
169     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, 7);
170     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, 21);
171     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, 1);
172 
173     processAxis(ARBITRARY_TIME, EV_ABS, ABS_X, 50);
174     processAxis(ARBITRARY_TIME, EV_ABS, ABS_Y, 100);
175     processAxis(ARBITRARY_TIME, EV_ABS, ABS_PRESSURE, 42);
176 
177     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
178     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
179     std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
180 
181     ASSERT_TRUE(schs.has_value());
182     ASSERT_EQ(2, schs->state.finger_cnt);
183     const FingerState& finger1 = schs->state.fingers[0];
184     EXPECT_EQ(123, finger1.tracking_id);
185     EXPECT_NEAR(50, finger1.position_x, EPSILON);
186     EXPECT_NEAR(100, finger1.position_y, EPSILON);
187     EXPECT_NEAR(5, finger1.touch_major, EPSILON);
188     EXPECT_NEAR(4, finger1.touch_minor, EPSILON);
189     EXPECT_NEAR(42, finger1.pressure, EPSILON);
190     EXPECT_NEAR(2, finger1.orientation, EPSILON);
191     EXPECT_EQ(0u, finger1.flags);
192 
193     const FingerState& finger2 = schs->state.fingers[1];
194     EXPECT_EQ(456, finger2.tracking_id);
195     EXPECT_NEAR(-20, finger2.position_x, EPSILON);
196     EXPECT_NEAR(40, finger2.position_y, EPSILON);
197     EXPECT_NEAR(8, finger2.touch_major, EPSILON);
198     EXPECT_NEAR(7, finger2.touch_minor, EPSILON);
199     EXPECT_NEAR(21, finger2.pressure, EPSILON);
200     EXPECT_NEAR(1, finger2.orientation, EPSILON);
201     EXPECT_EQ(0u, finger2.flags);
202 }
203 
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OnePalmDisableReportPalms,REQUIRES_FLAGS_DISABLED (REPORT_PALMS))204 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OnePalmDisableReportPalms,
205                   REQUIRES_FLAGS_DISABLED(REPORT_PALMS)) {
206     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
207     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
208     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
209     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
210     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
211 
212     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
213     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
214     std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
215     ASSERT_TRUE(schs.has_value());
216     EXPECT_EQ(0, schs->state.touch_cnt);
217     EXPECT_EQ(0, schs->state.finger_cnt);
218 }
219 
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OnePalmEnableReportPalms,REQUIRES_FLAGS_ENABLED (REPORT_PALMS))220 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OnePalmEnableReportPalms,
221                   REQUIRES_FLAGS_ENABLED(REPORT_PALMS)) {
222     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
223     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
224     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
225     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
226     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
227 
228     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
229     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
230     std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
231     ASSERT_TRUE(schs.has_value());
232     EXPECT_EQ(1, schs->state.touch_cnt);
233     EXPECT_EQ(1, schs->state.finger_cnt);
234     EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
235 }
236 
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OneFingerTurningIntoAPalmDisableReportPalms,REQUIRES_FLAGS_DISABLED (REPORT_PALMS))237 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OneFingerTurningIntoAPalmDisableReportPalms,
238                   REQUIRES_FLAGS_DISABLED(REPORT_PALMS)) {
239     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
240     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
241     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
242     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
243     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
244 
245     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
246     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
247 
248     std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
249     ASSERT_TRUE(schs.has_value());
250     EXPECT_EQ(1, schs->state.touch_cnt);
251     EXPECT_EQ(1, schs->state.finger_cnt);
252 
253     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
254     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 51);
255     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 99);
256 
257     schs = processSync(ARBITRARY_TIME);
258     ASSERT_TRUE(schs.has_value());
259     EXPECT_EQ(0, schs->state.touch_cnt);
260     ASSERT_EQ(0, schs->state.finger_cnt);
261 
262     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 53);
263     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 97);
264 
265     schs = processSync(ARBITRARY_TIME);
266     ASSERT_TRUE(schs.has_value());
267     EXPECT_EQ(0, schs->state.touch_cnt);
268     EXPECT_EQ(0, schs->state.finger_cnt);
269 
270     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
271     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 55);
272     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 95);
273     schs = processSync(ARBITRARY_TIME);
274     ASSERT_TRUE(schs.has_value());
275     EXPECT_EQ(1, schs->state.touch_cnt);
276     ASSERT_EQ(1, schs->state.finger_cnt);
277     const FingerState& newFinger = schs->state.fingers[0];
278     EXPECT_EQ(123, newFinger.tracking_id);
279     EXPECT_NEAR(55, newFinger.position_x, EPSILON);
280     EXPECT_NEAR(95, newFinger.position_y, EPSILON);
281 }
282 
TEST_F_WITH_FLAGS(HardwareStateConverterTest,OneFingerTurningIntoAPalmEnableReportPalms,REQUIRES_FLAGS_ENABLED (REPORT_PALMS))283 TEST_F_WITH_FLAGS(HardwareStateConverterTest, OneFingerTurningIntoAPalmEnableReportPalms,
284                   REQUIRES_FLAGS_ENABLED(REPORT_PALMS)) {
285     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
286     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
287     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
288     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
289     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
290 
291     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
292     processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
293 
294     std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
295     ASSERT_TRUE(schs.has_value());
296     EXPECT_EQ(1, schs->state.touch_cnt);
297     EXPECT_EQ(1, schs->state.finger_cnt);
298     EXPECT_EQ(FingerState::ToolType::kFinger, schs->state.fingers[0].tool_type);
299 
300     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
301     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 51);
302     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 99);
303 
304     schs = processSync(ARBITRARY_TIME);
305     ASSERT_TRUE(schs.has_value());
306     EXPECT_EQ(1, schs->state.touch_cnt);
307     ASSERT_EQ(1, schs->state.finger_cnt);
308     EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
309 
310     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 53);
311     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 97);
312 
313     schs = processSync(ARBITRARY_TIME);
314     ASSERT_TRUE(schs.has_value());
315     EXPECT_EQ(1, schs->state.touch_cnt);
316     EXPECT_EQ(1, schs->state.finger_cnt);
317     EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
318 
319     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
320     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 55);
321     processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 95);
322     schs = processSync(ARBITRARY_TIME);
323     ASSERT_TRUE(schs.has_value());
324     EXPECT_EQ(1, schs->state.touch_cnt);
325     ASSERT_EQ(1, schs->state.finger_cnt);
326     const FingerState& newFinger = schs->state.fingers[0];
327     EXPECT_EQ(FingerState::ToolType::kFinger, newFinger.tool_type);
328     EXPECT_EQ(123, newFinger.tracking_id);
329     EXPECT_NEAR(55, newFinger.position_x, EPSILON);
330     EXPECT_NEAR(95, newFinger.position_y, EPSILON);
331 }
332 
TEST_F(HardwareStateConverterTest,ButtonPressed)333 TEST_F(HardwareStateConverterTest, ButtonPressed) {
334     processAxis(ARBITRARY_TIME, EV_KEY, BTN_LEFT, 1);
335     std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
336 
337     ASSERT_TRUE(schs.has_value());
338     EXPECT_EQ(GESTURES_BUTTON_LEFT, schs->state.buttons_down);
339 }
340 
TEST_F(HardwareStateConverterTest,MscTimestamp)341 TEST_F(HardwareStateConverterTest, MscTimestamp) {
342     processAxis(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1200000);
343     std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
344 
345     ASSERT_TRUE(schs.has_value());
346     EXPECT_NEAR(1.2, schs->state.msc_timestamp, EPSILON);
347 }
348 
349 } // namespace android
350