Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90729403 authored by Jeff Brown's avatar Jeff Brown
Browse files

Detect when pointer has stopped moving.

Some input devices do not generate ACTION_MOVE events while all
pointers have stopped, thereby lulling the VelocityTracker into
a false sense of complacency.  Before handling the following sample,
reset the VelocityTracker state so as not to be influenced by
earlier samples before the pointer stopped.  The velocity after
stopping is assumed to be discontinuous.

Bug: 6413587
Change-Id: I6387bc036ff141d083d3d17a89e37eeaa3188349
parent dcab190b
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ public:
    struct Estimator {
        static const size_t MAX_DEGREE = 2;

        // Estimator time base.
        nsecs_t time;

        // Polynomial coefficients describing motion in X and Y.
        float xCoeff[MAX_DEGREE + 1], yCoeff[MAX_DEGREE + 1];

@@ -48,6 +51,7 @@ public:
        float confidence;

        inline void clear() {
            time = 0;
            degree = 0;
            confidence = 0;
            for (size_t i = 0; i <= MAX_DEGREE; i++) {
@@ -58,7 +62,6 @@ public:
    };

    VelocityTracker();
    VelocityTracker(VelocityTrackerStrategy* strategy);
    ~VelocityTracker();

    // Resets the velocity tracker state.
@@ -96,6 +99,7 @@ public:
    inline BitSet32 getCurrentPointerIdBits() const { return mCurrentPointerIdBits; }

private:
    nsecs_t mLastEventTime;
    BitSet32 mCurrentPointerIdBits;
    int32_t mActivePointerId;
    VelocityTrackerStrategy* mStrategy;
+25 −6
Original line number Diff line number Diff line
@@ -33,6 +33,16 @@

namespace android {

// Nanoseconds per milliseconds.
static const nsecs_t NANOS_PER_MS = 1000000;

// Threshold for determining that a pointer has stopped moving.
// Some input devices do not send ACTION_MOVE events in the case where a pointer has
// stopped.  We need to detect this case so that we can accurately predict the
// velocity after the pointer starts moving again.
static const nsecs_t ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS;


static float vectorDot(const float* a, const float* b, uint32_t m) {
    float r = 0;
    while (m--) {
@@ -89,15 +99,10 @@ static String8 matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMa
// --- VelocityTracker ---

VelocityTracker::VelocityTracker() :
        mCurrentPointerIdBits(0), mActivePointerId(-1),
        mLastEventTime(0), mCurrentPointerIdBits(0), mActivePointerId(-1),
        mStrategy(new LeastSquaresVelocityTrackerStrategy()) {
}

VelocityTracker::VelocityTracker(VelocityTrackerStrategy* strategy) :
        mCurrentPointerIdBits(0), mActivePointerId(-1),
        mStrategy(strategy) {
}

VelocityTracker::~VelocityTracker() {
    delete mStrategy;
}
@@ -125,6 +130,18 @@ void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Posi
        idBits.clearLastMarkedBit();
    }

    if ((mCurrentPointerIdBits.value & idBits.value)
            && eventTime >= mLastEventTime + ASSUME_POINTER_STOPPED_TIME) {
#if DEBUG_VELOCITY
        ALOGD("VelocityTracker: stopped for %0.3f ms, clearing state.",
                (eventTime - mLastEventTime) * 0.000001f);
#endif
        // We have not received any movements for too long.  Assume that all pointers
        // have stopped.
        mStrategy->clear();
    }
    mLastEventTime = eventTime;

    mCurrentPointerIdBits = idBits;
    if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) {
        mActivePointerId = idBits.isEmpty() ? -1 : idBits.firstMarkedBit();
@@ -467,6 +484,7 @@ bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
        uint32_t n = degree + 1;
        if (solveLeastSquares(time, x, m, n, outEstimator->xCoeff, &xdet)
                && solveLeastSquares(time, y, m, n, outEstimator->yCoeff, &ydet)) {
            outEstimator->time = newestMovement.eventTime;
            outEstimator->degree = degree;
            outEstimator->confidence = xdet * ydet;
#if DEBUG_LEAST_SQUARES
@@ -483,6 +501,7 @@ bool LeastSquaresVelocityTrackerStrategy::getEstimator(uint32_t id,
    // No velocity data available for this pointer, but we do have its current position.
    outEstimator->xCoeff[0] = x[0];
    outEstimator->yCoeff[0] = y[0];
    outEstimator->time = newestMovement.eventTime;
    outEstimator->degree = 0;
    outEstimator->confidence = 1;
    return true;