Merge "Ignore the closing MotionEvent of swipe gestures for falsing" into tm-qpr-dev
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index bc0f995..f83885b 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -38,6 +38,7 @@
public class FalsingDataProvider {
private static final long MOTION_EVENT_AGE_MS = 1000;
+ private static final long DROP_EVENT_THRESHOLD_MS = 50;
private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
private final int mWidthPixels;
@@ -60,6 +61,7 @@
private float mAngle = 0;
private MotionEvent mFirstRecentMotionEvent;
private MotionEvent mLastMotionEvent;
+ private boolean mDropLastEvent;
private boolean mJustUnlockedWithFace;
private boolean mA11YAction;
@@ -95,6 +97,12 @@
// Ensure prior gesture was completed. May be a no-op.
completePriorGesture();
}
+
+ // Drop the gesture closing event if it is close in time to a previous ACTION_MOVE event.
+ // The reason is that the closing ACTION_UP event of a swipe can be a bit offseted from the
+ // previous ACTION_MOVE event and when it happens, it makes some classifiers fail.
+ mDropLastEvent = shouldDropEvent(motionEvent);
+
mRecentMotionEvents.addAll(motionEvents);
FalsingClassifier.logVerbose("Size: " + mRecentMotionEvents.size());
@@ -129,6 +137,7 @@
mPriorMotionEvents = mRecentMotionEvents;
mRecentMotionEvents = new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
}
+ mDropLastEvent = false;
mA11YAction = false;
}
@@ -150,8 +159,18 @@
return mYdpi;
}
+ /**
+ * Get the {@link MotionEvent}s of the most recent gesture.
+ *
+ * Note that this list may not include the last recorded event.
+ * @see #mDropLastEvent
+ */
public List<MotionEvent> getRecentMotionEvents() {
- return mRecentMotionEvents;
+ if (!mDropLastEvent || mRecentMotionEvents.isEmpty()) {
+ return mRecentMotionEvents;
+ } else {
+ return mRecentMotionEvents.subList(0, mRecentMotionEvents.size() - 1);
+ }
}
public List<MotionEvent> getPriorMotionEvents() {
@@ -169,7 +188,12 @@
return mFirstRecentMotionEvent;
}
- /** Get the last recorded {@link MotionEvent}. */
+ /**
+ * Get the last {@link MotionEvent} of the most recent gesture.
+ *
+ * Note that this may be the event prior to the last recorded event.
+ * @see #mDropLastEvent
+ */
public MotionEvent getLastMotionEvent() {
recalculateData();
return mLastMotionEvent;
@@ -236,12 +260,13 @@
return;
}
- if (mRecentMotionEvents.isEmpty()) {
+ List<MotionEvent> recentMotionEvents = getRecentMotionEvents();
+ if (recentMotionEvents.isEmpty()) {
mFirstRecentMotionEvent = null;
mLastMotionEvent = null;
} else {
- mFirstRecentMotionEvent = mRecentMotionEvents.get(0);
- mLastMotionEvent = mRecentMotionEvents.get(mRecentMotionEvents.size() - 1);
+ mFirstRecentMotionEvent = recentMotionEvents.get(0);
+ mLastMotionEvent = recentMotionEvents.get(recentMotionEvents.size() - 1);
}
calculateAngleInternal();
@@ -249,6 +274,17 @@
mDirty = false;
}
+ private boolean shouldDropEvent(MotionEvent event) {
+ if (mRecentMotionEvents.size() < 3) return false;
+
+ MotionEvent lastEvent = mRecentMotionEvents.get(mRecentMotionEvents.size() - 1);
+ boolean isCompletingGesture = event.getActionMasked() == MotionEvent.ACTION_UP
+ && lastEvent.getActionMasked() == MotionEvent.ACTION_MOVE;
+ boolean isRecentEvent =
+ event.getEventTime() - lastEvent.getEventTime() < DROP_EVENT_THRESHOLD_MS;
+ return isCompletingGesture && isRecentEvent;
+ }
+
private void calculateAngleInternal() {
if (mRecentMotionEvents.size() < 2) {
mAngle = Float.MAX_VALUE;
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
index e5da389..addd8e2 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
@@ -183,7 +183,7 @@
@Override
public List<MotionEvent> subList(int fromIndex, int toIndex) {
- throw new UnsupportedOperationException();
+ return mMotionEvents.subList(fromIndex, toIndex);
}
class Iter implements ListIterator<MotionEvent> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
index faa5db4..ab6d5b7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DistanceClassifierTest.java
@@ -94,7 +94,9 @@
mClassifier.onTouchEvent(appendMoveEvent(1, 16, 3));
mClassifier.onTouchEvent(appendMoveEvent(1, 17, 300));
mClassifier.onTouchEvent(appendMoveEvent(1, 18, 301));
- mClassifier.onTouchEvent(appendUpEvent(1, 19, 501));
+ mClassifier.onTouchEvent(appendMoveEvent(1, 19, 501));
+ mClassifier.onTouchEvent(appendUpEvent(1, 19, 501)); //event will be dropped
+
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index 2edc3d3..8eadadf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -75,16 +75,17 @@
}
@Test
- public void test_trackMotionEvents() {
+ public void test_trackMotionEvents_dropUpEvent() {
mDataProvider.onMotionEvent(appendDownEvent(2, 9));
mDataProvider.onMotionEvent(appendMoveEvent(4, 7));
- mDataProvider.onMotionEvent(appendUpEvent(6, 5));
+ mDataProvider.onMotionEvent(appendMoveEvent(6, 5));
+ mDataProvider.onMotionEvent(appendUpEvent(0, 0)); // event will be dropped
List<MotionEvent> motionEventList = mDataProvider.getRecentMotionEvents();
assertThat(motionEventList.size()).isEqualTo(3);
assertThat(motionEventList.get(0).getActionMasked()).isEqualTo(MotionEvent.ACTION_DOWN);
assertThat(motionEventList.get(1).getActionMasked()).isEqualTo(MotionEvent.ACTION_MOVE);
- assertThat(motionEventList.get(2).getActionMasked()).isEqualTo(MotionEvent.ACTION_UP);
+ assertThat(motionEventList.get(2).getActionMasked()).isEqualTo(MotionEvent.ACTION_MOVE);
assertThat(motionEventList.get(0).getEventTime()).isEqualTo(1L);
assertThat(motionEventList.get(1).getEventTime()).isEqualTo(2L);
assertThat(motionEventList.get(2).getEventTime()).isEqualTo(3L);
@@ -97,6 +98,28 @@
}
@Test
+ public void test_trackMotionEvents_keepUpEvent() {
+ mDataProvider.onMotionEvent(appendDownEvent(2, 9));
+ mDataProvider.onMotionEvent(appendMoveEvent(4, 7));
+ mDataProvider.onMotionEvent(appendUpEvent(0, 0, 100));
+ List<MotionEvent> motionEventList = mDataProvider.getRecentMotionEvents();
+
+ assertThat(motionEventList.size()).isEqualTo(3);
+ assertThat(motionEventList.get(0).getActionMasked()).isEqualTo(MotionEvent.ACTION_DOWN);
+ assertThat(motionEventList.get(1).getActionMasked()).isEqualTo(MotionEvent.ACTION_MOVE);
+ assertThat(motionEventList.get(2).getActionMasked()).isEqualTo(MotionEvent.ACTION_UP);
+ assertThat(motionEventList.get(0).getEventTime()).isEqualTo(1L);
+ assertThat(motionEventList.get(1).getEventTime()).isEqualTo(2L);
+ assertThat(motionEventList.get(2).getEventTime()).isEqualTo(100);
+ assertThat(motionEventList.get(0).getX()).isEqualTo(2f);
+ assertThat(motionEventList.get(1).getX()).isEqualTo(4f);
+ assertThat(motionEventList.get(2).getX()).isEqualTo(0f);
+ assertThat(motionEventList.get(0).getY()).isEqualTo(9f);
+ assertThat(motionEventList.get(1).getY()).isEqualTo(7f);
+ assertThat(motionEventList.get(2).getY()).isEqualTo(0f);
+ }
+
+ @Test
public void test_trackRecentMotionEvents() {
mDataProvider.onMotionEvent(appendDownEvent(2, 9, 1));
mDataProvider.onMotionEvent(appendMoveEvent(4, 7, 800));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
index c343c20..ae2b8bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ZigZagClassifierTest.java
@@ -68,6 +68,15 @@
}
@Test
+ public void testPass_dropClosingUpEvent() {
+ appendMoveEvent(0, 0);
+ appendMoveEvent(0, 100);
+ appendMoveEvent(0, 200);
+ appendUpEvent(0, 180); // this event would push us over the maxDevianceY
+ assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
+ }
+
+ @Test
public void testPass_fewTouchesHorizontal() {
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
appendMoveEvent(0, 0);