1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef UI_EVENTS_GESTURE_DETECTION_VELOCITY_TRACKER_H_
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define UI_EVENTS_GESTURE_DETECTION_VELOCITY_TRACKER_H_
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/basictypes.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/time/time.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/events/gesture_detection/bitset_32.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ui {
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class MotionEvent;
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class VelocityTrackerStrategy;
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct Estimator;
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct Position;
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Port of VelocityTracker from Android
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * platform/frameworks/native/include/input/VelocityTracker.h
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * Change-Id: I4983db61b53e28479fc90d9211fafff68f7f49a6
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// * Please update the Change-Id as upstream Android changes are pulled.
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class VelocityTracker {
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  enum {
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The maximum number of pointers to use when computing the velocity.
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Note that the supplied MotionEvent may expose more than 16 pointers, but
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // at most |MAX_POINTERS| will be used.
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    MAX_POINTERS = 16,
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  enum Strategy {
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 1st order least squares.  Quality: POOR.
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Frequently underfits the touch data especially when the finger
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // accelerates or changes direction.  Often underestimates velocity.  The
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // direction is overly influenced by historical touch points.
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LSQ1,
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 2nd order least squares.  Quality: VERY GOOD.
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Pretty much ideal, but can be confused by certain kinds of touch data,
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // particularly if the panel has a tendency to generate delayed,
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // duplicate or jittery touch coordinates when the finger is released.
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LSQ2,
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 3rd order least squares.  Quality: UNUSABLE.
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Frequently overfits the touch data yielding wildly divergent estimates
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // of the velocity when the finger is released.
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LSQ3,
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 2nd order weighted least squares, delta weighting.
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Quality: EXPERIMENTAL
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WLSQ2_DELTA,
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 2nd order weighted least squares, central weighting.
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Quality: EXPERIMENTAL
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WLSQ2_CENTRAL,
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 2nd order weighted least squares, recent weighting.
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Quality: EXPERIMENTAL
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    WLSQ2_RECENT,
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 1st order integrating filter.  Quality: GOOD.
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Not as good as 'lsq2' because it cannot estimate acceleration but it is
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // more tolerant of errors.  Like 'lsq1', this strategy tends to
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // underestimate
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // the velocity of a fling but this strategy tends to respond to changes in
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // direction more quickly and accurately.
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    INT1,
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // 2nd order integrating filter.  Quality: EXPERIMENTAL.
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // For comparison purposes only.  Unlike 'int1' this strategy can compensate
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // for acceleration but it typically overestimates the effect.
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    INT2,
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    STRATEGY_MAX = INT2,
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The default velocity tracker strategy.
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Although other strategies are available for testing and comparison
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // purposes, this is the strategy that applications will actually use.  Be
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // very careful when adjusting the default strategy because it can
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // dramatically affect (often in a bad way) the user experience.
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    STRATEGY_DEFAULT = LSQ2,
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Creates a velocity tracker using the default strategy for the platform.
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  VelocityTracker();
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Creates a velocity tracker using the specified strategy.
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If strategy is NULL, uses the default strategy for the platform.
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  explicit VelocityTracker(Strategy strategy);
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ~VelocityTracker();
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Resets the velocity tracker state.
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Clear();
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Adds movement information for all pointers in a MotionEvent, including
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // historical samples.
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void AddMovement(const MotionEvent& event);
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Gets the velocity of the specified pointer id in position units per second.
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns false and sets the velocity components to zero if there is
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // insufficient movement information for the pointer.
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool GetVelocity(uint32_t id, float* outVx, float* outVy) const;
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Gets the active pointer id, or -1 if none.
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  inline int32_t GetActivePointerId() const { return active_pointer_id_; }
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Gets a bitset containing all pointer ids from the most recent movement.
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  inline BitSet32 GetCurrentPointerIdBits() const {
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return current_pointer_id_bits_;
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Resets the velocity tracker state for specific pointers.
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Call this method when some pointers have changed and may be reusing
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // an id that was assigned to a different pointer earlier.
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void ClearPointers(BitSet32 id_bits);
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Adds movement information for a set of pointers.
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The id_bits bitfield specifies the pointer ids of the pointers whose
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // positions
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // are included in the movement.
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The positions array contains position information for each pointer in order
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // by
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // increasing id.  Its size should be equal to the number of one bits in
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // id_bits.
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void AddMovement(const base::TimeTicks& event_time,
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   BitSet32 id_bits,
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   const Position* positions);
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Gets an estimator for the recent movements of the specified pointer id.
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Returns false and clears the estimator if there is no information available
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // about the pointer.
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool GetEstimator(uint32_t id, Estimator* out_estimator) const;
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TimeTicks last_event_time_;
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BitSet32 current_pointer_id_bits_;
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int32_t active_pointer_id_;
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<VelocityTrackerStrategy> strategy_;
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(VelocityTracker);
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace ui
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // UI_EVENTS_GESTURE_DETECTION_VELOCITY_TRACKER_H_
151