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#ifndef UI_EVENTS_GESTURE_DETECTION_MOTION_EVENT_BUFFER_H_
6#define UI_EVENTS_GESTURE_DETECTION_MOTION_EVENT_BUFFER_H_
7
8#include "base/memory/scoped_ptr.h"
9#include "base/memory/scoped_vector.h"
10#include "base/time/time.h"
11#include "ui/events/gesture_detection/gesture_detection_export.h"
12
13namespace ui {
14
15class MotionEvent;
16
17// Allows event forwarding and flush requests from a |MotionEventBuffer|.
18class MotionEventBufferClient {
19 public:
20  virtual ~MotionEventBufferClient() {}
21  virtual void ForwardMotionEvent(const MotionEvent& event) = 0;
22  virtual void SetNeedsFlush() = 0;
23};
24
25// Utility class for buffering streamed MotionEventVector until a given flush.
26// Events that can be combined will remain buffered, and depending on the flush
27// time and buffered events, a resampled event with history will be synthesized.
28// The primary purpose of this class is to ensure a smooth output motion signal
29// by resampling a discrete input signal that may run on a different frequency
30// or lack alignment with the output display signal.
31// Note that this class is largely based on code from Android's existing touch
32// pipeline (in particular, logic from ImageTransport, http://goo.gl/Ixsb0D).
33// See the design doc at http://goo.gl/MdmpCf for more details.
34class GESTURE_DETECTION_EXPORT MotionEventBuffer {
35 public:
36  // The provided |client| must not be null, and |enable_resampling| determines
37  // resampling behavior (see |resample_|).
38  MotionEventBuffer(MotionEventBufferClient* client, bool enable_resampling);
39  ~MotionEventBuffer();
40
41  // Should be called upon receipt of an event from the platform, prior to event
42  // dispatch to UI or content components. Events that can be coalesced will
43  // remain buffered until the next |Flush()|, while other events will be
44  // forwarded immediately (incidentally flushing currently buffered events).
45  void OnMotionEvent(const MotionEvent& event);
46
47  // Forward any buffered events, resampling if necessary (see |resample_|)
48  // according to the provided |frame_time|. This should be called in response
49  // to |SetNeedsFlush()| calls on the client. If the buffer is empty, no
50  // events will be forwarded, and if another flush is necessary it will be
51  // requested.
52  void Flush(base::TimeTicks frame_time);
53
54 private:
55  typedef ScopedVector<MotionEvent> MotionEventVector;
56
57  void FlushWithoutResampling(MotionEventVector events);
58
59  MotionEventBufferClient* const client_;
60  MotionEventVector buffered_events_;
61
62  // Time of the most recently extrapolated event. This will be 0 if the
63  // last sent event was not extrapolated. Used internally to guard against
64  // conflicts between events received from the platfrom that may have an
65  // earlier timestamp than that synthesized at the latest resample.
66  base::TimeTicks last_extrapolated_event_time_;
67
68  // Whether buffered events should be resampled upon |Flush()|. If true, short
69  // horizon interpolation/extrapolation will be used to synthesize the
70  // forwarded event. Otherwise the most recently buffered event will be
71  // forwarded, with preceding events as historical entries. Defaults to true.
72  bool resample_;
73
74  DISALLOW_COPY_AND_ASSIGN(MotionEventBuffer);
75};
76
77}  // namespace ui
78
79#endif  // UI_EVENTS_GESTURE_DETECTION_MOTION_EVENT_BUFFER_H_
80