Add timestamps to predicted events
Following the behavior of the original prediction library, the
predicted events did not contain the down event or event time.
However, this information can be useful when computing the strokes.
This CL also removes a path that would add predictions if it was
not possible to provide as many predictions as requested.
Bug: 283093719
Test: added logging to the sample app to monitor the data, and
the timestamps are correctly populated
Relnote: "Predicted motion events now report the correct down and event time"
Change-Id: I400595643e50e8cdd5c2686df65ce4cd7965b598
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java
index 3f02764..f091db8 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/MultiPointerPredictor.java
@@ -123,9 +123,6 @@
pointerIds[i] = mPredictorMap.keyAt(i);
SinglePointerPredictor predictor = mPredictorMap.valueAt(i);
singlePointerEvents[i] = predictor.predict(predictionTargetMs);
- // If predictor consumer expect more sample, generate sample where position and
- // pressure are constant
- singlePointerEvents[i] = predictor.appendPredictedEvent(singlePointerEvents[i]);
}
// Compute minimal history size for every predicted single pointer MotionEvent
diff --git a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
index 74dfc7c..093ecd9 100644
--- a/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
+++ b/input/input-motionprediction/src/main/java/androidx/input/motionprediction/kalman/SinglePointerPredictor.java
@@ -67,6 +67,7 @@
private final DVector2 mLastPosition = new DVector2();
private long mPrevEventTime;
+ private long mDownEventTime;
private List<Float> mReportRates = new LinkedList<>();
private int mExpectedPredictionSampleSize = -1;
private float mReportRateMs = 0;
@@ -97,11 +98,13 @@
public SinglePointerPredictor() {
mKalman.reset();
mPrevEventTime = 0;
+ mDownEventTime = 0;
}
void initStrokePrediction(int pointerId, int toolType) {
mKalman.reset();
mPrevEventTime = 0;
+ mDownEventTime = 0;
mPointerId = pointerId;
mToolType = toolType;
}
@@ -173,6 +176,9 @@
event));
return false;
}
+
+ mDownEventTime = event.getDownTime();
+
for (BatchedMotionEvent ev : BatchedMotionEvent.iterate(event)) {
MotionEvent.PointerCoords pointerCoords = ev.coords[pointerIndex];
update(pointerCoords.x, pointerCoords.y, pointerCoords.pressure,
@@ -226,6 +232,7 @@
predictionTargetInSamples = mExpectedPredictionSampleSize;
}
+ long nextPredictedEventTime = mPrevEventTime + Math.round(mReportRateMs);
int i = 0;
for (; i < predictionTargetInSamples; i++) {
mAcceleration.a1 += mJank.a1 * JANK_INFLUENCE;
@@ -252,8 +259,8 @@
if (predictedEvent == null) {
predictedEvent =
MotionEvent.obtain(
- 0 /* downTime */,
- 0 /* eventTime */,
+ mDownEventTime /* downTime */,
+ nextPredictedEventTime /* eventTime */,
MotionEvent.ACTION_MOVE /* action */,
1 /* pointerCount */,
pointerProperties /* pointer properties */,
@@ -267,8 +274,9 @@
0 /* source */,
0 /* flags */);
} else {
- predictedEvent.addBatch(0, coords, 0);
+ predictedEvent.addBatch(nextPredictedEventTime, coords, 0);
}
+ nextPredictedEventTime += Math.round(mReportRateMs);
}
return predictedEvent;