blob: 06e19bb644270c165c2a7c9fbc1cb9624a7069fb [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
Paul Ramireze37f8342024-08-28 18:42:21 +000019#include <gtest/gtest.h>
20
21#include <chrono>
Paul Ramireze2bb1872024-08-12 20:21:13 +000022#include <memory>
23#include <optional>
Paul Ramireze2bb1872024-08-12 20:21:13 +000024
Paul Ramirez00cf5d02024-09-05 17:10:12 +000025#include <TestEventMatchers.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000026#include <TestInputChannel.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000027#include <android-base/logging.h>
Paul Ramirez00cf5d02024-09-05 17:10:12 +000028#include <gmock/gmock.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000029#include <gtest/gtest.h>
30#include <input/BlockingQueue.h>
Paul Ramireze37f8342024-08-28 18:42:21 +000031#include <input/Input.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000032#include <input/InputEventBuilders.h>
Paul Ramireze37f8342024-08-28 18:42:21 +000033#include <input/Resampler.h>
Paul Ramirez87f1c012024-09-18 18:23:14 +000034#include <utils/Looper.h>
Paul Ramireze2bb1872024-08-12 20:21:13 +000035#include <utils/StrongPointer.h>
36
37namespace android {
38
Paul Ramirezcd7488c2024-09-13 23:01:12 +000039namespace {
40
41using std::chrono::nanoseconds;
42
Paul Ramirez00cf5d02024-09-05 17:10:12 +000043using ::testing::AllOf;
44using ::testing::Matcher;
Paul Ramirez00cf5d02024-09-05 17:10:12 +000045
Siarhei Vishniakouccd71472024-10-08 15:39:33 -070046constexpr auto ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN;
47constexpr auto ACTION_MOVE = AMOTION_EVENT_ACTION_MOVE;
48
Paul Ramireze37f8342024-08-28 18:42:21 +000049struct Pointer {
50 int32_t id{0};
51 ToolType toolType{ToolType::FINGER};
52 float x{0.0f};
53 float y{0.0f};
54 bool isResampled{false};
55
56 PointerBuilder asPointerBuilder() const {
57 return PointerBuilder{id, toolType}.x(x).y(y).isResampled(isResampled);
58 }
59};
Paul Ramirezcd7488c2024-09-13 23:01:12 +000060} // namespace
61
Paul Ramireze2bb1872024-08-12 20:21:13 +000062class InputConsumerTest : public testing::Test, public InputConsumerCallbacks {
63protected:
64 InputConsumerTest()
65 : mClientTestChannel{std::make_shared<TestInputChannel>("TestChannel")},
Paul Ramirez87f1c012024-09-18 18:23:14 +000066 mLooper{sp<Looper>::make(/*allowNonCallbacks=*/false)} {
67 Looper::setForThread(mLooper);
Paul Ramireze37f8342024-08-28 18:42:21 +000068 mConsumer = std::make_unique<
69 InputConsumerNoResampling>(mClientTestChannel, mLooper, *this,
70 []() { return std::make_unique<LegacyResampler>(); });
Paul Ramireze2bb1872024-08-12 20:21:13 +000071 }
72
Paul Ramirez87f1c012024-09-18 18:23:14 +000073 void invokeLooperCallback() const {
74 sp<LooperCallback> callback;
75 ASSERT_TRUE(mLooper->getFdStateDebug(mClientTestChannel->getFd(), /*ident=*/nullptr,
76 /*events=*/nullptr, &callback, /*data=*/nullptr));
77 callback->handleEvent(mClientTestChannel->getFd(), ALOOPER_EVENT_INPUT, /*data=*/nullptr);
78 }
79
Paul Ramirez00cf5d02024-09-05 17:10:12 +000080 void assertOnBatchedInputEventPendingWasCalled() {
81 ASSERT_GT(mOnBatchedInputEventPendingInvocationCount, 0UL)
82 << "onBatchedInputEventPending has not been called.";
83 --mOnBatchedInputEventPendingInvocationCount;
84 }
85
Siarhei Vishniakouccd71472024-10-08 15:39:33 -070086 std::unique_ptr<MotionEvent> assertReceivedMotionEvent(const Matcher<MotionEvent>& matcher) {
87 if (mMotionEvents.empty()) {
88 ADD_FAILURE() << "No motion events received";
89 return nullptr;
90 }
91 std::unique_ptr<MotionEvent> motionEvent = std::move(mMotionEvents.front());
92 mMotionEvents.pop();
93 if (motionEvent == nullptr) {
94 ADD_FAILURE() << "The consumed motion event should never be null";
95 return nullptr;
96 }
Paul Ramirez00cf5d02024-09-05 17:10:12 +000097 EXPECT_THAT(*motionEvent, matcher);
Siarhei Vishniakouccd71472024-10-08 15:39:33 -070098 return motionEvent;
Paul Ramirez00cf5d02024-09-05 17:10:12 +000099 }
Paul Ramireze2bb1872024-08-12 20:21:13 +0000100
Paul Ramireze37f8342024-08-28 18:42:21 +0000101 InputMessage nextPointerMessage(std::chrono::nanoseconds eventTime, DeviceId deviceId,
102 int32_t action, const Pointer& pointer);
103
Paul Ramireze2bb1872024-08-12 20:21:13 +0000104 std::shared_ptr<TestInputChannel> mClientTestChannel;
Paul Ramirez87f1c012024-09-18 18:23:14 +0000105 sp<Looper> mLooper;
Paul Ramireze2bb1872024-08-12 20:21:13 +0000106 std::unique_ptr<InputConsumerNoResampling> mConsumer;
107
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700108 std::queue<std::unique_ptr<KeyEvent>> mKeyEvents;
109 std::queue<std::unique_ptr<MotionEvent>> mMotionEvents;
110 std::queue<std::unique_ptr<FocusEvent>> mFocusEvents;
111 std::queue<std::unique_ptr<CaptureEvent>> mCaptureEvents;
112 std::queue<std::unique_ptr<DragEvent>> mDragEvents;
113 std::queue<std::unique_ptr<TouchModeEvent>> mTouchModeEvents;
Paul Ramireze2bb1872024-08-12 20:21:13 +0000114
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700115 // Whether or not to automatically call "finish" whenever a motion event is received.
116 bool mShouldFinishMotions{true};
117
Paul Ramireze2bb1872024-08-12 20:21:13 +0000118private:
Paul Ramireze37f8342024-08-28 18:42:21 +0000119 uint32_t mLastSeq{0};
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000120 size_t mOnBatchedInputEventPendingInvocationCount{0};
Paul Ramireze2bb1872024-08-12 20:21:13 +0000121
122 // InputConsumerCallbacks interface
123 void onKeyEvent(std::unique_ptr<KeyEvent> event, uint32_t seq) override {
124 mKeyEvents.push(std::move(event));
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700125 mConsumer->finishInputEvent(seq, /*handled=*/true);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000126 }
127 void onMotionEvent(std::unique_ptr<MotionEvent> event, uint32_t seq) override {
128 mMotionEvents.push(std::move(event));
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700129 if (mShouldFinishMotions) {
130 mConsumer->finishInputEvent(seq, /*handled=*/true);
131 }
Paul Ramireze2bb1872024-08-12 20:21:13 +0000132 }
133 void onBatchedInputEventPending(int32_t pendingBatchSource) override {
134 if (!mConsumer->probablyHasInput()) {
135 ADD_FAILURE() << "should deterministically have input because there is a batch";
136 }
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000137 ++mOnBatchedInputEventPendingInvocationCount;
Paul Ramireze2bb1872024-08-12 20:21:13 +0000138 };
139 void onFocusEvent(std::unique_ptr<FocusEvent> event, uint32_t seq) override {
140 mFocusEvents.push(std::move(event));
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700141 mConsumer->finishInputEvent(seq, /*handled=*/true);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000142 };
143 void onCaptureEvent(std::unique_ptr<CaptureEvent> event, uint32_t seq) override {
144 mCaptureEvents.push(std::move(event));
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700145 mConsumer->finishInputEvent(seq, /*handled=*/true);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000146 };
147 void onDragEvent(std::unique_ptr<DragEvent> event, uint32_t seq) override {
148 mDragEvents.push(std::move(event));
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700149 mConsumer->finishInputEvent(seq, /*handled=*/true);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000150 }
151 void onTouchModeEvent(std::unique_ptr<TouchModeEvent> event, uint32_t seq) override {
152 mTouchModeEvents.push(std::move(event));
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700153 mConsumer->finishInputEvent(seq, /*handled=*/true);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000154 };
155};
156
Paul Ramireze37f8342024-08-28 18:42:21 +0000157InputMessage InputConsumerTest::nextPointerMessage(std::chrono::nanoseconds eventTime,
158 DeviceId deviceId, int32_t action,
159 const Pointer& pointer) {
160 ++mLastSeq;
161 return InputMessageBuilder{InputMessage::Type::MOTION, mLastSeq}
162 .eventTime(eventTime.count())
163 .deviceId(deviceId)
164 .source(AINPUT_SOURCE_TOUCHSCREEN)
165 .action(action)
166 .pointer(pointer.asPointerBuilder())
167 .build();
168}
169
Paul Ramireze2bb1872024-08-12 20:21:13 +0000170TEST_F(InputConsumerTest, MessageStreamBatchedInMotionEvent) {
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000171 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}
172 .eventTime(nanoseconds{0ms}.count())
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700173 .action(ACTION_DOWN)
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000174 .build());
175 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}
176 .eventTime(nanoseconds{5ms}.count())
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700177 .action(ACTION_MOVE)
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000178 .build());
179 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/2}
180 .eventTime(nanoseconds{10ms}.count())
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700181 .action(ACTION_MOVE)
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000182 .build());
Paul Ramireze2bb1872024-08-12 20:21:13 +0000183
184 mClientTestChannel->assertNoSentMessages();
185
Paul Ramirez87f1c012024-09-18 18:23:14 +0000186 invokeLooperCallback();
Paul Ramireze2bb1872024-08-12 20:21:13 +0000187
188 assertOnBatchedInputEventPendingWasCalled();
189
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000190 mConsumer->consumeBatchedInputEvents(/*frameTime=*/std::nullopt);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000191
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700192 assertReceivedMotionEvent(WithMotionAction(ACTION_DOWN));
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000193
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700194 std::unique_ptr<MotionEvent> moveMotionEvent =
195 assertReceivedMotionEvent(WithMotionAction(ACTION_MOVE));
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000196 ASSERT_NE(moveMotionEvent, nullptr);
Paul Ramirez37242c82024-10-18 23:16:43 +0000197 EXPECT_EQ(moveMotionEvent->getHistorySize() + 1, 2UL);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000198
199 mClientTestChannel->assertFinishMessage(/*seq=*/0, /*handled=*/true);
200 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
201 mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000202}
Paul Ramireze2bb1872024-08-12 20:21:13 +0000203
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000204TEST_F(InputConsumerTest, LastBatchedSampleIsLessThanResampleTime) {
205 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}
206 .eventTime(nanoseconds{0ms}.count())
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700207 .action(ACTION_DOWN)
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000208 .build());
209 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}
210 .eventTime(nanoseconds{5ms}.count())
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700211 .action(ACTION_MOVE)
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000212 .build());
213 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/2}
214 .eventTime(nanoseconds{10ms}.count())
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700215 .action(ACTION_MOVE)
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000216 .build());
217 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/3}
218 .eventTime(nanoseconds{15ms}.count())
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700219 .action(ACTION_MOVE)
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000220 .build());
221
222 mClientTestChannel->assertNoSentMessages();
223
Paul Ramirez87f1c012024-09-18 18:23:14 +0000224 invokeLooperCallback();
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000225
226 assertOnBatchedInputEventPendingWasCalled();
227
228 mConsumer->consumeBatchedInputEvents(16'000'000 /*ns*/);
229
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700230 assertReceivedMotionEvent(WithMotionAction(ACTION_DOWN));
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000231
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700232 std::unique_ptr<MotionEvent> moveMotionEvent =
233 assertReceivedMotionEvent(WithMotionAction(ACTION_MOVE));
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000234 ASSERT_NE(moveMotionEvent, nullptr);
235 const size_t numSamples = moveMotionEvent->getHistorySize() + 1;
236 EXPECT_LT(moveMotionEvent->getHistoricalEventTime(numSamples - 2),
237 moveMotionEvent->getEventTime());
238
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700239 mClientTestChannel->assertFinishMessage(/*seq=*/0, /*handled=*/true);
240 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
241 mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
242 // The event with seq=3 remains unconsumed, and therefore finish will not be called for it until
243 // after the consumer is destroyed.
244 mConsumer.reset();
245 mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/false);
246 mClientTestChannel->assertNoSentMessages();
247}
Paul Ramirezcd7488c2024-09-13 23:01:12 +0000248
Siarhei Vishniakoubc723092024-10-08 15:41:51 -0700249/**
250 * During normal operation, the user of InputConsumer (callbacks) is expected to call "finish"
251 * for each input event received in InputConsumerCallbacks.
252 * If the InputConsumer is destroyed, the events that were already sent to the callbacks will not
253 * be finished automatically.
254 */
255TEST_F(InputConsumerTest, UnhandledEventsNotFinishedInDestructor) {
256 mClientTestChannel->enqueueMessage(
257 InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}.action(ACTION_DOWN).build());
258 mClientTestChannel->enqueueMessage(
259 InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}.action(ACTION_MOVE).build());
260 mShouldFinishMotions = false;
261 invokeLooperCallback();
262 assertOnBatchedInputEventPendingWasCalled();
263 assertReceivedMotionEvent(WithMotionAction(ACTION_DOWN));
264 mClientTestChannel->assertNoSentMessages();
265 // The "finishInputEvent" was not called by the InputConsumerCallbacks.
266 // Now, destroy the consumer and check that the "finish" was not called automatically for the
267 // DOWN event, but was called for the undelivered MOVE event.
268 mConsumer.reset();
269 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/false);
270 mClientTestChannel->assertNoSentMessages();
271}
272
273/**
274 * Send an event to the InputConsumer, but do not invoke "consumeBatchedInputEvents", thus leaving
275 * the input event unconsumed by the callbacks. Ensure that no crash occurs when the consumer is
276 * destroyed.
277 * This test is similar to the one above, but here we are calling "finish"
278 * automatically for any event received in the callbacks.
279 */
280TEST_F(InputConsumerTest, UnconsumedEventDoesNotCauseACrash) {
281 mClientTestChannel->enqueueMessage(
282 InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}.action(ACTION_DOWN).build());
283 invokeLooperCallback();
284 assertReceivedMotionEvent(WithMotionAction(ACTION_DOWN));
285 mClientTestChannel->assertFinishMessage(/*seq=*/0, /*handled=*/true);
286 mClientTestChannel->enqueueMessage(
287 InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}.action(ACTION_MOVE).build());
288 invokeLooperCallback();
289 mConsumer.reset();
290 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/false);
Paul Ramireze2bb1872024-08-12 20:21:13 +0000291}
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000292
293TEST_F(InputConsumerTest, BatchedEventsMultiDeviceConsumption) {
294 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}
295 .deviceId(0)
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700296 .action(ACTION_DOWN)
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000297 .build());
298
Paul Ramirez87f1c012024-09-18 18:23:14 +0000299 invokeLooperCallback();
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700300 assertReceivedMotionEvent(AllOf(WithDeviceId(0), WithMotionAction(ACTION_DOWN)));
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000301
302 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/1}
303 .deviceId(0)
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700304 .action(ACTION_MOVE)
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000305 .build());
306 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/2}
307 .deviceId(0)
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700308 .action(ACTION_MOVE)
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000309 .build());
310 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/3}
311 .deviceId(0)
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700312 .action(ACTION_MOVE)
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000313 .build());
314
315 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/4}
316 .deviceId(1)
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700317 .action(ACTION_DOWN)
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000318 .build());
319
Paul Ramirez87f1c012024-09-18 18:23:14 +0000320 invokeLooperCallback();
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700321 assertReceivedMotionEvent(AllOf(WithDeviceId(1), WithMotionAction(ACTION_DOWN)));
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000322
323 mClientTestChannel->enqueueMessage(InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/5}
324 .deviceId(0)
325 .action(AMOTION_EVENT_ACTION_UP)
326 .build());
327
Paul Ramirez87f1c012024-09-18 18:23:14 +0000328 invokeLooperCallback();
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700329 assertReceivedMotionEvent(AllOf(WithDeviceId(0), WithMotionAction(ACTION_MOVE)));
Paul Ramirez00cf5d02024-09-05 17:10:12 +0000330
331 mClientTestChannel->assertFinishMessage(/*seq=*/0, /*handled=*/true);
332 mClientTestChannel->assertFinishMessage(/*seq=*/4, /*handled=*/true);
333 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
334 mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
335 mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
336}
Paul Ramireze37f8342024-08-28 18:42:21 +0000337
338/**
339 * The test supposes a 60Hz Vsync rate and a 200Hz input rate. The InputMessages are intertwined as
340 * in a real use cases. The test's two devices should be resampled independently. Moreover, the
341 * InputMessage stream layout for the test is:
342 *
343 * DOWN(0, 0ms)
344 * MOVE(0, 5ms)
345 * MOVE(0, 10ms)
346 * DOWN(1, 15ms)
347 *
348 * CONSUME(16ms)
349 *
350 * MOVE(1, 20ms)
351 * MOVE(1, 25ms)
352 * MOVE(0, 30ms)
353 *
354 * CONSUME(32ms)
355 *
356 * MOVE(0, 35ms)
357 * UP(1, 40ms)
358 * UP(0, 45ms)
359 *
360 * CONSUME(48ms)
361 *
362 * The first field is device ID, and the second field is event time.
363 */
364TEST_F(InputConsumerTest, MultiDeviceResampling) {
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700365 mClientTestChannel->enqueueMessage(
366 nextPointerMessage(0ms, /*deviceId=*/0, ACTION_DOWN, Pointer{.x = 0, .y = 0}));
Paul Ramireze37f8342024-08-28 18:42:21 +0000367
368 mClientTestChannel->assertNoSentMessages();
369
370 invokeLooperCallback();
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700371 assertReceivedMotionEvent(
372 AllOf(WithDeviceId(0), WithMotionAction(ACTION_DOWN), WithSampleCount(1)));
Paul Ramireze37f8342024-08-28 18:42:21 +0000373
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700374 mClientTestChannel->enqueueMessage(
375 nextPointerMessage(5ms, /*deviceId=*/0, ACTION_MOVE, Pointer{.x = 1.0f, .y = 2.0f}));
376 mClientTestChannel->enqueueMessage(
377 nextPointerMessage(10ms, /*deviceId=*/0, ACTION_MOVE, Pointer{.x = 2.0f, .y = 4.0f}));
378 mClientTestChannel->enqueueMessage(
379 nextPointerMessage(15ms, /*deviceId=*/1, ACTION_DOWN, Pointer{.x = 10.0f, .y = 10.0f}));
Paul Ramireze37f8342024-08-28 18:42:21 +0000380
381 invokeLooperCallback();
382 mConsumer->consumeBatchedInputEvents(16'000'000 /*ns*/);
383
Paul Ramireze37f8342024-08-28 18:42:21 +0000384 assertReceivedMotionEvent(
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700385 AllOf(WithDeviceId(1), WithMotionAction(ACTION_DOWN), WithSampleCount(1)));
386 assertReceivedMotionEvent(
387 AllOf(WithDeviceId(0), WithMotionAction(ACTION_MOVE), WithSampleCount(3),
Paul Ramireze37f8342024-08-28 18:42:21 +0000388 WithSample(/*sampleIndex=*/2,
389 Sample{11ms,
390 {PointerArgs{.x = 2.2f, .y = 4.4f, .isResampled = true}}})));
391
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700392 mClientTestChannel->enqueueMessage(
393 nextPointerMessage(20ms, /*deviceId=*/1, ACTION_MOVE, Pointer{.x = 11.0f, .y = 12.0f}));
394 mClientTestChannel->enqueueMessage(
395 nextPointerMessage(25ms, /*deviceId=*/1, ACTION_MOVE, Pointer{.x = 12.0f, .y = 14.0f}));
396 mClientTestChannel->enqueueMessage(
397 nextPointerMessage(30ms, /*deviceId=*/0, ACTION_MOVE, Pointer{.x = 5.0f, .y = 6.0f}));
Paul Ramireze37f8342024-08-28 18:42:21 +0000398
399 invokeLooperCallback();
400 assertOnBatchedInputEventPendingWasCalled();
401 mConsumer->consumeBatchedInputEvents(32'000'000 /*ns*/);
402
403 assertReceivedMotionEvent(
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700404 AllOf(WithDeviceId(1), WithMotionAction(ACTION_MOVE), WithSampleCount(3),
Paul Ramireze37f8342024-08-28 18:42:21 +0000405 WithSample(/*sampleIndex=*/2,
406 Sample{27ms,
407 {PointerArgs{.x = 12.4f, .y = 14.8f, .isResampled = true}}})));
408
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700409 mClientTestChannel->enqueueMessage(
410 nextPointerMessage(35ms, /*deviceId=*/0, ACTION_MOVE, Pointer{.x = 8.0f, .y = 9.0f}));
Paul Ramireze37f8342024-08-28 18:42:21 +0000411 mClientTestChannel->enqueueMessage(nextPointerMessage(40ms, /*deviceId=*/1,
412 AMOTION_EVENT_ACTION_UP,
413 Pointer{.x = 12.0f, .y = 14.0f}));
414 mClientTestChannel->enqueueMessage(nextPointerMessage(45ms, /*deviceId=*/0,
415 AMOTION_EVENT_ACTION_UP,
416 Pointer{.x = 8.0f, .y = 9.0f}));
417
418 invokeLooperCallback();
419 mConsumer->consumeBatchedInputEvents(48'000'000 /*ns*/);
420
421 assertReceivedMotionEvent(
422 AllOf(WithDeviceId(1), WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSampleCount(1)));
423
424 assertReceivedMotionEvent(
Siarhei Vishniakouccd71472024-10-08 15:39:33 -0700425 AllOf(WithDeviceId(0), WithMotionAction(ACTION_MOVE), WithSampleCount(3),
Paul Ramireze37f8342024-08-28 18:42:21 +0000426 WithSample(/*sampleIndex=*/2,
427 Sample{37'500'000ns,
428 {PointerArgs{.x = 9.5f, .y = 10.5f, .isResampled = true}}})));
429
430 assertReceivedMotionEvent(
431 AllOf(WithDeviceId(0), WithMotionAction(AMOTION_EVENT_ACTION_UP), WithSampleCount(1)));
432
433 // The sequence order is based on the expected consumption. Each sequence number corresponds to
434 // one of the previously enqueued messages.
435 mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
436 mClientTestChannel->assertFinishMessage(/*seq=*/4, /*handled=*/true);
437 mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
438 mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
439 mClientTestChannel->assertFinishMessage(/*seq=*/5, /*handled=*/true);
440 mClientTestChannel->assertFinishMessage(/*seq=*/6, /*handled=*/true);
441 mClientTestChannel->assertFinishMessage(/*seq=*/9, /*handled=*/true);
442 mClientTestChannel->assertFinishMessage(/*seq=*/7, /*handled=*/true);
443 mClientTestChannel->assertFinishMessage(/*seq=*/8, /*handled=*/true);
444 mClientTestChannel->assertFinishMessage(/*seq=*/10, /*handled=*/true);
445}
Paul Ramirez37242c82024-10-18 23:16:43 +0000446
Paul Ramireze2bb1872024-08-12 20:21:13 +0000447} // namespace android