blob: cbb078299c2e8083411494a014df058e7c599bb5 [file] [log] [blame]
Jeff Brown8a90e6e2012-05-11 12:24:35 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _ANDROIDFW_VELOCITY_TRACKER_H
18#define _ANDROIDFW_VELOCITY_TRACKER_H
19
20#include <androidfw/Input.h>
21#include <utils/Timers.h>
22#include <utils/BitSet.h>
23
24namespace android {
25
Jeff Brown85bd0d62012-05-13 15:30:42 -070026class VelocityTrackerStrategy;
27
Jeff Brown8a90e6e2012-05-11 12:24:35 -070028/*
29 * Calculates the velocity of pointer movements over time.
30 */
31class VelocityTracker {
32public:
Jeff Brown8a90e6e2012-05-11 12:24:35 -070033 struct Position {
34 float x, y;
35 };
36
37 struct Estimator {
38 static const size_t MAX_DEGREE = 2;
39
Jeff Brown90729402012-05-14 18:46:18 -070040 // Estimator time base.
41 nsecs_t time;
42
Jeff Brown8a90e6e2012-05-11 12:24:35 -070043 // Polynomial coefficients describing motion in X and Y.
44 float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
45
46 // Polynomial degree (number of coefficients), or zero if no information is
47 // available.
48 uint32_t degree;
49
50 // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
51 float confidence;
52
53 inline void clear() {
Jeff Brown90729402012-05-14 18:46:18 -070054 time = 0;
Jeff Brown8a90e6e2012-05-11 12:24:35 -070055 degree = 0;
56 confidence = 0;
57 for (size_t i = 0; i <= MAX_DEGREE; i++) {
58 xCoeff[i] = 0;
59 yCoeff[i] = 0;
60 }
61 }
62 };
63
64 VelocityTracker();
Jeff Brown85bd0d62012-05-13 15:30:42 -070065 ~VelocityTracker();
Jeff Brown8a90e6e2012-05-11 12:24:35 -070066
67 // Resets the velocity tracker state.
68 void clear();
69
70 // Resets the velocity tracker state for specific pointers.
71 // Call this method when some pointers have changed and may be reusing
72 // an id that was assigned to a different pointer earlier.
73 void clearPointers(BitSet32 idBits);
74
75 // Adds movement information for a set of pointers.
76 // The idBits bitfield specifies the pointer ids of the pointers whose positions
77 // are included in the movement.
78 // The positions array contains position information for each pointer in order by
79 // increasing id. Its size should be equal to the number of one bits in idBits.
80 void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
81
82 // Adds movement information for all pointers in a MotionEvent, including historical samples.
83 void addMovement(const MotionEvent* event);
84
85 // Gets the velocity of the specified pointer id in position units per second.
86 // Returns false and sets the velocity components to zero if there is
87 // insufficient movement information for the pointer.
88 bool getVelocity(uint32_t id, float* outVx, float* outVy) const;
89
Jeff Brown85bd0d62012-05-13 15:30:42 -070090 // Gets an estimator for the recent movements of the specified pointer id.
Jeff Brown8a90e6e2012-05-11 12:24:35 -070091 // Returns false and clears the estimator if there is no information available
92 // about the pointer.
Jeff Brown85bd0d62012-05-13 15:30:42 -070093 bool getEstimator(uint32_t id, Estimator* outEstimator) const;
Jeff Brown8a90e6e2012-05-11 12:24:35 -070094
95 // Gets the active pointer id, or -1 if none.
96 inline int32_t getActivePointerId() const { return mActivePointerId; }
97
98 // Gets a bitset containing all pointer ids from the most recent movement.
Jeff Brown85bd0d62012-05-13 15:30:42 -070099 inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
Jeff Brown8a90e6e2012-05-11 12:24:35 -0700100
101private:
Jeff Brown90729402012-05-14 18:46:18 -0700102 nsecs_t mLastEventTime;
Jeff Brown85bd0d62012-05-13 15:30:42 -0700103 BitSet32 mCurrentPointerIdBits;
104 int32_t mActivePointerId;
105 VelocityTrackerStrategy* mStrategy;
106};
107
108
109/*
110 * Implements a particular velocity tracker algorithm.
111 */
112class VelocityTrackerStrategy {
113protected:
114 VelocityTrackerStrategy() { }
115
116public:
117 virtual ~VelocityTrackerStrategy() { }
118
119 virtual void clear() = 0;
120 virtual void clearPointers(BitSet32 idBits) = 0;
121 virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
122 const VelocityTracker::Position* positions) = 0;
123 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
124};
125
126
127/*
128 * Velocity tracker algorithm based on least-squares linear regression.
129 */
130class LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
131public:
132 LeastSquaresVelocityTrackerStrategy();
133 virtual ~LeastSquaresVelocityTrackerStrategy();
134
135 virtual void clear();
136 virtual void clearPointers(BitSet32 idBits);
137 virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
138 const VelocityTracker::Position* positions);
139 virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
140
141private:
142 // Polynomial degree. Must be less than or equal to Estimator::MAX_DEGREE.
143 static const uint32_t DEGREE = 2;
144
145 // Sample horizon.
146 // We don't use too much history by default since we want to react to quick
147 // changes in direction.
148 static const nsecs_t HORIZON = 100 * 1000000; // 100 ms
149
Jeff Brown8a90e6e2012-05-11 12:24:35 -0700150 // Number of samples to keep.
151 static const uint32_t HISTORY_SIZE = 20;
152
153 struct Movement {
154 nsecs_t eventTime;
155 BitSet32 idBits;
Jeff Brown85bd0d62012-05-13 15:30:42 -0700156 VelocityTracker::Position positions[MAX_POINTERS];
Jeff Brown8a90e6e2012-05-11 12:24:35 -0700157
Jeff Brown85bd0d62012-05-13 15:30:42 -0700158 inline const VelocityTracker::Position& getPosition(uint32_t id) const {
Jeff Brown8a90e6e2012-05-11 12:24:35 -0700159 return positions[idBits.getIndexOfBit(id)];
160 }
161 };
162
163 uint32_t mIndex;
164 Movement mMovements[HISTORY_SIZE];
Jeff Brown8a90e6e2012-05-11 12:24:35 -0700165};
166
167} // namespace android
168
169#endif // _ANDROIDFW_VELOCITY_TRACKER_H