1/* 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#define LOG_TAG "VelocityControl" 18//#define LOG_NDEBUG 0 19 20// Log debug messages about acceleration. 21#define DEBUG_ACCELERATION 0 22 23#include <math.h> 24#include <limits.h> 25 26#include <input/VelocityControl.h> 27#include <utils/BitSet.h> 28#include <utils/Timers.h> 29 30namespace android { 31 32// --- VelocityControl --- 33 34const nsecs_t VelocityControl::STOP_TIME; 35 36VelocityControl::VelocityControl() { 37 reset(); 38} 39 40void VelocityControl::setParameters(const VelocityControlParameters& parameters) { 41 mParameters = parameters; 42 reset(); 43} 44 45void VelocityControl::reset() { 46 mLastMovementTime = LLONG_MIN; 47 mRawPosition.x = 0; 48 mRawPosition.y = 0; 49 mVelocityTracker.clear(); 50} 51 52void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) { 53 if ((deltaX && *deltaX) || (deltaY && *deltaY)) { 54 if (eventTime >= mLastMovementTime + STOP_TIME) { 55#if DEBUG_ACCELERATION 56 ALOGD("VelocityControl: stopped, last movement was %0.3fms ago", 57 (eventTime - mLastMovementTime) * 0.000001f); 58#endif 59 reset(); 60 } 61 62 mLastMovementTime = eventTime; 63 if (deltaX) { 64 mRawPosition.x += *deltaX; 65 } 66 if (deltaY) { 67 mRawPosition.y += *deltaY; 68 } 69 mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition); 70 71 float vx, vy; 72 float scale = mParameters.scale; 73 if (mVelocityTracker.getVelocity(0, &vx, &vy)) { 74 float speed = hypotf(vx, vy) * scale; 75 if (speed >= mParameters.highThreshold) { 76 // Apply full acceleration above the high speed threshold. 77 scale *= mParameters.acceleration; 78 } else if (speed > mParameters.lowThreshold) { 79 // Linearly interpolate the acceleration to apply between the low and high 80 // speed thresholds. 81 scale *= 1 + (speed - mParameters.lowThreshold) 82 / (mParameters.highThreshold - mParameters.lowThreshold) 83 * (mParameters.acceleration - 1); 84 } 85 86#if DEBUG_ACCELERATION 87 ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): " 88 "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f", 89 mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 90 mParameters.acceleration, 91 vx, vy, speed, scale / mParameters.scale); 92#endif 93 } else { 94#if DEBUG_ACCELERATION 95 ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity", 96 mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 97 mParameters.acceleration); 98#endif 99 } 100 101 if (deltaX) { 102 *deltaX *= scale; 103 } 104 if (deltaY) { 105 *deltaY *= scale; 106 } 107 } 108} 109 110} // namespace android 111