15912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/*
25912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Copyright (C) 2012 The Android Open Source Project
35912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *
45912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
55912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * you may not use this file except in compliance with the License.
65912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * You may obtain a copy of the License at
75912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *
85912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
95912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown *
105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Unless required by applicable law or agreed to in writing, software
115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * See the License for the specific language governing permissions and
145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * limitations under the License.
155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */
165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#ifndef _LIBINPUT_VELOCITY_TRACKER_H
185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#define _LIBINPUT_VELOCITY_TRACKER_H
195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <input/Input.h>
215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <utils/Timers.h>
225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#include <utils/BitSet.h>
235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownnamespace android {
255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass VelocityTrackerStrategy;
275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/*
295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Calculates the velocity of pointer movements over time.
305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */
315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass VelocityTracker {
325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownpublic:
335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    struct Position {
345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float x, y;
355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    };
365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    struct Estimator {
385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        static const size_t MAX_DEGREE = 4;
395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Estimator time base.
415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t time;
425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Polynomial coefficients describing motion in X and Y.
445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];
455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Polynomial degree (number of coefficients), or zero if no information is
475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // available.
485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t degree;
495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Confidence (coefficient of determination), between 0 (no fit) and 1 (perfect fit).
515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float confidence;
525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        inline void clear() {
545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            time = 0;
555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            degree = 0;
565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            confidence = 0;
575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            for (size_t i = 0; i <= MAX_DEGREE; i++) {
585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                xCoeff[i] = 0;
595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown                yCoeff[i] = 0;
605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            }
615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    };
635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Creates a velocity tracker using the specified strategy.
655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // If strategy is NULL, uses the default strategy for the platform.
665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    VelocityTracker(const char* strategy = NULL);
675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ~VelocityTracker();
695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Resets the velocity tracker state.
715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    void clear();
725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Resets the velocity tracker state for specific pointers.
745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Call this method when some pointers have changed and may be reusing
755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // an id that was assigned to a different pointer earlier.
765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    void clearPointers(BitSet32 idBits);
775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Adds movement information for a set of pointers.
795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // The idBits bitfield specifies the pointer ids of the pointers whose positions
805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // are included in the movement.
815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // The positions array contains position information for each pointer in order by
825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // increasing id.  Its size should be equal to the number of one bits in idBits.
835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    void addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions);
845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Adds movement information for all pointers in a MotionEvent, including historical samples.
865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    void addMovement(const MotionEvent* event);
875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Gets the velocity of the specified pointer id in position units per second.
895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Returns false and sets the velocity components to zero if there is
905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // insufficient movement information for the pointer.
915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    bool getVelocity(uint32_t id, float* outVx, float* outVy) const;
925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Gets an estimator for the recent movements of the specified pointer id.
945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Returns false and clears the estimator if there is no information available
955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // about the pointer.
965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    bool getEstimator(uint32_t id, Estimator* outEstimator) const;
975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Gets the active pointer id, or -1 if none.
995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    inline int32_t getActivePointerId() const { return mActivePointerId; }
1005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Gets a bitset containing all pointer ids from the most recent movement.
1025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }
1035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownprivate:
1055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    static const char* DEFAULT_STRATEGY;
1065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    nsecs_t mLastEventTime;
1085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    BitSet32 mCurrentPointerIdBits;
1095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    int32_t mActivePointerId;
1105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    VelocityTrackerStrategy* mStrategy;
1115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    bool configureStrategy(const char* strategy);
1135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    static VelocityTrackerStrategy* createStrategy(const char* strategy);
1155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown};
1165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/*
1195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Implements a particular velocity tracker algorithm.
1205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */
1215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass VelocityTrackerStrategy {
1225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownprotected:
1235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    VelocityTrackerStrategy() { }
1245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownpublic:
1265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual ~VelocityTrackerStrategy() { }
1275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clear() = 0;
1295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clearPointers(BitSet32 idBits) = 0;
1305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
1315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const VelocityTracker::Position* positions) = 0;
1325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const = 0;
1335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown};
1345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/*
1375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Velocity tracker algorithm based on least-squares linear regression.
1385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */
1395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass LeastSquaresVelocityTrackerStrategy : public VelocityTrackerStrategy {
1405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownpublic:
1415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    enum Weighting {
1425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // No weights applied.  All data points are equally reliable.
1435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        WEIGHTING_NONE,
1445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Weight by time delta.  Data points clustered together are weighted less.
1465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        WEIGHTING_DELTA,
1475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Weight such that points within a certain horizon are weighed more than those
1495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // outside of that horizon.
1505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        WEIGHTING_CENTRAL,
1515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        // Weight such that points older than a certain amount are weighed less.
1535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        WEIGHTING_RECENT,
1545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    };
1555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Degree must be no greater than Estimator::MAX_DEGREE.
1575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = WEIGHTING_NONE);
1585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual ~LeastSquaresVelocityTrackerStrategy();
1595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clear();
1615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clearPointers(BitSet32 idBits);
1625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
1635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const VelocityTracker::Position* positions);
1645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
1655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownprivate:
1675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Sample horizon.
1685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // We don't use too much history by default since we want to react to quick
1695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // changes in direction.
1705912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    static const nsecs_t HORIZON = 100 * 1000000; // 100 ms
1715912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1725912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Number of samples to keep.
1735912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    static const uint32_t HISTORY_SIZE = 20;
1745912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1755912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    struct Movement {
1765912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime;
1775912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        BitSet32 idBits;
1785912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        VelocityTracker::Position positions[MAX_POINTERS];
1795912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1805912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
1815912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return positions[idBits.getIndexOfBit(id)];
1825912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
1835912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    };
1845912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1855912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    float chooseWeight(uint32_t index) const;
1865912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1875912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const uint32_t mDegree;
1885912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const Weighting mWeighting;
1895912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t mIndex;
1905912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    Movement mMovements[HISTORY_SIZE];
1915912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown};
1925912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1935912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
1945912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/*
1955912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Velocity tracker algorithm that uses an IIR filter.
1965912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */
1975912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy {
1985912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownpublic:
1995912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Degree must be 1 or 2.
2005912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    IntegratingVelocityTrackerStrategy(uint32_t degree);
2015912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    ~IntegratingVelocityTrackerStrategy();
2025912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2035912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clear();
2045912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clearPointers(BitSet32 idBits);
2055912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
2065912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const VelocityTracker::Position* positions);
2075912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
2085912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2095912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownprivate:
2105912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Current state estimate for a particular pointer.
2115912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    struct State {
2125912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t updateTime;
2135912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        uint32_t degree;
2145912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2155912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float xpos, xvel, xaccel;
2165912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        float ypos, yvel, yaccel;
2175912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    };
2185912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2195912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    const uint32_t mDegree;
2205912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    BitSet32 mPointerIdBits;
2215912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    State mPointerState[MAX_POINTER_ID + 1];
2225912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2235912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    void initState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
2245912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    void updateState(State& state, nsecs_t eventTime, float xpos, float ypos) const;
2255912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    void populateEstimator(const State& state, VelocityTracker::Estimator* outEstimator) const;
2265912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown};
2275912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2285912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2295912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown/*
2305912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown * Velocity tracker strategy used prior to ICS.
2315912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown */
2325912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownclass LegacyVelocityTrackerStrategy : public VelocityTrackerStrategy {
2335912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownpublic:
2345912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    LegacyVelocityTrackerStrategy();
2355912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual ~LegacyVelocityTrackerStrategy();
2365912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2375912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clear();
2385912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void clearPointers(BitSet32 idBits);
2395912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual void addMovement(nsecs_t eventTime, BitSet32 idBits,
2405912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            const VelocityTracker::Position* positions);
2415912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    virtual bool getEstimator(uint32_t id, VelocityTracker::Estimator* outEstimator) const;
2425912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2435912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brownprivate:
2445912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Oldest sample to consider when calculating the velocity.
2455912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    static const nsecs_t HORIZON = 200 * 1000000; // 100 ms
2465912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2475912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // Number of samples to keep.
2485912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    static const uint32_t HISTORY_SIZE = 20;
2495912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2505912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    // The minimum duration between samples when estimating velocity.
2515912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms
2525912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2535912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    struct Movement {
2545912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        nsecs_t eventTime;
2555912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        BitSet32 idBits;
2565912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        VelocityTracker::Position positions[MAX_POINTERS];
2575912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2585912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        inline const VelocityTracker::Position& getPosition(uint32_t id) const {
2595912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown            return positions[idBits.getIndexOfBit(id)];
2605912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown        }
2615912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    };
2625912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2635912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    uint32_t mIndex;
2645912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown    Movement mMovements[HISTORY_SIZE];
2655912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown};
2665912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2675912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown} // namespace android
2685912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown
2695912f95d26f77d2b6df13e1f2672e48e3f9b871cJeff Brown#endif // _LIBINPUT_VELOCITY_TRACKER_H
270