1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #pragma once 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IInputConstants.h> 20*38e8c45fSAndroid Build Coastguard Worker #include <input/Input.h> 21*38e8c45fSAndroid Build Coastguard Worker #include <input/RingBuffer.h> 22*38e8c45fSAndroid Build Coastguard Worker #include <utils/BitSet.h> 23*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h> 24*38e8c45fSAndroid Build Coastguard Worker #include <map> 25*38e8c45fSAndroid Build Coastguard Worker #include <set> 26*38e8c45fSAndroid Build Coastguard Worker 27*38e8c45fSAndroid Build Coastguard Worker namespace android { 28*38e8c45fSAndroid Build Coastguard Worker 29*38e8c45fSAndroid Build Coastguard Worker class VelocityTrackerStrategy; 30*38e8c45fSAndroid Build Coastguard Worker 31*38e8c45fSAndroid Build Coastguard Worker /* 32*38e8c45fSAndroid Build Coastguard Worker * Calculates the velocity of pointer movements over time. 33*38e8c45fSAndroid Build Coastguard Worker */ 34*38e8c45fSAndroid Build Coastguard Worker class VelocityTracker { 35*38e8c45fSAndroid Build Coastguard Worker public: 36*38e8c45fSAndroid Build Coastguard Worker static const size_t MAX_DEGREE = 4; 37*38e8c45fSAndroid Build Coastguard Worker 38*38e8c45fSAndroid Build Coastguard Worker enum class Strategy : int32_t { 39*38e8c45fSAndroid Build Coastguard Worker DEFAULT = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_DEFAULT, 40*38e8c45fSAndroid Build Coastguard Worker IMPULSE = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_IMPULSE, 41*38e8c45fSAndroid Build Coastguard Worker LSQ1 = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_LSQ1, 42*38e8c45fSAndroid Build Coastguard Worker LSQ2 = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_LSQ2, 43*38e8c45fSAndroid Build Coastguard Worker LSQ3 = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_LSQ3, 44*38e8c45fSAndroid Build Coastguard Worker WLSQ2_DELTA = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_WLSQ2_DELTA, 45*38e8c45fSAndroid Build Coastguard Worker WLSQ2_CENTRAL = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_WLSQ2_CENTRAL, 46*38e8c45fSAndroid Build Coastguard Worker WLSQ2_RECENT = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_WLSQ2_RECENT, 47*38e8c45fSAndroid Build Coastguard Worker INT1 = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_INT1, 48*38e8c45fSAndroid Build Coastguard Worker INT2 = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_INT2, 49*38e8c45fSAndroid Build Coastguard Worker LEGACY = android::os::IInputConstants::VELOCITY_TRACKER_STRATEGY_LEGACY, 50*38e8c45fSAndroid Build Coastguard Worker MIN = IMPULSE, 51*38e8c45fSAndroid Build Coastguard Worker MAX = LEGACY, 52*38e8c45fSAndroid Build Coastguard Worker ftl_last = LEGACY, 53*38e8c45fSAndroid Build Coastguard Worker }; 54*38e8c45fSAndroid Build Coastguard Worker 55*38e8c45fSAndroid Build Coastguard Worker /* 56*38e8c45fSAndroid Build Coastguard Worker * Contains all available velocity data from a VelocityTracker. 57*38e8c45fSAndroid Build Coastguard Worker */ 58*38e8c45fSAndroid Build Coastguard Worker struct ComputedVelocity { getVelocityComputedVelocity59*38e8c45fSAndroid Build Coastguard Worker inline std::optional<float> getVelocity(int32_t axis, int32_t id) const { 60*38e8c45fSAndroid Build Coastguard Worker const auto& axisVelocities = mVelocities.find(axis); 61*38e8c45fSAndroid Build Coastguard Worker if (axisVelocities == mVelocities.end()) { 62*38e8c45fSAndroid Build Coastguard Worker return {}; 63*38e8c45fSAndroid Build Coastguard Worker } 64*38e8c45fSAndroid Build Coastguard Worker 65*38e8c45fSAndroid Build Coastguard Worker const auto& axisIdVelocity = axisVelocities->second.find(id); 66*38e8c45fSAndroid Build Coastguard Worker if (axisIdVelocity == axisVelocities->second.end()) { 67*38e8c45fSAndroid Build Coastguard Worker return {}; 68*38e8c45fSAndroid Build Coastguard Worker } 69*38e8c45fSAndroid Build Coastguard Worker 70*38e8c45fSAndroid Build Coastguard Worker return axisIdVelocity->second; 71*38e8c45fSAndroid Build Coastguard Worker } 72*38e8c45fSAndroid Build Coastguard Worker addVelocityComputedVelocity73*38e8c45fSAndroid Build Coastguard Worker inline void addVelocity(int32_t axis, int32_t id, float velocity) { 74*38e8c45fSAndroid Build Coastguard Worker mVelocities[axis][id] = velocity; 75*38e8c45fSAndroid Build Coastguard Worker } 76*38e8c45fSAndroid Build Coastguard Worker 77*38e8c45fSAndroid Build Coastguard Worker private: 78*38e8c45fSAndroid Build Coastguard Worker std::map<int32_t /*axis*/, std::map<int32_t /*pointerId*/, float /*velocity*/>> mVelocities; 79*38e8c45fSAndroid Build Coastguard Worker }; 80*38e8c45fSAndroid Build Coastguard Worker 81*38e8c45fSAndroid Build Coastguard Worker // Creates a velocity tracker using the specified strategy for each supported axis. 82*38e8c45fSAndroid Build Coastguard Worker // If strategy is not provided, uses the default strategy for the platform. 83*38e8c45fSAndroid Build Coastguard Worker // TODO(b/32830165): support axis-specific strategies. 84*38e8c45fSAndroid Build Coastguard Worker VelocityTracker(const Strategy strategy = Strategy::DEFAULT); 85*38e8c45fSAndroid Build Coastguard Worker 86*38e8c45fSAndroid Build Coastguard Worker /** Return true if the axis is supported for velocity tracking, false otherwise. */ 87*38e8c45fSAndroid Build Coastguard Worker static bool isAxisSupported(int32_t axis); 88*38e8c45fSAndroid Build Coastguard Worker 89*38e8c45fSAndroid Build Coastguard Worker // Resets the velocity tracker state. 90*38e8c45fSAndroid Build Coastguard Worker void clear(); 91*38e8c45fSAndroid Build Coastguard Worker 92*38e8c45fSAndroid Build Coastguard Worker // Resets the velocity tracker state for a specific pointer. 93*38e8c45fSAndroid Build Coastguard Worker // Call this method when some pointers have changed and may be reusing 94*38e8c45fSAndroid Build Coastguard Worker // an id that was assigned to a different pointer earlier. 95*38e8c45fSAndroid Build Coastguard Worker void clearPointer(int32_t pointerId); 96*38e8c45fSAndroid Build Coastguard Worker 97*38e8c45fSAndroid Build Coastguard Worker // Adds movement information for a pointer for a specific axis 98*38e8c45fSAndroid Build Coastguard Worker void addMovement(nsecs_t eventTime, int32_t pointerId, int32_t axis, float position); 99*38e8c45fSAndroid Build Coastguard Worker 100*38e8c45fSAndroid Build Coastguard Worker // Adds movement information for all pointers in a MotionEvent, including historical samples. 101*38e8c45fSAndroid Build Coastguard Worker void addMovement(const MotionEvent& event); 102*38e8c45fSAndroid Build Coastguard Worker 103*38e8c45fSAndroid Build Coastguard Worker // Returns the velocity of the specified pointer id and axis in position units per second. 104*38e8c45fSAndroid Build Coastguard Worker // Returns empty optional if there is insufficient movement information for the pointer, or if 105*38e8c45fSAndroid Build Coastguard Worker // the given axis is not supported for velocity tracking. 106*38e8c45fSAndroid Build Coastguard Worker std::optional<float> getVelocity(int32_t axis, int32_t pointerId) const; 107*38e8c45fSAndroid Build Coastguard Worker 108*38e8c45fSAndroid Build Coastguard Worker // Returns a ComputedVelocity instance with all available velocity data, using the given units 109*38e8c45fSAndroid Build Coastguard Worker // (reference: units == 1 means "per millisecond"), and clamping each velocity between 110*38e8c45fSAndroid Build Coastguard Worker // [-maxVelocity, maxVelocity], inclusive. 111*38e8c45fSAndroid Build Coastguard Worker ComputedVelocity getComputedVelocity(int32_t units, float maxVelocity); 112*38e8c45fSAndroid Build Coastguard Worker 113*38e8c45fSAndroid Build Coastguard Worker // Gets the active pointer id, or -1 if none. getActivePointerId()114*38e8c45fSAndroid Build Coastguard Worker inline int32_t getActivePointerId() const { return mActivePointerId.value_or(-1); } 115*38e8c45fSAndroid Build Coastguard Worker 116*38e8c45fSAndroid Build Coastguard Worker private: 117*38e8c45fSAndroid Build Coastguard Worker nsecs_t mLastEventTime; 118*38e8c45fSAndroid Build Coastguard Worker BitSet32 mCurrentPointerIdBits; 119*38e8c45fSAndroid Build Coastguard Worker std::optional<int32_t> mActivePointerId; 120*38e8c45fSAndroid Build Coastguard Worker 121*38e8c45fSAndroid Build Coastguard Worker // An override strategy passed in the constructor to be used for all axes. 122*38e8c45fSAndroid Build Coastguard Worker // This strategy will apply to all axes, unless the default strategy is specified here. 123*38e8c45fSAndroid Build Coastguard Worker // When default strategy is specified, then each axis will use a potentially different strategy 124*38e8c45fSAndroid Build Coastguard Worker // based on a hardcoded mapping. 125*38e8c45fSAndroid Build Coastguard Worker const Strategy mOverrideStrategy; 126*38e8c45fSAndroid Build Coastguard Worker // Maps axes to their respective VelocityTrackerStrategy instances. 127*38e8c45fSAndroid Build Coastguard Worker // Note that, only axes that have had MotionEvents (and not all supported axes) will be here. 128*38e8c45fSAndroid Build Coastguard Worker std::map<int32_t /*axis*/, std::unique_ptr<VelocityTrackerStrategy>> mConfiguredStrategies; 129*38e8c45fSAndroid Build Coastguard Worker 130*38e8c45fSAndroid Build Coastguard Worker void configureStrategy(int32_t axis); 131*38e8c45fSAndroid Build Coastguard Worker 132*38e8c45fSAndroid Build Coastguard Worker // Generates a VelocityTrackerStrategy instance for the given Strategy type. 133*38e8c45fSAndroid Build Coastguard Worker // The `deltaValues` parameter indicates whether or not the created strategy should treat motion 134*38e8c45fSAndroid Build Coastguard Worker // values as deltas (and not as absolute values). This the parameter is applicable only for 135*38e8c45fSAndroid Build Coastguard Worker // strategies that support differential axes. 136*38e8c45fSAndroid Build Coastguard Worker static std::unique_ptr<VelocityTrackerStrategy> createStrategy(const Strategy strategy, 137*38e8c45fSAndroid Build Coastguard Worker bool deltaValues); 138*38e8c45fSAndroid Build Coastguard Worker }; 139*38e8c45fSAndroid Build Coastguard Worker 140*38e8c45fSAndroid Build Coastguard Worker 141*38e8c45fSAndroid Build Coastguard Worker /* 142*38e8c45fSAndroid Build Coastguard Worker * Implements a particular velocity tracker algorithm. 143*38e8c45fSAndroid Build Coastguard Worker */ 144*38e8c45fSAndroid Build Coastguard Worker class VelocityTrackerStrategy { 145*38e8c45fSAndroid Build Coastguard Worker protected: VelocityTrackerStrategy()146*38e8c45fSAndroid Build Coastguard Worker VelocityTrackerStrategy() { } 147*38e8c45fSAndroid Build Coastguard Worker 148*38e8c45fSAndroid Build Coastguard Worker public: ~VelocityTrackerStrategy()149*38e8c45fSAndroid Build Coastguard Worker virtual ~VelocityTrackerStrategy() { } 150*38e8c45fSAndroid Build Coastguard Worker 151*38e8c45fSAndroid Build Coastguard Worker virtual void clearPointer(int32_t pointerId) = 0; 152*38e8c45fSAndroid Build Coastguard Worker virtual void addMovement(nsecs_t eventTime, int32_t pointerId, float position) = 0; 153*38e8c45fSAndroid Build Coastguard Worker virtual std::optional<float> getVelocity(int32_t pointerId) const = 0; 154*38e8c45fSAndroid Build Coastguard Worker }; 155*38e8c45fSAndroid Build Coastguard Worker 156*38e8c45fSAndroid Build Coastguard Worker /** 157*38e8c45fSAndroid Build Coastguard Worker * A `VelocityTrackerStrategy` that accumulates added data points and processes the accumulated data 158*38e8c45fSAndroid Build Coastguard Worker * points when getting velocity. 159*38e8c45fSAndroid Build Coastguard Worker */ 160*38e8c45fSAndroid Build Coastguard Worker class AccumulatingVelocityTrackerStrategy : public VelocityTrackerStrategy { 161*38e8c45fSAndroid Build Coastguard Worker public: 162*38e8c45fSAndroid Build Coastguard Worker AccumulatingVelocityTrackerStrategy(nsecs_t horizonNanos, bool maintainHorizonDuringAdd); 163*38e8c45fSAndroid Build Coastguard Worker 164*38e8c45fSAndroid Build Coastguard Worker void addMovement(nsecs_t eventTime, int32_t pointerId, float position) override; 165*38e8c45fSAndroid Build Coastguard Worker void clearPointer(int32_t pointerId) override; 166*38e8c45fSAndroid Build Coastguard Worker 167*38e8c45fSAndroid Build Coastguard Worker protected: 168*38e8c45fSAndroid Build Coastguard Worker struct Movement { 169*38e8c45fSAndroid Build Coastguard Worker nsecs_t eventTime; 170*38e8c45fSAndroid Build Coastguard Worker float position; 171*38e8c45fSAndroid Build Coastguard Worker }; 172*38e8c45fSAndroid Build Coastguard Worker 173*38e8c45fSAndroid Build Coastguard Worker // Number of samples to keep. 174*38e8c45fSAndroid Build Coastguard Worker // If different strategies would like to maintain different history size, we can make this a 175*38e8c45fSAndroid Build Coastguard Worker // protected const field. 176*38e8c45fSAndroid Build Coastguard Worker static constexpr uint32_t HISTORY_SIZE = 20; 177*38e8c45fSAndroid Build Coastguard Worker 178*38e8c45fSAndroid Build Coastguard Worker /** 179*38e8c45fSAndroid Build Coastguard Worker * Duration, in nanoseconds, since the latest movement where a movement may be considered for 180*38e8c45fSAndroid Build Coastguard Worker * velocity calculation. 181*38e8c45fSAndroid Build Coastguard Worker */ 182*38e8c45fSAndroid Build Coastguard Worker const nsecs_t mHorizonNanos; 183*38e8c45fSAndroid Build Coastguard Worker /** 184*38e8c45fSAndroid Build Coastguard Worker * If true, data points outside of horizon (see `mHorizonNanos`) will be cleared after each 185*38e8c45fSAndroid Build Coastguard Worker * addition of a new movement. 186*38e8c45fSAndroid Build Coastguard Worker */ 187*38e8c45fSAndroid Build Coastguard Worker const bool mMaintainHorizonDuringAdd; 188*38e8c45fSAndroid Build Coastguard Worker std::map<int32_t /*pointerId*/, RingBuffer<Movement>> mMovements; 189*38e8c45fSAndroid Build Coastguard Worker }; 190*38e8c45fSAndroid Build Coastguard Worker 191*38e8c45fSAndroid Build Coastguard Worker /* 192*38e8c45fSAndroid Build Coastguard Worker * Velocity tracker algorithm based on least-squares linear regression. 193*38e8c45fSAndroid Build Coastguard Worker */ 194*38e8c45fSAndroid Build Coastguard Worker class LeastSquaresVelocityTrackerStrategy : public AccumulatingVelocityTrackerStrategy { 195*38e8c45fSAndroid Build Coastguard Worker public: 196*38e8c45fSAndroid Build Coastguard Worker enum class Weighting { 197*38e8c45fSAndroid Build Coastguard Worker // No weights applied. All data points are equally reliable. 198*38e8c45fSAndroid Build Coastguard Worker NONE, 199*38e8c45fSAndroid Build Coastguard Worker 200*38e8c45fSAndroid Build Coastguard Worker // Weight by time delta. Data points clustered together are weighted less. 201*38e8c45fSAndroid Build Coastguard Worker DELTA, 202*38e8c45fSAndroid Build Coastguard Worker 203*38e8c45fSAndroid Build Coastguard Worker // Weight such that points within a certain horizon are weighed more than those 204*38e8c45fSAndroid Build Coastguard Worker // outside of that horizon. 205*38e8c45fSAndroid Build Coastguard Worker CENTRAL, 206*38e8c45fSAndroid Build Coastguard Worker 207*38e8c45fSAndroid Build Coastguard Worker // Weight such that points older than a certain amount are weighed less. 208*38e8c45fSAndroid Build Coastguard Worker RECENT, 209*38e8c45fSAndroid Build Coastguard Worker }; 210*38e8c45fSAndroid Build Coastguard Worker 211*38e8c45fSAndroid Build Coastguard Worker // Degree must be no greater than VelocityTracker::MAX_DEGREE. 212*38e8c45fSAndroid Build Coastguard Worker LeastSquaresVelocityTrackerStrategy(uint32_t degree, Weighting weighting = Weighting::NONE); 213*38e8c45fSAndroid Build Coastguard Worker ~LeastSquaresVelocityTrackerStrategy() override; 214*38e8c45fSAndroid Build Coastguard Worker 215*38e8c45fSAndroid Build Coastguard Worker std::optional<float> getVelocity(int32_t pointerId) const override; 216*38e8c45fSAndroid Build Coastguard Worker 217*38e8c45fSAndroid Build Coastguard Worker private: 218*38e8c45fSAndroid Build Coastguard Worker // Sample horizon. 219*38e8c45fSAndroid Build Coastguard Worker // We don't use too much history by default since we want to react to quick 220*38e8c45fSAndroid Build Coastguard Worker // changes in direction. 221*38e8c45fSAndroid Build Coastguard Worker static const nsecs_t HORIZON = 100 * 1000000; // 100 ms 222*38e8c45fSAndroid Build Coastguard Worker 223*38e8c45fSAndroid Build Coastguard Worker float chooseWeight(int32_t pointerId, uint32_t index) const; 224*38e8c45fSAndroid Build Coastguard Worker /** 225*38e8c45fSAndroid Build Coastguard Worker * An optimized least-squares solver for degree 2 and no weight (i.e. `Weighting.NONE`). 226*38e8c45fSAndroid Build Coastguard Worker * The provided container of movements shall NOT be empty, and shall have the movements in 227*38e8c45fSAndroid Build Coastguard Worker * chronological order. 228*38e8c45fSAndroid Build Coastguard Worker */ 229*38e8c45fSAndroid Build Coastguard Worker std::optional<float> solveUnweightedLeastSquaresDeg2( 230*38e8c45fSAndroid Build Coastguard Worker const RingBuffer<Movement>& movements) const; 231*38e8c45fSAndroid Build Coastguard Worker 232*38e8c45fSAndroid Build Coastguard Worker const uint32_t mDegree; 233*38e8c45fSAndroid Build Coastguard Worker const Weighting mWeighting; 234*38e8c45fSAndroid Build Coastguard Worker }; 235*38e8c45fSAndroid Build Coastguard Worker 236*38e8c45fSAndroid Build Coastguard Worker /* 237*38e8c45fSAndroid Build Coastguard Worker * Velocity tracker algorithm that uses an IIR filter. 238*38e8c45fSAndroid Build Coastguard Worker */ 239*38e8c45fSAndroid Build Coastguard Worker class IntegratingVelocityTrackerStrategy : public VelocityTrackerStrategy { 240*38e8c45fSAndroid Build Coastguard Worker public: 241*38e8c45fSAndroid Build Coastguard Worker // Degree must be 1 or 2. 242*38e8c45fSAndroid Build Coastguard Worker IntegratingVelocityTrackerStrategy(uint32_t degree); 243*38e8c45fSAndroid Build Coastguard Worker ~IntegratingVelocityTrackerStrategy() override; 244*38e8c45fSAndroid Build Coastguard Worker 245*38e8c45fSAndroid Build Coastguard Worker void clearPointer(int32_t pointerId) override; 246*38e8c45fSAndroid Build Coastguard Worker void addMovement(nsecs_t eventTime, int32_t pointerId, float positions) override; 247*38e8c45fSAndroid Build Coastguard Worker std::optional<float> getVelocity(int32_t pointerId) const override; 248*38e8c45fSAndroid Build Coastguard Worker 249*38e8c45fSAndroid Build Coastguard Worker private: 250*38e8c45fSAndroid Build Coastguard Worker // Current state estimate for a particular pointer. 251*38e8c45fSAndroid Build Coastguard Worker struct State { 252*38e8c45fSAndroid Build Coastguard Worker nsecs_t updateTime; 253*38e8c45fSAndroid Build Coastguard Worker uint32_t degree; 254*38e8c45fSAndroid Build Coastguard Worker 255*38e8c45fSAndroid Build Coastguard Worker float pos, vel, accel; 256*38e8c45fSAndroid Build Coastguard Worker }; 257*38e8c45fSAndroid Build Coastguard Worker 258*38e8c45fSAndroid Build Coastguard Worker const uint32_t mDegree; 259*38e8c45fSAndroid Build Coastguard Worker BitSet32 mPointerIdBits; 260*38e8c45fSAndroid Build Coastguard Worker State mPointerState[MAX_POINTER_ID + 1]; 261*38e8c45fSAndroid Build Coastguard Worker 262*38e8c45fSAndroid Build Coastguard Worker void initState(State& state, nsecs_t eventTime, float pos) const; 263*38e8c45fSAndroid Build Coastguard Worker void updateState(State& state, nsecs_t eventTime, float pos) const; 264*38e8c45fSAndroid Build Coastguard Worker }; 265*38e8c45fSAndroid Build Coastguard Worker 266*38e8c45fSAndroid Build Coastguard Worker 267*38e8c45fSAndroid Build Coastguard Worker /* 268*38e8c45fSAndroid Build Coastguard Worker * Velocity tracker strategy used prior to ICS. 269*38e8c45fSAndroid Build Coastguard Worker */ 270*38e8c45fSAndroid Build Coastguard Worker class LegacyVelocityTrackerStrategy : public AccumulatingVelocityTrackerStrategy { 271*38e8c45fSAndroid Build Coastguard Worker public: 272*38e8c45fSAndroid Build Coastguard Worker LegacyVelocityTrackerStrategy(); 273*38e8c45fSAndroid Build Coastguard Worker ~LegacyVelocityTrackerStrategy() override; 274*38e8c45fSAndroid Build Coastguard Worker 275*38e8c45fSAndroid Build Coastguard Worker std::optional<float> getVelocity(int32_t pointerId) const override; 276*38e8c45fSAndroid Build Coastguard Worker 277*38e8c45fSAndroid Build Coastguard Worker private: 278*38e8c45fSAndroid Build Coastguard Worker // Oldest sample to consider when calculating the velocity. 279*38e8c45fSAndroid Build Coastguard Worker static const nsecs_t HORIZON = 200 * 1000000; // 100 ms 280*38e8c45fSAndroid Build Coastguard Worker 281*38e8c45fSAndroid Build Coastguard Worker // The minimum duration between samples when estimating velocity. 282*38e8c45fSAndroid Build Coastguard Worker static const nsecs_t MIN_DURATION = 10 * 1000000; // 10 ms 283*38e8c45fSAndroid Build Coastguard Worker }; 284*38e8c45fSAndroid Build Coastguard Worker 285*38e8c45fSAndroid Build Coastguard Worker class ImpulseVelocityTrackerStrategy : public AccumulatingVelocityTrackerStrategy { 286*38e8c45fSAndroid Build Coastguard Worker public: 287*38e8c45fSAndroid Build Coastguard Worker ImpulseVelocityTrackerStrategy(bool deltaValues); 288*38e8c45fSAndroid Build Coastguard Worker ~ImpulseVelocityTrackerStrategy() override; 289*38e8c45fSAndroid Build Coastguard Worker 290*38e8c45fSAndroid Build Coastguard Worker std::optional<float> getVelocity(int32_t pointerId) const override; 291*38e8c45fSAndroid Build Coastguard Worker 292*38e8c45fSAndroid Build Coastguard Worker private: 293*38e8c45fSAndroid Build Coastguard Worker // Sample horizon. 294*38e8c45fSAndroid Build Coastguard Worker // We don't use too much history by default since we want to react to quick 295*38e8c45fSAndroid Build Coastguard Worker // changes in direction. 296*38e8c45fSAndroid Build Coastguard Worker static constexpr nsecs_t HORIZON = 100 * 1000000; // 100 ms 297*38e8c45fSAndroid Build Coastguard Worker 298*38e8c45fSAndroid Build Coastguard Worker // Whether or not the input movement values for the strategy come in the form of delta values. 299*38e8c45fSAndroid Build Coastguard Worker // If the input values are not deltas, the strategy needs to calculate deltas as part of its 300*38e8c45fSAndroid Build Coastguard Worker // velocity calculation. 301*38e8c45fSAndroid Build Coastguard Worker const bool mDeltaValues; 302*38e8c45fSAndroid Build Coastguard Worker }; 303*38e8c45fSAndroid Build Coastguard Worker 304*38e8c45fSAndroid Build Coastguard Worker } // namespace android 305