1 /*
2 * Copyright 2023 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/HardwareProperties.h>
17
18 #include <memory>
19 #include <set>
20
21 #include <gtest/gtest.h>
22 #include <linux/input-event-codes.h>
23
24 #include "EventHub.h"
25 #include "InputDevice.h"
26 #include "InterfaceMocks.h"
27 #include "TestConstants.h"
28 #include "include/gestures.h"
29
30 namespace android {
31
32 using testing::Return;
33
34 class HardwarePropertiesTest : public testing::Test {
35 public:
HardwarePropertiesTest()36 HardwarePropertiesTest() {
37 EXPECT_CALL(mMockInputReaderContext, getEventHub()).WillRepeatedly(Return(&mMockEventHub));
38 InputDeviceIdentifier identifier;
39 identifier.name = "device";
40 identifier.location = "USB1";
41 mDevice = std::make_unique<InputDevice>(&mMockInputReaderContext, DEVICE_ID,
42 /*generation=*/2, identifier);
43 mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID);
44 }
45
46 protected:
47 static constexpr int32_t DEVICE_ID = END_RESERVED_ID + 1000;
48 static constexpr int32_t EVENTHUB_ID = 1;
49
setupValidAxis(int axis,int32_t min,int32_t max,int32_t resolution)50 void setupValidAxis(int axis, int32_t min, int32_t max, int32_t resolution) {
51 EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis))
52 .WillRepeatedly(Return(std::optional<RawAbsoluteAxisInfo>{{
53 .minValue = min,
54 .maxValue = max,
55 .flat = 0,
56 .fuzz = 0,
57 .resolution = resolution,
58 }}));
59 }
60
setupInvalidAxis(int axis)61 void setupInvalidAxis(int axis) {
62 EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis))
63 .WillRepeatedly(Return(std::nullopt));
64 }
65
setProperty(int property,bool value)66 void setProperty(int property, bool value) {
67 EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, property))
68 .WillRepeatedly(Return(value));
69 }
70
setButtonsPresent(std::set<int> buttonCodes,bool present)71 void setButtonsPresent(std::set<int> buttonCodes, bool present) {
72 for (const auto& buttonCode : buttonCodes) {
73 EXPECT_CALL(mMockEventHub, hasScanCode(EVENTHUB_ID, buttonCode))
74 .WillRepeatedly(Return(present));
75 }
76 }
77
78 MockEventHubInterface mMockEventHub;
79 MockInputReaderContext mMockInputReaderContext;
80 std::unique_ptr<InputDevice> mDevice;
81 std::unique_ptr<InputDeviceContext> mDeviceContext;
82 };
83
TEST_F(HardwarePropertiesTest,FancyTouchpad)84 TEST_F(HardwarePropertiesTest, FancyTouchpad) {
85 setupValidAxis(ABS_MT_POSITION_X, 0, 2048, 27);
86 setupValidAxis(ABS_MT_POSITION_Y, 0, 1500, 30);
87 setupValidAxis(ABS_MT_ORIENTATION, -3, 4, 0);
88 setupValidAxis(ABS_MT_SLOT, 0, 15, 0);
89 setupValidAxis(ABS_MT_PRESSURE, 0, 256, 0);
90
91 setProperty(INPUT_PROP_SEMI_MT, false);
92 setProperty(INPUT_PROP_BUTTONPAD, true);
93
94 setButtonsPresent({BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP,
95 BTN_TOOL_QUINTTAP},
96 true);
97
98 HardwareProperties hwprops = createHardwareProperties(*mDeviceContext);
99 EXPECT_NEAR(0, hwprops.left, EPSILON);
100 EXPECT_NEAR(0, hwprops.top, EPSILON);
101 EXPECT_NEAR(2048, hwprops.right, EPSILON);
102 EXPECT_NEAR(1500, hwprops.bottom, EPSILON);
103
104 EXPECT_NEAR(27, hwprops.res_x, EPSILON);
105 EXPECT_NEAR(30, hwprops.res_y, EPSILON);
106
107 EXPECT_NEAR(-3, hwprops.orientation_minimum, EPSILON);
108 EXPECT_NEAR(4, hwprops.orientation_maximum, EPSILON);
109
110 EXPECT_EQ(16, hwprops.max_finger_cnt);
111 EXPECT_EQ(5, hwprops.max_touch_cnt);
112
113 EXPECT_FALSE(hwprops.supports_t5r2);
114 EXPECT_FALSE(hwprops.support_semi_mt);
115 EXPECT_TRUE(hwprops.is_button_pad);
116 EXPECT_FALSE(hwprops.has_wheel);
117 EXPECT_FALSE(hwprops.wheel_is_hi_res);
118 EXPECT_FALSE(hwprops.is_haptic_pad);
119 EXPECT_TRUE(hwprops.reports_pressure);
120 }
121
TEST_F(HardwarePropertiesTest,BasicTouchpad)122 TEST_F(HardwarePropertiesTest, BasicTouchpad) {
123 setupValidAxis(ABS_MT_POSITION_X, 0, 1024, 0);
124 setupValidAxis(ABS_MT_POSITION_Y, 0, 768, 0);
125 setupValidAxis(ABS_MT_SLOT, 0, 7, 0);
126
127 setupInvalidAxis(ABS_MT_ORIENTATION);
128 setupInvalidAxis(ABS_MT_PRESSURE);
129
130 setProperty(INPUT_PROP_SEMI_MT, false);
131 setProperty(INPUT_PROP_BUTTONPAD, false);
132
133 setButtonsPresent({BTN_TOOL_FINGER, BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP}, true);
134 setButtonsPresent({BTN_TOOL_QUADTAP, BTN_TOOL_QUINTTAP}, false);
135
136 HardwareProperties hwprops = createHardwareProperties(*mDeviceContext);
137 EXPECT_NEAR(0, hwprops.left, EPSILON);
138 EXPECT_NEAR(0, hwprops.top, EPSILON);
139 EXPECT_NEAR(1024, hwprops.right, EPSILON);
140 EXPECT_NEAR(768, hwprops.bottom, EPSILON);
141
142 EXPECT_NEAR(0, hwprops.res_x, EPSILON);
143 EXPECT_NEAR(0, hwprops.res_y, EPSILON);
144
145 EXPECT_NEAR(0, hwprops.orientation_minimum, EPSILON);
146 EXPECT_NEAR(0, hwprops.orientation_maximum, EPSILON);
147
148 EXPECT_EQ(8, hwprops.max_finger_cnt);
149 EXPECT_EQ(3, hwprops.max_touch_cnt);
150
151 EXPECT_FALSE(hwprops.supports_t5r2);
152 EXPECT_FALSE(hwprops.support_semi_mt);
153 EXPECT_FALSE(hwprops.is_button_pad);
154 EXPECT_FALSE(hwprops.has_wheel);
155 EXPECT_FALSE(hwprops.wheel_is_hi_res);
156 EXPECT_FALSE(hwprops.is_haptic_pad);
157 EXPECT_FALSE(hwprops.reports_pressure);
158 }
159
160 } // namespace android
161