Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / events / gesture_detection / motion_event_buffer_unittest.cc
blob5e23bd529fd7663016eb1aaac66f33516da4339d
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/motion_event_test_utils.h"
12 using base::TimeDelta;
13 using base::TimeTicks;
14 using ui::test::MockMotionEvent;
16 namespace ui {
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) \
25 { \
26 SCOPED_TRACE(testing::Message()); \
27 ExpectEquals((A), (B)); \
29 #define EXPECT_EVENT_IGNORING_HISTORY_EQ(A, B) \
30 { \
31 SCOPED_TRACE(testing::Message()); \
32 ExpectEqualsIgnoringHistory((A), (B)); \
34 #define EXPECT_EVENT_HISTORY_EQ(A, I, B) \
35 { \
36 SCOPED_TRACE(testing::Message()); \
37 ExpectEqualsHistoryIndex((A), (I), (B)); \
40 class MotionEventBufferTest : public testing::Test,
41 public MotionEventBufferClient {
42 public:
43 MotionEventBufferTest() : needs_flush_(false) {}
44 ~MotionEventBufferTest() override {}
46 // MotionEventBufferClient implementation.
47 void ForwardMotionEvent(const MotionEvent& event) override {
48 forwarded_events_.push_back(event.Clone().release());
51 void SetNeedsFlush() override { needs_flush_ = true; }
53 bool GetAndResetNeedsFlush() {
54 bool needs_flush = needs_flush_;
55 needs_flush_ = false;
56 return 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,
82 const MotionEvent& b,
83 bool ignore_history) {
84 EXPECT_EQ(a.GetAction(), b.GetAction());
85 if (a.GetAction() == MotionEvent::ACTION_POINTER_DOWN ||
86 a.GetAction() == MotionEvent::ACTION_POINTER_UP) {
87 EXPECT_EQ(a.GetActionIndex(), b.GetActionIndex());
89 EXPECT_EQ(a.GetButtonState(), b.GetButtonState());
90 EXPECT_EQ(a.GetEventTime(), b.GetEventTime());
92 ASSERT_EQ(a.GetPointerCount(), b.GetPointerCount());
93 for (size_t i = 0; i < a.GetPointerCount(); ++i) {
94 int bi = b.FindPointerIndexOfId(a.GetPointerId(i));
95 ASSERT_NE(bi, -1);
96 EXPECT_EQ(a.GetX(i), b.GetX(bi));
97 EXPECT_EQ(a.GetY(i), b.GetY(bi));
98 EXPECT_EQ(a.GetRawX(i), b.GetRawX(bi));
99 EXPECT_EQ(a.GetRawY(i), b.GetRawY(bi));
100 EXPECT_EQ(a.GetTouchMajor(i), b.GetTouchMajor(bi));
101 EXPECT_EQ(a.GetTouchMinor(i), b.GetTouchMinor(bi));
102 EXPECT_EQ(a.GetOrientation(i), b.GetOrientation(bi));
103 EXPECT_EQ(a.GetPressure(i), b.GetPressure(bi));
104 EXPECT_EQ(a.GetToolType(i), b.GetToolType(bi));
107 if (ignore_history)
108 return;
110 ASSERT_EQ(a.GetHistorySize(), b.GetHistorySize());
111 for (size_t h = 0; h < a.GetHistorySize(); ++h)
112 ExpectEqualsHistoryIndex(a, h, b);
115 // Verify that all public data of |a|, excluding history, equals that of |b|.
116 static void ExpectEqualsIgnoringHistory(const MotionEvent& a,
117 const MotionEvent& b) {
118 const bool ignore_history = true;
119 ExpectEqualsImpl(a, b, ignore_history);
122 // Verify that all public data of |a| equals that of |b|.
123 static void ExpectEquals(const MotionEvent& a, const MotionEvent& b) {
124 const bool ignore_history = false;
125 ExpectEqualsImpl(a, b, ignore_history);
128 // Verify that the historical data of |a| given by |historical_index|
129 // corresponds to the *raw* data of |b|.
130 static void ExpectEqualsHistoryIndex(const MotionEvent& a,
131 size_t history_index,
132 const MotionEvent& b) {
133 ASSERT_LT(history_index, a.GetHistorySize());
134 EXPECT_EQ(a.GetPointerCount(), b.GetPointerCount());
135 EXPECT_TRUE(a.GetHistoricalEventTime(history_index) == b.GetEventTime());
137 for (size_t i = 0; i < a.GetPointerCount(); ++i) {
138 int bi = b.FindPointerIndexOfId(a.GetPointerId(i));
139 ASSERT_NE(bi, -1);
140 EXPECT_EQ(a.GetHistoricalX(i, history_index), b.GetX(bi));
141 EXPECT_EQ(a.GetHistoricalY(i, history_index), b.GetY(bi));
142 EXPECT_EQ(a.GetHistoricalTouchMajor(i, history_index),
143 b.GetTouchMajor(bi));
147 protected:
148 void RunResample(base::TimeDelta flush_time_delta,
149 base::TimeDelta event_time_delta) {
150 for (base::TimeDelta offset; offset < event_time_delta;
151 offset += event_time_delta / 3) {
152 SCOPED_TRACE(testing::Message()
153 << "Resample(offset="
154 << static_cast<int>(offset.InMilliseconds()) << "ms)");
155 RunResample(flush_time_delta, event_time_delta, offset);
159 // Given an event and flush sampling frequency, inject a stream of events,
160 // flushing at appropriate points in the stream. Verify that the continuous
161 // velocity sampled by the *input* stream matches the discrete velocity
162 // as computed from the resampled *output* stream.
163 void RunResample(base::TimeDelta flush_time_delta,
164 base::TimeDelta event_time_delta,
165 base::TimeDelta event_time_offset) {
166 base::TimeTicks event_time = base::TimeTicks::Now();
167 base::TimeTicks flush_time =
168 event_time + flush_time_delta - event_time_offset;
169 base::TimeTicks max_event_time =
170 event_time + base::TimeDelta::FromSecondsD(0.5f);
171 const size_t min_expected_events =
172 static_cast<size_t>((max_event_time - flush_time) /
173 std::max(event_time_delta, flush_time_delta));
175 MotionEventBuffer buffer(this, true);
177 gfx::Vector2dF velocity(33.f, -11.f);
178 gfx::PointF position(17.f, 42.f);
179 scoped_ptr<MotionEvent> last_flushed_event;
180 size_t events = 0;
181 float last_dx = 0, last_dy = 0;
182 base::TimeDelta last_dt;
183 while (event_time < max_event_time) {
184 position += gfx::ScaleVector2d(velocity, event_time_delta.InSecondsF());
185 MockMotionEvent move(
186 MotionEvent::ACTION_MOVE, event_time, position.x(), position.y());
187 buffer.OnMotionEvent(move);
188 event_time += event_time_delta;
190 while (flush_time < event_time) {
191 buffer.Flush(flush_time);
192 flush_time += flush_time_delta;
193 const MotionEvent* current_flushed_event = GetLastEvent();
194 if (current_flushed_event) {
195 if (!last_flushed_event) {
196 last_flushed_event = current_flushed_event->Clone();
197 continue;
200 base::TimeDelta dt = current_flushed_event->GetEventTime() -
201 last_flushed_event->GetEventTime();
202 EXPECT_GE(dt.ToInternalValue(), 0);
203 // A time delta of 0 is possible if the flush rate is greater than the
204 // event rate, in which case we can simply skip forward.
205 if (dt == base::TimeDelta())
206 continue;
208 const float dx =
209 current_flushed_event->GetX() - last_flushed_event->GetX();
210 const float dy =
211 current_flushed_event->GetY() - last_flushed_event->GetY();
212 const float dt_s = (current_flushed_event->GetEventTime() -
213 last_flushed_event->GetEventTime()).InSecondsF();
215 // The discrete velocity should mirror the constant velocity.
216 EXPECT_NEAR(velocity.x(), dx / dt_s, kVelocityEpsilon);
217 EXPECT_NEAR(velocity.y(), dy / dt_s, kVelocityEpsilon);
219 // The impulse delta for each frame should remain constant.
220 if (last_dy)
221 EXPECT_NEAR(dx, last_dx, kDeltaEpsilon);
222 if (last_dy)
223 EXPECT_NEAR(dy, last_dy, kDeltaEpsilon);
225 // The timestamp delta should remain constant.
226 if (last_dt != base::TimeDelta())
227 EXPECT_TRUE((dt - last_dt).InMillisecondsF() < kDeltaEpsilon);
229 last_dx = dx;
230 last_dy = dy;
231 last_dt = dt;
232 last_flushed_event = current_flushed_event->Clone();
233 events += GetAndResetForwardedEvents().size();
237 events += GetAndResetForwardedEvents().size();
238 EXPECT_GE(events, min_expected_events);
241 private:
242 ScopedVector<MotionEvent> forwarded_events_;
243 bool needs_flush_;
246 TEST_F(MotionEventBufferTest, BufferEmpty) {
247 MotionEventBuffer buffer(this, true);
249 buffer.Flush(base::TimeTicks::Now());
250 EXPECT_FALSE(GetAndResetNeedsFlush());
251 EXPECT_FALSE(GetLastEvent());
254 TEST_F(MotionEventBufferTest, BufferWithOneMoveNotResampled) {
255 base::TimeTicks event_time = base::TimeTicks::Now();
256 MotionEventBuffer buffer(this, true);
258 MockMotionEvent move(MotionEvent::ACTION_MOVE, event_time, 4.f, 4.f);
259 buffer.OnMotionEvent(move);
260 EXPECT_TRUE(GetAndResetNeedsFlush());
261 EXPECT_FALSE(GetLastEvent());
263 buffer.Flush(event_time + ResampleDelta());
264 EXPECT_FALSE(GetAndResetNeedsFlush());
265 ASSERT_TRUE(GetLastEvent());
266 EXPECT_EVENT_EQ(move, *GetLastEvent());
267 EXPECT_EQ(1U, GetAndResetForwardedEvents().size());
270 TEST_F(MotionEventBufferTest, BufferFlushedOnNonActionMove) {
271 base::TimeTicks event_time = base::TimeTicks::Now();
272 MotionEventBuffer buffer(this, true);
274 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
275 buffer.OnMotionEvent(move0);
276 EXPECT_TRUE(GetAndResetNeedsFlush());
277 EXPECT_FALSE(GetLastEvent());
279 event_time += base::TimeDelta::FromMilliseconds(5);
281 // The second move should remain buffered.
282 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
283 buffer.OnMotionEvent(move1);
284 EXPECT_FALSE(GetAndResetNeedsFlush());
285 EXPECT_FALSE(GetLastEvent());
287 // The third move should remain buffered.
288 MockMotionEvent move2(MotionEvent::ACTION_MOVE, event_time, 3.f, 3.f);
289 buffer.OnMotionEvent(move2);
290 EXPECT_FALSE(GetAndResetNeedsFlush());
291 EXPECT_FALSE(GetLastEvent());
293 // The up should flush the buffer.
294 MockMotionEvent up(MotionEvent::ACTION_UP, event_time, 4.f, 4.f);
295 buffer.OnMotionEvent(up);
296 EXPECT_FALSE(GetAndResetNeedsFlush());
298 // The flushed events should include the up and the moves, with the latter
299 // combined into a single event with history.
300 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
301 ASSERT_EQ(2U, events.size());
302 EXPECT_EVENT_EQ(up, *events.back());
303 EXPECT_EQ(2U, events.front()->GetHistorySize());
304 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move2);
305 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
306 EXPECT_EVENT_HISTORY_EQ(*events.front(), 1, move1);
309 TEST_F(MotionEventBufferTest, BufferFlushedOnIncompatibleActionMove) {
310 base::TimeTicks event_time = base::TimeTicks::Now();
311 MotionEventBuffer buffer(this, true);
313 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
314 buffer.OnMotionEvent(move0);
315 EXPECT_TRUE(GetAndResetNeedsFlush());
316 EXPECT_FALSE(GetLastEvent());
318 event_time += base::TimeDelta::FromMilliseconds(5);
320 // The second move has a different pointer count, flushing the first.
321 MockMotionEvent move1(
322 MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f, 3.f, 3.f);
323 buffer.OnMotionEvent(move1);
324 EXPECT_FALSE(GetAndResetNeedsFlush());
325 ASSERT_TRUE(GetLastEvent());
326 EXPECT_EVENT_EQ(move0, *GetLastEvent());
328 event_time += base::TimeDelta::FromMilliseconds(5);
330 // The third move has differing tool types, flushing the second.
331 MockMotionEvent move2(move1);
332 move2.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
333 buffer.OnMotionEvent(move2);
334 EXPECT_FALSE(GetAndResetNeedsFlush());
335 EXPECT_EVENT_EQ(move1, *GetLastEvent());
337 event_time += base::TimeDelta::FromMilliseconds(5);
339 // The flushed event should only include the latest move event.
340 buffer.Flush(event_time);
341 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
342 ASSERT_EQ(3U, events.size());
343 EXPECT_EVENT_EQ(move2, *events.back());
344 EXPECT_FALSE(GetAndResetNeedsFlush());
346 event_time += base::TimeDelta::FromMilliseconds(5);
348 // Events with different pointer ids should not combine.
349 PointerProperties pointer0(5.f, 5.f, 1.f);
350 pointer0.id = 1;
351 PointerProperties pointer1(10.f, 10.f, 2.f);
352 pointer1.id = 2;
353 MotionEventGeneric move3(MotionEvent::ACTION_MOVE, event_time, pointer0);
354 move3.PushPointer(pointer1);
355 buffer.OnMotionEvent(move3);
356 ASSERT_FALSE(GetLastEvent());
357 EXPECT_TRUE(GetAndResetNeedsFlush());
359 MotionEventGeneric move4(MotionEvent::ACTION_MOVE, event_time, pointer0);
360 pointer1.id = 7;
361 move4.PushPointer(pointer1);
362 buffer.OnMotionEvent(move2);
363 EXPECT_FALSE(GetAndResetNeedsFlush());
364 ASSERT_TRUE(GetLastEvent());
365 EXPECT_EVENT_EQ(move3, *GetLastEvent());
368 TEST_F(MotionEventBufferTest, OnlyActionMoveBuffered) {
369 base::TimeTicks event_time = base::TimeTicks::Now();
370 MotionEventBuffer buffer(this, true);
372 MockMotionEvent down(MotionEvent::ACTION_DOWN, event_time, 1.f, 1.f);
373 buffer.OnMotionEvent(down);
374 EXPECT_FALSE(GetAndResetNeedsFlush());
375 ASSERT_TRUE(GetLastEvent());
376 EXPECT_EVENT_EQ(down, *GetLastEvent());
378 GetAndResetForwardedEvents();
380 MockMotionEvent up(MotionEvent::ACTION_UP, event_time, 2.f, 2.f);
381 buffer.OnMotionEvent(up);
382 EXPECT_FALSE(GetAndResetNeedsFlush());
383 ASSERT_TRUE(GetLastEvent());
384 EXPECT_EVENT_EQ(up, *GetLastEvent());
386 GetAndResetForwardedEvents();
388 MockMotionEvent cancel(MotionEvent::ACTION_CANCEL, event_time, 3.f, 3.f);
389 buffer.OnMotionEvent(cancel);
390 EXPECT_FALSE(GetAndResetNeedsFlush());
391 ASSERT_TRUE(GetLastEvent());
392 EXPECT_EVENT_EQ(cancel, *GetLastEvent());
394 GetAndResetForwardedEvents();
396 MockMotionEvent move(MotionEvent::ACTION_MOVE, event_time, 4.f, 4.f);
397 buffer.OnMotionEvent(move);
398 EXPECT_TRUE(GetAndResetNeedsFlush());
399 EXPECT_FALSE(GetLastEvent());
401 base::TimeTicks flush_time = move.GetEventTime() + ResampleDelta();
402 buffer.Flush(flush_time);
403 EXPECT_FALSE(GetAndResetNeedsFlush());
404 ASSERT_TRUE(GetLastEvent());
405 EXPECT_EVENT_EQ(move, *GetLastEvent());
408 TEST_F(MotionEventBufferTest, OutOfOrderPointersBuffered) {
409 base::TimeTicks event_time = base::TimeTicks::Now();
410 MotionEventBuffer buffer(this, true);
412 PointerProperties p0(1.f, 2.f, 3.f);
413 p0.id = 1;
414 PointerProperties p1(2.f, 1.f, 0.5f);
415 p1.id = 2;
417 MotionEventGeneric move0(MotionEvent::ACTION_MOVE, event_time, p0);
418 move0.PushPointer(p1);
419 buffer.OnMotionEvent(move0);
420 EXPECT_TRUE(GetAndResetNeedsFlush());
421 ASSERT_FALSE(GetLastEvent());
423 event_time += base::TimeDelta::FromMilliseconds(5);
425 // The second move should remain buffered even if the logical pointers are
426 // in a different order.
427 MotionEventGeneric move1(MotionEvent::ACTION_MOVE, event_time, p1);
428 move1.PushPointer(p0);
429 buffer.OnMotionEvent(move1);
430 EXPECT_FALSE(GetAndResetNeedsFlush());
431 ASSERT_FALSE(GetLastEvent());
433 // As the two events are logically the same but for ordering and time, the
434 // synthesized event should yield a logically identical event.
435 base::TimeTicks flush_time = move1.GetEventTime() + ResampleDelta();
436 buffer.Flush(flush_time);
437 EXPECT_FALSE(GetAndResetNeedsFlush());
438 ASSERT_TRUE(GetLastEvent());
439 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
440 ASSERT_EQ(1U, events.size());
441 EXPECT_EVENT_IGNORING_HISTORY_EQ(move1, *events.front());
442 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
445 TEST_F(MotionEventBufferTest, FlushedEventsNeverLaterThanFlushTime) {
446 base::TimeTicks event_time = base::TimeTicks::Now();
447 MotionEventBuffer buffer(this, true);
449 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
450 buffer.OnMotionEvent(move0);
451 ASSERT_FALSE(GetLastEvent());
452 EXPECT_TRUE(GetAndResetNeedsFlush());
454 // The second move should remain buffered.
455 event_time += LargeDelta();
456 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
457 buffer.OnMotionEvent(move1);
458 ASSERT_FALSE(GetLastEvent());
459 EXPECT_FALSE(GetAndResetNeedsFlush());
461 // A flush occurring too early should not forward any events.
462 base::TimeTicks flush_time = move0.GetEventTime() - ResampleDelta();
463 buffer.Flush(flush_time);
464 ASSERT_FALSE(GetLastEvent());
465 EXPECT_TRUE(GetAndResetNeedsFlush());
467 // With resampling enabled, a flush occurring before the resample
468 // offset should not forward any events.
469 flush_time = move0.GetEventTime();
470 buffer.Flush(flush_time);
471 ASSERT_FALSE(GetLastEvent());
472 EXPECT_TRUE(GetAndResetNeedsFlush());
474 // Only the first event should get flushed, as the flush timestamp precedes
475 // the second's timestamp by a sufficient amount (preventing interpolation).
476 flush_time = move0.GetEventTime() + ResampleDelta();
477 buffer.Flush(flush_time);
479 // There should only be one flushed event.
480 EXPECT_TRUE(GetAndResetNeedsFlush());
481 ASSERT_TRUE(GetLastEvent());
482 EXPECT_TRUE(GetLastEvent()->GetEventTime() <= flush_time);
483 GetAndResetForwardedEvents();
485 // Flushing again with a similar timestamp should have no effect other than
486 // triggering another flush request.
487 flush_time += base::TimeDelta::FromMilliseconds(1);
488 buffer.Flush(flush_time);
489 EXPECT_FALSE(GetLastEvent());
490 EXPECT_TRUE(GetAndResetNeedsFlush());
492 // Flushing after the second move's time should trigger forwarding.
493 flush_time = move1.GetEventTime() + ResampleDelta();
494 buffer.Flush(flush_time);
495 ASSERT_TRUE(GetLastEvent());
496 EXPECT_EVENT_EQ(move1, *GetLastEvent());
497 EXPECT_FALSE(GetAndResetNeedsFlush());
500 TEST_F(MotionEventBufferTest, NoResamplingWhenDisabled) {
501 base::TimeTicks event_time = base::TimeTicks::Now();
502 const bool resampling_enabled = false;
503 MotionEventBuffer buffer(this, resampling_enabled);
505 // Queue two events.
506 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
507 buffer.OnMotionEvent(move0);
508 ASSERT_FALSE(GetLastEvent());
509 EXPECT_TRUE(GetAndResetNeedsFlush());
511 event_time += base::TimeDelta::FromMilliseconds(5);
512 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 15.f, 30.f);
513 buffer.OnMotionEvent(move1);
514 ASSERT_FALSE(GetLastEvent());
515 EXPECT_FALSE(GetAndResetNeedsFlush());
517 // Flush at a time between the first and second events.
518 base::TimeTicks interpolated_time =
519 move0.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 2;
520 base::TimeTicks flush_time = interpolated_time;
521 buffer.Flush(flush_time);
522 ASSERT_TRUE(GetLastEvent());
523 EXPECT_TRUE(GetAndResetNeedsFlush());
525 // There should only be one flushed event, with the second remaining buffered
526 // and no resampling having occurred.
527 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
528 ASSERT_EQ(1U, events.size());
529 EXPECT_EVENT_EQ(move0, *events.front());
531 // The second move should be flushed without resampling.
532 flush_time = move1.GetEventTime();
533 buffer.Flush(flush_time);
534 ASSERT_TRUE(GetLastEvent());
535 EXPECT_EVENT_EQ(move1, *GetLastEvent());
536 GetAndResetForwardedEvents();
538 // Now queue two more events.
539 move0 = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
540 buffer.OnMotionEvent(move0);
541 ASSERT_FALSE(GetLastEvent());
542 EXPECT_TRUE(GetAndResetNeedsFlush());
544 // The second move should remain buffered.
545 event_time += base::TimeDelta::FromMilliseconds(5);
546 move1 = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
547 buffer.OnMotionEvent(move1);
548 ASSERT_FALSE(GetLastEvent());
549 EXPECT_FALSE(GetAndResetNeedsFlush());
551 // Sample at a time beyond the first and second events.
552 flush_time =
553 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime());
554 buffer.Flush(flush_time);
555 ASSERT_TRUE(GetLastEvent());
556 EXPECT_FALSE(GetAndResetNeedsFlush());
558 // There should only be one flushed event, with the first event in the history
559 // and the second event as the actual event data (no resampling).
560 events = GetAndResetForwardedEvents();
561 ASSERT_EQ(1U, events.size());
562 EXPECT_EQ(1U, events.front()->GetHistorySize());
563 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move1);
564 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
567 TEST_F(MotionEventBufferTest, NoResamplingWithOutOfOrderActionMove) {
568 base::TimeTicks event_time = base::TimeTicks::Now();
569 MotionEventBuffer buffer(this, true);
571 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
572 buffer.OnMotionEvent(move0);
573 ASSERT_FALSE(GetLastEvent());
574 EXPECT_TRUE(GetAndResetNeedsFlush());
576 // The second move should remain buffered.
577 event_time += base::TimeDelta::FromMilliseconds(10);
578 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
579 buffer.OnMotionEvent(move1);
580 ASSERT_FALSE(GetLastEvent());
581 EXPECT_FALSE(GetAndResetNeedsFlush());
583 // Sample at a time beyond the first and second events.
584 base::TimeTicks extrapolated_time =
585 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime());
586 base::TimeTicks flush_time = extrapolated_time + ResampleDelta();
587 buffer.Flush(flush_time);
588 ASSERT_TRUE(GetLastEvent());
589 EXPECT_FALSE(GetAndResetNeedsFlush());
591 // There should only be one flushed event, with the event extrapolated from
592 // the two events.
593 base::TimeTicks expected_time =
594 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 2;
595 ScopedVector<MotionEvent> events0 = GetAndResetForwardedEvents();
596 ASSERT_EQ(1U, events0.size());
597 EXPECT_EQ(2U, events0.front()->GetHistorySize());
598 EXPECT_EQ(expected_time, events0.front()->GetEventTime());
599 EXPECT_FALSE(GetAndResetNeedsFlush());
601 // Try enqueuing an event *after* the second event but *before* the
602 // extrapolated event. It should be dropped.
603 event_time = move1.GetEventTime() + base::TimeDelta::FromMilliseconds(1);
604 MockMotionEvent move2(MotionEvent::ACTION_MOVE, event_time, 15.f, 25.f);
605 buffer.OnMotionEvent(move1);
606 ASSERT_FALSE(GetLastEvent());
607 EXPECT_FALSE(GetAndResetNeedsFlush());
609 // Finally queue an event *after* the extrapolated event.
610 event_time = expected_time + base::TimeDelta::FromMilliseconds(1);
611 MockMotionEvent move3(MotionEvent::ACTION_MOVE, event_time, 15.f, 25.f);
612 buffer.OnMotionEvent(move3);
613 ASSERT_FALSE(GetLastEvent());
614 EXPECT_TRUE(GetAndResetNeedsFlush());
616 // The flushed event should simply be the latest event.
617 flush_time = event_time + ResampleDelta();
618 buffer.Flush(flush_time);
619 ASSERT_TRUE(GetLastEvent());
620 ScopedVector<MotionEvent> events1 = GetAndResetForwardedEvents();
621 ASSERT_EQ(1U, events1.size());
622 EXPECT_EVENT_EQ(move3, *events1.front());
623 EXPECT_FALSE(GetAndResetNeedsFlush());
626 TEST_F(MotionEventBufferTest, NoResamplingWithSmallTimeDeltaBetweenMoves) {
627 base::TimeTicks event_time = base::TimeTicks::Now();
628 MotionEventBuffer buffer(this, true);
630 // The first move should be buffered.
631 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
632 buffer.OnMotionEvent(move0);
633 ASSERT_FALSE(GetLastEvent());
634 EXPECT_TRUE(GetAndResetNeedsFlush());
636 // The second move should remain buffered.
637 event_time += SmallDelta();
638 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
639 buffer.OnMotionEvent(move1);
640 ASSERT_FALSE(GetLastEvent());
641 EXPECT_FALSE(GetAndResetNeedsFlush());
643 base::TimeTicks flush_time = event_time + ResampleDelta();
644 buffer.Flush(flush_time);
645 EXPECT_FALSE(GetAndResetNeedsFlush());
647 // There should only be one flushed event, and no resampling should have
648 // occured between the first and the second as they were temporally too close.
649 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
650 ASSERT_EQ(1U, events.size());
651 EXPECT_EQ(1U, events.front()->GetHistorySize());
652 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move1);
653 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
656 TEST_F(MotionEventBufferTest, NoResamplingWithMismatchBetweenMoves) {
657 base::TimeTicks event_time = base::TimeTicks::Now();
658 MotionEventBuffer buffer(this, true);
660 // The first move should be buffered.
661 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
662 buffer.OnMotionEvent(move0);
663 ASSERT_FALSE(GetLastEvent());
664 EXPECT_TRUE(GetAndResetNeedsFlush());
666 // The second move should remain buffered.
667 event_time += SmallDelta();
668 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
669 buffer.OnMotionEvent(move1);
670 ASSERT_FALSE(GetLastEvent());
671 EXPECT_FALSE(GetAndResetNeedsFlush());
673 base::TimeTicks flush_time = event_time + ResampleDelta();
674 buffer.Flush(flush_time);
675 EXPECT_FALSE(GetAndResetNeedsFlush());
677 // There should only be one flushed event, and no resampling should have
678 // occured between the first and the second as they were temporally too close.
679 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
680 ASSERT_EQ(1U, events.size());
681 EXPECT_EQ(1U, events.front()->GetHistorySize());
682 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move1);
683 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
686 TEST_F(MotionEventBufferTest, Interpolation) {
687 base::TimeTicks event_time = base::TimeTicks::Now();
688 MotionEventBuffer buffer(this, true);
690 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
691 buffer.OnMotionEvent(move0);
692 ASSERT_FALSE(GetLastEvent());
693 EXPECT_TRUE(GetAndResetNeedsFlush());
695 // The second move should remain buffered.
696 event_time += base::TimeDelta::FromMilliseconds(5);
697 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 15.f, 30.f);
698 buffer.OnMotionEvent(move1);
699 ASSERT_FALSE(GetLastEvent());
700 EXPECT_FALSE(GetAndResetNeedsFlush());
702 // Sample at a time between the first and second events.
703 base::TimeTicks interpolated_time =
704 move0.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 3;
705 base::TimeTicks flush_time = interpolated_time + ResampleDelta();
706 buffer.Flush(flush_time);
707 ASSERT_TRUE(GetLastEvent());
708 EXPECT_TRUE(GetAndResetNeedsFlush());
710 // There should only be one flushed event, with the event interpolated between
711 // the two events. The second event should remain buffered.
712 float alpha = (interpolated_time - move0.GetEventTime()).InMillisecondsF() /
713 (move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
714 MockMotionEvent interpolated_event(
715 MotionEvent::ACTION_MOVE,
716 interpolated_time,
717 move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * alpha,
718 move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * alpha);
719 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
720 ASSERT_EQ(1U, events.size());
721 EXPECT_EQ(1U, events.front()->GetHistorySize());
722 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), interpolated_event);
723 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
725 // The second move should be flushed without resampling.
726 flush_time = move1.GetEventTime() + ResampleDelta();
727 buffer.Flush(flush_time);
728 ASSERT_TRUE(GetLastEvent());
729 EXPECT_EVENT_EQ(move1, *GetLastEvent());
732 TEST_F(MotionEventBufferTest, Extrapolation) {
733 base::TimeTicks event_time = base::TimeTicks::Now();
734 MotionEventBuffer buffer(this, true);
736 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
737 buffer.OnMotionEvent(move0);
738 ASSERT_FALSE(GetLastEvent());
739 EXPECT_TRUE(GetAndResetNeedsFlush());
741 // The second move should remain buffered.
742 event_time += base::TimeDelta::FromMilliseconds(5);
743 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
744 buffer.OnMotionEvent(move1);
745 ASSERT_FALSE(GetLastEvent());
746 EXPECT_FALSE(GetAndResetNeedsFlush());
748 // Sample at a time beyond the first and second events.
749 base::TimeTicks extrapolated_time =
750 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime());
751 base::TimeTicks flush_time = extrapolated_time + ResampleDelta();
752 buffer.Flush(flush_time);
753 ASSERT_TRUE(GetLastEvent());
754 EXPECT_FALSE(GetAndResetNeedsFlush());
756 // There should only be one flushed event, with the event extrapolated from
757 // the two events. The first and second events should be in the history.
758 // Note that the maximum extrapolation is limited by *half* of the time delta
759 // between the two events, hence we divide the relative delta by 2 in
760 // determining the extrapolated event.
761 base::TimeTicks expected_time =
762 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 2;
763 float expected_alpha =
764 (expected_time - move0.GetEventTime()).InMillisecondsF() /
765 (move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
766 MockMotionEvent extrapolated_event(
767 MotionEvent::ACTION_MOVE,
768 expected_time,
769 move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * expected_alpha,
770 move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * expected_alpha);
771 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
772 ASSERT_EQ(1U, events.size());
773 EXPECT_EQ(2U, events.front()->GetHistorySize());
774 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), extrapolated_event);
775 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
776 EXPECT_EVENT_HISTORY_EQ(*events.front(), 1, move1);
779 TEST_F(MotionEventBufferTest, ExtrapolationHorizonLimited) {
780 base::TimeTicks event_time = base::TimeTicks::Now();
781 MotionEventBuffer buffer(this, true);
783 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
784 buffer.OnMotionEvent(move0);
785 ASSERT_FALSE(GetLastEvent());
786 EXPECT_TRUE(GetAndResetNeedsFlush());
788 // The second move should remain buffered.
789 event_time += base::TimeDelta::FromMilliseconds(24);
790 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
791 buffer.OnMotionEvent(move1);
792 ASSERT_FALSE(GetLastEvent());
793 EXPECT_FALSE(GetAndResetNeedsFlush());
795 // Sample at a time beyond the first and second events.
796 base::TimeTicks extrapolated_time =
797 event_time + base::TimeDelta::FromMilliseconds(24);
798 base::TimeTicks flush_time = extrapolated_time + ResampleDelta();
799 buffer.Flush(flush_time);
800 ASSERT_TRUE(GetLastEvent());
801 EXPECT_FALSE(GetAndResetNeedsFlush());
803 // There should only be one flushed event, with the event extrapolated from
804 // the two events. The first and second events should be in the history.
805 // Note that the maximum extrapolation is limited by 8 ms.
806 base::TimeTicks expected_time =
807 move1.GetEventTime() + base::TimeDelta::FromMilliseconds(8);
808 float expected_alpha =
809 (expected_time - move0.GetEventTime()).InMillisecondsF() /
810 (move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
811 MockMotionEvent extrapolated_event(
812 MotionEvent::ACTION_MOVE,
813 expected_time,
814 move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * expected_alpha,
815 move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * expected_alpha);
816 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
817 ASSERT_EQ(1U, events.size());
818 EXPECT_EQ(2U, events.front()->GetHistorySize());
819 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), extrapolated_event);
820 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
821 EXPECT_EVENT_HISTORY_EQ(*events.front(), 1, move1);
824 TEST_F(MotionEventBufferTest, ResamplingWithReorderedPointers) {
828 TEST_F(MotionEventBufferTest, Resampling30to60) {
829 base::TimeDelta flush_time_delta =
830 base::TimeDelta::FromMillisecondsD(1000. / 60.);
831 base::TimeDelta event_time_delta =
832 base::TimeDelta::FromMillisecondsD(1000. / 30.);
834 RunResample(flush_time_delta, event_time_delta);
837 TEST_F(MotionEventBufferTest, Resampling60to60) {
838 base::TimeDelta flush_time_delta =
839 base::TimeDelta::FromMillisecondsD(1000. / 60.);
840 base::TimeDelta event_time_delta =
841 base::TimeDelta::FromMillisecondsD(1000. / 60.);
843 RunResample(flush_time_delta, event_time_delta);
846 TEST_F(MotionEventBufferTest, Resampling100to60) {
847 base::TimeDelta flush_time_delta =
848 base::TimeDelta::FromMillisecondsD(1000. / 60.);
849 base::TimeDelta event_time_delta =
850 base::TimeDelta::FromMillisecondsD(1000. / 100.);
852 RunResample(flush_time_delta, event_time_delta);
855 TEST_F(MotionEventBufferTest, Resampling120to60) {
856 base::TimeDelta flush_time_delta =
857 base::TimeDelta::FromMillisecondsD(1000. / 60.);
858 base::TimeDelta event_time_delta =
859 base::TimeDelta::FromMillisecondsD(1000. / 120.);
861 RunResample(flush_time_delta, event_time_delta);
864 TEST_F(MotionEventBufferTest, Resampling150to60) {
865 base::TimeDelta flush_time_delta =
866 base::TimeDelta::FromMillisecondsD(1000. / 60.);
867 base::TimeDelta event_time_delta =
868 base::TimeDelta::FromMillisecondsD(1000. / 150.);
870 RunResample(flush_time_delta, event_time_delta);
873 } // namespace ui