blob: 7a0005b4f57ac1420eed3987e0c36bc03f145928 [file] [log] [blame]
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -07001/*
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
17#include "TouchpadInputMapper.h"
18
19#include <android-base/logging.h>
20#include <gtest/gtest.h>
21
Byoungho Jungee6268f2023-10-30 17:27:26 +090022#include <com_android_input_flags.h>
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070023#include <thread>
24#include "FakePointerController.h"
25#include "InputMapperTest.h"
26#include "InterfaceMocks.h"
Prabir Pradhane3b28dd2023-10-06 04:19:29 +000027#include "TestEventMatchers.h"
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070028
29#define TAG "TouchpadInputMapper_test"
30
31namespace android {
32
33using testing::Return;
34using testing::VariantWith;
35constexpr auto ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN;
36constexpr auto ACTION_UP = AMOTION_EVENT_ACTION_UP;
37constexpr auto BUTTON_PRESS = AMOTION_EVENT_ACTION_BUTTON_PRESS;
38constexpr auto BUTTON_RELEASE = AMOTION_EVENT_ACTION_BUTTON_RELEASE;
39constexpr auto HOVER_MOVE = AMOTION_EVENT_ACTION_HOVER_MOVE;
Byoungho Jungee6268f2023-10-30 17:27:26 +090040constexpr int32_t DISPLAY_ID = 0;
41constexpr int32_t DISPLAY_WIDTH = 480;
42constexpr int32_t DISPLAY_HEIGHT = 800;
43constexpr std::optional<uint8_t> NO_PORT = std::nullopt; // no physical port is specified
44
45namespace input_flags = com::android::input::flags;
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070046
47/**
48 * Unit tests for TouchpadInputMapper.
49 */
Byoungho Jungee6268f2023-10-30 17:27:26 +090050class TouchpadInputMapperTestBase : public InputMapperUnitTest {
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -070051protected:
52 void SetUp() override {
53 InputMapperUnitTest::SetUp();
54
55 // Present scan codes: BTN_TOUCH and BTN_TOOL_FINGER
56 expectScanCodes(/*present=*/true,
57 {BTN_LEFT, BTN_RIGHT, BTN_TOOL_FINGER, BTN_TOOL_QUINTTAP, BTN_TOUCH,
58 BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP});
59 // Missing scan codes that the mapper checks for.
60 expectScanCodes(/*present=*/false,
61 {BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_BRUSH, BTN_TOOL_PENCIL,
62 BTN_TOOL_AIRBRUSH});
63
64 // Current scan code state - all keys are UP by default
65 setScanCodeState(KeyState::UP, {BTN_TOUCH, BTN_STYLUS,
66 BTN_STYLUS2, BTN_0,
67 BTN_TOOL_FINGER, BTN_TOOL_PEN,
68 BTN_TOOL_RUBBER, BTN_TOOL_BRUSH,
69 BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH,
70 BTN_TOOL_MOUSE, BTN_TOOL_LENS,
71 BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP,
72 BTN_TOOL_QUADTAP, BTN_TOOL_QUINTTAP,
73 BTN_LEFT, BTN_RIGHT,
74 BTN_MIDDLE, BTN_BACK,
75 BTN_SIDE, BTN_FORWARD,
76 BTN_EXTRA, BTN_TASK});
77
78 setKeyCodeState(KeyState::UP,
79 {AKEYCODE_STYLUS_BUTTON_PRIMARY, AKEYCODE_STYLUS_BUTTON_SECONDARY});
80
81 // Key mappings
82 EXPECT_CALL(mMockEventHub,
83 mapKey(EVENTHUB_ID, BTN_LEFT, /*usageCode=*/0, /*metaState=*/0, testing::_,
84 testing::_, testing::_))
85 .WillRepeatedly(Return(NAME_NOT_FOUND));
86
87 // Input properties - only INPUT_PROP_BUTTONPAD
88 EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_BUTTONPAD))
89 .WillRepeatedly(Return(true));
90 EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_SEMI_MT))
91 .WillRepeatedly(Return(false));
92
93 // Axes that the device has
94 setupAxis(ABS_MT_SLOT, /*valid=*/true, /*min=*/0, /*max=*/4, /*resolution=*/0);
95 setupAxis(ABS_MT_POSITION_X, /*valid=*/true, /*min=*/0, /*max=*/2000, /*resolution=*/24);
96 setupAxis(ABS_MT_POSITION_Y, /*valid=*/true, /*min=*/0, /*max=*/1000, /*resolution=*/24);
97 setupAxis(ABS_MT_PRESSURE, /*valid=*/true, /*min*/ 0, /*max=*/255, /*resolution=*/0);
98 // Axes that the device does not have
99 setupAxis(ABS_MT_ORIENTATION, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
100 setupAxis(ABS_MT_TOUCH_MAJOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
101 setupAxis(ABS_MT_TOUCH_MINOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
102 setupAxis(ABS_MT_WIDTH_MAJOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
103 setupAxis(ABS_MT_WIDTH_MINOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
104
105 EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, testing::_))
106 .WillRepeatedly([](int32_t eventHubId, int32_t, int32_t* outValue) {
107 *outValue = 0;
108 return OK;
109 });
110 mMapper = createInputMapper<TouchpadInputMapper>(*mDeviceContext, mReaderConfiguration);
111 }
112};
113
Byoungho Jungee6268f2023-10-30 17:27:26 +0900114class TouchpadInputMapperTest : public TouchpadInputMapperTestBase {
115protected:
116 void SetUp() override {
117 input_flags::enable_pointer_choreographer(false);
118 TouchpadInputMapperTestBase::SetUp();
119 }
120};
121
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700122/**
123 * Start moving the finger and then click the left touchpad button. Check whether HOVER_EXIT is
124 * generated when hovering stops. Currently, it is not.
125 * In the current implementation, HOVER_MOVE and ACTION_DOWN events are not sent out right away,
126 * but only after the button is released.
127 */
128TEST_F(TouchpadInputMapperTest, HoverAndLeftButtonPress) {
129 std::list<NotifyArgs> args;
130
131 args += process(EV_ABS, ABS_MT_TRACKING_ID, 1);
132 args += process(EV_KEY, BTN_TOUCH, 1);
133 setScanCodeState(KeyState::DOWN, {BTN_TOOL_FINGER});
134 args += process(EV_KEY, BTN_TOOL_FINGER, 1);
135 args += process(EV_ABS, ABS_MT_POSITION_X, 50);
136 args += process(EV_ABS, ABS_MT_POSITION_Y, 50);
137 args += process(EV_ABS, ABS_MT_PRESSURE, 1);
138 args += process(EV_SYN, SYN_REPORT, 0);
139 ASSERT_THAT(args, testing::IsEmpty());
140
141 // Without this sleep, the test fails.
142 // TODO(b/284133337): Figure out whether this can be removed
143 std::this_thread::sleep_for(std::chrono::milliseconds(20));
144
145 args += process(EV_KEY, BTN_LEFT, 1);
146 setScanCodeState(KeyState::DOWN, {BTN_LEFT});
147 args += process(EV_SYN, SYN_REPORT, 0);
148
149 args += process(EV_KEY, BTN_LEFT, 0);
150 setScanCodeState(KeyState::UP, {BTN_LEFT});
151 args += process(EV_SYN, SYN_REPORT, 0);
152 ASSERT_THAT(args,
153 ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE)),
154 VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_DOWN)),
155 VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_PRESS)),
156 VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_RELEASE)),
Harry Cutts48e7a402023-07-07 15:22:40 +0000157 VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_UP)),
158 VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700159
160 // Liftoff
161 args.clear();
162 args += process(EV_ABS, ABS_MT_PRESSURE, 0);
163 args += process(EV_ABS, ABS_MT_TRACKING_ID, -1);
164 args += process(EV_KEY, BTN_TOUCH, 0);
165 setScanCodeState(KeyState::UP, {BTN_TOOL_FINGER});
166 args += process(EV_KEY, BTN_TOOL_FINGER, 0);
167 args += process(EV_SYN, SYN_REPORT, 0);
168 ASSERT_THAT(args, testing::IsEmpty());
169}
170
Byoungho Jungee6268f2023-10-30 17:27:26 +0900171class TouchpadInputMapperTestWithChoreographer : public TouchpadInputMapperTestBase {
172protected:
173 void SetUp() override {
174 input_flags::enable_pointer_choreographer(true);
175 TouchpadInputMapperTestBase::SetUp();
176 }
177};
178
179/**
180 * Start moving the finger and then click the left touchpad button. Check whether HOVER_EXIT is
181 * generated when hovering stops. Currently, it is not.
182 * In the current implementation, HOVER_MOVE and ACTION_DOWN events are not sent out right away,
183 * but only after the button is released.
184 */
185TEST_F(TouchpadInputMapperTestWithChoreographer, HoverAndLeftButtonPress) {
186 mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
187 mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
188 /*isActive=*/true, "local:0", NO_PORT, ViewportType::INTERNAL);
189
190 std::list<NotifyArgs> args;
191
192 args += mMapper->reconfigure(systemTime(SYSTEM_TIME_MONOTONIC), mReaderConfiguration,
193 InputReaderConfiguration::Change::DISPLAY_INFO);
194 ASSERT_THAT(args, testing::IsEmpty());
195
196 args += process(EV_ABS, ABS_MT_TRACKING_ID, 1);
197 args += process(EV_KEY, BTN_TOUCH, 1);
198 setScanCodeState(KeyState::DOWN, {BTN_TOOL_FINGER});
199 args += process(EV_KEY, BTN_TOOL_FINGER, 1);
200 args += process(EV_ABS, ABS_MT_POSITION_X, 50);
201 args += process(EV_ABS, ABS_MT_POSITION_Y, 50);
202 args += process(EV_ABS, ABS_MT_PRESSURE, 1);
203 args += process(EV_SYN, SYN_REPORT, 0);
204 ASSERT_THAT(args, testing::IsEmpty());
205
206 // Without this sleep, the test fails.
207 // TODO(b/284133337): Figure out whether this can be removed
208 std::this_thread::sleep_for(std::chrono::milliseconds(20));
209
210 args += process(EV_KEY, BTN_LEFT, 1);
211 setScanCodeState(KeyState::DOWN, {BTN_LEFT});
212 args += process(EV_SYN, SYN_REPORT, 0);
213
214 args += process(EV_KEY, BTN_LEFT, 0);
215 setScanCodeState(KeyState::UP, {BTN_LEFT});
216 args += process(EV_SYN, SYN_REPORT, 0);
217 ASSERT_THAT(args,
218 ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE)),
219 VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_DOWN)),
220 VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_PRESS)),
221 VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_RELEASE)),
222 VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_UP)),
223 VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE))));
224
225 // Liftoff
226 args.clear();
227 args += process(EV_ABS, ABS_MT_PRESSURE, 0);
228 args += process(EV_ABS, ABS_MT_TRACKING_ID, -1);
229 args += process(EV_KEY, BTN_TOUCH, 0);
230 setScanCodeState(KeyState::UP, {BTN_TOOL_FINGER});
231 args += process(EV_KEY, BTN_TOOL_FINGER, 0);
232 args += process(EV_SYN, SYN_REPORT, 0);
233 ASSERT_THAT(args, testing::IsEmpty());
234}
235
Siarhei Vishniakou979f2d82023-05-16 14:26:24 -0700236} // namespace android