platformKeys: Add per-extension sign permissions.
[chromium-blink-merge.git] / ui / events / gesture_detection / motion_event_buffer_unittest.cc
blobda3ffe500a8bdae13e768d9cecb452a862a4f84b
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.GetId(), b.GetId());
85 EXPECT_EQ(a.GetAction(), b.GetAction());
86 if (a.GetAction() == MotionEvent::ACTION_POINTER_DOWN ||
87 a.GetAction() == MotionEvent::ACTION_POINTER_UP) {
88 EXPECT_EQ(a.GetActionIndex(), b.GetActionIndex());
90 EXPECT_EQ(a.GetButtonState(), b.GetButtonState());
91 EXPECT_EQ(a.GetEventTime(), b.GetEventTime());
93 ASSERT_EQ(a.GetPointerCount(), b.GetPointerCount());
94 for (size_t i = 0; i < a.GetPointerCount(); ++i) {
95 int bi = b.FindPointerIndexOfId(a.GetPointerId(i));
96 ASSERT_NE(bi, -1);
97 EXPECT_EQ(a.GetX(i), b.GetX(bi));
98 EXPECT_EQ(a.GetY(i), b.GetY(bi));
99 EXPECT_EQ(a.GetRawX(i), b.GetRawX(bi));
100 EXPECT_EQ(a.GetRawY(i), b.GetRawY(bi));
101 EXPECT_EQ(a.GetTouchMajor(i), b.GetTouchMajor(bi));
102 EXPECT_EQ(a.GetTouchMinor(i), b.GetTouchMinor(bi));
103 EXPECT_EQ(a.GetOrientation(i), b.GetOrientation(bi));
104 EXPECT_EQ(a.GetPressure(i), b.GetPressure(bi));
105 EXPECT_EQ(a.GetToolType(i), b.GetToolType(bi));
108 if (ignore_history)
109 return;
111 ASSERT_EQ(a.GetHistorySize(), b.GetHistorySize());
112 for (size_t h = 0; h < a.GetHistorySize(); ++h)
113 ExpectEqualsHistoryIndex(a, h, b);
116 // Verify that all public data of |a|, excluding history, equals that of |b|.
117 static void ExpectEqualsIgnoringHistory(const MotionEvent& a,
118 const MotionEvent& b) {
119 const bool ignore_history = true;
120 ExpectEqualsImpl(a, b, ignore_history);
123 // Verify that all public data of |a| equals that of |b|.
124 static void ExpectEquals(const MotionEvent& a, const MotionEvent& b) {
125 const bool ignore_history = false;
126 ExpectEqualsImpl(a, b, ignore_history);
129 // Verify that the historical data of |a| given by |historical_index|
130 // corresponds to the *raw* data of |b|.
131 static void ExpectEqualsHistoryIndex(const MotionEvent& a,
132 size_t history_index,
133 const MotionEvent& b) {
134 ASSERT_LT(history_index, a.GetHistorySize());
135 EXPECT_EQ(a.GetPointerCount(), b.GetPointerCount());
136 EXPECT_TRUE(a.GetHistoricalEventTime(history_index) == b.GetEventTime());
138 for (size_t i = 0; i < a.GetPointerCount(); ++i) {
139 int bi = b.FindPointerIndexOfId(a.GetPointerId(i));
140 ASSERT_NE(bi, -1);
141 EXPECT_EQ(a.GetHistoricalX(i, history_index), b.GetX(bi));
142 EXPECT_EQ(a.GetHistoricalY(i, history_index), b.GetY(bi));
143 EXPECT_EQ(a.GetHistoricalTouchMajor(i, history_index),
144 b.GetTouchMajor(bi));
148 protected:
149 void RunResample(base::TimeDelta flush_time_delta,
150 base::TimeDelta event_time_delta) {
151 for (base::TimeDelta offset; offset < event_time_delta;
152 offset += event_time_delta / 3) {
153 SCOPED_TRACE(testing::Message()
154 << "Resample(offset="
155 << static_cast<int>(offset.InMilliseconds()) << "ms)");
156 RunResample(flush_time_delta, event_time_delta, offset);
160 // Given an event and flush sampling frequency, inject a stream of events,
161 // flushing at appropriate points in the stream. Verify that the continuous
162 // velocity sampled by the *input* stream matches the discrete velocity
163 // as computed from the resampled *output* stream.
164 void RunResample(base::TimeDelta flush_time_delta,
165 base::TimeDelta event_time_delta,
166 base::TimeDelta event_time_offset) {
167 base::TimeTicks event_time = base::TimeTicks::Now();
168 base::TimeTicks flush_time =
169 event_time + flush_time_delta - event_time_offset;
170 base::TimeTicks max_event_time =
171 event_time + base::TimeDelta::FromSecondsD(0.5f);
172 const size_t min_expected_events =
173 static_cast<size_t>((max_event_time - flush_time) /
174 std::max(event_time_delta, flush_time_delta));
176 MotionEventBuffer buffer(this, true);
178 gfx::Vector2dF velocity(33.f, -11.f);
179 gfx::PointF position(17.f, 42.f);
180 scoped_ptr<MotionEvent> last_flushed_event;
181 size_t events = 0;
182 float last_dx = 0, last_dy = 0;
183 base::TimeDelta last_dt;
184 while (event_time < max_event_time) {
185 position += gfx::ScaleVector2d(velocity, event_time_delta.InSecondsF());
186 MockMotionEvent move(
187 MotionEvent::ACTION_MOVE, event_time, position.x(), position.y());
188 buffer.OnMotionEvent(move);
189 event_time += event_time_delta;
191 while (flush_time < event_time) {
192 buffer.Flush(flush_time);
193 flush_time += flush_time_delta;
194 const MotionEvent* current_flushed_event = GetLastEvent();
195 if (current_flushed_event) {
196 if (!last_flushed_event) {
197 last_flushed_event = current_flushed_event->Clone();
198 continue;
201 base::TimeDelta dt = current_flushed_event->GetEventTime() -
202 last_flushed_event->GetEventTime();
203 EXPECT_GE(dt.ToInternalValue(), 0);
204 // A time delta of 0 is possible if the flush rate is greater than the
205 // event rate, in which case we can simply skip forward.
206 if (dt == base::TimeDelta())
207 continue;
209 const float dx =
210 current_flushed_event->GetX() - last_flushed_event->GetX();
211 const float dy =
212 current_flushed_event->GetY() - last_flushed_event->GetY();
213 const float dt_s = (current_flushed_event->GetEventTime() -
214 last_flushed_event->GetEventTime()).InSecondsF();
216 // The discrete velocity should mirror the constant velocity.
217 EXPECT_NEAR(velocity.x(), dx / dt_s, kVelocityEpsilon);
218 EXPECT_NEAR(velocity.y(), dy / dt_s, kVelocityEpsilon);
220 // The impulse delta for each frame should remain constant.
221 if (last_dy)
222 EXPECT_NEAR(dx, last_dx, kDeltaEpsilon);
223 if (last_dy)
224 EXPECT_NEAR(dy, last_dy, kDeltaEpsilon);
226 // The timestamp delta should remain constant.
227 if (last_dt != base::TimeDelta())
228 EXPECT_TRUE((dt - last_dt).InMillisecondsF() < kDeltaEpsilon);
230 last_dx = dx;
231 last_dy = dy;
232 last_dt = dt;
233 last_flushed_event = current_flushed_event->Clone();
234 events += GetAndResetForwardedEvents().size();
238 events += GetAndResetForwardedEvents().size();
239 EXPECT_GE(events, min_expected_events);
242 private:
243 ScopedVector<MotionEvent> forwarded_events_;
244 bool needs_flush_;
247 TEST_F(MotionEventBufferTest, BufferEmpty) {
248 MotionEventBuffer buffer(this, true);
250 buffer.Flush(base::TimeTicks::Now());
251 EXPECT_FALSE(GetAndResetNeedsFlush());
252 EXPECT_FALSE(GetLastEvent());
255 TEST_F(MotionEventBufferTest, BufferWithOneMoveNotResampled) {
256 base::TimeTicks event_time = base::TimeTicks::Now();
257 MotionEventBuffer buffer(this, true);
259 MockMotionEvent move(MotionEvent::ACTION_MOVE, event_time, 4.f, 4.f);
260 buffer.OnMotionEvent(move);
261 EXPECT_TRUE(GetAndResetNeedsFlush());
262 EXPECT_FALSE(GetLastEvent());
264 buffer.Flush(event_time + ResampleDelta());
265 EXPECT_FALSE(GetAndResetNeedsFlush());
266 ASSERT_TRUE(GetLastEvent());
267 EXPECT_EVENT_EQ(move, *GetLastEvent());
268 EXPECT_EQ(1U, GetAndResetForwardedEvents().size());
271 TEST_F(MotionEventBufferTest, BufferFlushedOnNonActionMove) {
272 base::TimeTicks event_time = base::TimeTicks::Now();
273 MotionEventBuffer buffer(this, true);
275 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
276 buffer.OnMotionEvent(move0);
277 EXPECT_TRUE(GetAndResetNeedsFlush());
278 EXPECT_FALSE(GetLastEvent());
280 event_time += base::TimeDelta::FromMilliseconds(5);
282 // The second move should remain buffered.
283 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
284 buffer.OnMotionEvent(move1);
285 EXPECT_FALSE(GetAndResetNeedsFlush());
286 EXPECT_FALSE(GetLastEvent());
288 // The third move should remain buffered.
289 MockMotionEvent move2(MotionEvent::ACTION_MOVE, event_time, 3.f, 3.f);
290 buffer.OnMotionEvent(move2);
291 EXPECT_FALSE(GetAndResetNeedsFlush());
292 EXPECT_FALSE(GetLastEvent());
294 // The up should flush the buffer.
295 MockMotionEvent up(MotionEvent::ACTION_UP, event_time, 4.f, 4.f);
296 buffer.OnMotionEvent(up);
297 EXPECT_FALSE(GetAndResetNeedsFlush());
299 // The flushed events should include the up and the moves, with the latter
300 // combined into a single event with history.
301 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
302 ASSERT_EQ(2U, events.size());
303 EXPECT_EVENT_EQ(up, *events.back());
304 EXPECT_EQ(2U, events.front()->GetHistorySize());
305 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move2);
306 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
307 EXPECT_EVENT_HISTORY_EQ(*events.front(), 1, move1);
310 TEST_F(MotionEventBufferTest, BufferFlushedOnIncompatibleActionMove) {
311 base::TimeTicks event_time = base::TimeTicks::Now();
312 MotionEventBuffer buffer(this, true);
314 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
315 buffer.OnMotionEvent(move0);
316 EXPECT_TRUE(GetAndResetNeedsFlush());
317 EXPECT_FALSE(GetLastEvent());
319 event_time += base::TimeDelta::FromMilliseconds(5);
321 // The second move has a different pointer count, flushing the first.
322 MockMotionEvent move1(
323 MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f, 3.f, 3.f);
324 buffer.OnMotionEvent(move1);
325 EXPECT_FALSE(GetAndResetNeedsFlush());
326 ASSERT_TRUE(GetLastEvent());
327 EXPECT_EVENT_EQ(move0, *GetLastEvent());
329 event_time += base::TimeDelta::FromMilliseconds(5);
331 // The third move has differing tool types, flushing the second.
332 MockMotionEvent move2(move1);
333 move2.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
334 buffer.OnMotionEvent(move2);
335 EXPECT_FALSE(GetAndResetNeedsFlush());
336 EXPECT_EVENT_EQ(move1, *GetLastEvent());
338 event_time += base::TimeDelta::FromMilliseconds(5);
340 // The flushed event should only include the latest move event.
341 buffer.Flush(event_time);
342 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
343 ASSERT_EQ(3U, events.size());
344 EXPECT_EVENT_EQ(move2, *events.back());
345 EXPECT_FALSE(GetAndResetNeedsFlush());
347 event_time += base::TimeDelta::FromMilliseconds(5);
349 // Events with different pointer ids should not combine.
350 PointerProperties pointer0(5.f, 5.f, 1.f);
351 pointer0.id = 1;
352 PointerProperties pointer1(10.f, 10.f, 2.f);
353 pointer1.id = 2;
354 MotionEventGeneric move3(MotionEvent::ACTION_MOVE, event_time, pointer0);
355 move3.PushPointer(pointer1);
356 buffer.OnMotionEvent(move3);
357 ASSERT_FALSE(GetLastEvent());
358 EXPECT_TRUE(GetAndResetNeedsFlush());
360 MotionEventGeneric move4(MotionEvent::ACTION_MOVE, event_time, pointer0);
361 pointer1.id = 7;
362 move4.PushPointer(pointer1);
363 buffer.OnMotionEvent(move2);
364 EXPECT_FALSE(GetAndResetNeedsFlush());
365 ASSERT_TRUE(GetLastEvent());
366 EXPECT_EVENT_EQ(move3, *GetLastEvent());
369 TEST_F(MotionEventBufferTest, OnlyActionMoveBuffered) {
370 base::TimeTicks event_time = base::TimeTicks::Now();
371 MotionEventBuffer buffer(this, true);
373 MockMotionEvent down(MotionEvent::ACTION_DOWN, event_time, 1.f, 1.f);
374 buffer.OnMotionEvent(down);
375 EXPECT_FALSE(GetAndResetNeedsFlush());
376 ASSERT_TRUE(GetLastEvent());
377 EXPECT_EVENT_EQ(down, *GetLastEvent());
379 GetAndResetForwardedEvents();
381 MockMotionEvent up(MotionEvent::ACTION_UP, event_time, 2.f, 2.f);
382 buffer.OnMotionEvent(up);
383 EXPECT_FALSE(GetAndResetNeedsFlush());
384 ASSERT_TRUE(GetLastEvent());
385 EXPECT_EVENT_EQ(up, *GetLastEvent());
387 GetAndResetForwardedEvents();
389 MockMotionEvent cancel(MotionEvent::ACTION_CANCEL, event_time, 3.f, 3.f);
390 buffer.OnMotionEvent(cancel);
391 EXPECT_FALSE(GetAndResetNeedsFlush());
392 ASSERT_TRUE(GetLastEvent());
393 EXPECT_EVENT_EQ(cancel, *GetLastEvent());
395 GetAndResetForwardedEvents();
397 MockMotionEvent move(MotionEvent::ACTION_MOVE, event_time, 4.f, 4.f);
398 buffer.OnMotionEvent(move);
399 EXPECT_TRUE(GetAndResetNeedsFlush());
400 EXPECT_FALSE(GetLastEvent());
402 base::TimeTicks flush_time = move.GetEventTime() + ResampleDelta();
403 buffer.Flush(flush_time);
404 EXPECT_FALSE(GetAndResetNeedsFlush());
405 ASSERT_TRUE(GetLastEvent());
406 EXPECT_EVENT_EQ(move, *GetLastEvent());
409 TEST_F(MotionEventBufferTest, OutOfOrderPointersBuffered) {
410 base::TimeTicks event_time = base::TimeTicks::Now();
411 MotionEventBuffer buffer(this, true);
413 PointerProperties p0(1.f, 2.f, 3.f);
414 p0.id = 1;
415 PointerProperties p1(2.f, 1.f, 0.5f);
416 p1.id = 2;
418 MotionEventGeneric move0(MotionEvent::ACTION_MOVE, event_time, p0);
419 move0.PushPointer(p1);
420 buffer.OnMotionEvent(move0);
421 EXPECT_TRUE(GetAndResetNeedsFlush());
422 ASSERT_FALSE(GetLastEvent());
424 event_time += base::TimeDelta::FromMilliseconds(5);
426 // The second move should remain buffered even if the logical pointers are
427 // in a different order.
428 MotionEventGeneric move1(MotionEvent::ACTION_MOVE, event_time, p1);
429 move1.PushPointer(p0);
430 buffer.OnMotionEvent(move1);
431 EXPECT_FALSE(GetAndResetNeedsFlush());
432 ASSERT_FALSE(GetLastEvent());
434 // As the two events are logically the same but for ordering and time, the
435 // synthesized event should yield a logically identical event.
436 base::TimeTicks flush_time = move1.GetEventTime() + ResampleDelta();
437 buffer.Flush(flush_time);
438 EXPECT_FALSE(GetAndResetNeedsFlush());
439 ASSERT_TRUE(GetLastEvent());
440 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
441 ASSERT_EQ(1U, events.size());
442 EXPECT_EVENT_IGNORING_HISTORY_EQ(move1, *events.front());
443 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
446 TEST_F(MotionEventBufferTest, FlushedEventsNeverLaterThanFlushTime) {
447 base::TimeTicks event_time = base::TimeTicks::Now();
448 MotionEventBuffer buffer(this, true);
450 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
451 buffer.OnMotionEvent(move0);
452 ASSERT_FALSE(GetLastEvent());
453 EXPECT_TRUE(GetAndResetNeedsFlush());
455 // The second move should remain buffered.
456 event_time += LargeDelta();
457 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
458 buffer.OnMotionEvent(move1);
459 ASSERT_FALSE(GetLastEvent());
460 EXPECT_FALSE(GetAndResetNeedsFlush());
462 // A flush occurring too early should not forward any events.
463 base::TimeTicks flush_time = move0.GetEventTime() - ResampleDelta();
464 buffer.Flush(flush_time);
465 ASSERT_FALSE(GetLastEvent());
466 EXPECT_TRUE(GetAndResetNeedsFlush());
468 // With resampling enabled, a flush occurring before the resample
469 // offset should not forward any events.
470 flush_time = move0.GetEventTime();
471 buffer.Flush(flush_time);
472 ASSERT_FALSE(GetLastEvent());
473 EXPECT_TRUE(GetAndResetNeedsFlush());
475 // Only the first event should get flushed, as the flush timestamp precedes
476 // the second's timestamp by a sufficient amount (preventing interpolation).
477 flush_time = move0.GetEventTime() + ResampleDelta();
478 buffer.Flush(flush_time);
480 // There should only be one flushed event.
481 EXPECT_TRUE(GetAndResetNeedsFlush());
482 ASSERT_TRUE(GetLastEvent());
483 EXPECT_TRUE(GetLastEvent()->GetEventTime() <= flush_time);
484 GetAndResetForwardedEvents();
486 // Flushing again with a similar timestamp should have no effect other than
487 // triggering another flush request.
488 flush_time += base::TimeDelta::FromMilliseconds(1);
489 buffer.Flush(flush_time);
490 EXPECT_FALSE(GetLastEvent());
491 EXPECT_TRUE(GetAndResetNeedsFlush());
493 // Flushing after the second move's time should trigger forwarding.
494 flush_time = move1.GetEventTime() + ResampleDelta();
495 buffer.Flush(flush_time);
496 ASSERT_TRUE(GetLastEvent());
497 EXPECT_EVENT_EQ(move1, *GetLastEvent());
498 EXPECT_FALSE(GetAndResetNeedsFlush());
501 TEST_F(MotionEventBufferTest, NoResamplingWhenDisabled) {
502 base::TimeTicks event_time = base::TimeTicks::Now();
503 const bool resampling_enabled = false;
504 MotionEventBuffer buffer(this, resampling_enabled);
506 // Queue two events.
507 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
508 buffer.OnMotionEvent(move0);
509 ASSERT_FALSE(GetLastEvent());
510 EXPECT_TRUE(GetAndResetNeedsFlush());
512 event_time += base::TimeDelta::FromMilliseconds(5);
513 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 15.f, 30.f);
514 buffer.OnMotionEvent(move1);
515 ASSERT_FALSE(GetLastEvent());
516 EXPECT_FALSE(GetAndResetNeedsFlush());
518 // Flush at a time between the first and second events.
519 base::TimeTicks interpolated_time =
520 move0.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 2;
521 base::TimeTicks flush_time = interpolated_time;
522 buffer.Flush(flush_time);
523 ASSERT_TRUE(GetLastEvent());
524 EXPECT_TRUE(GetAndResetNeedsFlush());
526 // There should only be one flushed event, with the second remaining buffered
527 // and no resampling having occurred.
528 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
529 ASSERT_EQ(1U, events.size());
530 EXPECT_EVENT_EQ(move0, *events.front());
532 // The second move should be flushed without resampling.
533 flush_time = move1.GetEventTime();
534 buffer.Flush(flush_time);
535 ASSERT_TRUE(GetLastEvent());
536 EXPECT_EVENT_EQ(move1, *GetLastEvent());
537 GetAndResetForwardedEvents();
539 // Now queue two more events.
540 move0 = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
541 buffer.OnMotionEvent(move0);
542 ASSERT_FALSE(GetLastEvent());
543 EXPECT_TRUE(GetAndResetNeedsFlush());
545 // The second move should remain buffered.
546 event_time += base::TimeDelta::FromMilliseconds(5);
547 move1 = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
548 buffer.OnMotionEvent(move1);
549 ASSERT_FALSE(GetLastEvent());
550 EXPECT_FALSE(GetAndResetNeedsFlush());
552 // Sample at a time beyond the first and second events.
553 flush_time =
554 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime());
555 buffer.Flush(flush_time);
556 ASSERT_TRUE(GetLastEvent());
557 EXPECT_FALSE(GetAndResetNeedsFlush());
559 // There should only be one flushed event, with the first event in the history
560 // and the second event as the actual event data (no resampling).
561 events = GetAndResetForwardedEvents();
562 ASSERT_EQ(1U, events.size());
563 EXPECT_EQ(1U, events.front()->GetHistorySize());
564 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move1);
565 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
568 TEST_F(MotionEventBufferTest, NoResamplingWithOutOfOrderActionMove) {
569 base::TimeTicks event_time = base::TimeTicks::Now();
570 MotionEventBuffer buffer(this, true);
572 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
573 buffer.OnMotionEvent(move0);
574 ASSERT_FALSE(GetLastEvent());
575 EXPECT_TRUE(GetAndResetNeedsFlush());
577 // The second move should remain buffered.
578 event_time += base::TimeDelta::FromMilliseconds(10);
579 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
580 buffer.OnMotionEvent(move1);
581 ASSERT_FALSE(GetLastEvent());
582 EXPECT_FALSE(GetAndResetNeedsFlush());
584 // Sample at a time beyond the first and second events.
585 base::TimeTicks extrapolated_time =
586 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime());
587 base::TimeTicks flush_time = extrapolated_time + ResampleDelta();
588 buffer.Flush(flush_time);
589 ASSERT_TRUE(GetLastEvent());
590 EXPECT_FALSE(GetAndResetNeedsFlush());
592 // There should only be one flushed event, with the event extrapolated from
593 // the two events.
594 base::TimeTicks expected_time =
595 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 2;
596 ScopedVector<MotionEvent> events0 = GetAndResetForwardedEvents();
597 ASSERT_EQ(1U, events0.size());
598 EXPECT_EQ(2U, events0.front()->GetHistorySize());
599 EXPECT_EQ(expected_time, events0.front()->GetEventTime());
600 EXPECT_FALSE(GetAndResetNeedsFlush());
602 // Try enqueuing an event *after* the second event but *before* the
603 // extrapolated event. It should be dropped.
604 event_time = move1.GetEventTime() + base::TimeDelta::FromMilliseconds(1);
605 MockMotionEvent move2(MotionEvent::ACTION_MOVE, event_time, 15.f, 25.f);
606 buffer.OnMotionEvent(move1);
607 ASSERT_FALSE(GetLastEvent());
608 EXPECT_FALSE(GetAndResetNeedsFlush());
610 // Finally queue an event *after* the extrapolated event.
611 event_time = expected_time + base::TimeDelta::FromMilliseconds(1);
612 MockMotionEvent move3(MotionEvent::ACTION_MOVE, event_time, 15.f, 25.f);
613 buffer.OnMotionEvent(move3);
614 ASSERT_FALSE(GetLastEvent());
615 EXPECT_TRUE(GetAndResetNeedsFlush());
617 // The flushed event should simply be the latest event.
618 flush_time = event_time + ResampleDelta();
619 buffer.Flush(flush_time);
620 ASSERT_TRUE(GetLastEvent());
621 ScopedVector<MotionEvent> events1 = GetAndResetForwardedEvents();
622 ASSERT_EQ(1U, events1.size());
623 EXPECT_EVENT_EQ(move3, *events1.front());
624 EXPECT_FALSE(GetAndResetNeedsFlush());
627 TEST_F(MotionEventBufferTest, NoResamplingWithSmallTimeDeltaBetweenMoves) {
628 base::TimeTicks event_time = base::TimeTicks::Now();
629 MotionEventBuffer buffer(this, true);
631 // The first move should be buffered.
632 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
633 buffer.OnMotionEvent(move0);
634 ASSERT_FALSE(GetLastEvent());
635 EXPECT_TRUE(GetAndResetNeedsFlush());
637 // The second move should remain buffered.
638 event_time += SmallDelta();
639 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
640 buffer.OnMotionEvent(move1);
641 ASSERT_FALSE(GetLastEvent());
642 EXPECT_FALSE(GetAndResetNeedsFlush());
644 base::TimeTicks flush_time = event_time + ResampleDelta();
645 buffer.Flush(flush_time);
646 EXPECT_FALSE(GetAndResetNeedsFlush());
648 // There should only be one flushed event, and no resampling should have
649 // occured between the first and the second as they were temporally too close.
650 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
651 ASSERT_EQ(1U, events.size());
652 EXPECT_EQ(1U, events.front()->GetHistorySize());
653 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move1);
654 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
657 TEST_F(MotionEventBufferTest, NoResamplingWithMismatchBetweenMoves) {
658 base::TimeTicks event_time = base::TimeTicks::Now();
659 MotionEventBuffer buffer(this, true);
661 // The first move should be buffered.
662 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
663 buffer.OnMotionEvent(move0);
664 ASSERT_FALSE(GetLastEvent());
665 EXPECT_TRUE(GetAndResetNeedsFlush());
667 // The second move should remain buffered.
668 event_time += SmallDelta();
669 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
670 buffer.OnMotionEvent(move1);
671 ASSERT_FALSE(GetLastEvent());
672 EXPECT_FALSE(GetAndResetNeedsFlush());
674 base::TimeTicks flush_time = event_time + ResampleDelta();
675 buffer.Flush(flush_time);
676 EXPECT_FALSE(GetAndResetNeedsFlush());
678 // There should only be one flushed event, and no resampling should have
679 // occured between the first and the second as they were temporally too close.
680 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
681 ASSERT_EQ(1U, events.size());
682 EXPECT_EQ(1U, events.front()->GetHistorySize());
683 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), move1);
684 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
687 TEST_F(MotionEventBufferTest, Interpolation) {
688 base::TimeTicks event_time = base::TimeTicks::Now();
689 MotionEventBuffer buffer(this, true);
691 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
692 buffer.OnMotionEvent(move0);
693 ASSERT_FALSE(GetLastEvent());
694 EXPECT_TRUE(GetAndResetNeedsFlush());
696 // The second move should remain buffered.
697 event_time += base::TimeDelta::FromMilliseconds(5);
698 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 15.f, 30.f);
699 buffer.OnMotionEvent(move1);
700 ASSERT_FALSE(GetLastEvent());
701 EXPECT_FALSE(GetAndResetNeedsFlush());
703 // Sample at a time between the first and second events.
704 base::TimeTicks interpolated_time =
705 move0.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 3;
706 base::TimeTicks flush_time = interpolated_time + ResampleDelta();
707 buffer.Flush(flush_time);
708 ASSERT_TRUE(GetLastEvent());
709 EXPECT_TRUE(GetAndResetNeedsFlush());
711 // There should only be one flushed event, with the event interpolated between
712 // the two events. The second event should remain buffered.
713 float alpha = (interpolated_time - move0.GetEventTime()).InMillisecondsF() /
714 (move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
715 MockMotionEvent interpolated_event(
716 MotionEvent::ACTION_MOVE,
717 interpolated_time,
718 move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * alpha,
719 move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * alpha);
720 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
721 ASSERT_EQ(1U, events.size());
722 EXPECT_EQ(1U, events.front()->GetHistorySize());
723 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), interpolated_event);
724 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
726 // The second move should be flushed without resampling.
727 flush_time = move1.GetEventTime() + ResampleDelta();
728 buffer.Flush(flush_time);
729 ASSERT_TRUE(GetLastEvent());
730 EXPECT_EVENT_EQ(move1, *GetLastEvent());
733 TEST_F(MotionEventBufferTest, Extrapolation) {
734 base::TimeTicks event_time = base::TimeTicks::Now();
735 MotionEventBuffer buffer(this, true);
737 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
738 buffer.OnMotionEvent(move0);
739 ASSERT_FALSE(GetLastEvent());
740 EXPECT_TRUE(GetAndResetNeedsFlush());
742 // The second move should remain buffered.
743 event_time += base::TimeDelta::FromMilliseconds(5);
744 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
745 buffer.OnMotionEvent(move1);
746 ASSERT_FALSE(GetLastEvent());
747 EXPECT_FALSE(GetAndResetNeedsFlush());
749 // Sample at a time beyond the first and second events.
750 base::TimeTicks extrapolated_time =
751 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime());
752 base::TimeTicks flush_time = extrapolated_time + ResampleDelta();
753 buffer.Flush(flush_time);
754 ASSERT_TRUE(GetLastEvent());
755 EXPECT_FALSE(GetAndResetNeedsFlush());
757 // There should only be one flushed event, with the event extrapolated from
758 // the two events. The first and second events should be in the history.
759 // Note that the maximum extrapolation is limited by *half* of the time delta
760 // between the two events, hence we divide the relative delta by 2 in
761 // determining the extrapolated event.
762 base::TimeTicks expected_time =
763 move1.GetEventTime() + (move1.GetEventTime() - move0.GetEventTime()) / 2;
764 float expected_alpha =
765 (expected_time - move0.GetEventTime()).InMillisecondsF() /
766 (move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
767 MockMotionEvent extrapolated_event(
768 MotionEvent::ACTION_MOVE,
769 expected_time,
770 move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * expected_alpha,
771 move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * expected_alpha);
772 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
773 ASSERT_EQ(1U, events.size());
774 EXPECT_EQ(2U, events.front()->GetHistorySize());
775 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), extrapolated_event);
776 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
777 EXPECT_EVENT_HISTORY_EQ(*events.front(), 1, move1);
780 TEST_F(MotionEventBufferTest, ExtrapolationHorizonLimited) {
781 base::TimeTicks event_time = base::TimeTicks::Now();
782 MotionEventBuffer buffer(this, true);
784 MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
785 buffer.OnMotionEvent(move0);
786 ASSERT_FALSE(GetLastEvent());
787 EXPECT_TRUE(GetAndResetNeedsFlush());
789 // The second move should remain buffered.
790 event_time += base::TimeDelta::FromMilliseconds(24);
791 MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
792 buffer.OnMotionEvent(move1);
793 ASSERT_FALSE(GetLastEvent());
794 EXPECT_FALSE(GetAndResetNeedsFlush());
796 // Sample at a time beyond the first and second events.
797 base::TimeTicks extrapolated_time =
798 event_time + base::TimeDelta::FromMilliseconds(24);
799 base::TimeTicks flush_time = extrapolated_time + ResampleDelta();
800 buffer.Flush(flush_time);
801 ASSERT_TRUE(GetLastEvent());
802 EXPECT_FALSE(GetAndResetNeedsFlush());
804 // There should only be one flushed event, with the event extrapolated from
805 // the two events. The first and second events should be in the history.
806 // Note that the maximum extrapolation is limited by 8 ms.
807 base::TimeTicks expected_time =
808 move1.GetEventTime() + base::TimeDelta::FromMilliseconds(8);
809 float expected_alpha =
810 (expected_time - move0.GetEventTime()).InMillisecondsF() /
811 (move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
812 MockMotionEvent extrapolated_event(
813 MotionEvent::ACTION_MOVE,
814 expected_time,
815 move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * expected_alpha,
816 move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * expected_alpha);
817 ScopedVector<MotionEvent> events = GetAndResetForwardedEvents();
818 ASSERT_EQ(1U, events.size());
819 EXPECT_EQ(2U, events.front()->GetHistorySize());
820 EXPECT_EVENT_IGNORING_HISTORY_EQ(*events.front(), extrapolated_event);
821 EXPECT_EVENT_HISTORY_EQ(*events.front(), 0, move0);
822 EXPECT_EVENT_HISTORY_EQ(*events.front(), 1, move1);
825 TEST_F(MotionEventBufferTest, ResamplingWithReorderedPointers) {
829 TEST_F(MotionEventBufferTest, Resampling30to60) {
830 base::TimeDelta flush_time_delta =
831 base::TimeDelta::FromMillisecondsD(1000. / 60.);
832 base::TimeDelta event_time_delta =
833 base::TimeDelta::FromMillisecondsD(1000. / 30.);
835 RunResample(flush_time_delta, event_time_delta);
838 TEST_F(MotionEventBufferTest, Resampling60to60) {
839 base::TimeDelta flush_time_delta =
840 base::TimeDelta::FromMillisecondsD(1000. / 60.);
841 base::TimeDelta event_time_delta =
842 base::TimeDelta::FromMillisecondsD(1000. / 60.);
844 RunResample(flush_time_delta, event_time_delta);
847 TEST_F(MotionEventBufferTest, Resampling100to60) {
848 base::TimeDelta flush_time_delta =
849 base::TimeDelta::FromMillisecondsD(1000. / 60.);
850 base::TimeDelta event_time_delta =
851 base::TimeDelta::FromMillisecondsD(1000. / 100.);
853 RunResample(flush_time_delta, event_time_delta);
856 TEST_F(MotionEventBufferTest, Resampling120to60) {
857 base::TimeDelta flush_time_delta =
858 base::TimeDelta::FromMillisecondsD(1000. / 60.);
859 base::TimeDelta event_time_delta =
860 base::TimeDelta::FromMillisecondsD(1000. / 120.);
862 RunResample(flush_time_delta, event_time_delta);
865 TEST_F(MotionEventBufferTest, Resampling150to60) {
866 base::TimeDelta flush_time_delta =
867 base::TimeDelta::FromMillisecondsD(1000. / 60.);
868 base::TimeDelta event_time_delta =
869 base::TimeDelta::FromMillisecondsD(1000. / 150.);
871 RunResample(flush_time_delta, event_time_delta);
874 } // namespace ui