blob: 92cd462c9a8c6e7077d8d5bc5b2bacf9791cafec [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
22#include <thread>
23#include "FakePointerController.h"
24#include "InputMapperTest.h"
25#include "InterfaceMocks.h"
26#include "TestInputListenerMatchers.h"
27
28#define TAG "TouchpadInputMapper_test"
29
30namespace android {
31
32using testing::Return;
33using testing::VariantWith;
34constexpr auto ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN;
35constexpr auto ACTION_UP = AMOTION_EVENT_ACTION_UP;
36constexpr auto BUTTON_PRESS = AMOTION_EVENT_ACTION_BUTTON_PRESS;
37constexpr auto BUTTON_RELEASE = AMOTION_EVENT_ACTION_BUTTON_RELEASE;
38constexpr auto HOVER_MOVE = AMOTION_EVENT_ACTION_HOVER_MOVE;
39
40/**
41 * Unit tests for TouchpadInputMapper.
42 */
43class TouchpadInputMapperTest : public InputMapperUnitTest {
44protected:
45 void SetUp() override {
46 InputMapperUnitTest::SetUp();
47
48 // Present scan codes: BTN_TOUCH and BTN_TOOL_FINGER
49 expectScanCodes(/*present=*/true,
50 {BTN_LEFT, BTN_RIGHT, BTN_TOOL_FINGER, BTN_TOOL_QUINTTAP, BTN_TOUCH,
51 BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP});
52 // Missing scan codes that the mapper checks for.
53 expectScanCodes(/*present=*/false,
54 {BTN_TOOL_PEN, BTN_TOOL_RUBBER, BTN_TOOL_BRUSH, BTN_TOOL_PENCIL,
55 BTN_TOOL_AIRBRUSH});
56
57 // Current scan code state - all keys are UP by default
58 setScanCodeState(KeyState::UP, {BTN_TOUCH, BTN_STYLUS,
59 BTN_STYLUS2, BTN_0,
60 BTN_TOOL_FINGER, BTN_TOOL_PEN,
61 BTN_TOOL_RUBBER, BTN_TOOL_BRUSH,
62 BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH,
63 BTN_TOOL_MOUSE, BTN_TOOL_LENS,
64 BTN_TOOL_DOUBLETAP, BTN_TOOL_TRIPLETAP,
65 BTN_TOOL_QUADTAP, BTN_TOOL_QUINTTAP,
66 BTN_LEFT, BTN_RIGHT,
67 BTN_MIDDLE, BTN_BACK,
68 BTN_SIDE, BTN_FORWARD,
69 BTN_EXTRA, BTN_TASK});
70
71 setKeyCodeState(KeyState::UP,
72 {AKEYCODE_STYLUS_BUTTON_PRIMARY, AKEYCODE_STYLUS_BUTTON_SECONDARY});
73
74 // Key mappings
75 EXPECT_CALL(mMockEventHub,
76 mapKey(EVENTHUB_ID, BTN_LEFT, /*usageCode=*/0, /*metaState=*/0, testing::_,
77 testing::_, testing::_))
78 .WillRepeatedly(Return(NAME_NOT_FOUND));
79
80 // Input properties - only INPUT_PROP_BUTTONPAD
81 EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_BUTTONPAD))
82 .WillRepeatedly(Return(true));
83 EXPECT_CALL(mMockEventHub, hasInputProperty(EVENTHUB_ID, INPUT_PROP_SEMI_MT))
84 .WillRepeatedly(Return(false));
85
86 // Axes that the device has
87 setupAxis(ABS_MT_SLOT, /*valid=*/true, /*min=*/0, /*max=*/4, /*resolution=*/0);
88 setupAxis(ABS_MT_POSITION_X, /*valid=*/true, /*min=*/0, /*max=*/2000, /*resolution=*/24);
89 setupAxis(ABS_MT_POSITION_Y, /*valid=*/true, /*min=*/0, /*max=*/1000, /*resolution=*/24);
90 setupAxis(ABS_MT_PRESSURE, /*valid=*/true, /*min*/ 0, /*max=*/255, /*resolution=*/0);
91 // Axes that the device does not have
92 setupAxis(ABS_MT_ORIENTATION, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
93 setupAxis(ABS_MT_TOUCH_MAJOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
94 setupAxis(ABS_MT_TOUCH_MINOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
95 setupAxis(ABS_MT_WIDTH_MAJOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
96 setupAxis(ABS_MT_WIDTH_MINOR, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
97
98 EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, testing::_))
99 .WillRepeatedly([](int32_t eventHubId, int32_t, int32_t* outValue) {
100 *outValue = 0;
101 return OK;
102 });
103 mMapper = createInputMapper<TouchpadInputMapper>(*mDeviceContext, mReaderConfiguration);
104 }
105};
106
107/**
108 * Start moving the finger and then click the left touchpad button. Check whether HOVER_EXIT is
109 * generated when hovering stops. Currently, it is not.
110 * In the current implementation, HOVER_MOVE and ACTION_DOWN events are not sent out right away,
111 * but only after the button is released.
112 */
113TEST_F(TouchpadInputMapperTest, HoverAndLeftButtonPress) {
114 std::list<NotifyArgs> args;
115
116 args += process(EV_ABS, ABS_MT_TRACKING_ID, 1);
117 args += process(EV_KEY, BTN_TOUCH, 1);
118 setScanCodeState(KeyState::DOWN, {BTN_TOOL_FINGER});
119 args += process(EV_KEY, BTN_TOOL_FINGER, 1);
120 args += process(EV_ABS, ABS_MT_POSITION_X, 50);
121 args += process(EV_ABS, ABS_MT_POSITION_Y, 50);
122 args += process(EV_ABS, ABS_MT_PRESSURE, 1);
123 args += process(EV_SYN, SYN_REPORT, 0);
124 ASSERT_THAT(args, testing::IsEmpty());
125
126 // Without this sleep, the test fails.
127 // TODO(b/284133337): Figure out whether this can be removed
128 std::this_thread::sleep_for(std::chrono::milliseconds(20));
129
130 args += process(EV_KEY, BTN_LEFT, 1);
131 setScanCodeState(KeyState::DOWN, {BTN_LEFT});
132 args += process(EV_SYN, SYN_REPORT, 0);
133
134 args += process(EV_KEY, BTN_LEFT, 0);
135 setScanCodeState(KeyState::UP, {BTN_LEFT});
136 args += process(EV_SYN, SYN_REPORT, 0);
137 ASSERT_THAT(args,
138 ElementsAre(VariantWith<NotifyMotionArgs>(WithMotionAction(HOVER_MOVE)),
139 VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_DOWN)),
140 VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_PRESS)),
141 VariantWith<NotifyMotionArgs>(WithMotionAction(BUTTON_RELEASE)),
142 VariantWith<NotifyMotionArgs>(WithMotionAction(ACTION_UP))));
143
144 // Liftoff
145 args.clear();
146 args += process(EV_ABS, ABS_MT_PRESSURE, 0);
147 args += process(EV_ABS, ABS_MT_TRACKING_ID, -1);
148 args += process(EV_KEY, BTN_TOUCH, 0);
149 setScanCodeState(KeyState::UP, {BTN_TOOL_FINGER});
150 args += process(EV_KEY, BTN_TOOL_FINGER, 0);
151 args += process(EV_SYN, SYN_REPORT, 0);
152 ASSERT_THAT(args, testing::IsEmpty());
153}
154
155} // namespace android