Prevent entries with identical times
Currently, VelocityTracker adds all MotionEvents with actions DOWN,
MOVE, and POINTER_DOWN. But sometimes these events can have identical
timestamps, for example MOVE and the following POINTER_DOWN.
This breaks algorithms that rely on computing differences between
times of the events. If the difference is zero, and division is
performed, then very large numbers can result from this.
Bug: 129797752
Test: atest libinput_tests
Change-Id: I843fd9efbdbf786ab7aa5ed62b4e1395ae7cf335
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index 42d774e..c6cc4fc 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -382,7 +382,16 @@
void LeastSquaresVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
const VelocityTracker::Position* positions) {
- if (++mIndex == HISTORY_SIZE) {
+ if (mMovements[mIndex].eventTime != eventTime) {
+ // When ACTION_POINTER_DOWN happens, we will first receive ACTION_MOVE with the coordinates
+ // of the existing pointers, and then ACTION_POINTER_DOWN with the coordinates that include
+ // the new pointer. If the eventtimes for both events are identical, just update the data
+ // for this time.
+ // We only compare against the last value, as it is likely that addMovement is called
+ // in chronological order as events occur.
+ mIndex++;
+ }
+ if (mIndex == HISTORY_SIZE) {
mIndex = 0;
}
@@ -1017,7 +1026,16 @@
void ImpulseVelocityTrackerStrategy::addMovement(nsecs_t eventTime, BitSet32 idBits,
const VelocityTracker::Position* positions) {
- if (++mIndex == HISTORY_SIZE) {
+ if (mMovements[mIndex].eventTime != eventTime) {
+ // When ACTION_POINTER_DOWN happens, we will first receive ACTION_MOVE with the coordinates
+ // of the existing pointers, and then ACTION_POINTER_DOWN with the coordinates that include
+ // the new pointer. If the eventtimes for both events are identical, just update the data
+ // for this time.
+ // We only compare against the last value, as it is likely that addMovement is called
+ // in chronological order as events occur.
+ mIndex++;
+ }
+ if (mIndex == HISTORY_SIZE) {
mIndex = 0;
}