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