xref: /aosp_15_r20/frameworks/native/include/input/VelocityControl.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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 <vector>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <input/AccelerationCurve.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <input/Input.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <input/VelocityTracker.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h>
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker using android::base::StringPrintf;
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker namespace android {
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker /*
32*38e8c45fSAndroid Build Coastguard Worker  * Specifies parameters that govern pointer or wheel acceleration.
33*38e8c45fSAndroid Build Coastguard Worker  */
34*38e8c45fSAndroid Build Coastguard Worker struct VelocityControlParameters {
35*38e8c45fSAndroid Build Coastguard Worker     // A scale factor that is multiplied with the raw velocity deltas
36*38e8c45fSAndroid Build Coastguard Worker     // prior to applying any other velocity control factors.  The scale
37*38e8c45fSAndroid Build Coastguard Worker     // factor should be used to adapt the input device resolution
38*38e8c45fSAndroid Build Coastguard Worker     // (eg. counts per inch) to the output device resolution (eg. pixels per inch).
39*38e8c45fSAndroid Build Coastguard Worker     //
40*38e8c45fSAndroid Build Coastguard Worker     // Must be a positive value.
41*38e8c45fSAndroid Build Coastguard Worker     // Default is 1.0 (no scaling).
42*38e8c45fSAndroid Build Coastguard Worker     float scale;
43*38e8c45fSAndroid Build Coastguard Worker 
44*38e8c45fSAndroid Build Coastguard Worker     // The scaled speed at which acceleration begins to be applied.
45*38e8c45fSAndroid Build Coastguard Worker     // This value establishes the upper bound of a low speed regime for
46*38e8c45fSAndroid Build Coastguard Worker     // small precise motions that are performed without any acceleration.
47*38e8c45fSAndroid Build Coastguard Worker     //
48*38e8c45fSAndroid Build Coastguard Worker     // Must be a non-negative value.
49*38e8c45fSAndroid Build Coastguard Worker     // Default is 0.0 (no low threshold).
50*38e8c45fSAndroid Build Coastguard Worker     float lowThreshold;
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker     // The scaled speed at which maximum acceleration is applied.
53*38e8c45fSAndroid Build Coastguard Worker     // The difference between highThreshold and lowThreshold controls
54*38e8c45fSAndroid Build Coastguard Worker     // the range of speeds over which the acceleration factor is interpolated.
55*38e8c45fSAndroid Build Coastguard Worker     // The wider the range, the smoother the acceleration.
56*38e8c45fSAndroid Build Coastguard Worker     //
57*38e8c45fSAndroid Build Coastguard Worker     // Must be a non-negative value greater than or equal to lowThreshold.
58*38e8c45fSAndroid Build Coastguard Worker     // Default is 0.0 (no high threshold).
59*38e8c45fSAndroid Build Coastguard Worker     float highThreshold;
60*38e8c45fSAndroid Build Coastguard Worker 
61*38e8c45fSAndroid Build Coastguard Worker     // The acceleration factor.
62*38e8c45fSAndroid Build Coastguard Worker     // When the speed is above the low speed threshold, the velocity will scaled
63*38e8c45fSAndroid Build Coastguard Worker     // by an interpolated value between 1.0 and this amount.
64*38e8c45fSAndroid Build Coastguard Worker     //
65*38e8c45fSAndroid Build Coastguard Worker     // Must be a positive greater than or equal to 1.0.
66*38e8c45fSAndroid Build Coastguard Worker     // Default is 1.0 (no acceleration).
67*38e8c45fSAndroid Build Coastguard Worker     float acceleration;
68*38e8c45fSAndroid Build Coastguard Worker 
VelocityControlParametersVelocityControlParameters69*38e8c45fSAndroid Build Coastguard Worker     VelocityControlParameters() :
70*38e8c45fSAndroid Build Coastguard Worker             scale(1.0f), lowThreshold(0.0f), highThreshold(0.0f), acceleration(1.0f) {
71*38e8c45fSAndroid Build Coastguard Worker     }
72*38e8c45fSAndroid Build Coastguard Worker 
VelocityControlParametersVelocityControlParameters73*38e8c45fSAndroid Build Coastguard Worker     VelocityControlParameters(float scale, float lowThreshold,
74*38e8c45fSAndroid Build Coastguard Worker             float highThreshold, float acceleration) :
75*38e8c45fSAndroid Build Coastguard Worker             scale(scale), lowThreshold(lowThreshold),
76*38e8c45fSAndroid Build Coastguard Worker             highThreshold(highThreshold), acceleration(acceleration) {
77*38e8c45fSAndroid Build Coastguard Worker     }
78*38e8c45fSAndroid Build Coastguard Worker 
dumpVelocityControlParameters79*38e8c45fSAndroid Build Coastguard Worker     std::string dump() const {
80*38e8c45fSAndroid Build Coastguard Worker         return StringPrintf("scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, "
81*38e8c45fSAndroid Build Coastguard Worker                             "acceleration=%0.3f\n",
82*38e8c45fSAndroid Build Coastguard Worker                             scale, lowThreshold, highThreshold, acceleration);
83*38e8c45fSAndroid Build Coastguard Worker     }
84*38e8c45fSAndroid Build Coastguard Worker };
85*38e8c45fSAndroid Build Coastguard Worker 
86*38e8c45fSAndroid Build Coastguard Worker /*
87*38e8c45fSAndroid Build Coastguard Worker  * Implements mouse pointer and wheel speed control and acceleration.
88*38e8c45fSAndroid Build Coastguard Worker  */
89*38e8c45fSAndroid Build Coastguard Worker class VelocityControl {
90*38e8c45fSAndroid Build Coastguard Worker public:
91*38e8c45fSAndroid Build Coastguard Worker     VelocityControl();
~VelocityControl()92*38e8c45fSAndroid Build Coastguard Worker     virtual ~VelocityControl() {}
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker     /* Resets the current movement counters to zero.
95*38e8c45fSAndroid Build Coastguard Worker      * This has the effect of nullifying any acceleration. */
96*38e8c45fSAndroid Build Coastguard Worker     void reset();
97*38e8c45fSAndroid Build Coastguard Worker 
98*38e8c45fSAndroid Build Coastguard Worker     /* Translates a raw movement delta into an appropriately
99*38e8c45fSAndroid Build Coastguard Worker      * scaled / accelerated delta based on the current velocity. */
100*38e8c45fSAndroid Build Coastguard Worker     void move(nsecs_t eventTime, float* deltaX, float* deltaY);
101*38e8c45fSAndroid Build Coastguard Worker 
102*38e8c45fSAndroid Build Coastguard Worker protected:
103*38e8c45fSAndroid Build Coastguard Worker     virtual void scaleDeltas(float* deltaX, float* deltaY) = 0;
104*38e8c45fSAndroid Build Coastguard Worker 
105*38e8c45fSAndroid Build Coastguard Worker     // If no movements are received within this amount of time,
106*38e8c45fSAndroid Build Coastguard Worker     // we assume the movement has stopped and reset the movement counters.
107*38e8c45fSAndroid Build Coastguard Worker     static const nsecs_t STOP_TIME = 500 * 1000000; // 500 ms
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker     nsecs_t mLastMovementTime;
110*38e8c45fSAndroid Build Coastguard Worker     float mRawPositionX, mRawPositionY;
111*38e8c45fSAndroid Build Coastguard Worker     VelocityTracker mVelocityTracker;
112*38e8c45fSAndroid Build Coastguard Worker };
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker /**
115*38e8c45fSAndroid Build Coastguard Worker  * Velocity control using a simple acceleration curve where the acceleration factor increases
116*38e8c45fSAndroid Build Coastguard Worker  * linearly with movement speed, subject to minimum and maximum values.
117*38e8c45fSAndroid Build Coastguard Worker  */
118*38e8c45fSAndroid Build Coastguard Worker class SimpleVelocityControl : public VelocityControl {
119*38e8c45fSAndroid Build Coastguard Worker public:
120*38e8c45fSAndroid Build Coastguard Worker     /** Gets the various parameters. */
121*38e8c45fSAndroid Build Coastguard Worker     const VelocityControlParameters& getParameters() const;
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker     /** Sets the various parameters. */
124*38e8c45fSAndroid Build Coastguard Worker     void setParameters(const VelocityControlParameters& parameters);
125*38e8c45fSAndroid Build Coastguard Worker 
126*38e8c45fSAndroid Build Coastguard Worker protected:
127*38e8c45fSAndroid Build Coastguard Worker     virtual void scaleDeltas(float* deltaX, float* deltaY) override;
128*38e8c45fSAndroid Build Coastguard Worker 
129*38e8c45fSAndroid Build Coastguard Worker private:
130*38e8c45fSAndroid Build Coastguard Worker     VelocityControlParameters mParameters;
131*38e8c45fSAndroid Build Coastguard Worker };
132*38e8c45fSAndroid Build Coastguard Worker 
133*38e8c45fSAndroid Build Coastguard Worker /** Velocity control using a curve made up of multiple reciprocal segments. */
134*38e8c45fSAndroid Build Coastguard Worker class CurvedVelocityControl : public VelocityControl {
135*38e8c45fSAndroid Build Coastguard Worker public:
136*38e8c45fSAndroid Build Coastguard Worker     CurvedVelocityControl();
137*38e8c45fSAndroid Build Coastguard Worker 
138*38e8c45fSAndroid Build Coastguard Worker     /** Sets the curve to be used for acceleration. */
139*38e8c45fSAndroid Build Coastguard Worker     void setCurve(const std::vector<AccelerationCurveSegment>& curve);
140*38e8c45fSAndroid Build Coastguard Worker 
141*38e8c45fSAndroid Build Coastguard Worker     void setAccelerationEnabled(bool enabled);
142*38e8c45fSAndroid Build Coastguard Worker 
143*38e8c45fSAndroid Build Coastguard Worker protected:
144*38e8c45fSAndroid Build Coastguard Worker     virtual void scaleDeltas(float* deltaX, float* deltaY) override;
145*38e8c45fSAndroid Build Coastguard Worker 
146*38e8c45fSAndroid Build Coastguard Worker private:
147*38e8c45fSAndroid Build Coastguard Worker     const AccelerationCurveSegment& segmentForSpeed(float speedMmPerS);
148*38e8c45fSAndroid Build Coastguard Worker 
149*38e8c45fSAndroid Build Coastguard Worker     bool mAccelerationEnabled = true;
150*38e8c45fSAndroid Build Coastguard Worker     std::vector<AccelerationCurveSegment> mCurveSegments;
151*38e8c45fSAndroid Build Coastguard Worker };
152*38e8c45fSAndroid Build Coastguard Worker 
153*38e8c45fSAndroid Build Coastguard Worker } // namespace android
154