@@ -197,8 +197,6 @@ TEST_F(InputConsumerResamplingTest, EventIsResampled) {
197197 mClientTestChannel ->enqueueMessage (nextPointerMessage (
198198 {0ms, {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }}, AMOTION_EVENT_ACTION_DOWN}));
199199
200- mClientTestChannel ->assertNoSentMessages ();
201-
202200 invokeLooperCallback ();
203201 assertReceivedMotionEvent ({InputEventEntry{0ms,
204202 {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }},
@@ -238,8 +236,6 @@ TEST_F(InputConsumerResamplingTest, EventIsResampledWithDifferentId) {
238236 mClientTestChannel ->enqueueMessage (nextPointerMessage (
239237 {0ms, {Pointer{.id = 1 , .x = 10 .0f , .y = 20 .0f }}, AMOTION_EVENT_ACTION_DOWN}));
240238
241- mClientTestChannel ->assertNoSentMessages ();
242-
243239 invokeLooperCallback ();
244240 assertReceivedMotionEvent ({InputEventEntry{0ms,
245241 {Pointer{.id = 1 , .x = 10 .0f , .y = 20 .0f }},
@@ -280,8 +276,6 @@ TEST_F(InputConsumerResamplingTest, StylusEventIsResampled) {
280276 {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f , .toolType = ToolType::STYLUS}},
281277 AMOTION_EVENT_ACTION_DOWN}));
282278
283- mClientTestChannel ->assertNoSentMessages ();
284-
285279 invokeLooperCallback ();
286280 assertReceivedMotionEvent ({InputEventEntry{0ms,
287281 {Pointer{.id = 0 ,
@@ -338,8 +332,6 @@ TEST_F(InputConsumerResamplingTest, MouseEventIsResampled) {
338332 {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f , .toolType = ToolType::MOUSE}},
339333 AMOTION_EVENT_ACTION_DOWN}));
340334
341- mClientTestChannel ->assertNoSentMessages ();
342-
343335 invokeLooperCallback ();
344336 assertReceivedMotionEvent ({InputEventEntry{0ms,
345337 {Pointer{.id = 0 ,
@@ -396,8 +388,6 @@ TEST_F(InputConsumerResamplingTest, PalmEventIsNotResampled) {
396388 {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f , .toolType = ToolType::PALM}},
397389 AMOTION_EVENT_ACTION_DOWN}));
398390
399- mClientTestChannel ->assertNoSentMessages ();
400-
401391 invokeLooperCallback ();
402392 assertReceivedMotionEvent (
403393 {InputEventEntry{0ms,
@@ -438,8 +428,6 @@ TEST_F(InputConsumerResamplingTest, SampleTimeEqualsEventTime) {
438428 mClientTestChannel ->enqueueMessage (nextPointerMessage (
439429 {0ms, {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }}, AMOTION_EVENT_ACTION_DOWN}));
440430
441- mClientTestChannel ->assertNoSentMessages ();
442-
443431 invokeLooperCallback ();
444432 assertReceivedMotionEvent ({InputEventEntry{0ms,
445433 {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }},
@@ -468,4 +456,114 @@ TEST_F(InputConsumerResamplingTest, SampleTimeEqualsEventTime) {
468456 mClientTestChannel ->assertFinishMessage (/* seq=*/ 3 , /* handled=*/ true );
469457}
470458
459+ /* *
460+ * Once we send a resampled value to the app, we should continue to send the last predicted value if
461+ * a pointer does not move. Only real values are used to determine if a pointer does not move.
462+ */
463+ TEST_F (InputConsumerResamplingTest, ResampledValueIsUsedForIdenticalCoordinates) {
464+ // Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
465+ // InputEvent with a single action.
466+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
467+ {0ms, {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }}, AMOTION_EVENT_ACTION_DOWN}));
468+
469+ invokeLooperCallback ();
470+ assertReceivedMotionEvent ({InputEventEntry{0ms,
471+ {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }},
472+ AMOTION_EVENT_ACTION_DOWN}});
473+
474+ // Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y
475+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
476+ {10ms, {Pointer{.id = 0 , .x = 20 .0f , .y = 30 .0f }}, AMOTION_EVENT_ACTION_MOVE}));
477+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
478+ {20ms, {Pointer{.id = 0 , .x = 30 .0f , .y = 30 .0f }}, AMOTION_EVENT_ACTION_MOVE}));
479+
480+ invokeLooperCallback ();
481+ mConsumer ->consumeBatchedInputEvents (nanoseconds{35ms}.count ());
482+ assertReceivedMotionEvent (
483+ {InputEventEntry{10ms,
484+ {Pointer{.id = 0 , .x = 20 .0f , .y = 30 .0f }},
485+ AMOTION_EVENT_ACTION_MOVE},
486+ InputEventEntry{20ms,
487+ {Pointer{.id = 0 , .x = 30 .0f , .y = 30 .0f }},
488+ AMOTION_EVENT_ACTION_MOVE},
489+ InputEventEntry{25ms,
490+ {Pointer{.id = 0 , .x = 35 .0f , .y = 30 .0f , .isResampled = true }},
491+ AMOTION_EVENT_ACTION_MOVE}});
492+
493+ // Coordinate value 30 has been resampled to 35. When a new event comes in with value 30 again,
494+ // the system should still report 35.
495+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
496+ {40ms, {Pointer{.id = 0 , .x = 30 .0f , .y = 30 .0f }}, AMOTION_EVENT_ACTION_MOVE}));
497+
498+ invokeLooperCallback ();
499+ mConsumer ->consumeBatchedInputEvents (nanoseconds{45ms + 5ms /* RESAMPLE_LATENCY*/ }.count ());
500+ assertReceivedMotionEvent (
501+ {InputEventEntry{40ms,
502+ {Pointer{.id = 0 , .x = 35 .0f , .y = 30 .0f , .isResampled = true }},
503+ AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten
504+ InputEventEntry{45ms,
505+ {Pointer{.id = 0 , .x = 35 .0f , .y = 30 .0f , .isResampled = true }},
506+ AMOTION_EVENT_ACTION_MOVE}}); // resampled event, rewritten
507+
508+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 1 , /* handled=*/ true );
509+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 2 , /* handled=*/ true );
510+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 3 , /* handled=*/ true );
511+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 4 , /* handled=*/ true );
512+ }
513+
514+ TEST_F (InputConsumerResamplingTest, OldEventReceivedAfterResampleOccurs) {
515+ // Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
516+ // InputEvent with a single action.
517+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
518+ {0ms, {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }}, AMOTION_EVENT_ACTION_DOWN}));
519+
520+ invokeLooperCallback ();
521+ assertReceivedMotionEvent ({InputEventEntry{0ms,
522+ {Pointer{.id = 0 , .x = 10 .0f , .y = 20 .0f }},
523+ AMOTION_EVENT_ACTION_DOWN}});
524+
525+ // Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y
526+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
527+ {10ms, {Pointer{.id = 0 , .x = 20 .0f , .y = 30 .0f }}, AMOTION_EVENT_ACTION_MOVE}));
528+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
529+ {20ms, {Pointer{.id = 0 , .x = 30 .0f , .y = 30 .0f }}, AMOTION_EVENT_ACTION_MOVE}));
530+
531+ invokeLooperCallback ();
532+ mConsumer ->consumeBatchedInputEvents (nanoseconds{35ms}.count ());
533+ assertReceivedMotionEvent (
534+ {InputEventEntry{10ms,
535+ {Pointer{.id = 0 , .x = 20 .0f , .y = 30 .0f }},
536+ AMOTION_EVENT_ACTION_MOVE},
537+ InputEventEntry{20ms,
538+ {Pointer{.id = 0 , .x = 30 .0f , .y = 30 .0f }},
539+ AMOTION_EVENT_ACTION_MOVE},
540+ InputEventEntry{25ms,
541+ {Pointer{.id = 0 , .x = 35 .0f , .y = 30 .0f , .isResampled = true }},
542+ AMOTION_EVENT_ACTION_MOVE}});
543+
544+ // Above, the resampled event is at 25ms rather than at 30 ms = 35ms - RESAMPLE_LATENCY
545+ // because we are further bound by how far we can extrapolate by the "last time delta".
546+ // That's 50% of (20 ms - 10ms) => 5ms. So we can't predict more than 5 ms into the future
547+ // from the event at 20ms, which is why the resampled event is at t = 25 ms.
548+
549+ // We resampled the event to 25 ms. Now, an older 'real' event comes in.
550+ mClientTestChannel ->enqueueMessage (nextPointerMessage (
551+ {24ms, {Pointer{.id = 0 , .x = 40 .0f , .y = 30 .0f }}, AMOTION_EVENT_ACTION_MOVE}));
552+
553+ invokeLooperCallback ();
554+ mConsumer ->consumeBatchedInputEvents (nanoseconds{50ms}.count ());
555+ assertReceivedMotionEvent (
556+ {InputEventEntry{24ms,
557+ {Pointer{.id = 0 , .x = 35 .0f , .y = 30 .0f , .isResampled = true }},
558+ AMOTION_EVENT_ACTION_MOVE}, // original event, rewritten
559+ InputEventEntry{26ms,
560+ {Pointer{.id = 0 , .x = 45 .0f , .y = 30 .0f , .isResampled = true }},
561+ AMOTION_EVENT_ACTION_MOVE}}); // resampled event, rewritten
562+
563+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 1 , /* handled=*/ true );
564+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 2 , /* handled=*/ true );
565+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 3 , /* handled=*/ true );
566+ mClientTestChannel ->assertFinishMessage (/* seq=*/ 4 , /* handled=*/ true );
567+ }
568+
471569} // namespace android
0 commit comments