Skip to content

Commit afcdc8b

Browse files
Treehugger RobotAndroid (Google) Code Review
authored andcommitted
Merge "Add check to not resample when resample time equals motion event time" into main
2 parents 93b295c + 7f1efed commit afcdc8b

3 files changed

Lines changed: 51 additions & 8 deletions

File tree

include/input/Resampler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ class LegacyResampler final : public Resampler {
6565
* extrapolation takes place and `resampleTime` is too far in the future. If `futureSample` is
6666
* not null, interpolation will occur. If `futureSample` is null and there is enough historical
6767
* data, LegacyResampler will extrapolate. Otherwise, no resampling takes place and
68-
* `motionEvent` is unmodified.
68+
* `motionEvent` is unmodified. Furthermore, motionEvent is not resampled if resampleTime equals
69+
* the last sample eventTime of motionEvent.
6970
*/
7071
void resampleMotionEvent(std::chrono::nanoseconds frameTime, MotionEvent& motionEvent,
7172
const InputMessage* futureSample) override;

libs/input/Resampler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,11 @@ void LegacyResampler::resampleMotionEvent(nanoseconds frameTime, MotionEvent& mo
249249
const InputMessage* futureSample) {
250250
const nanoseconds resampleTime = frameTime - RESAMPLE_LATENCY;
251251

252+
if (resampleTime.count() == motionEvent.getEventTime()) {
253+
LOG_IF(INFO, debugResampling()) << "Not resampled. Resample time equals motion event time.";
254+
return;
255+
}
256+
252257
updateLatestSamples(motionEvent);
253258

254259
const std::optional<Sample> sample = (futureSample != nullptr)

libs/input/tests/InputConsumerResampling_test.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
/*
32
* Copyright (C) 2024 The Android Open Source Project
43
*
@@ -193,7 +192,7 @@ void InputConsumerResamplingTest::assertReceivedMotionEvent(
193192
* last two real events, which would put this time at: 20 ms + (20 ms - 10 ms) / 2 = 25 ms.
194193
*/
195194
TEST_F(InputConsumerResamplingTest, EventIsResampled) {
196-
// Initial ACTION_DOWN should be separate, because the first consume event will only return
195+
// Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
197196
// InputEvent with a single action.
198197
mClientTestChannel->enqueueMessage(nextPointerMessage(
199198
{0ms, {Pointer{.id = 0, .x = 10.0f, .y = 20.0f}}, AMOTION_EVENT_ACTION_DOWN}));
@@ -234,7 +233,7 @@ TEST_F(InputConsumerResamplingTest, EventIsResampled) {
234233
* have these hardcoded.
235234
*/
236235
TEST_F(InputConsumerResamplingTest, EventIsResampledWithDifferentId) {
237-
// Initial ACTION_DOWN should be separate, because the first consume event will only return
236+
// Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
238237
// InputEvent with a single action.
239238
mClientTestChannel->enqueueMessage(nextPointerMessage(
240239
{0ms, {Pointer{.id = 1, .x = 10.0f, .y = 20.0f}}, AMOTION_EVENT_ACTION_DOWN}));
@@ -274,7 +273,7 @@ TEST_F(InputConsumerResamplingTest, EventIsResampledWithDifferentId) {
274273
* Stylus pointer coordinates are resampled.
275274
*/
276275
TEST_F(InputConsumerResamplingTest, StylusEventIsResampled) {
277-
// Initial ACTION_DOWN should be separate, because the first consume event will only return
276+
// Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
278277
// InputEvent with a single action.
279278
mClientTestChannel->enqueueMessage(nextPointerMessage(
280279
{0ms,
@@ -332,9 +331,8 @@ TEST_F(InputConsumerResamplingTest, StylusEventIsResampled) {
332331
* Mouse pointer coordinates are resampled.
333332
*/
334333
TEST_F(InputConsumerResamplingTest, MouseEventIsResampled) {
335-
// Initial ACTION_DOWN should be separate, because the first consume event will only return
334+
// Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
336335
// InputEvent with a single action.
337-
338336
mClientTestChannel->enqueueMessage(nextPointerMessage(
339337
{0ms,
340338
{Pointer{.id = 0, .x = 10.0f, .y = 20.0f, .toolType = ToolType::MOUSE}},
@@ -391,7 +389,7 @@ TEST_F(InputConsumerResamplingTest, MouseEventIsResampled) {
391389
* Motion events with palm tool type are not resampled.
392390
*/
393391
TEST_F(InputConsumerResamplingTest, PalmEventIsNotResampled) {
394-
// Initial ACTION_DOWN should be separate, because the first consume event will only return
392+
// Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
395393
// InputEvent with a single action.
396394
mClientTestChannel->enqueueMessage(nextPointerMessage(
397395
{0ms,
@@ -431,4 +429,43 @@ TEST_F(InputConsumerResamplingTest, PalmEventIsNotResampled) {
431429
mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
432430
}
433431

432+
/**
433+
* Event should not be resampled when sample time is equal to event time.
434+
*/
435+
TEST_F(InputConsumerResamplingTest, SampleTimeEqualsEventTime) {
436+
// Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
437+
// InputEvent with a single action.
438+
mClientTestChannel->enqueueMessage(nextPointerMessage(
439+
{0ms, {Pointer{.id = 0, .x = 10.0f, .y = 20.0f}}, AMOTION_EVENT_ACTION_DOWN}));
440+
441+
mClientTestChannel->assertNoSentMessages();
442+
443+
invokeLooperCallback();
444+
assertReceivedMotionEvent({InputEventEntry{0ms,
445+
{Pointer{.id = 0, .x = 10.0f, .y = 20.0f}},
446+
AMOTION_EVENT_ACTION_DOWN}});
447+
448+
// Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y
449+
mClientTestChannel->enqueueMessage(nextPointerMessage(
450+
{10ms, {Pointer{.id = 0, .x = 20.0f, .y = 30.0f}}, AMOTION_EVENT_ACTION_MOVE}));
451+
mClientTestChannel->enqueueMessage(nextPointerMessage(
452+
{20ms, {Pointer{.id = 0, .x = 30.0f, .y = 30.0f}}, AMOTION_EVENT_ACTION_MOVE}));
453+
454+
invokeLooperCallback();
455+
mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + 5ms /*RESAMPLE_LATENCY*/}.count());
456+
457+
// MotionEvent should not resampled because the resample time falls exactly on the existing
458+
// event time.
459+
assertReceivedMotionEvent({InputEventEntry{10ms,
460+
{Pointer{.id = 0, .x = 20.0f, .y = 30.0f}},
461+
AMOTION_EVENT_ACTION_MOVE},
462+
InputEventEntry{20ms,
463+
{Pointer{.id = 0, .x = 30.0f, .y = 30.0f}},
464+
AMOTION_EVENT_ACTION_MOVE}});
465+
466+
mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
467+
mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
468+
mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
469+
}
470+
434471
} // namespace android

0 commit comments

Comments
 (0)