• 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 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