1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/logging.h"
7 #include "base/time/time.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/events/gesture_detection/motion_event_buffer.h"
10 #include "ui/events/test/mock_motion_event.h"
12 using base::TimeDelta
;
13 using base::TimeTicks
;
14 using ui::test::MockMotionEvent
;
18 const int kSmallDeltaMs
= 1;
19 const int kLargeDeltaMs
= 50;
20 const int kResampleDeltaMs
= 5;
21 const float kVelocityEpsilon
= 0.01f
;
22 const float kDeltaEpsilon
= 0.1f
;
24 #define EXPECT_EVENT_EQ(A, B) \
26 SCOPED_TRACE(testing::Message()); \
27 ExpectEquals((A), (B)); \
29 #define EXPECT_EVENT_IGNORING_HISTORY_EQ(A, B) \
31 SCOPED_TRACE(testing::Message()); \
32 ExpectEqualsIgnoringHistory((A), (B)); \
34 #define EXPECT_EVENT_HISTORY_EQ(A, I, B) \
36 SCOPED_TRACE(testing::Message()); \
37 ExpectEqualsHistoryIndex((A), (I), (B)); \
40 class MotionEventBufferTest
: public testing::Test
,
41 public MotionEventBufferClient
{
43 MotionEventBufferTest() : needs_flush_(false) {}
44 virtual ~MotionEventBufferTest() {}
46 // MotionEventBufferClient implementation.
47 virtual void ForwardMotionEvent(const MotionEvent
& event
) OVERRIDE
{
48 forwarded_events_
.push_back(event
.Clone().release());
51 virtual void SetNeedsFlush() OVERRIDE
{ needs_flush_
= true; }
53 bool GetAndResetNeedsFlush() {
54 bool needs_flush
= needs_flush_
;
59 ScopedVector
<MotionEvent
> GetAndResetForwardedEvents() {
60 ScopedVector
<MotionEvent
> forwarded_events
;
61 forwarded_events
.swap(forwarded_events_
);
62 return forwarded_events
.Pass();
65 const MotionEvent
* GetLastEvent() const {
66 return forwarded_events_
.empty() ? NULL
: forwarded_events_
.back();
69 static base::TimeDelta
LargeDelta() {
70 return base::TimeDelta::FromMilliseconds(kLargeDeltaMs
);
73 static base::TimeDelta
SmallDelta() {
74 return base::TimeDelta::FromMilliseconds(kSmallDeltaMs
);
77 static base::TimeDelta
ResampleDelta() {
78 return base::TimeDelta::FromMilliseconds(kResampleDeltaMs
);
81 static void ExpectEqualsImpl(const MotionEvent
& a
,
83 bool ignore_history
) {
84 EXPECT_EQ(a
.GetId(), b
.GetId());
85 EXPECT_EQ(a
.GetAction(), b
.GetAction());
86 EXPECT_EQ(a
.GetActionIndex(), b
.GetActionIndex());
87 EXPECT_EQ(a
.GetButtonState(), b
.GetButtonState());
88 EXPECT_EQ(a
.GetEventTime(), b
.GetEventTime());
90 ASSERT_EQ(a
.GetPointerCount(), b
.GetPointerCount());
91 for (size_t i
= 0; i
< a
.GetPointerCount(); ++i
) {
92 int bi
= b
.FindPointerIndexOfId(a
.GetPointerId(i
));
94 EXPECT_EQ(a
.GetX(i
), b
.GetX(bi
));
95 EXPECT_EQ(a
.GetY(i
), b
.GetY(bi
));
96 EXPECT_EQ(a
.GetRawX(i
), b
.GetRawX(bi
));
97 EXPECT_EQ(a
.GetRawY(i
), b
.GetRawY(bi
));
98 EXPECT_EQ(a
.GetTouchMajor(i
), b
.GetTouchMajor(bi
));
99 EXPECT_EQ(a
.GetPressure(i
), b
.GetPressure(bi
));
100 EXPECT_EQ(a
.GetToolType(i
), b
.GetToolType(bi
));
106 ASSERT_EQ(a
.GetHistorySize(), b
.GetHistorySize());
107 for (size_t h
= 0; h
< a
.GetHistorySize(); ++h
)
108 ExpectEqualsHistoryIndex(a
, h
, b
);
111 // Verify that all public data of |a|, excluding history, equals that of |b|.
112 static void ExpectEqualsIgnoringHistory(const MotionEvent
& a
,
113 const MotionEvent
& b
) {
114 const bool ignore_history
= true;
115 ExpectEqualsImpl(a
, b
, ignore_history
);
118 // Verify that all public data of |a| equals that of |b|.
119 static void ExpectEquals(const MotionEvent
& a
, const MotionEvent
& b
) {
120 const bool ignore_history
= false;
121 ExpectEqualsImpl(a
, b
, ignore_history
);
124 // Verify that the historical data of |a| given by |historical_index|
125 // corresponds to the *raw* data of |b|.
126 static void ExpectEqualsHistoryIndex(const MotionEvent
& a
,
127 size_t history_index
,
128 const MotionEvent
& b
) {
129 ASSERT_LT(history_index
, a
.GetHistorySize());
130 EXPECT_EQ(a
.GetPointerCount(), b
.GetPointerCount());
131 EXPECT_TRUE(a
.GetHistoricalEventTime(history_index
) == b
.GetEventTime());
133 for (size_t i
= 0; i
< a
.GetPointerCount(); ++i
) {
134 int bi
= b
.FindPointerIndexOfId(a
.GetPointerId(i
));
136 EXPECT_EQ(a
.GetHistoricalX(i
, history_index
), b
.GetX(bi
));
137 EXPECT_EQ(a
.GetHistoricalY(i
, history_index
), b
.GetY(bi
));
138 EXPECT_EQ(a
.GetHistoricalTouchMajor(i
, history_index
),
139 b
.GetTouchMajor(bi
));
144 void RunResample(base::TimeDelta flush_time_delta
,
145 base::TimeDelta event_time_delta
) {
146 for (base::TimeDelta offset
; offset
< event_time_delta
;
147 offset
+= event_time_delta
/ 3) {
148 SCOPED_TRACE(testing::Message()
149 << "Resample(offset="
150 << static_cast<int>(offset
.InMilliseconds()) << "ms)");
151 RunResample(flush_time_delta
, event_time_delta
, offset
);
155 // Given an event and flush sampling frequency, inject a stream of events,
156 // flushing at appropriate points in the stream. Verify that the continuous
157 // velocity sampled by the *input* stream matches the discrete velocity
158 // as computed from the resampled *output* stream.
159 void RunResample(base::TimeDelta flush_time_delta
,
160 base::TimeDelta event_time_delta
,
161 base::TimeDelta event_time_offset
) {
162 base::TimeTicks event_time
= base::TimeTicks::Now();
163 base::TimeTicks flush_time
=
164 event_time
+ flush_time_delta
- event_time_offset
;
165 base::TimeTicks max_event_time
=
166 event_time
+ base::TimeDelta::FromSecondsD(0.5f
);
167 const size_t min_expected_events
=
168 static_cast<size_t>((max_event_time
- flush_time
) /
169 std::max(event_time_delta
, flush_time_delta
));
171 MotionEventBuffer
buffer(this, true);
173 gfx::Vector2dF
velocity(33.f
, -11.f
);
174 gfx::PointF
position(17.f
, 42.f
);
175 scoped_ptr
<MotionEvent
> last_flushed_event
;
177 float last_dx
= 0, last_dy
= 0;
178 base::TimeDelta last_dt
;
179 while (event_time
< max_event_time
) {
180 position
+= gfx::ScaleVector2d(velocity
, event_time_delta
.InSecondsF());
181 MockMotionEvent
move(
182 MotionEvent::ACTION_MOVE
, event_time
, position
.x(), position
.y());
183 buffer
.OnMotionEvent(move
);
184 event_time
+= event_time_delta
;
186 while (flush_time
< event_time
) {
187 buffer
.Flush(flush_time
);
188 flush_time
+= flush_time_delta
;
189 const MotionEvent
* current_flushed_event
= GetLastEvent();
190 if (current_flushed_event
) {
191 if (!last_flushed_event
) {
192 last_flushed_event
= current_flushed_event
->Clone();
196 base::TimeDelta dt
= current_flushed_event
->GetEventTime() -
197 last_flushed_event
->GetEventTime();
198 EXPECT_GE(dt
.ToInternalValue(), 0);
199 // A time delta of 0 is possible if the flush rate is greater than the
200 // event rate, in which case we can simply skip forward.
201 if (dt
== base::TimeDelta())
205 current_flushed_event
->GetX() - last_flushed_event
->GetX();
207 current_flushed_event
->GetY() - last_flushed_event
->GetY();
208 const float dt_s
= (current_flushed_event
->GetEventTime() -
209 last_flushed_event
->GetEventTime()).InSecondsF();
211 // The discrete velocity should mirror the constant velocity.
212 EXPECT_NEAR(velocity
.x(), dx
/ dt_s
, kVelocityEpsilon
);
213 EXPECT_NEAR(velocity
.y(), dy
/ dt_s
, kVelocityEpsilon
);
215 // The impulse delta for each frame should remain constant.
217 EXPECT_NEAR(dx
, last_dx
, kDeltaEpsilon
);
219 EXPECT_NEAR(dy
, last_dy
, kDeltaEpsilon
);
221 // The timestamp delta should remain constant.
222 if (last_dt
!= base::TimeDelta())
223 EXPECT_TRUE((dt
- last_dt
).InMillisecondsF() < kDeltaEpsilon
);
228 last_flushed_event
= current_flushed_event
->Clone();
229 events
+= GetAndResetForwardedEvents().size();
233 events
+= GetAndResetForwardedEvents().size();
234 EXPECT_GE(events
, min_expected_events
);
238 ScopedVector
<MotionEvent
> forwarded_events_
;
242 TEST_F(MotionEventBufferTest
, BufferEmpty
) {
243 MotionEventBuffer
buffer(this, true);
245 buffer
.Flush(base::TimeTicks::Now());
246 EXPECT_FALSE(GetAndResetNeedsFlush());
247 EXPECT_FALSE(GetLastEvent());
250 TEST_F(MotionEventBufferTest
, BufferWithOneMoveNotResampled
) {
251 base::TimeTicks event_time
= base::TimeTicks::Now();
252 MotionEventBuffer
buffer(this, true);
254 MockMotionEvent
move(MotionEvent::ACTION_MOVE
, event_time
, 4.f
, 4.f
);
255 buffer
.OnMotionEvent(move
);
256 EXPECT_TRUE(GetAndResetNeedsFlush());
257 EXPECT_FALSE(GetLastEvent());
259 buffer
.Flush(event_time
+ ResampleDelta());
260 EXPECT_FALSE(GetAndResetNeedsFlush());
261 ASSERT_TRUE(GetLastEvent());
262 EXPECT_EVENT_EQ(move
, *GetLastEvent());
263 EXPECT_EQ(1U, GetAndResetForwardedEvents().size());
266 TEST_F(MotionEventBufferTest
, BufferFlushedOnNonActionMove
) {
267 base::TimeTicks event_time
= base::TimeTicks::Now();
268 MotionEventBuffer
buffer(this, true);
270 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 1.f
, 1.f
);
271 buffer
.OnMotionEvent(move0
);
272 EXPECT_TRUE(GetAndResetNeedsFlush());
273 EXPECT_FALSE(GetLastEvent());
275 event_time
+= base::TimeDelta::FromMilliseconds(5);
277 // The second move should remain buffered.
278 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 2.f
, 2.f
);
279 buffer
.OnMotionEvent(move1
);
280 EXPECT_FALSE(GetAndResetNeedsFlush());
281 EXPECT_FALSE(GetLastEvent());
283 // The third move should remain buffered.
284 MockMotionEvent
move2(MotionEvent::ACTION_MOVE
, event_time
, 3.f
, 3.f
);
285 buffer
.OnMotionEvent(move2
);
286 EXPECT_FALSE(GetAndResetNeedsFlush());
287 EXPECT_FALSE(GetLastEvent());
289 // The up should flush the buffer.
290 MockMotionEvent
up(MotionEvent::ACTION_UP
, event_time
, 4.f
, 4.f
);
291 buffer
.OnMotionEvent(up
);
292 EXPECT_FALSE(GetAndResetNeedsFlush());
294 // The flushed events should include the up and the moves, with the latter
295 // combined into a single event with history.
296 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
297 ASSERT_EQ(2U, events
.size());
298 EXPECT_EVENT_EQ(up
, *events
.back());
299 EXPECT_EQ(2U, events
.front()->GetHistorySize());
300 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events
.front(), move2
);
301 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
302 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 1, move1
);
305 TEST_F(MotionEventBufferTest
, BufferFlushedOnIncompatibleActionMove
) {
306 base::TimeTicks event_time
= base::TimeTicks::Now();
307 MotionEventBuffer
buffer(this, true);
309 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 1.f
, 1.f
);
310 buffer
.OnMotionEvent(move0
);
311 EXPECT_TRUE(GetAndResetNeedsFlush());
312 EXPECT_FALSE(GetLastEvent());
314 event_time
+= base::TimeDelta::FromMilliseconds(5);
316 // The second move has a different pointer count, flushing the first.
317 MockMotionEvent
move1(
318 MotionEvent::ACTION_MOVE
, event_time
, 2.f
, 2.f
, 3.f
, 3.f
);
319 buffer
.OnMotionEvent(move1
);
320 EXPECT_FALSE(GetAndResetNeedsFlush());
321 ASSERT_TRUE(GetLastEvent());
322 EXPECT_EVENT_EQ(move0
, *GetLastEvent());
324 event_time
+= base::TimeDelta::FromMilliseconds(5);
326 // The third move has differing tool types, flushing the second.
327 MockMotionEvent
move2(move1
);
328 move2
.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS
);
329 buffer
.OnMotionEvent(move2
);
330 EXPECT_FALSE(GetAndResetNeedsFlush());
331 EXPECT_EVENT_EQ(move1
, *GetLastEvent());
333 event_time
+= base::TimeDelta::FromMilliseconds(5);
335 // The flushed event should only include the latest move event.
336 buffer
.Flush(event_time
);
337 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
338 ASSERT_EQ(3U, events
.size());
339 EXPECT_EVENT_EQ(move2
, *events
.back());
340 EXPECT_FALSE(GetAndResetNeedsFlush());
342 event_time
+= base::TimeDelta::FromMilliseconds(5);
344 // Events with different pointer ids should not combine.
345 PointerProperties
pointer0(5.f
, 5.f
);
347 PointerProperties
pointer1(10.f
, 10.f
);
349 MotionEventGeneric
move3(MotionEvent::ACTION_MOVE
, event_time
, pointer0
);
350 move3
.PushPointer(pointer1
);
351 buffer
.OnMotionEvent(move3
);
352 ASSERT_FALSE(GetLastEvent());
353 EXPECT_TRUE(GetAndResetNeedsFlush());
355 MotionEventGeneric
move4(MotionEvent::ACTION_MOVE
, event_time
, pointer0
);
357 move4
.PushPointer(pointer1
);
358 buffer
.OnMotionEvent(move2
);
359 EXPECT_FALSE(GetAndResetNeedsFlush());
360 ASSERT_TRUE(GetLastEvent());
361 EXPECT_EVENT_EQ(move3
, *GetLastEvent());
364 TEST_F(MotionEventBufferTest
, OnlyActionMoveBuffered
) {
365 base::TimeTicks event_time
= base::TimeTicks::Now();
366 MotionEventBuffer
buffer(this, true);
368 MockMotionEvent
down(MotionEvent::ACTION_DOWN
, event_time
, 1.f
, 1.f
);
369 buffer
.OnMotionEvent(down
);
370 EXPECT_FALSE(GetAndResetNeedsFlush());
371 ASSERT_TRUE(GetLastEvent());
372 EXPECT_EVENT_EQ(down
, *GetLastEvent());
374 GetAndResetForwardedEvents();
376 MockMotionEvent
up(MotionEvent::ACTION_UP
, event_time
, 2.f
, 2.f
);
377 buffer
.OnMotionEvent(up
);
378 EXPECT_FALSE(GetAndResetNeedsFlush());
379 ASSERT_TRUE(GetLastEvent());
380 EXPECT_EVENT_EQ(up
, *GetLastEvent());
382 GetAndResetForwardedEvents();
384 MockMotionEvent
cancel(MotionEvent::ACTION_CANCEL
, event_time
, 3.f
, 3.f
);
385 buffer
.OnMotionEvent(cancel
);
386 EXPECT_FALSE(GetAndResetNeedsFlush());
387 ASSERT_TRUE(GetLastEvent());
388 EXPECT_EVENT_EQ(cancel
, *GetLastEvent());
390 GetAndResetForwardedEvents();
392 MockMotionEvent
move(MotionEvent::ACTION_MOVE
, event_time
, 4.f
, 4.f
);
393 buffer
.OnMotionEvent(move
);
394 EXPECT_TRUE(GetAndResetNeedsFlush());
395 EXPECT_FALSE(GetLastEvent());
397 base::TimeTicks flush_time
= move
.GetEventTime() + ResampleDelta();
398 buffer
.Flush(flush_time
);
399 EXPECT_FALSE(GetAndResetNeedsFlush());
400 ASSERT_TRUE(GetLastEvent());
401 EXPECT_EVENT_EQ(move
, *GetLastEvent());
404 TEST_F(MotionEventBufferTest
, OutOfOrderPointersBuffered
) {
405 base::TimeTicks event_time
= base::TimeTicks::Now();
406 MotionEventBuffer
buffer(this, true);
408 PointerProperties
p0(1.f
, 2.f
);
410 PointerProperties
p1(2.f
, 1.f
);
413 MotionEventGeneric
move0(MotionEvent::ACTION_MOVE
, event_time
, p0
);
414 move0
.PushPointer(p1
);
415 buffer
.OnMotionEvent(move0
);
416 EXPECT_TRUE(GetAndResetNeedsFlush());
417 ASSERT_FALSE(GetLastEvent());
419 event_time
+= base::TimeDelta::FromMilliseconds(5);
421 // The second move should remain buffered even if the logical pointers are
422 // in a different order.
423 MotionEventGeneric
move1(MotionEvent::ACTION_MOVE
, event_time
, p1
);
424 move1
.PushPointer(p0
);
425 buffer
.OnMotionEvent(move1
);
426 EXPECT_FALSE(GetAndResetNeedsFlush());
427 ASSERT_FALSE(GetLastEvent());
429 // As the two events are logically the same but for ordering and time, the
430 // synthesized event should yield a logically identical event.
431 base::TimeTicks flush_time
= move1
.GetEventTime() + ResampleDelta();
432 buffer
.Flush(flush_time
);
433 EXPECT_FALSE(GetAndResetNeedsFlush());
434 ASSERT_TRUE(GetLastEvent());
435 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
436 ASSERT_EQ(1U, events
.size());
437 EXPECT_EVENT_IGNORING_HISTORY_EQ(move1
, *events
.front());
438 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
441 TEST_F(MotionEventBufferTest
, FlushedEventsNeverLaterThanFlushTime
) {
442 base::TimeTicks event_time
= base::TimeTicks::Now();
443 MotionEventBuffer
buffer(this, true);
445 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 1.f
, 1.f
);
446 buffer
.OnMotionEvent(move0
);
447 ASSERT_FALSE(GetLastEvent());
448 EXPECT_TRUE(GetAndResetNeedsFlush());
450 // The second move should remain buffered.
451 event_time
+= LargeDelta();
452 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 2.f
, 2.f
);
453 buffer
.OnMotionEvent(move1
);
454 ASSERT_FALSE(GetLastEvent());
455 EXPECT_FALSE(GetAndResetNeedsFlush());
457 // A flush occurring too early should not forward any events.
458 base::TimeTicks flush_time
= move0
.GetEventTime() - ResampleDelta();
459 buffer
.Flush(flush_time
);
460 ASSERT_FALSE(GetLastEvent());
461 EXPECT_TRUE(GetAndResetNeedsFlush());
463 // With resampling enabled, a flush occurring before the resample
464 // offset should not forward any events.
465 flush_time
= move0
.GetEventTime();
466 buffer
.Flush(flush_time
);
467 ASSERT_FALSE(GetLastEvent());
468 EXPECT_TRUE(GetAndResetNeedsFlush());
470 // Only the first event should get flushed, as the flush timestamp precedes
471 // the second's timestamp by a sufficient amount (preventing interpolation).
472 flush_time
= move0
.GetEventTime() + ResampleDelta();
473 buffer
.Flush(flush_time
);
475 // There should only be one flushed event.
476 EXPECT_TRUE(GetAndResetNeedsFlush());
477 ASSERT_TRUE(GetLastEvent());
478 EXPECT_TRUE(GetLastEvent()->GetEventTime() <= flush_time
);
479 GetAndResetForwardedEvents();
481 // Flushing again with a similar timestamp should have no effect other than
482 // triggering another flush request.
483 flush_time
+= base::TimeDelta::FromMilliseconds(1);
484 buffer
.Flush(flush_time
);
485 EXPECT_FALSE(GetLastEvent());
486 EXPECT_TRUE(GetAndResetNeedsFlush());
488 // Flushing after the second move's time should trigger forwarding.
489 flush_time
= move1
.GetEventTime() + ResampleDelta();
490 buffer
.Flush(flush_time
);
491 ASSERT_TRUE(GetLastEvent());
492 EXPECT_EVENT_EQ(move1
, *GetLastEvent());
493 EXPECT_FALSE(GetAndResetNeedsFlush());
496 TEST_F(MotionEventBufferTest
, NoResamplingWhenDisabled
) {
497 base::TimeTicks event_time
= base::TimeTicks::Now();
498 const bool resampling_enabled
= false;
499 MotionEventBuffer
buffer(this, resampling_enabled
);
502 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 5.f
, 10.f
);
503 buffer
.OnMotionEvent(move0
);
504 ASSERT_FALSE(GetLastEvent());
505 EXPECT_TRUE(GetAndResetNeedsFlush());
507 event_time
+= base::TimeDelta::FromMilliseconds(5);
508 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 15.f
, 30.f
);
509 buffer
.OnMotionEvent(move1
);
510 ASSERT_FALSE(GetLastEvent());
511 EXPECT_FALSE(GetAndResetNeedsFlush());
513 // Flush at a time between the first and second events.
514 base::TimeTicks interpolated_time
=
515 move0
.GetEventTime() + (move1
.GetEventTime() - move0
.GetEventTime()) / 2;
516 base::TimeTicks flush_time
= interpolated_time
;
517 buffer
.Flush(flush_time
);
518 ASSERT_TRUE(GetLastEvent());
519 EXPECT_TRUE(GetAndResetNeedsFlush());
521 // There should only be one flushed event, with the second remaining buffered
522 // and no resampling having occurred.
523 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
524 ASSERT_EQ(1U, events
.size());
525 EXPECT_EVENT_EQ(move0
, *events
.front());
527 // The second move should be flushed without resampling.
528 flush_time
= move1
.GetEventTime();
529 buffer
.Flush(flush_time
);
530 ASSERT_TRUE(GetLastEvent());
531 EXPECT_EVENT_EQ(move1
, *GetLastEvent());
532 GetAndResetForwardedEvents();
534 // Now queue two more events.
535 move0
= MockMotionEvent(MotionEvent::ACTION_MOVE
, event_time
, 5.f
, 10.f
);
536 buffer
.OnMotionEvent(move0
);
537 ASSERT_FALSE(GetLastEvent());
538 EXPECT_TRUE(GetAndResetNeedsFlush());
540 // The second move should remain buffered.
541 event_time
+= base::TimeDelta::FromMilliseconds(5);
542 move1
= MockMotionEvent(MotionEvent::ACTION_MOVE
, event_time
, 10.f
, 20.f
);
543 buffer
.OnMotionEvent(move1
);
544 ASSERT_FALSE(GetLastEvent());
545 EXPECT_FALSE(GetAndResetNeedsFlush());
547 // Sample at a time beyond the first and second events.
549 move1
.GetEventTime() + (move1
.GetEventTime() - move0
.GetEventTime());
550 buffer
.Flush(flush_time
);
551 ASSERT_TRUE(GetLastEvent());
552 EXPECT_FALSE(GetAndResetNeedsFlush());
554 // There should only be one flushed event, with the first event in the history
555 // and the second event as the actual event data (no resampling).
556 events
= GetAndResetForwardedEvents();
557 ASSERT_EQ(1U, events
.size());
558 EXPECT_EQ(1U, events
.front()->GetHistorySize());
559 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events
.front(), move1
);
560 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
563 TEST_F(MotionEventBufferTest
, NoResamplingWithOutOfOrderActionMove
) {
564 base::TimeTicks event_time
= base::TimeTicks::Now();
565 MotionEventBuffer
buffer(this, true);
567 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 5.f
, 10.f
);
568 buffer
.OnMotionEvent(move0
);
569 ASSERT_FALSE(GetLastEvent());
570 EXPECT_TRUE(GetAndResetNeedsFlush());
572 // The second move should remain buffered.
573 event_time
+= base::TimeDelta::FromMilliseconds(10);
574 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 10.f
, 20.f
);
575 buffer
.OnMotionEvent(move1
);
576 ASSERT_FALSE(GetLastEvent());
577 EXPECT_FALSE(GetAndResetNeedsFlush());
579 // Sample at a time beyond the first and second events.
580 base::TimeTicks extrapolated_time
=
581 move1
.GetEventTime() + (move1
.GetEventTime() - move0
.GetEventTime());
582 base::TimeTicks flush_time
= extrapolated_time
+ ResampleDelta();
583 buffer
.Flush(flush_time
);
584 ASSERT_TRUE(GetLastEvent());
585 EXPECT_FALSE(GetAndResetNeedsFlush());
587 // There should only be one flushed event, with the event extrapolated from
589 base::TimeTicks expected_time
=
590 move1
.GetEventTime() + (move1
.GetEventTime() - move0
.GetEventTime()) / 2;
591 ScopedVector
<MotionEvent
> events0
= GetAndResetForwardedEvents();
592 ASSERT_EQ(1U, events0
.size());
593 EXPECT_EQ(2U, events0
.front()->GetHistorySize());
594 EXPECT_EQ(expected_time
, events0
.front()->GetEventTime());
595 EXPECT_FALSE(GetAndResetNeedsFlush());
597 // Try enqueuing an event *after* the second event but *before* the
598 // extrapolated event. It should be dropped.
599 event_time
= move1
.GetEventTime() + base::TimeDelta::FromMilliseconds(1);
600 MockMotionEvent
move2(MotionEvent::ACTION_MOVE
, event_time
, 15.f
, 25.f
);
601 buffer
.OnMotionEvent(move1
);
602 ASSERT_FALSE(GetLastEvent());
603 EXPECT_FALSE(GetAndResetNeedsFlush());
605 // Finally queue an event *after* the extrapolated event.
606 event_time
= expected_time
+ base::TimeDelta::FromMilliseconds(1);
607 MockMotionEvent
move3(MotionEvent::ACTION_MOVE
, event_time
, 15.f
, 25.f
);
608 buffer
.OnMotionEvent(move3
);
609 ASSERT_FALSE(GetLastEvent());
610 EXPECT_TRUE(GetAndResetNeedsFlush());
612 // The flushed event should simply be the latest event.
613 flush_time
= event_time
+ ResampleDelta();
614 buffer
.Flush(flush_time
);
615 ASSERT_TRUE(GetLastEvent());
616 ScopedVector
<MotionEvent
> events1
= GetAndResetForwardedEvents();
617 ASSERT_EQ(1U, events1
.size());
618 EXPECT_EVENT_EQ(move3
, *events1
.front());
619 EXPECT_FALSE(GetAndResetNeedsFlush());
622 TEST_F(MotionEventBufferTest
, NoResamplingWithSmallTimeDeltaBetweenMoves
) {
623 base::TimeTicks event_time
= base::TimeTicks::Now();
624 MotionEventBuffer
buffer(this, true);
626 // The first move should be buffered.
627 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 1.f
, 1.f
);
628 buffer
.OnMotionEvent(move0
);
629 ASSERT_FALSE(GetLastEvent());
630 EXPECT_TRUE(GetAndResetNeedsFlush());
632 // The second move should remain buffered.
633 event_time
+= SmallDelta();
634 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 2.f
, 2.f
);
635 buffer
.OnMotionEvent(move1
);
636 ASSERT_FALSE(GetLastEvent());
637 EXPECT_FALSE(GetAndResetNeedsFlush());
639 base::TimeTicks flush_time
= event_time
+ ResampleDelta();
640 buffer
.Flush(flush_time
);
641 EXPECT_FALSE(GetAndResetNeedsFlush());
643 // There should only be one flushed event, and no resampling should have
644 // occured between the first and the second as they were temporally too close.
645 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
646 ASSERT_EQ(1U, events
.size());
647 EXPECT_EQ(1U, events
.front()->GetHistorySize());
648 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events
.front(), move1
);
649 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
652 TEST_F(MotionEventBufferTest
, NoResamplingWithMismatchBetweenMoves
) {
653 base::TimeTicks event_time
= base::TimeTicks::Now();
654 MotionEventBuffer
buffer(this, true);
656 // The first move should be buffered.
657 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 1.f
, 1.f
);
658 buffer
.OnMotionEvent(move0
);
659 ASSERT_FALSE(GetLastEvent());
660 EXPECT_TRUE(GetAndResetNeedsFlush());
662 // The second move should remain buffered.
663 event_time
+= SmallDelta();
664 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 2.f
, 2.f
);
665 buffer
.OnMotionEvent(move1
);
666 ASSERT_FALSE(GetLastEvent());
667 EXPECT_FALSE(GetAndResetNeedsFlush());
669 base::TimeTicks flush_time
= event_time
+ ResampleDelta();
670 buffer
.Flush(flush_time
);
671 EXPECT_FALSE(GetAndResetNeedsFlush());
673 // There should only be one flushed event, and no resampling should have
674 // occured between the first and the second as they were temporally too close.
675 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
676 ASSERT_EQ(1U, events
.size());
677 EXPECT_EQ(1U, events
.front()->GetHistorySize());
678 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events
.front(), move1
);
679 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
682 TEST_F(MotionEventBufferTest
, Interpolation
) {
683 base::TimeTicks event_time
= base::TimeTicks::Now();
684 MotionEventBuffer
buffer(this, true);
686 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 5.f
, 10.f
);
687 buffer
.OnMotionEvent(move0
);
688 ASSERT_FALSE(GetLastEvent());
689 EXPECT_TRUE(GetAndResetNeedsFlush());
691 // The second move should remain buffered.
692 event_time
+= base::TimeDelta::FromMilliseconds(5);
693 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 15.f
, 30.f
);
694 buffer
.OnMotionEvent(move1
);
695 ASSERT_FALSE(GetLastEvent());
696 EXPECT_FALSE(GetAndResetNeedsFlush());
698 // Sample at a time between the first and second events.
699 base::TimeTicks interpolated_time
=
700 move0
.GetEventTime() + (move1
.GetEventTime() - move0
.GetEventTime()) / 3;
701 base::TimeTicks flush_time
= interpolated_time
+ ResampleDelta();
702 buffer
.Flush(flush_time
);
703 ASSERT_TRUE(GetLastEvent());
704 EXPECT_TRUE(GetAndResetNeedsFlush());
706 // There should only be one flushed event, with the event interpolated between
707 // the two events. The second event should remain buffered.
708 float alpha
= (interpolated_time
- move0
.GetEventTime()).InMillisecondsF() /
709 (move1
.GetEventTime() - move0
.GetEventTime()).InMillisecondsF();
710 MockMotionEvent
interpolated_event(
711 MotionEvent::ACTION_MOVE
,
713 move0
.GetX(0) + (move1
.GetX(0) - move0
.GetX(0)) * alpha
,
714 move0
.GetY(0) + (move1
.GetY(0) - move0
.GetY(0)) * alpha
);
715 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
716 ASSERT_EQ(1U, events
.size());
717 EXPECT_EQ(1U, events
.front()->GetHistorySize());
718 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events
.front(), interpolated_event
);
719 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
721 // The second move should be flushed without resampling.
722 flush_time
= move1
.GetEventTime() + ResampleDelta();
723 buffer
.Flush(flush_time
);
724 ASSERT_TRUE(GetLastEvent());
725 EXPECT_EVENT_EQ(move1
, *GetLastEvent());
728 TEST_F(MotionEventBufferTest
, Extrapolation
) {
729 base::TimeTicks event_time
= base::TimeTicks::Now();
730 MotionEventBuffer
buffer(this, true);
732 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 5.f
, 10.f
);
733 buffer
.OnMotionEvent(move0
);
734 ASSERT_FALSE(GetLastEvent());
735 EXPECT_TRUE(GetAndResetNeedsFlush());
737 // The second move should remain buffered.
738 event_time
+= base::TimeDelta::FromMilliseconds(5);
739 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 10.f
, 20.f
);
740 buffer
.OnMotionEvent(move1
);
741 ASSERT_FALSE(GetLastEvent());
742 EXPECT_FALSE(GetAndResetNeedsFlush());
744 // Sample at a time beyond the first and second events.
745 base::TimeTicks extrapolated_time
=
746 move1
.GetEventTime() + (move1
.GetEventTime() - move0
.GetEventTime());
747 base::TimeTicks flush_time
= extrapolated_time
+ ResampleDelta();
748 buffer
.Flush(flush_time
);
749 ASSERT_TRUE(GetLastEvent());
750 EXPECT_FALSE(GetAndResetNeedsFlush());
752 // There should only be one flushed event, with the event extrapolated from
753 // the two events. The first and second events should be in the history.
754 // Note that the maximum extrapolation is limited by *half* of the time delta
755 // between the two events, hence we divide the relative delta by 2 in
756 // determining the extrapolated event.
757 base::TimeTicks expected_time
=
758 move1
.GetEventTime() + (move1
.GetEventTime() - move0
.GetEventTime()) / 2;
759 float expected_alpha
=
760 (expected_time
- move0
.GetEventTime()).InMillisecondsF() /
761 (move1
.GetEventTime() - move0
.GetEventTime()).InMillisecondsF();
762 MockMotionEvent
extrapolated_event(
763 MotionEvent::ACTION_MOVE
,
765 move0
.GetX(0) + (move1
.GetX(0) - move0
.GetX(0)) * expected_alpha
,
766 move0
.GetY(0) + (move1
.GetY(0) - move0
.GetY(0)) * expected_alpha
);
767 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
768 ASSERT_EQ(1U, events
.size());
769 EXPECT_EQ(2U, events
.front()->GetHistorySize());
770 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events
.front(), extrapolated_event
);
771 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
772 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 1, move1
);
775 TEST_F(MotionEventBufferTest
, ExtrapolationHorizonLimited
) {
776 base::TimeTicks event_time
= base::TimeTicks::Now();
777 MotionEventBuffer
buffer(this, true);
779 MockMotionEvent
move0(MotionEvent::ACTION_MOVE
, event_time
, 5.f
, 10.f
);
780 buffer
.OnMotionEvent(move0
);
781 ASSERT_FALSE(GetLastEvent());
782 EXPECT_TRUE(GetAndResetNeedsFlush());
784 // The second move should remain buffered.
785 event_time
+= base::TimeDelta::FromMilliseconds(24);
786 MockMotionEvent
move1(MotionEvent::ACTION_MOVE
, event_time
, 10.f
, 20.f
);
787 buffer
.OnMotionEvent(move1
);
788 ASSERT_FALSE(GetLastEvent());
789 EXPECT_FALSE(GetAndResetNeedsFlush());
791 // Sample at a time beyond the first and second events.
792 base::TimeTicks extrapolated_time
=
793 event_time
+ base::TimeDelta::FromMilliseconds(24);
794 base::TimeTicks flush_time
= extrapolated_time
+ ResampleDelta();
795 buffer
.Flush(flush_time
);
796 ASSERT_TRUE(GetLastEvent());
797 EXPECT_FALSE(GetAndResetNeedsFlush());
799 // There should only be one flushed event, with the event extrapolated from
800 // the two events. The first and second events should be in the history.
801 // Note that the maximum extrapolation is limited by 8 ms.
802 base::TimeTicks expected_time
=
803 move1
.GetEventTime() + base::TimeDelta::FromMilliseconds(8);
804 float expected_alpha
=
805 (expected_time
- move0
.GetEventTime()).InMillisecondsF() /
806 (move1
.GetEventTime() - move0
.GetEventTime()).InMillisecondsF();
807 MockMotionEvent
extrapolated_event(
808 MotionEvent::ACTION_MOVE
,
810 move0
.GetX(0) + (move1
.GetX(0) - move0
.GetX(0)) * expected_alpha
,
811 move0
.GetY(0) + (move1
.GetY(0) - move0
.GetY(0)) * expected_alpha
);
812 ScopedVector
<MotionEvent
> events
= GetAndResetForwardedEvents();
813 ASSERT_EQ(1U, events
.size());
814 EXPECT_EQ(2U, events
.front()->GetHistorySize());
815 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events
.front(), extrapolated_event
);
816 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 0, move0
);
817 EXPECT_EVENT_HISTORY_EQ(*events
.front(), 1, move1
);
820 TEST_F(MotionEventBufferTest
, ResamplingWithReorderedPointers
) {
824 TEST_F(MotionEventBufferTest
, Resampling30to60
) {
825 base::TimeDelta flush_time_delta
=
826 base::TimeDelta::FromMillisecondsD(1000. / 60.);
827 base::TimeDelta event_time_delta
=
828 base::TimeDelta::FromMillisecondsD(1000. / 30.);
830 RunResample(flush_time_delta
, event_time_delta
);
833 TEST_F(MotionEventBufferTest
, Resampling60to60
) {
834 base::TimeDelta flush_time_delta
=
835 base::TimeDelta::FromMillisecondsD(1000. / 60.);
836 base::TimeDelta event_time_delta
=
837 base::TimeDelta::FromMillisecondsD(1000. / 60.);
839 RunResample(flush_time_delta
, event_time_delta
);
842 TEST_F(MotionEventBufferTest
, Resampling100to60
) {
843 base::TimeDelta flush_time_delta
=
844 base::TimeDelta::FromMillisecondsD(1000. / 60.);
845 base::TimeDelta event_time_delta
=
846 base::TimeDelta::FromMillisecondsD(1000. / 100.);
848 RunResample(flush_time_delta
, event_time_delta
);
851 TEST_F(MotionEventBufferTest
, Resampling120to60
) {
852 base::TimeDelta flush_time_delta
=
853 base::TimeDelta::FromMillisecondsD(1000. / 60.);
854 base::TimeDelta event_time_delta
=
855 base::TimeDelta::FromMillisecondsD(1000. / 120.);
857 RunResample(flush_time_delta
, event_time_delta
);
860 TEST_F(MotionEventBufferTest
, Resampling150to60
) {
861 base::TimeDelta flush_time_delta
=
862 base::TimeDelta::FromMillisecondsD(1000. / 60.);
863 base::TimeDelta event_time_delta
=
864 base::TimeDelta::FromMillisecondsD(1000. / 150.);
866 RunResample(flush_time_delta
, event_time_delta
);