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 class HardwareStateConverterTest : public testing::Test {
37 public:
HardwareStateConverterTest()38 HardwareStateConverterTest()
39 : mFakeEventHub(std::make_shared<FakeEventHub>()),
40 mFakePolicy(sp<FakeInputReaderPolicy>::make()),
41 mReader(mFakeEventHub, mFakePolicy, mFakeListener),
42 mDevice(newDevice()),
43 mDeviceContext(*mDevice, EVENTHUB_ID) {
44 const size_t slotCount = 8;
45 mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_MT_SLOT, 0, slotCount - 1, 0, 0, 0);
46 mAccumulator.configure(mDeviceContext, slotCount, /*usingSlotsProtocol=*/true);
47 mConverter = std::make_unique<HardwareStateConverter>(mDeviceContext, mAccumulator);
48 }
49
50 protected:
51 static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
52 static constexpr int32_t EVENTHUB_ID = 1;
53
newDevice()54 std::shared_ptr<InputDevice> newDevice() {
55 InputDeviceIdentifier identifier;
56 identifier.name = "device";
57 identifier.location = "USB1";
58 identifier.bus = 0;
59 std::shared_ptr<InputDevice> device =
60 std::make_shared<InputDevice>(mReader.getContext(), DEVICE_ID, /*generation=*/2,
61 identifier);
62 mReader.pushNextDevice(device);
63 mFakeEventHub->addDevice(EVENTHUB_ID, identifier.name, InputDeviceClass::TOUCHPAD,
64 identifier.bus);
65 mReader.loopOnce();
66 return device;
67 }
68
processAxis(nsecs_t when,int32_t type,int32_t code,int32_t value)69 void processAxis(nsecs_t when, int32_t type, int32_t code, int32_t value) {
70 RawEvent event;
71 event.when = when;
72 event.readTime = READ_TIME;
73 event.deviceId = EVENTHUB_ID;
74 event.type = type;
75 event.code = code;
76 event.value = value;
77 std::optional<SelfContainedHardwareState> schs = mConverter->processRawEvent(event);
78 EXPECT_FALSE(schs.has_value());
79 }
80
processSync(nsecs_t when)81 std::optional<SelfContainedHardwareState> processSync(nsecs_t when) {
82 RawEvent event;
83 event.when = when;
84 event.readTime = READ_TIME;
85 event.deviceId = EVENTHUB_ID;
86 event.type = EV_SYN;
87 event.code = SYN_REPORT;
88 event.value = 0;
89 return mConverter->processRawEvent(event);
90 }
91
92 std::shared_ptr<FakeEventHub> mFakeEventHub;
93 sp<FakeInputReaderPolicy> mFakePolicy;
94 TestInputListener mFakeListener;
95 InstrumentedInputReader mReader;
96 std::shared_ptr<InputDevice> mDevice;
97 InputDeviceContext mDeviceContext;
98 MultiTouchMotionAccumulator mAccumulator;
99 std::unique_ptr<HardwareStateConverter> mConverter;
100 };
101
TEST_F(HardwareStateConverterTest,OneFinger)102 TEST_F(HardwareStateConverterTest, OneFinger) {
103 const nsecs_t time = 1500000000;
104
105 processAxis(time, EV_ABS, ABS_MT_SLOT, 0);
106 processAxis(time, EV_ABS, ABS_MT_TRACKING_ID, 123);
107 processAxis(time, EV_ABS, ABS_MT_POSITION_X, 50);
108 processAxis(time, EV_ABS, ABS_MT_POSITION_Y, 100);
109 processAxis(time, EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
110 processAxis(time, EV_ABS, ABS_MT_TOUCH_MINOR, 4);
111 processAxis(time, EV_ABS, ABS_MT_PRESSURE, 42);
112 processAxis(time, EV_ABS, ABS_MT_ORIENTATION, 2);
113
114 processAxis(time, EV_ABS, ABS_X, 50);
115 processAxis(time, EV_ABS, ABS_Y, 100);
116 processAxis(time, EV_ABS, ABS_PRESSURE, 42);
117
118 processAxis(time, EV_KEY, BTN_TOUCH, 1);
119 processAxis(time, EV_KEY, BTN_TOOL_FINGER, 1);
120 std::optional<SelfContainedHardwareState> schs = processSync(time);
121
122 ASSERT_TRUE(schs.has_value());
123 const HardwareState& state = schs->state;
124 EXPECT_NEAR(1.5, state.timestamp, EPSILON);
125 EXPECT_EQ(0, state.buttons_down);
126 EXPECT_EQ(1, state.touch_cnt);
127
128 ASSERT_EQ(1, state.finger_cnt);
129 const FingerState& finger = state.fingers[0];
130 EXPECT_EQ(123, finger.tracking_id);
131 EXPECT_NEAR(50, finger.position_x, EPSILON);
132 EXPECT_NEAR(100, finger.position_y, EPSILON);
133 EXPECT_NEAR(5, finger.touch_major, EPSILON);
134 EXPECT_NEAR(4, finger.touch_minor, EPSILON);
135 EXPECT_NEAR(42, finger.pressure, EPSILON);
136 EXPECT_NEAR(2, finger.orientation, EPSILON);
137 EXPECT_EQ(0u, finger.flags);
138
139 EXPECT_EQ(0, state.rel_x);
140 EXPECT_EQ(0, state.rel_y);
141 EXPECT_EQ(0, state.rel_wheel);
142 EXPECT_EQ(0, state.rel_wheel_hi_res);
143 EXPECT_EQ(0, state.rel_hwheel);
144 EXPECT_NEAR(0.0, state.msc_timestamp, EPSILON);
145 }
146
TEST_F(HardwareStateConverterTest,TwoFingers)147 TEST_F(HardwareStateConverterTest, TwoFingers) {
148 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
149 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
150 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
151 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
152 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, 5);
153 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, 4);
154 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, 42);
155 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, 2);
156
157 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 1);
158 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 456);
159 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, -20);
160 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 40);
161 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, 8);
162 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, 7);
163 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, 21);
164 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, 1);
165
166 processAxis(ARBITRARY_TIME, EV_ABS, ABS_X, 50);
167 processAxis(ARBITRARY_TIME, EV_ABS, ABS_Y, 100);
168 processAxis(ARBITRARY_TIME, EV_ABS, ABS_PRESSURE, 42);
169
170 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
171 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
172 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
173
174 ASSERT_TRUE(schs.has_value());
175 ASSERT_EQ(2, schs->state.finger_cnt);
176 const FingerState& finger1 = schs->state.fingers[0];
177 EXPECT_EQ(123, finger1.tracking_id);
178 EXPECT_NEAR(50, finger1.position_x, EPSILON);
179 EXPECT_NEAR(100, finger1.position_y, EPSILON);
180 EXPECT_NEAR(5, finger1.touch_major, EPSILON);
181 EXPECT_NEAR(4, finger1.touch_minor, EPSILON);
182 EXPECT_NEAR(42, finger1.pressure, EPSILON);
183 EXPECT_NEAR(2, finger1.orientation, EPSILON);
184 EXPECT_EQ(0u, finger1.flags);
185
186 const FingerState& finger2 = schs->state.fingers[1];
187 EXPECT_EQ(456, finger2.tracking_id);
188 EXPECT_NEAR(-20, finger2.position_x, EPSILON);
189 EXPECT_NEAR(40, finger2.position_y, EPSILON);
190 EXPECT_NEAR(8, finger2.touch_major, EPSILON);
191 EXPECT_NEAR(7, finger2.touch_minor, EPSILON);
192 EXPECT_NEAR(21, finger2.pressure, EPSILON);
193 EXPECT_NEAR(1, finger2.orientation, EPSILON);
194 EXPECT_EQ(0u, finger2.flags);
195 }
196
TEST_F(HardwareStateConverterTest,OnePalm)197 TEST_F(HardwareStateConverterTest, OnePalm) {
198 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
199 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
200 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
201 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
202 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
203
204 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
205 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
206 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
207 ASSERT_TRUE(schs.has_value());
208 EXPECT_EQ(1, schs->state.touch_cnt);
209 EXPECT_EQ(1, schs->state.finger_cnt);
210 EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
211 }
212
TEST_F(HardwareStateConverterTest,OneFingerTurningIntoAPalmEnableReportPalms)213 TEST_F(HardwareStateConverterTest, OneFingerTurningIntoAPalmEnableReportPalms) {
214 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, 0);
215 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
216 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, 123);
217 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 50);
218 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 100);
219
220 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
221 processAxis(ARBITRARY_TIME, EV_KEY, BTN_TOOL_FINGER, 1);
222
223 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
224 ASSERT_TRUE(schs.has_value());
225 EXPECT_EQ(1, schs->state.touch_cnt);
226 EXPECT_EQ(1, schs->state.finger_cnt);
227 EXPECT_EQ(FingerState::ToolType::kFinger, schs->state.fingers[0].tool_type);
228
229 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_PALM);
230 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 51);
231 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 99);
232
233 schs = processSync(ARBITRARY_TIME);
234 ASSERT_TRUE(schs.has_value());
235 EXPECT_EQ(1, schs->state.touch_cnt);
236 ASSERT_EQ(1, schs->state.finger_cnt);
237 EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
238
239 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 53);
240 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 97);
241
242 schs = processSync(ARBITRARY_TIME);
243 ASSERT_TRUE(schs.has_value());
244 EXPECT_EQ(1, schs->state.touch_cnt);
245 EXPECT_EQ(1, schs->state.finger_cnt);
246 EXPECT_EQ(FingerState::ToolType::kPalm, schs->state.fingers[0].tool_type);
247
248 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, MT_TOOL_FINGER);
249 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, 55);
250 processAxis(ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, 95);
251 schs = processSync(ARBITRARY_TIME);
252 ASSERT_TRUE(schs.has_value());
253 EXPECT_EQ(1, schs->state.touch_cnt);
254 ASSERT_EQ(1, schs->state.finger_cnt);
255 const FingerState& newFinger = schs->state.fingers[0];
256 EXPECT_EQ(FingerState::ToolType::kFinger, newFinger.tool_type);
257 EXPECT_EQ(123, newFinger.tracking_id);
258 EXPECT_NEAR(55, newFinger.position_x, EPSILON);
259 EXPECT_NEAR(95, newFinger.position_y, EPSILON);
260 }
261
TEST_F(HardwareStateConverterTest,ButtonPressed)262 TEST_F(HardwareStateConverterTest, ButtonPressed) {
263 processAxis(ARBITRARY_TIME, EV_KEY, BTN_LEFT, 1);
264 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
265
266 ASSERT_TRUE(schs.has_value());
267 EXPECT_EQ(GESTURES_BUTTON_LEFT, schs->state.buttons_down);
268 }
269
TEST_F(HardwareStateConverterTest,MscTimestamp)270 TEST_F(HardwareStateConverterTest, MscTimestamp) {
271 processAxis(ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, 1200000);
272 std::optional<SelfContainedHardwareState> schs = processSync(ARBITRARY_TIME);
273
274 ASSERT_TRUE(schs.has_value());
275 EXPECT_NEAR(1.2, schs->state.msc_timestamp, EPSILON);
276 }
277
278 } // namespace android
279