blob: dec78aa21edc0781b1328dd28c43cf16b031b5b4 [file] [log] [blame]
Paul Ramireze2bb1872024-08-12 20:21:13 +00001/**
2 * Copyright 2024 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 <input/InputConsumerNoResampling.h>
18
19#include <memory>
20#include <optional>
21#include <utility>
22
Paul Ramirez00cf5d02024-09-05 17:10:12 +000023#include <TestEventMatchers.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000024#include <TestInputChannel.h>
25#include <TestLooper.h>
26#include <android-base/logging.h>
Paul Ramirez00cf5d02024-09-05 17:10:12 +000027#include <gmock/gmock.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000028#include <gtest/gtest.h>
29#include <input/BlockingQueue.h>
30#include <input/InputEventBuilders.h>
31#include <utils/StrongPointer.h>
32
33namespace android {
34
Paul Ramirezcd7488c2024-09-13 23:01:12 +000035namespace {
36
37using std::chrono::nanoseconds;
38
Paul Ramirez00cf5d02024-09-05 17:10:12 +000039using ::testing::AllOf;
40using ::testing::Matcher;
41using ::testing::Not;
42
Paul Ramirezcd7488c2024-09-13 23:01:12 +000043} // namespace
44
Paul Ramireze2bb1872024-08-12 20:21:13 +000045class InputConsumerTest : public testing::Test, public InputConsumerCallbacks {
46protected:
47 InputConsumerTest()
48 : mClientTestChannel{std::make_shared<TestInputChannel>("TestChannel")},
49 mTestLooper{std::make_shared<TestLooper>()} {
50 Looper::setForThread(mTestLooper->getLooper());
Paul Ramirezcd7488c2024-09-13 23:01:12 +000051 mConsumer =
52 std::make_unique<InputConsumerNoResampling>(mClientTestChannel, mTestLooper, *this,
53 std::make_unique<LegacyResampler>());
Paul Ramireze2bb1872024-08-12 20:21:13 +000054 }
55
Paul Ramirez00cf5d02024-09-05 17:10:12 +000056 void assertOnBatchedInputEventPendingWasCalled() {
57 ASSERT_GT(mOnBatchedInputEventPendingInvocationCount, 0UL)
58 << "onBatchedInputEventPending has not been called.";
59 --mOnBatchedInputEventPendingInvocationCount;
60 }
61
62 void assertReceivedMotionEvent(const Matcher<MotionEvent>& matcher) {
63 std::unique_ptr<MotionEvent> motionEvent = mMotionEvents.pop();
64 ASSERT_NE(motionEvent, nullptr);
65 EXPECT_THAT(*motionEvent, matcher);
66 }
Paul Ramireze2bb1872024-08-12 20:21:13 +000067
68 std::shared_ptr<TestInputChannel> mClientTestChannel;
69 std::shared_ptr<TestLooper> mTestLooper;
70 std::unique_ptr<InputConsumerNoResampling> mConsumer;
71
72 BlockingQueue<std::unique_ptr<KeyEvent>> mKeyEvents;
73 BlockingQueue<std::unique_ptr<MotionEvent>> mMotionEvents;
74 BlockingQueue<std::unique_ptr<FocusEvent>> mFocusEvents;
75 BlockingQueue<std::unique_ptr<CaptureEvent>> mCaptureEvents;
76 BlockingQueue<std::unique_ptr<DragEvent>> mDragEvents;
77 BlockingQueue<std::unique_ptr<TouchModeEvent>> mTouchModeEvents;
78
79private:
Paul Ramirezcd7488c2024-09-13 23:01:12 +000080 size_t mOnBatchedInputEventPendingInvocationCount{0};
Paul Ramireze2bb1872024-08-12 20:21:13 +000081
82 // InputConsumerCallbacks interface
83 void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) override {
84 mKeyEvents.push(std::move(event));
85 mConsumer->finishInputEvent(seq, true);
86 }
87 void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) override {
88 mMotionEvents.push(std::move(event));
89 mConsumer->finishInputEvent(seq, true);
90 }
91 void onBatchedInputEventPending(int32_t pendingBatchSource) override {
92 if (!mConsumer->probablyHasInput()) {
93 ADD_FAILURE() << "should deterministically have input because there is a batch";
94 }
Paul Ramirezcd7488c2024-09-13 23:01:12 +000095 ++mOnBatchedInputEventPendingInvocationCount;
Paul Ramireze2bb1872024-08-12 20:21:13 +000096 };
97 void onFocusEvent(std::unique_ptr<FocusEvent> event, uint32_t seq) override {
98 mFocusEvents.push(std::move(event));
99 mConsumer->finishInputEvent(seq, true);
100 };
101 void onCaptureEvent(std::unique_ptr<CaptureEvent> event, uint32_t seq) override {
102 mCaptureEvents.push(std::move(event));
103 mConsumer->finishInputEvent(seq, true);
104 };
105 void onDragEvent(std::unique_ptr<DragEvent> event, uint32_t seq) override {
106 mDragEvents.push(std::move(event));
107 mConsumer->finishInputEvent(seq, true);
108 }
109 void onTouchModeEvent(std::unique_ptr<TouchModeEvent> event, uint32_t seq) override {
110 mTouchModeEvents.push(std::move(event));
111 mConsumer->finishInputEvent(seq, true);
112 };
113};
114
Paul Ramireze2bb1872024-08-12 20:21:13 +0000115TEST_F(InputConsumerTest, MessageStreamBatchedInMotionEvent) {
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000116 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}
117 .eventTime(nanoseconds{0ms}.count())
118 .action(AMOTION_EVENT_ACTION_DOWN)
119 .build());
120 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}
121 .eventTime(nanoseconds{5ms}.count())
122 .action(AMOTION_EVENT_ACTION_MOVE)
123 .build());
124 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/2}
125 .eventTime(nanoseconds{10ms}.count())
126 .action(AMOTION_EVENT_ACTION_MOVE)
127 .build());
Paul Ramireze2bb1872024-08-12 20:21:13 +0000128
129 mClientTestChannel->assertNoSentMessages();
130
131 mTestLooper->invokeCallback(mClientTestChannel->getFd(), ALOOPER_EVENT_INPUT);
132
133 assertOnBatchedInputEventPendingWasCalled();
134
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000135 mConsumer->consumeBatchedInputEvents(/*frameTime=*/std::nullopt);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000136
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000137 std::unique_ptr<MotionEvent> downMotionEvent = mMotionEvents.pop();
138 ASSERT_NE(downMotionEvent, nullptr);
139
140 std::unique_ptr<MotionEvent> moveMotionEvent = mMotionEvents.pop();
141 ASSERT_NE(moveMotionEvent, nullptr);
142 EXPECT_EQ(moveMotionEvent->getHistorySize() + 1, 3UL);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000143
144 mClientTestChannel->assertFinishMessage(/*seq=*/0, /*handled=*/true);
145 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
146 mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000147}
Paul Ramireze2bb1872024-08-12 20:21:13 +0000148
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000149TEST_F(InputConsumerTest, LastBatchedSampleIsLessThanResampleTime) {
150 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}
151 .eventTime(nanoseconds{0ms}.count())
152 .action(AMOTION_EVENT_ACTION_DOWN)
153 .build());
154 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}
155 .eventTime(nanoseconds{5ms}.count())
156 .action(AMOTION_EVENT_ACTION_MOVE)
157 .build());
158 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/2}
159 .eventTime(nanoseconds{10ms}.count())
160 .action(AMOTION_EVENT_ACTION_MOVE)
161 .build());
162 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/3}
163 .eventTime(nanoseconds{15ms}.count())
164 .action(AMOTION_EVENT_ACTION_MOVE)
165 .build());
166
167 mClientTestChannel->assertNoSentMessages();
168
169 mTestLooper->invokeCallback(mClientTestChannel->getFd(), ALOOPER_EVENT_INPUT);
170
171 assertOnBatchedInputEventPendingWasCalled();
172
173 mConsumer->consumeBatchedInputEvents(16'000'000 /*ns*/);
174
175 std::unique_ptr<MotionEvent> downMotionEvent = mMotionEvents.pop();
176 ASSERT_NE(downMotionEvent, nullptr);
177
178 std::unique_ptr<MotionEvent> moveMotionEvent = mMotionEvents.pop();
179 ASSERT_NE(moveMotionEvent, nullptr);
180 const size_t numSamples = moveMotionEvent->getHistorySize() + 1;
181 EXPECT_LT(moveMotionEvent->getHistoricalEventTime(numSamples - 2),
182 moveMotionEvent->getEventTime());
183
184 // Consume all remaining events before ending the test. Otherwise, the smart pointer that owns
185 // consumer is set to null before destroying consumer. This leads to a member function call on a
186 // null object.
187 // TODO(b/332613662): Remove this workaround.
188 mConsumer->consumeBatchedInputEvents(std::nullopt);
189
190 mClientTestChannel->assertFinishMessage(/*seq=*/0, true);
191 mClientTestChannel->assertFinishMessage(/*seq=*/1, true);
192 mClientTestChannel->assertFinishMessage(/*seq=*/2, true);
193 mClientTestChannel->assertFinishMessage(/*seq=*/3, true);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000194}
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000195
196TEST_F(InputConsumerTest, BatchedEventsMultiDeviceConsumption) {
197 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}
198 .deviceId(0)
199 .action(AMOTION_EVENT_ACTION_DOWN)
200 .build());
201
202 mTestLooper->invokeCallback(mClientTestChannel->getFd(), ALOOPER_EVENT_INPUT);
203 assertReceivedMotionEvent(AllOf(WithDeviceId(0), WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
204
205 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}
206 .deviceId(0)
207 .action(AMOTION_EVENT_ACTION_MOVE)
208 .build());
209 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/2}
210 .deviceId(0)
211 .action(AMOTION_EVENT_ACTION_MOVE)
212 .build());
213 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/3}
214 .deviceId(0)
215 .action(AMOTION_EVENT_ACTION_MOVE)
216 .build());
217
218 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/4}
219 .deviceId(1)
220 .action(AMOTION_EVENT_ACTION_DOWN)
221 .build());
222
223 mTestLooper->invokeCallback(mClientTestChannel->getFd(), ALOOPER_EVENT_INPUT);
224 assertReceivedMotionEvent(AllOf(WithDeviceId(1), WithMotionAction(AMOTION_EVENT_ACTION_DOWN)));
225
226 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/5}
227 .deviceId(0)
228 .action(AMOTION_EVENT_ACTION_UP)
229 .build());
230
231 mTestLooper->invokeCallback(mClientTestChannel->getFd(), ALOOPER_EVENT_INPUT);
232 assertReceivedMotionEvent(AllOf(WithDeviceId(0), WithMotionAction(AMOTION_EVENT_ACTION_MOVE),
233 Not(MotionEventIsResampled())));
234
235 mClientTestChannel->assertFinishMessage(/*seq=*/0, /*handled=*/true);
236 mClientTestChannel->assertFinishMessage(/*seq=*/4, /*handled=*/true);
237 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
238 mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
239 mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
240}
Paul Ramireze2bb1872024-08-12 20:21:13 +0000241} // namespace android