Reland "Conform to 1D VelocityTracker" (--try 2)
b7977568d002dbb9400e7004edf9cc64b4f6f470
Topic for the revert which is being rolled-forward: https://googleplex-android-review.git.corp.google.com/q/topic:revert-19762050-generic_vt-XWGGUQUHYR
Bug: 32830165
Test: android.view.cts.VelocityTrackerTest unaffected; touch fling works
Change-Id: Ifc1e5c3efa06656609ea2021b93706026165af8e
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 2d4da2c..a52fc75 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -180,9 +180,9 @@
private static native void nativeClear(long ptr);
private static native void nativeAddMovement(long ptr, MotionEvent event);
private static native void nativeComputeCurrentVelocity(long ptr, int units, float maxVelocity);
- private static native float nativeGetXVelocity(long ptr, int id);
- private static native float nativeGetYVelocity(long ptr, int id);
- private static native boolean nativeGetEstimator(long ptr, int id, Estimator outEstimator);
+ private static native float nativeGetVelocity(long ptr, int axis, int id);
+ private static native boolean nativeGetEstimator(
+ long ptr, int axis, int id, Estimator outEstimator);
static {
// Strategy string and IDs mapping lookup.
@@ -361,7 +361,7 @@
* @return The previously computed X velocity.
*/
public float getXVelocity() {
- return nativeGetXVelocity(mPtr, ACTIVE_POINTER_ID);
+ return getXVelocity(ACTIVE_POINTER_ID);
}
/**
@@ -371,7 +371,7 @@
* @return The previously computed Y velocity.
*/
public float getYVelocity() {
- return nativeGetYVelocity(mPtr, ACTIVE_POINTER_ID);
+ return getYVelocity(ACTIVE_POINTER_ID);
}
/**
@@ -382,7 +382,7 @@
* @return The previously computed X velocity.
*/
public float getXVelocity(int id) {
- return nativeGetXVelocity(mPtr, id);
+ return nativeGetVelocity(mPtr, MotionEvent.AXIS_X, id);
}
/**
@@ -393,7 +393,7 @@
* @return The previously computed Y velocity.
*/
public float getYVelocity(int id) {
- return nativeGetYVelocity(mPtr, id);
+ return nativeGetVelocity(mPtr, MotionEvent.AXIS_Y, id);
}
/**
@@ -403,6 +403,8 @@
* It is not necessary to call {@link #computeCurrentVelocity(int)} before calling
* this method.
*
+ * @param axis Which axis's velocity to return.
+ * Should be one of the axes defined in {@link MotionEvent}.
* @param id Which pointer's velocity to return.
* @param outEstimator The estimator to populate.
* @return True if an estimator was obtained, false if there is no information
@@ -410,11 +412,11 @@
*
* @hide For internal use only. Not a final API.
*/
- public boolean getEstimator(int id, Estimator outEstimator) {
+ public boolean getEstimator(int axis, int id, Estimator outEstimator) {
if (outEstimator == null) {
throw new IllegalArgumentException("outEstimator must not be null");
}
- return nativeGetEstimator(mPtr, id, outEstimator);
+ return nativeGetEstimator(mPtr, axis, id, outEstimator);
}
/**
@@ -434,16 +436,9 @@
private static final int MAX_DEGREE = 4;
/**
- * Polynomial coefficients describing motion in X.
+ * Polynomial coefficients describing motion.
*/
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public final float[] xCoeff = new float[MAX_DEGREE + 1];
-
- /**
- * Polynomial coefficients describing motion in Y.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public final float[] yCoeff = new float[MAX_DEGREE + 1];
+ public final float[] coeff = new float[MAX_DEGREE + 1];
/**
* Polynomial degree, or zero if only position information is available.
@@ -458,39 +453,21 @@
public float confidence;
/**
- * Gets an estimate of the X position of the pointer at the specified time point.
+ * Gets an estimate of the position of the pointer at the specified time point.
* @param time The time point in seconds, 0 is the last recorded time.
- * @return The estimated X coordinate.
+ * @return The estimated axis value.
*/
- public float estimateX(float time) {
- return estimate(time, xCoeff);
+ public float estimate(float time) {
+ return estimate(time, coeff);
}
/**
- * Gets an estimate of the Y position of the pointer at the specified time point.
- * @param time The time point in seconds, 0 is the last recorded time.
- * @return The estimated Y coordinate.
- */
- public float estimateY(float time) {
- return estimate(time, yCoeff);
- }
-
- /**
- * Gets the X coefficient with the specified index.
+ * Gets the coefficient with the specified index.
* @param index The index of the coefficient to return.
- * @return The X coefficient, or 0 if the index is greater than the degree.
+ * @return The coefficient, or 0 if the index is greater than the degree.
*/
- public float getXCoeff(int index) {
- return index <= degree ? xCoeff[index] : 0;
- }
-
- /**
- * Gets the Y coefficient with the specified index.
- * @param index The index of the coefficient to return.
- * @return The Y coefficient, or 0 if the index is greater than the degree.
- */
- public float getYCoeff(int index) {
- return index <= degree ? yCoeff[index] : 0;
+ public float getCoeff(int index) {
+ return index <= degree ? coeff[index] : 0;
}
private float estimate(float time, float[] c) {
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 9ee9b82..80d50ff 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -90,8 +90,10 @@
private float mBoundingBottom;
// Position estimator.
- private VelocityTracker.Estimator mEstimator = new VelocityTracker.Estimator();
- private VelocityTracker.Estimator mAltEstimator = new VelocityTracker.Estimator();
+ private VelocityTracker.Estimator mEstimatorX = new VelocityTracker.Estimator();
+ private VelocityTracker.Estimator mAltEstimatorX = new VelocityTracker.Estimator();
+ private VelocityTracker.Estimator mEstimatorY = new VelocityTracker.Estimator();
+ private VelocityTracker.Estimator mAltEstimatorY = new VelocityTracker.Estimator();
@UnsupportedAppUsage
public PointerState() {
@@ -679,11 +681,13 @@
ps.addTrace(coords.x, coords.y, true);
ps.mXVelocity = mVelocity.getXVelocity(id);
ps.mYVelocity = mVelocity.getYVelocity(id);
- mVelocity.getEstimator(id, ps.mEstimator);
+ mVelocity.getEstimator(MotionEvent.AXIS_X, id, ps.mEstimatorX);
+ mVelocity.getEstimator(MotionEvent.AXIS_Y, id, ps.mEstimatorY);
if (mAltVelocity != null) {
ps.mAltXVelocity = mAltVelocity.getXVelocity(id);
ps.mAltYVelocity = mAltVelocity.getYVelocity(id);
- mAltVelocity.getEstimator(id, ps.mAltEstimator);
+ mAltVelocity.getEstimator(MotionEvent.AXIS_X, id, ps.mAltEstimatorX);
+ mAltVelocity.getEstimator(MotionEvent.AXIS_Y, id, ps.mAltEstimatorY);
}
ps.mToolType = event.getToolType(i);
diff --git a/core/jni/android_view_VelocityTracker.cpp b/core/jni/android_view_VelocityTracker.cpp
index 46bd682..16b9f00 100644
--- a/core/jni/android_view_VelocityTracker.cpp
+++ b/core/jni/android_view_VelocityTracker.cpp
@@ -32,8 +32,7 @@
static const int ACTIVE_POINTER_ID = -1;
static struct {
- jfieldID xCoeff;
- jfieldID yCoeff;
+ jfieldID coeff;
jfieldID degree;
jfieldID confidence;
} gEstimatorClassInfo;
@@ -47,28 +46,22 @@
void clear();
void addMovement(const MotionEvent* event);
+ // TODO(b/32830165): consider supporting an overload that supports computing velocity only for
+ // a subset of the supported axes.
void computeCurrentVelocity(int32_t units, float maxVelocity);
- void getVelocity(int32_t id, float* outVx, float* outVy);
- bool getEstimator(int32_t id, VelocityTracker::Estimator* outEstimator);
+ float getVelocity(int32_t axis, int32_t id);
+ bool getEstimator(int32_t axis, int32_t id, VelocityTracker::Estimator* outEstimator);
private:
- struct Velocity {
- float vx, vy;
- };
-
VelocityTracker mVelocityTracker;
- int32_t mActivePointerId;
- BitSet32 mCalculatedIdBits;
- Velocity mCalculatedVelocity[MAX_POINTERS];
+ VelocityTracker::ComputedVelocity mComputedVelocity;
};
VelocityTrackerState::VelocityTrackerState(const VelocityTracker::Strategy strategy)
- : mVelocityTracker(strategy), mActivePointerId(-1) {}
+ : mVelocityTracker(strategy) {}
void VelocityTrackerState::clear() {
mVelocityTracker.clear();
- mActivePointerId = -1;
- mCalculatedIdBits.clear();
}
void VelocityTrackerState::addMovement(const MotionEvent* event) {
@@ -76,61 +69,20 @@
}
void VelocityTrackerState::computeCurrentVelocity(int32_t units, float maxVelocity) {
- BitSet32 idBits(mVelocityTracker.getCurrentPointerIdBits());
- mCalculatedIdBits = idBits;
-
- for (uint32_t index = 0; !idBits.isEmpty(); index++) {
- uint32_t id = idBits.clearFirstMarkedBit();
-
- float vx, vy;
- mVelocityTracker.getVelocity(id, &vx, &vy);
-
- vx = vx * units / 1000;
- vy = vy * units / 1000;
-
- if (vx > maxVelocity) {
- vx = maxVelocity;
- } else if (vx < -maxVelocity) {
- vx = -maxVelocity;
- }
- if (vy > maxVelocity) {
- vy = maxVelocity;
- } else if (vy < -maxVelocity) {
- vy = -maxVelocity;
- }
-
- Velocity& velocity = mCalculatedVelocity[index];
- velocity.vx = vx;
- velocity.vy = vy;
- }
+ mComputedVelocity = mVelocityTracker.getComputedVelocity(units, maxVelocity);
}
-void VelocityTrackerState::getVelocity(int32_t id, float* outVx, float* outVy) {
+float VelocityTrackerState::getVelocity(int32_t axis, int32_t id) {
if (id == ACTIVE_POINTER_ID) {
id = mVelocityTracker.getActivePointerId();
}
- float vx, vy;
- if (id >= 0 && id <= MAX_POINTER_ID && mCalculatedIdBits.hasBit(id)) {
- uint32_t index = mCalculatedIdBits.getIndexOfBit(id);
- const Velocity& velocity = mCalculatedVelocity[index];
- vx = velocity.vx;
- vy = velocity.vy;
- } else {
- vx = 0;
- vy = 0;
- }
-
- if (outVx) {
- *outVx = vx;
- }
- if (outVy) {
- *outVy = vy;
- }
+ return mComputedVelocity.getVelocity(axis, id).value_or(0);
}
-bool VelocityTrackerState::getEstimator(int32_t id, VelocityTracker::Estimator* outEstimator) {
- return mVelocityTracker.getEstimator(id, outEstimator);
+bool VelocityTrackerState::getEstimator(int32_t axis, int32_t id,
+ VelocityTracker::Estimator* outEstimator) {
+ return mVelocityTracker.getEstimator(axis, id, outEstimator);
}
// Return a strategy enum from integer value.
@@ -177,37 +129,25 @@
state->computeCurrentVelocity(units, maxVelocity);
}
-static jfloat android_view_VelocityTracker_nativeGetXVelocity(JNIEnv* env, jclass clazz,
- jlong ptr, jint id) {
+static jfloat android_view_VelocityTracker_nativeGetVelocity(JNIEnv* env, jclass clazz, jlong ptr,
+ jint axis, jint id) {
VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
- float vx;
- state->getVelocity(id, &vx, NULL);
- return vx;
-}
-
-static jfloat android_view_VelocityTracker_nativeGetYVelocity(JNIEnv* env, jclass clazz,
- jlong ptr, jint id) {
- VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
- float vy;
- state->getVelocity(id, NULL, &vy);
- return vy;
+ return state->getVelocity(axis, id);
}
static jboolean android_view_VelocityTracker_nativeGetEstimator(JNIEnv* env, jclass clazz,
- jlong ptr, jint id, jobject outEstimatorObj) {
+ jlong ptr, jint axis, jint id,
+ jobject outEstimatorObj) {
VelocityTrackerState* state = reinterpret_cast<VelocityTrackerState*>(ptr);
VelocityTracker::Estimator estimator;
- bool result = state->getEstimator(id, &estimator);
- jfloatArray xCoeffObj = jfloatArray(env->GetObjectField(outEstimatorObj,
- gEstimatorClassInfo.xCoeff));
- jfloatArray yCoeffObj = jfloatArray(env->GetObjectField(outEstimatorObj,
- gEstimatorClassInfo.yCoeff));
+ bool result = state->getEstimator(axis, id, &estimator);
- env->SetFloatArrayRegion(xCoeffObj, 0, VelocityTracker::Estimator::MAX_DEGREE + 1,
- estimator.xCoeff);
- env->SetFloatArrayRegion(yCoeffObj, 0, VelocityTracker::Estimator::MAX_DEGREE + 1,
- estimator.yCoeff);
+ jfloatArray coeffObj =
+ jfloatArray(env->GetObjectField(outEstimatorObj, gEstimatorClassInfo.coeff));
+
+ env->SetFloatArrayRegion(coeffObj, 0, VelocityTracker::Estimator::MAX_DEGREE + 1,
+ estimator.coeff);
env->SetIntField(outEstimatorObj, gEstimatorClassInfo.degree, estimator.degree);
env->SetFloatField(outEstimatorObj, gEstimatorClassInfo.confidence, estimator.confidence);
return result;
@@ -224,9 +164,8 @@
(void*)android_view_VelocityTracker_nativeAddMovement},
{"nativeComputeCurrentVelocity", "(JIF)V",
(void*)android_view_VelocityTracker_nativeComputeCurrentVelocity},
- {"nativeGetXVelocity", "(JI)F", (void*)android_view_VelocityTracker_nativeGetXVelocity},
- {"nativeGetYVelocity", "(JI)F", (void*)android_view_VelocityTracker_nativeGetYVelocity},
- {"nativeGetEstimator", "(JILandroid/view/VelocityTracker$Estimator;)Z",
+ {"nativeGetVelocity", "(JII)F", (void*)android_view_VelocityTracker_nativeGetVelocity},
+ {"nativeGetEstimator", "(JIILandroid/view/VelocityTracker$Estimator;)Z",
(void*)android_view_VelocityTracker_nativeGetEstimator},
};
@@ -236,8 +175,7 @@
jclass clazz = FindClassOrDie(env, "android/view/VelocityTracker$Estimator");
- gEstimatorClassInfo.xCoeff = GetFieldIDOrDie(env, clazz, "xCoeff", "[F");
- gEstimatorClassInfo.yCoeff = GetFieldIDOrDie(env, clazz, "yCoeff", "[F");
+ gEstimatorClassInfo.coeff = GetFieldIDOrDie(env, clazz, "coeff", "[F");
gEstimatorClassInfo.degree = GetFieldIDOrDie(env, clazz, "degree", "I");
gEstimatorClassInfo.confidence = GetFieldIDOrDie(env, clazz, "confidence", "F");