Home | History | Annotate | Download | only in input
      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 
     30 namespace android {
     31 
     32 // --- VelocityControl ---
     33 
     34 const nsecs_t VelocityControl::STOP_TIME;
     35 
     36 VelocityControl::VelocityControl() {
     37     reset();
     38 }
     39 
     40 void VelocityControl::setParameters(const VelocityControlParameters& parameters) {
     41     mParameters = parameters;
     42     reset();
     43 }
     44 
     45 void VelocityControl::reset() {
     46     mLastMovementTime = LLONG_MIN;
     47     mRawPosition.x = 0;
     48     mRawPosition.y = 0;
     49     mVelocityTracker.clear();
     50 }
     51 
     52 void 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