blob: 7ae9a2866457661de9ed6245fbc500bfadef2ad3 [file] [log] [blame]
Paul Ramirezbe9c5442024-07-10 00:12:41 +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/Resampler.h>
18
19#include <gtest/gtest.h>
20
21#include <chrono>
22#include <memory>
23#include <vector>
24
25#include <input/Input.h>
26#include <input/InputEventBuilders.h>
27#include <input/InputTransport.h>
28#include <utils/Timers.h>
29
30namespace android {
31
32namespace {
33
34using namespace std::literals::chrono_literals;
35
36constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION;
37
38struct Pointer {
39 int32_t id{0};
40 ToolType toolType{ToolType::FINGER};
41 float x{0.0f};
42 float y{0.0f};
43 bool isResampled{false};
44 /**
45 * Converts from Pointer to PointerCoords. Enables calling LegacyResampler methods and
46 * assertions only with the relevant data for tests.
47 */
48 operator PointerCoords() const;
49};
50
51Pointer::operator PointerCoords() const {
52 PointerCoords pointerCoords;
53 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
54 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
55 pointerCoords.isResampled = isResampled;
56 return pointerCoords;
57}
58
59struct InputSample {
60 std::chrono::milliseconds eventTime{0};
61 std::vector<Pointer> pointers{};
Paul Ramirezcf1b06e2024-08-01 17:11:58 +000062
63 explicit InputSample(std::chrono::milliseconds eventTime, const std::vector<Pointer>& pointers)
64 : eventTime{eventTime}, pointers{pointers} {}
Paul Ramirezbe9c5442024-07-10 00:12:41 +000065 /**
66 * Converts from InputSample to InputMessage. Enables calling LegacyResampler methods only with
67 * the relevant data for tests.
68 */
69 operator InputMessage() const;
70};
71
72InputSample::operator InputMessage() const {
Paul Ramirez7dfaa322024-08-21 17:44:45 +000073 InputMessageBuilder messageBuilder =
74 InputMessageBuilder{InputMessage::Type::MOTION, /*seq=*/0}
75 .eventTime(std::chrono::nanoseconds{eventTime}.count())
76 .source(AINPUT_SOURCE_TOUCHSCREEN)
77 .downTime(0);
Paul Ramirezcf1b06e2024-08-01 17:11:58 +000078
Paul Ramirez7dfaa322024-08-21 17:44:45 +000079 for (const Pointer& pointer : pointers) {
80 messageBuilder.pointer(
81 PointerBuilder{pointer.id, pointer.toolType}.x(pointer.x).y(pointer.y).isResampled(
82 pointer.isResampled));
Paul Ramirezbe9c5442024-07-10 00:12:41 +000083 }
Paul Ramirez7dfaa322024-08-21 17:44:45 +000084 return messageBuilder.build();
Paul Ramirezbe9c5442024-07-10 00:12:41 +000085}
86
87struct InputStream {
88 std::vector<InputSample> samples{};
89 int32_t action{0};
90 DeviceId deviceId{0};
91 /**
92 * Converts from InputStream to MotionEvent. Enables calling LegacyResampler methods only with
93 * the relevant data for tests.
94 */
95 operator MotionEvent() const;
96};
97
98InputStream::operator MotionEvent() const {
99 const InputSample& firstSample{*samples.begin()};
100 MotionEventBuilder motionEventBuilder =
101 MotionEventBuilder(action, AINPUT_SOURCE_CLASS_POINTER)
102 .downTime(0)
103 .eventTime(static_cast<std::chrono::nanoseconds>(firstSample.eventTime).count())
104 .deviceId(deviceId);
105 for (const Pointer& pointer : firstSample.pointers) {
106 const PointerBuilder pointerBuilder =
107 PointerBuilder(pointer.id, pointer.toolType).x(pointer.x).y(pointer.y);
108 motionEventBuilder.pointer(pointerBuilder);
109 }
110 MotionEvent motionEvent = motionEventBuilder.build();
111 const size_t numSamples = samples.size();
112 for (size_t i = 1; i < numSamples; ++i) {
113 std::vector<PointerCoords> pointersCoords{samples[i].pointers.begin(),
114 samples[i].pointers.end()};
115 motionEvent.addSample(static_cast<std::chrono::nanoseconds>(samples[i].eventTime).count(),
116 pointersCoords.data(), motionEvent.getId());
117 }
118 return motionEvent;
119}
120
121} // namespace
122
123class ResamplerTest : public testing::Test {
124protected:
125 ResamplerTest() : mResampler(std::make_unique<LegacyResampler>()) {}
126
127 ~ResamplerTest() override {}
128
129 void SetUp() override {}
130
131 void TearDown() override {}
132
133 std::unique_ptr<Resampler> mResampler;
134
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000135 /**
136 * Checks that beforeCall and afterCall are equal except for the mutated attributes by addSample
137 * member function.
138 * @param beforeCall MotionEvent before passing it to resampleMotionEvent
139 * @param afterCall MotionEvent after passing it to resampleMotionEvent
140 */
141 void assertMotionEventMetaDataDidNotMutate(const MotionEvent& beforeCall,
142 const MotionEvent& afterCall);
143
144 /**
145 * Asserts the MotionEvent is resampled by checking an increment in history size and that the
146 * resampled coordinates are near the expected ones.
147 */
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000148 void assertMotionEventIsResampledAndCoordsNear(
149 const MotionEvent& original, const MotionEvent& resampled,
150 const std::vector<PointerCoords>& expectedCoords);
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000151
152 void assertMotionEventIsNotResampled(const MotionEvent& original,
153 const MotionEvent& notResampled);
154};
155
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000156void ResamplerTest::assertMotionEventMetaDataDidNotMutate(const MotionEvent& beforeCall,
157 const MotionEvent& afterCall) {
158 EXPECT_EQ(beforeCall.getDeviceId(), afterCall.getDeviceId());
159 EXPECT_EQ(beforeCall.getAction(), afterCall.getAction());
160 EXPECT_EQ(beforeCall.getActionButton(), afterCall.getActionButton());
161 EXPECT_EQ(beforeCall.getButtonState(), afterCall.getButtonState());
162 EXPECT_EQ(beforeCall.getFlags(), afterCall.getFlags());
163 EXPECT_EQ(beforeCall.getEdgeFlags(), afterCall.getEdgeFlags());
164 EXPECT_EQ(beforeCall.getClassification(), afterCall.getClassification());
165 EXPECT_EQ(beforeCall.getPointerCount(), afterCall.getPointerCount());
166 EXPECT_EQ(beforeCall.getMetaState(), afterCall.getMetaState());
167 EXPECT_EQ(beforeCall.getSource(), afterCall.getSource());
168 EXPECT_EQ(beforeCall.getXPrecision(), afterCall.getXPrecision());
169 EXPECT_EQ(beforeCall.getYPrecision(), afterCall.getYPrecision());
170 EXPECT_EQ(beforeCall.getDownTime(), afterCall.getDownTime());
171 EXPECT_EQ(beforeCall.getDisplayId(), afterCall.getDisplayId());
172}
173
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000174void ResamplerTest::assertMotionEventIsResampledAndCoordsNear(
175 const MotionEvent& original, const MotionEvent& resampled,
176 const std::vector<PointerCoords>& expectedCoords) {
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000177 assertMotionEventMetaDataDidNotMutate(original, resampled);
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000178
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000179 const size_t originalSampleSize = original.getHistorySize() + 1;
180 const size_t resampledSampleSize = resampled.getHistorySize() + 1;
181 EXPECT_EQ(originalSampleSize + 1, resampledSampleSize);
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000182
183 const size_t numPointers = resampled.getPointerCount();
184 const size_t beginLatestSample = resampledSampleSize - 1;
185 for (size_t i = 0; i < numPointers; ++i) {
186 SCOPED_TRACE(i);
187 EXPECT_EQ(original.getPointerId(i), resampled.getPointerId(i));
188 EXPECT_EQ(original.getToolType(i), resampled.getToolType(i));
189
190 const PointerCoords& resampledCoords =
191 resampled.getSamplePointerCoords()[beginLatestSample * numPointers + i];
192
193 EXPECT_TRUE(resampledCoords.isResampled);
194 EXPECT_NEAR(expectedCoords[i].getX(), resampledCoords.getX(), EPSILON);
195 EXPECT_NEAR(expectedCoords[i].getY(), resampledCoords.getY(), EPSILON);
196 }
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000197}
198
199void ResamplerTest::assertMotionEventIsNotResampled(const MotionEvent& original,
200 const MotionEvent& notResampled) {
201 assertMotionEventMetaDataDidNotMutate(original, notResampled);
202 const size_t originalSampleSize = original.getHistorySize() + 1;
203 const size_t notResampledSampleSize = notResampled.getHistorySize() + 1;
204 EXPECT_EQ(originalSampleSize, notResampledSampleSize);
205}
206
Paul Ramirez68ca3d12024-08-12 23:00:50 +0000207TEST_F(ResamplerTest, NonResampledAxesArePreserved) {
208 constexpr float TOUCH_MAJOR_VALUE = 1.0f;
209
210 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000211 InputStream{{InputSample{5ms, {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false}}}},
Paul Ramirez68ca3d12024-08-12 23:00:50 +0000212 AMOTION_EVENT_ACTION_MOVE};
213
214 constexpr std::chrono::nanoseconds eventTime{10ms};
215 PointerCoords pointerCoords{};
216 pointerCoords.isResampled = false;
217 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, 2.0f);
218 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, 2.0f);
219 pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, TOUCH_MAJOR_VALUE);
220
221 motionEvent.addSample(eventTime.count(), &pointerCoords, motionEvent.getId());
222
223 const InputMessage futureSample =
224 InputSample{15ms, {{.id = 0, .x = 3.0f, .y = 4.0f, .isResampled = false}}};
225
226 const MotionEvent originalMotionEvent = motionEvent;
227
228 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
229
230 EXPECT_EQ(motionEvent.getTouchMajor(0), TOUCH_MAJOR_VALUE);
231
232 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000233 {Pointer{.id = 0,
234 .x = 2.2f,
235 .y = 2.4f,
236 .isResampled = true}});
Paul Ramirez68ca3d12024-08-12 23:00:50 +0000237}
238
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000239TEST_F(ResamplerTest, SinglePointerNotEnoughDataToResample) {
240 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000241 InputStream{{InputSample{5ms, {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false}}}},
242 AMOTION_EVENT_ACTION_MOVE};
243
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000244 const MotionEvent originalMotionEvent = motionEvent;
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000245
246 mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
247
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000248 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
249}
250
251TEST_F(ResamplerTest, SinglePointerDifferentDeviceIdBetweenMotionEvents) {
252 MotionEvent motionFromFirstDevice =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000253 InputStream{{InputSample{4ms, {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false}}},
254 InputSample{8ms, {{.id = 0, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000255 AMOTION_EVENT_ACTION_MOVE,
256 .deviceId = 0};
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000257
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000258 mResampler->resampleMotionEvent(10ms, motionFromFirstDevice, nullptr);
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000259
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000260 MotionEvent motionFromSecondDevice =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000261 InputStream{{InputSample{11ms,
262 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000263 AMOTION_EVENT_ACTION_MOVE,
264 .deviceId = 1};
265 const MotionEvent originalMotionEvent = motionFromSecondDevice;
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000266
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000267 mResampler->resampleMotionEvent(12ms, motionFromSecondDevice, nullptr);
268 // The MotionEvent should not be resampled because the second event came from a different device
269 // than the previous event.
270 assertMotionEventIsNotResampled(originalMotionEvent, motionFromSecondDevice);
271}
272
273// Increments of 16 ms for display refresh rate
274// Increments of 6 ms for input frequency
275// Resampling latency is known to be 5 ms
276// Therefore, first resampling time will be 11 ms
277
278/**
279 * Timeline
280 * ----+----------------------+---------+---------+---------+----------
281 * 0ms 10ms 11ms 15ms 16ms
282 * DOWN MOVE | MSG |
283 * resample frame
284 * Resampling occurs at 11ms. It is possible to interpolate because there is a sample available
285 * after the resample time. It is assumed that the InputMessage frequency is 100Hz, and the frame
286 * frequency is 60Hz. This means the time between InputMessage samples is 10ms, and the time between
287 * frames is ~16ms. Resample time is frameTime - RESAMPLE_LATENCY. The resampled sample must be the
288 * last one in the batch to consume.
289 */
290TEST_F(ResamplerTest, SinglePointerSingleSampleInterpolation) {
291 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000292 InputStream{{InputSample{10ms,
293 {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000294 AMOTION_EVENT_ACTION_MOVE};
295 const InputMessage futureSample =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000296 InputSample{15ms, {{.id = 0, .x = 2.0f, .y = 4.0f, .isResampled = false}}};
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000297
298 const MotionEvent originalMotionEvent = motionEvent;
299
300 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
301
302 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000303 {Pointer{.id = 0,
304 .x = 1.2f,
305 .y = 2.4f,
306 .isResampled = true}});
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000307}
308
309TEST_F(ResamplerTest, SinglePointerDeltaTooSmallInterpolation) {
310 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000311 InputStream{{InputSample{10ms,
312 {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000313 AMOTION_EVENT_ACTION_MOVE};
314 const InputMessage futureSample =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000315 InputSample{11ms, {{.id = 0, .x = 2.0f, .y = 4.0f, .isResampled = false}}};
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000316
317 const MotionEvent originalMotionEvent = motionEvent;
318
319 mResampler->resampleMotionEvent(10'500'000ns, motionEvent, &futureSample);
320
321 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
322}
323
324/**
325 * Tests extrapolation given two MotionEvents with a single sample.
326 */
327TEST_F(ResamplerTest, SinglePointerSingleSampleExtrapolation) {
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000328 MotionEvent firstMotionEvent =
329 InputStream{{InputSample{5ms, {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000330 AMOTION_EVENT_ACTION_MOVE};
331
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000332 mResampler->resampleMotionEvent(9ms, firstMotionEvent, nullptr);
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000333
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000334 MotionEvent secondMotionEvent =
335 InputStream{{InputSample{10ms,
336 {{.id = 0, .x = 2.0f, .y = 4.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000337 AMOTION_EVENT_ACTION_MOVE};
338
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000339 const MotionEvent originalMotionEvent = secondMotionEvent;
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000340
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000341 mResampler->resampleMotionEvent(11ms, secondMotionEvent, nullptr);
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000342
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000343 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, secondMotionEvent,
344 {Pointer{.id = 0,
345 .x = 2.2f,
346 .y = 4.4f,
347 .isResampled = true}});
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000348 // Integrity of the whole motionEvent
349 // History size should increment by 1
350 // Check if the resampled value is the last one
351 // Check if the resampleTime is correct
352 // Check if the PointerCoords are consistent with the other computations
353}
354
355TEST_F(ResamplerTest, SinglePointerMultipleSampleInterpolation) {
356 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000357 InputStream{{InputSample{5ms, {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}},
358 InputSample{10ms,
359 {{.id = 0, .x = 2.0f, .y = 3.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000360 AMOTION_EVENT_ACTION_MOVE};
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000361
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000362 const InputMessage futureSample =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000363 InputSample{15ms, {{.id = 0, .x = 3.0f, .y = 5.0f, .isResampled = false}}};
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000364
365 const MotionEvent originalMotionEvent = motionEvent;
366
367 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
368
369 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000370 {Pointer{.id = 0,
371 .x = 2.2f,
372 .y = 3.4f,
373 .isResampled = true}});
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000374}
375
376TEST_F(ResamplerTest, SinglePointerMultipleSampleExtrapolation) {
377 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000378 InputStream{{InputSample{5ms, {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}},
379 InputSample{10ms,
380 {{.id = 0, .x = 2.0f, .y = 4.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000381 AMOTION_EVENT_ACTION_MOVE};
382
383 const MotionEvent originalMotionEvent = motionEvent;
384
385 mResampler->resampleMotionEvent(11ms, motionEvent, nullptr);
386
387 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000388 {Pointer{.id = 0,
389 .x = 2.2f,
390 .y = 4.4f,
391 .isResampled = true}});
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000392}
393
394TEST_F(ResamplerTest, SinglePointerDeltaTooSmallExtrapolation) {
395 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000396 InputStream{{InputSample{9ms, {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}},
397 InputSample{10ms,
398 {{.id = 0, .x = 2.0f, .y = 4.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000399 AMOTION_EVENT_ACTION_MOVE};
400
401 const MotionEvent originalMotionEvent = motionEvent;
402
403 mResampler->resampleMotionEvent(11ms, motionEvent, nullptr);
404
405 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
406}
407
408TEST_F(ResamplerTest, SinglePointerDeltaTooLargeExtrapolation) {
409 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000410 InputStream{{InputSample{5ms, {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}},
411 InputSample{26ms,
412 {{.id = 0, .x = 2.0f, .y = 4.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000413 AMOTION_EVENT_ACTION_MOVE};
414
415 const MotionEvent originalMotionEvent = motionEvent;
416
417 mResampler->resampleMotionEvent(27ms, motionEvent, nullptr);
418
419 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
420}
421
422TEST_F(ResamplerTest, SinglePointerResampleTimeTooFarExtrapolation) {
423 MotionEvent motionEvent =
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000424 InputStream{{InputSample{5ms, {{.id = 0, .x = 1.0f, .y = 2.0f, .isResampled = false}}},
425 InputSample{25ms,
426 {{.id = 0, .x = 2.0f, .y = 4.0f, .isResampled = false}}}},
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000427 AMOTION_EVENT_ACTION_MOVE};
428
429 const MotionEvent originalMotionEvent = motionEvent;
430
431 mResampler->resampleMotionEvent(43ms, motionEvent, nullptr);
432
433 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
Paul Ramirezcf1b06e2024-08-01 17:11:58 +0000434 {Pointer{.id = 0,
435 .x = 2.4f,
436 .y = 4.8f,
437 .isResampled = true}});
438}
439
440TEST_F(ResamplerTest, MultiplePointerSingleSampleInterpolation) {
441 MotionEvent motionEvent =
442 InputStream{{InputSample{5ms,
443 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
444 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
445 AMOTION_EVENT_ACTION_MOVE};
446
447 const InputMessage futureSample =
448 InputSample{15ms,
449 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
450 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false}}};
451
452 const MotionEvent originalMotionEvent = motionEvent;
453
454 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
455
456 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
457 {Pointer{.x = 2.2f, .y = 2.2f, .isResampled = true},
458 Pointer{.x = 3.2f, .y = 3.2f, .isResampled = true}});
459}
460
461TEST_F(ResamplerTest, MultiplePointerSingleSampleExtrapolation) {
462 MotionEvent firstMotionEvent =
463 InputStream{{InputSample{5ms,
464 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
465 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
466 AMOTION_EVENT_ACTION_MOVE};
467
468 mResampler->resampleMotionEvent(9ms, firstMotionEvent, /*futureSample=*/nullptr);
469
470 MotionEvent secondMotionEvent =
471 InputStream{{InputSample{10ms,
472 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
473 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false}}}},
474 AMOTION_EVENT_ACTION_MOVE};
475
476 const MotionEvent originalMotionEvent = secondMotionEvent;
477
478 mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
479
480 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, secondMotionEvent,
481 {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
482 Pointer{.x = 4.4f, .y = 4.4f, .isResampled = true}});
483}
484
485TEST_F(ResamplerTest, MultiplePointerMultipleSampleInterpolation) {
486 MotionEvent motionEvent =
487 InputStream{{InputSample{5ms,
488 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
489 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}},
490 InputSample{10ms,
491 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
492 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false}}}},
493 AMOTION_EVENT_ACTION_MOVE};
494 const InputMessage futureSample =
495 InputSample{15ms,
496 {{.id = 0, .x = 5.0f, .y = 5.0f, .isResampled = false},
497 {.id = 1, .x = 6.0f, .y = 6.0f, .isResampled = false}}};
498
499 const MotionEvent originalMotionEvent = motionEvent;
500
501 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
502
503 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
504 {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
505 Pointer{.x = 4.4f, .y = 4.4f, .isResampled = true}});
506}
507
508TEST_F(ResamplerTest, MultiplePointerMultipleSampleExtrapolation) {
509 MotionEvent motionEvent =
510 InputStream{{InputSample{5ms,
511 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
512 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}},
513 InputSample{10ms,
514 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
515 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false}}}},
516 AMOTION_EVENT_ACTION_MOVE};
517
518 const MotionEvent originalMotionEvent = motionEvent;
519
520 mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
521
522 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
523 {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
524 Pointer{.x = 4.4f, .y = 4.4f, .isResampled = true}});
525}
526
527TEST_F(ResamplerTest, MultiplePointerIncreaseNumPointersInterpolation) {
528 MotionEvent motionEvent =
529 InputStream{{InputSample{10ms,
530 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
531 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
532 AMOTION_EVENT_ACTION_MOVE};
533
534 const InputMessage futureSample =
535 InputSample{15ms,
536 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
537 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
538 {.id = 2, .x = 5.0f, .y = 5.0f, .isResampled = false}}};
539
540 const MotionEvent originalMotionEvent = motionEvent;
541
542 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
543
544 assertMotionEventIsResampledAndCoordsNear(originalMotionEvent, motionEvent,
545 {Pointer{.x = 1.4f, .y = 1.4f, .isResampled = true},
546 Pointer{.x = 2.4f, .y = 2.4f, .isResampled = true}});
547
548 MotionEvent secondMotionEvent =
549 InputStream{{InputSample{25ms,
550 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
551 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
552 {.id = 2, .x = 5.0f, .y = 5.0f, .isResampled = false}}}},
553 AMOTION_EVENT_ACTION_MOVE};
554
555 const InputMessage secondFutureSample =
556 InputSample{30ms,
557 {{.id = 0, .x = 5.0f, .y = 5.0f, .isResampled = false},
558 {.id = 1, .x = 6.0f, .y = 6.0f, .isResampled = false},
559 {.id = 2, .x = 7.0f, .y = 7.0f, .isResampled = false}}};
560
561 const MotionEvent originalSecondMotionEvent = secondMotionEvent;
562
563 mResampler->resampleMotionEvent(27ms, secondMotionEvent, &secondFutureSample);
564
565 assertMotionEventIsResampledAndCoordsNear(originalSecondMotionEvent, secondMotionEvent,
566 {Pointer{.x = 3.8f, .y = 3.8f, .isResampled = true},
567 Pointer{.x = 4.8f, .y = 4.8f, .isResampled = true},
568 Pointer{.x = 5.8f, .y = 5.8f, .isResampled = true}});
569}
570
571TEST_F(ResamplerTest, MultiplePointerIncreaseNumPointersExtrapolation) {
572 MotionEvent firstMotionEvent =
573 InputStream{{InputSample{5ms,
574 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
575 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
576 AMOTION_EVENT_ACTION_MOVE};
577
578 mResampler->resampleMotionEvent(9ms, firstMotionEvent, /*futureSample=*/nullptr);
579
580 MotionEvent secondMotionEvent =
581 InputStream{{InputSample{10ms,
582 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
583 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
584 {.id = 2, .x = 5.0f, .y = 5.0f, .isResampled = false}}}},
585 AMOTION_EVENT_ACTION_MOVE};
586
587 const MotionEvent secondOriginalMotionEvent = secondMotionEvent;
588
589 mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
590
591 assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
592}
593
594TEST_F(ResamplerTest, MultiplePointerDecreaseNumPointersInterpolation) {
595 MotionEvent motionEvent =
596 InputStream{{InputSample{10ms,
597 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
598 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
599 {.id = 2, .x = 5.0f, .y = 5.0f, .isResampled = false}}}},
600 AMOTION_EVENT_ACTION_MOVE};
601
602 const InputMessage futureSample =
603 InputSample{15ms,
604 {{.id = 0, .x = 4.0f, .y = 4.0f, .isResampled = false},
605 {.id = 1, .x = 5.0f, .y = 5.0f, .isResampled = false}}};
606
607 const MotionEvent originalMotionEvent = motionEvent;
608
609 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
610
611 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
612}
613
614TEST_F(ResamplerTest, MultiplePointerDecreaseNumPointersExtrapolation) {
615 MotionEvent firstMotionEvent =
616 InputStream{{InputSample{5ms,
617 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
618 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false},
619 {.id = 2, .x = 3.0f, .y = 3.0f, .isResampled = false}}}},
620 AMOTION_EVENT_ACTION_MOVE};
621
622 mResampler->resampleMotionEvent(9ms, firstMotionEvent, /*futureSample=*/nullptr);
623
624 MotionEvent secondMotionEvent =
625 InputStream{{InputSample{10ms,
626 {{.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false},
627 {.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false}}}},
628 AMOTION_EVENT_ACTION_MOVE};
629
630 const MotionEvent secondOriginalMotionEvent = secondMotionEvent;
631
632 mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
633
634 assertMotionEventIsResampledAndCoordsNear(secondOriginalMotionEvent, secondMotionEvent,
635 {Pointer{.x = 3.4f, .y = 3.4f, .isResampled = true},
636 Pointer{.x = 4.4f, .y = 4.4f, .isResampled = true}});
637}
638
639TEST_F(ResamplerTest, MultiplePointerDifferentIdOrderInterpolation) {
640 MotionEvent motionEvent =
641 InputStream{{InputSample{10ms,
642 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
643 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
644 AMOTION_EVENT_ACTION_MOVE};
645
646 const InputMessage futureSample =
647 InputSample{15ms,
648 {{.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
649 {.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false}}};
650
651 const MotionEvent originalMotionEvent = motionEvent;
652
653 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
654
655 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
656}
657
658TEST_F(ResamplerTest, MultiplePointerDifferentIdOrderExtrapolation) {
659 MotionEvent firstMotionEvent =
660 InputStream{{InputSample{5ms,
661 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
662 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
663 AMOTION_EVENT_ACTION_MOVE};
664
665 mResampler->resampleMotionEvent(9ms, firstMotionEvent, /*futureSample=*/nullptr);
666
667 MotionEvent secondMotionEvent =
668 InputStream{{InputSample{10ms,
669 {{.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
670 {.id = 0, .x = 3.0f, .y = 3.0f, .isResampled = false}}}},
671 AMOTION_EVENT_ACTION_MOVE};
672
673 const MotionEvent secondOriginalMotionEvent = secondMotionEvent;
674
675 mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
676
677 assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
678}
679
680TEST_F(ResamplerTest, MultiplePointerDifferentIdsInterpolation) {
681 MotionEvent motionEvent =
682 InputStream{{InputSample{10ms,
683 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
684 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
685 AMOTION_EVENT_ACTION_MOVE};
686
687 const InputMessage futureSample =
688 InputSample{15ms,
689 {{.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
690 {.id = 2, .x = 3.0f, .y = 3.0f, .isResampled = false}}};
691
692 const MotionEvent originalMotionEvent = motionEvent;
693
694 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
695
696 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
697}
698
699TEST_F(ResamplerTest, MultiplePointerDifferentIdsExtrapolation) {
700 MotionEvent firstMotionEvent =
701 InputStream{{InputSample{5ms,
702 {{.id = 0, .x = 1.0f, .y = 1.0f, .isResampled = false},
703 {.id = 1, .x = 2.0f, .y = 2.0f, .isResampled = false}}}},
704 AMOTION_EVENT_ACTION_MOVE};
705
706 mResampler->resampleMotionEvent(9ms, firstMotionEvent, /*futureSample=*/nullptr);
707
708 MotionEvent secondMotionEvent =
709 InputStream{{InputSample{10ms,
710 {{.id = 1, .x = 4.0f, .y = 4.0f, .isResampled = false},
711 {.id = 2, .x = 3.0f, .y = 3.0f, .isResampled = false}}}},
712 AMOTION_EVENT_ACTION_MOVE};
713
714 const MotionEvent secondOriginalMotionEvent = secondMotionEvent;
715
716 mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
717
718 assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
719}
720
721TEST_F(ResamplerTest, MultiplePointerDifferentToolTypeInterpolation) {
722 MotionEvent motionEvent = InputStream{{InputSample{10ms,
723 {{.id = 0,
724 .toolType = ToolType::FINGER,
725 .x = 1.0f,
726 .y = 1.0f,
727 .isResampled = false},
728 {.id = 1,
729 .toolType = ToolType::FINGER,
730 .x = 2.0f,
731 .y = 2.0f,
732 .isResampled = false}}}},
733 AMOTION_EVENT_ACTION_MOVE};
734
735 const InputMessage futureSample = InputSample{15ms,
736 {{.id = 0,
737 .toolType = ToolType::FINGER,
738 .x = 3.0,
739 .y = 3.0,
740 .isResampled = false},
741 {.id = 1,
742 .toolType = ToolType::STYLUS,
743 .x = 4.0,
744 .y = 4.0,
745 .isResampled = false}}};
746
747 const MotionEvent originalMotionEvent = motionEvent;
748
749 mResampler->resampleMotionEvent(11ms, motionEvent, &futureSample);
750
751 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
752}
753
754TEST_F(ResamplerTest, MultiplePointerDifferentToolTypeExtrapolation) {
755 MotionEvent firstMotionEvent = InputStream{{InputSample{5ms,
756 {{.id = 0,
757 .toolType = ToolType::FINGER,
758 .x = 1.0f,
759 .y = 1.0f,
760 .isResampled = false},
761 {.id = 1,
762 .toolType = ToolType::FINGER,
763 .x = 2.0f,
764 .y = 2.0f,
765 .isResampled = false}}}},
766 AMOTION_EVENT_ACTION_MOVE};
767
768 mResampler->resampleMotionEvent(9ms, firstMotionEvent, /*futureSample=*/nullptr);
769
770 MotionEvent secondMotionEvent = InputStream{{InputSample{10ms,
771 {{.id = 0,
772 .toolType = ToolType::FINGER,
773 .x = 1.0f,
774 .y = 1.0f,
775 .isResampled = false},
776 {.id = 1,
777 .toolType = ToolType::STYLUS,
778 .x = 2.0f,
779 .y = 2.0f,
780 .isResampled = false}}}},
781 AMOTION_EVENT_ACTION_MOVE};
782
783 const MotionEvent secondOriginalMotionEvent = secondMotionEvent;
784
785 mResampler->resampleMotionEvent(11ms, secondMotionEvent, /*futureSample=*/nullptr);
786
787 assertMotionEventIsNotResampled(secondOriginalMotionEvent, secondMotionEvent);
788}
789
790TEST_F(ResamplerTest, MultiplePointerShouldNotResampleToolTypeInterpolation) {
791 MotionEvent motionEvent = InputStream{{InputSample{10ms,
792 {{.id = 0,
793 .toolType = ToolType::PALM,
794 .x = 1.0f,
795 .y = 1.0f,
796 .isResampled = false},
797 {.id = 1,
798 .toolType = ToolType::PALM,
799 .x = 2.0f,
800 .y = 2.0f,
801 .isResampled = false}}}},
802 AMOTION_EVENT_ACTION_MOVE};
803
804 const InputMessage futureSample = InputSample{15ms,
805 {{.id = 0,
806 .toolType = ToolType::PALM,
807 .x = 3.0,
808 .y = 3.0,
809 .isResampled = false},
810 {.id = 1,
811 .toolType = ToolType::PALM,
812 .x = 4.0,
813 .y = 4.0,
814 .isResampled = false}}};
815
816 const MotionEvent originalMotionEvent = motionEvent;
817
818 mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
819
820 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
821}
822
823TEST_F(ResamplerTest, MultiplePointerShouldNotResampleToolTypeExtrapolation) {
824 MotionEvent motionEvent = InputStream{{InputSample{5ms,
825 {{.id = 0,
826 .toolType = ToolType::PALM,
827 .x = 1.0f,
828 .y = 1.0f,
829 .isResampled = false},
830 {.id = 1,
831 .toolType = ToolType::PALM,
832 .x = 2.0f,
833 .y = 2.0f,
834 .isResampled = false}}},
835 InputSample{10ms,
836 {{.id = 0,
837 .toolType = ToolType::PALM,
838 .x = 3.0f,
839 .y = 3.0f,
840 .isResampled = false},
841 {.id = 1,
842 .toolType = ToolType::PALM,
843 .x = 4.0f,
844 .y = 4.0f,
845 .isResampled = false}}}},
846 AMOTION_EVENT_ACTION_MOVE};
847
848 const MotionEvent originalMotionEvent = motionEvent;
849
850 mResampler->resampleMotionEvent(11ms, motionEvent, /*futureSample=*/nullptr);
851
852 assertMotionEventIsNotResampled(originalMotionEvent, motionEvent);
Paul Ramirezbe9c5442024-07-10 00:12:41 +0000853}
854} // namespace android