Revert "Check whether pointer has stopped at liftoff"
This reverts commit 456acaae9592985f6424cd244c55de9982537f42.
Test: not tested, this is a revert
Bug: 236335820
Reason for revert: breaks NumberPickerTest
Change-Id: I9b1e2002c51e96c52b7bb13f55ae1331ffb4915b
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index 76aaf61..7f427f2 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -27,8 +27,6 @@
#include <utils/BitSet.h>
#include <utils/Timers.h>
-using std::literals::chrono_literals::operator""ms;
-
namespace android {
/**
@@ -59,14 +57,8 @@
// 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 std::chrono::duration ASSUME_POINTER_STOPPED_TIME = 40ms;
+static const nsecs_t ASSUME_POINTER_STOPPED_TIME = 40 * NANOS_PER_MS;
-static std::string toString(std::chrono::nanoseconds t) {
- std::stringstream stream;
- stream.precision(1);
- stream << std::fixed << std::chrono::duration<float, std::milli>(t).count() << " ms";
- return stream.str();
-}
static float vectorDot(const float* a, const float* b, uint32_t m) {
float r = 0;
@@ -154,14 +146,18 @@
VelocityTracker::Strategy strategy) {
switch (strategy) {
case VelocityTracker::Strategy::IMPULSE:
- ALOGI_IF(DEBUG_STRATEGY, "Initializing impulse strategy");
+ if (DEBUG_STRATEGY) {
+ ALOGI("Initializing impulse strategy");
+ }
return std::make_unique<ImpulseVelocityTrackerStrategy>();
case VelocityTracker::Strategy::LSQ1:
return std::make_unique<LeastSquaresVelocityTrackerStrategy>(1);
case VelocityTracker::Strategy::LSQ2:
- ALOGI_IF(DEBUG_STRATEGY && !DEBUG_IMPULSE, "Initializing lsq2 strategy");
+ if (DEBUG_STRATEGY && !DEBUG_IMPULSE) {
+ ALOGI("Initializing lsq2 strategy");
+ }
return std::make_unique<LeastSquaresVelocityTrackerStrategy>(2);
case VelocityTracker::Strategy::LSQ3:
@@ -225,11 +221,12 @@
idBits.clearLastMarkedBit();
}
- if ((mCurrentPointerIdBits.value & idBits.value) &&
- std::chrono::nanoseconds(eventTime - mLastEventTime) > ASSUME_POINTER_STOPPED_TIME) {
- ALOGD_IF(DEBUG_VELOCITY, "VelocityTracker: stopped for %s, clearing state.",
- toString(std::chrono::nanoseconds(eventTime - mLastEventTime)).c_str());
-
+ 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);
+ }
// We have not received any movements for too long. Assume that all pointers
// have stopped.
mStrategy->clear();
@@ -284,18 +281,8 @@
case AMOTION_EVENT_ACTION_MOVE:
case AMOTION_EVENT_ACTION_HOVER_MOVE:
break;
- case AMOTION_EVENT_ACTION_POINTER_UP:
- case AMOTION_EVENT_ACTION_UP: {
- std::chrono::nanoseconds delaySinceLastEvent(event->getEventTime() - mLastEventTime);
- if (delaySinceLastEvent > ASSUME_POINTER_STOPPED_TIME) {
- ALOGD_IF(DEBUG_VELOCITY,
- "VelocityTracker: stopped for %s, clearing state upon pointer liftoff.",
- toString(delaySinceLastEvent).c_str());
- // We have not received any movements for too long. Assume that all pointers
- // have stopped.
- mStrategy->clear();
- }
- // These actions because they do not convey any new information about
+ default:
+ // Ignore all other actions because they do not convey any new information about
// pointer movement. We also want to preserve the last known velocity of the pointers.
// Note that ACTION_UP and ACTION_POINTER_UP always report the last known position
// of the pointers that went up. ACTION_POINTER_UP does include the new position of
@@ -305,10 +292,6 @@
// before adding the movement.
return;
}
- default:
- // Ignore all other actions.
- return;
- }
size_t pointerCount = event->getPointerCount();
if (pointerCount > MAX_POINTERS) {
@@ -455,10 +438,10 @@
static bool solveLeastSquares(const std::vector<float>& x, const std::vector<float>& y,
const std::vector<float>& w, uint32_t n, float* outB, float* outDet) {
const size_t m = x.size();
-
- ALOGD_IF(DEBUG_STRATEGY, "solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
- vectorToString(x).c_str(), vectorToString(y).c_str(), vectorToString(w).c_str());
-
+ if (DEBUG_STRATEGY) {
+ ALOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s, w=%s", int(m), int(n),
+ vectorToString(x).c_str(), vectorToString(y).c_str(), vectorToString(w).c_str());
+ }
LOG_ALWAYS_FATAL_IF(m != y.size() || m != w.size(), "Mismatched vector sizes");
// Expand the X vector to a matrix A, pre-multiplied by the weights.
@@ -469,9 +452,9 @@
a[i][h] = a[i - 1][h] * x[h];
}
}
-
- ALOGD_IF(DEBUG_STRATEGY, " - a=%s",
- matrixToString(&a[0][0], m, n, false /*rowMajor*/).c_str());
+ if (DEBUG_STRATEGY) {
+ ALOGD(" - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).c_str());
+ }
// Apply the Gram-Schmidt process to A to obtain its QR decomposition.
float q[n][m]; // orthonormal basis, column-major order
@@ -490,7 +473,9 @@
float norm = vectorNorm(&q[j][0], m);
if (norm < 0.000001f) {
// vectors are linearly dependent or zero so no solution
- ALOGD_IF(DEBUG_STRATEGY, " - no solution, norm=%f", norm);
+ if (DEBUG_STRATEGY) {
+ ALOGD(" - no solution, norm=%f", norm);
+ }
return false;
}
@@ -533,8 +518,9 @@
}
outB[i] /= r[i][i];
}
-
- ALOGD_IF(DEBUG_STRATEGY, " - b=%s", vectorToString(outB, n).c_str());
+ if (DEBUG_STRATEGY) {
+ ALOGD(" - b=%s", vectorToString(outB, n).c_str());
+ }
// Calculate the coefficient of determination as 1 - (SSerr / SStot) where
// SSerr is the residual sum of squares (variance of the error),
@@ -560,11 +546,11 @@
sstot += w[h] * w[h] * var * var;
}
*outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1;
-
- ALOGD_IF(DEBUG_STRATEGY, " - sserr=%f", sserr);
- ALOGD_IF(DEBUG_STRATEGY, " - sstot=%f", sstot);
- ALOGD_IF(DEBUG_STRATEGY, " - det=%f", *outDet);
-
+ if (DEBUG_STRATEGY) {
+ ALOGD(" - sserr=%f", sserr);
+ ALOGD(" - sstot=%f", sstot);
+ ALOGD(" - det=%f", *outDet);
+ }
return true;
}
@@ -687,11 +673,11 @@
outEstimator->time = newestMovement.eventTime;
outEstimator->degree = degree;
outEstimator->confidence = xdet * ydet;
-
- ALOGD_IF(DEBUG_STRATEGY, "estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
- int(outEstimator->degree), vectorToString(outEstimator->xCoeff, n).c_str(),
- vectorToString(outEstimator->yCoeff, n).c_str(), outEstimator->confidence);
-
+ if (DEBUG_STRATEGY) {
+ ALOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f",
+ int(outEstimator->degree), vectorToString(outEstimator->xCoeff, n).c_str(),
+ vectorToString(outEstimator->yCoeff, n).c_str(), outEstimator->confidence);
+ }
return true;
}
}
@@ -1199,10 +1185,9 @@
outEstimator->time = newestMovement.eventTime;
outEstimator->degree = 2; // similar results to 2nd degree fit
outEstimator->confidence = 1;
-
- ALOGD_IF(DEBUG_STRATEGY, "velocity: (%.1f, %.1f)", outEstimator->xCoeff[1],
- outEstimator->yCoeff[1]);
-
+ if (DEBUG_STRATEGY) {
+ ALOGD("velocity: (%.1f, %.1f)", outEstimator->xCoeff[1], outEstimator->yCoeff[1]);
+ }
if (DEBUG_IMPULSE) {
// TODO(b/134179997): delete this block once the switch to 'impulse' is complete.
// Calculate the lsq2 velocity for the same inputs to allow runtime comparisons
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index 4a445de..a87b187 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -26,9 +26,7 @@
#include <gui/constants.h>
#include <input/VelocityTracker.h>
-using std::literals::chrono_literals::operator""ms;
-using std::literals::chrono_literals::operator""ns;
-using std::literals::chrono_literals::operator""us;
+using namespace std::chrono_literals;
using android::base::StringPrintf;
namespace android {
@@ -151,7 +149,8 @@
if (i == 0) {
action = AMOTION_EVENT_ACTION_DOWN;
EXPECT_EQ(1U, pointerCount) << "First event should only have 1 pointer";
- } else if ((i == motions.size() - 1) && pointerCount == 1) {
+ } else if (i == motions.size() - 1) {
+ EXPECT_EQ(1U, pointerCount) << "Last event should only have 1 pointer";
action = AMOTION_EVENT_ACTION_UP;
} else {
const MotionEventEntry& previousEntry = motions[i-1];
@@ -196,7 +195,7 @@
static void computeAndCheckVelocity(const VelocityTracker::Strategy strategy,
const std::vector<MotionEventEntry>& motions, int32_t axis,
- float targetVelocity, uint32_t pointerId = DEFAULT_POINTER_ID) {
+ float targetVelocity) {
VelocityTracker vt(strategy);
float Vx, Vy;
@@ -205,7 +204,7 @@
vt.addMovement(&event);
}
- vt.getVelocity(pointerId, &Vx, &Vy);
+ vt.getVelocity(DEFAULT_POINTER_ID, &Vx, &Vy);
switch (axis) {
case AMOTION_EVENT_AXIS_X:
@@ -847,71 +846,13 @@
// Velocity should actually be zero, but we expect 0.016 here instead.
// This is close enough to zero, and is likely caused by division by a very small number.
- computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_X, 0);
- computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_Y, 0);
+ computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_X, -0.016);
+ computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_Y, -0.016);
computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X, 0);
computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_Y, 0);
}
/**
- * ================= Pointer liftoff ===============================================================
- */
-
-/**
- * The last movement of a pointer is always ACTION_POINTER_UP or ACTION_UP. If there's a short delay
- * between the last ACTION_MOVE and the next ACTION_POINTER_UP or ACTION_UP, velocity should not be
- * affected by the liftoff.
- */
-TEST_F(VelocityTrackerTest, ShortDelayBeforeActionUp) {
- std::vector<MotionEventEntry> motions = {
- {0ms, {{10, 0}}}, {10ms, {{20, 0}}}, {20ms, {{30, 0}}}, {30ms, {{30, 0}}}, // ACTION_UP
- };
- computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X,
- 1000);
- computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_X, 1000);
-}
-
-/**
- * The last movement of a single pointer is ACTION_UP. If there's a long delay between the last
- * ACTION_MOVE and the final ACTION_UP, velocity should be reported as zero because the pointer
- * should be assumed to have stopped.
- */
-TEST_F(VelocityTrackerTest, LongDelayBeforeActionUp) {
- std::vector<MotionEventEntry> motions = {
- {0ms, {{10, 0}}},
- {10ms, {{20, 0}}},
- {20ms, {{30, 0}}},
- {3000ms, {{30, 0}}}, // ACTION_UP
- };
- computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X, 0);
- computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_X, 0);
-}
-
-/**
- * The last movement of a pointer is always ACTION_POINTER_UP or ACTION_UP. If there's a long delay
- * before ACTION_POINTER_UP event, the movement should be assumed to have stopped.
- * The final velocity should be reported as zero for all pointers.
- */
-TEST_F(VelocityTrackerTest, LongDelayBeforeActionPointerUp) {
- std::vector<MotionEventEntry> motions = {
- {0ms, {{10, 0}}},
- {10ms, {{20, 0}, {100, 0}}},
- {20ms, {{30, 0}, {200, 0}}},
- {30ms, {{30, 0}, {300, 0}}},
- {40ms, {{30, 0}, {400, 0}}},
- {3000ms, {{30, 0}}}, // ACTION_POINTER_UP
- };
- computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X, 0,
- /*pointerId*/ 0);
- computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_X, 0,
- /*pointerId*/ 0);
- computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X, 0,
- /*pointerId*/ 1);
- computeAndCheckVelocity(VelocityTracker::Strategy::LSQ2, motions, AMOTION_EVENT_AXIS_X, 0,
- /*pointerId*/ 1);
-}
-
-/**
* ================== Tests for least squares fitting ==============================================
*
* Special care must be taken when constructing tests for LeastSquaresVelocityTrackerStrategy