summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java97
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/Stroke.java10
3 files changed, 77 insertions, 40 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java b/packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java
index 649279dac285..c83c74f69f90 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java
@@ -28,12 +28,10 @@ import java.util.ArrayList;
public class ClassifierData {
private SparseArray<Stroke> mCurrentStrokes = new SparseArray<>();
private ArrayList<Stroke> mEndingStrokes = new ArrayList<>();
- private float mXdpi;
- private float mYdpi;
+ private final float mDpi;
- public ClassifierData(float xdpi, float ydpi) {
- mXdpi = xdpi;
- mYdpi = ydpi;
+ public ClassifierData(float dpi) {
+ mDpi = dpi;
}
public void update(MotionEvent event) {
@@ -46,7 +44,7 @@ public class ClassifierData {
for (int i = 0; i < event.getPointerCount(); i++) {
int id = event.getPointerId(i);
if (mCurrentStrokes.get(id) == null) {
- mCurrentStrokes.put(id, new Stroke(event.getEventTimeNano(), mXdpi, mYdpi));
+ mCurrentStrokes.put(id, new Stroke(event.getEventTimeNano(), mDpi));
}
mCurrentStrokes.get(id).addPoint(event.getX(i), event.getY(i),
event.getEventTimeNano());
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
index 595a476c82dc..0e45ac19469a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java
@@ -23,8 +23,10 @@ import android.os.Build;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.DisplayMetrics;
import android.view.MotionEvent;
+import java.util.ArrayDeque;
import java.util.ArrayList;
/**
@@ -32,6 +34,7 @@ import java.util.ArrayList;
*/
public class HumanInteractionClassifier extends Classifier {
private static final String HIC_ENABLE = "HIC_enable";
+ private static final float FINGER_DISTANCE = 0.1f;
private static HumanInteractionClassifier sInstance = null;
private final Handler mHandler = new Handler();
@@ -39,11 +42,13 @@ public class HumanInteractionClassifier extends Classifier {
private ArrayList<StrokeClassifier> mStrokeClassifiers = new ArrayList<>();
private ArrayList<GestureClassifier> mGestureClassifiers = new ArrayList<>();
+ private ArrayDeque<MotionEvent> mBufferedEvents = new ArrayDeque<>();
private final int mStrokeClassifiersSize;
private final int mGestureClassifiersSize;
+ private final float mDpi;
private HistoryEvaluator mHistoryEvaluator;
- private boolean mEnableClassifier = false;
+ private boolean mEnableClassifier = true;
private int mCurrentType = Classifier.GENERIC;
protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
@@ -55,8 +60,13 @@ public class HumanInteractionClassifier extends Classifier {
private HumanInteractionClassifier(Context context) {
mContext = context;
- mClassifierData = new ClassifierData(mContext.getResources().getDisplayMetrics().xdpi,
- mContext.getResources().getDisplayMetrics().ydpi);
+ DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+
+ // If the phone is rotated to landscape, the calculations would be wrong if xdpi and ydpi
+ // were to be used separately. Due negligible differences in xdpi and ydpi we can just
+ // take the average.
+ mDpi = (displayMetrics.xdpi + displayMetrics.ydpi) / 2.0f;
+ mClassifierData = new ClassifierData(mDpi);
mHistoryEvaluator = new HistoryEvaluator();
mStrokeClassifiers.add(new AnglesVarianceClassifier(mClassifierData));
@@ -101,40 +111,71 @@ public class HumanInteractionClassifier extends Classifier {
@Override
public void onTouchEvent(MotionEvent event) {
- if (mEnableClassifier) {
- mClassifierData.update(event);
+ if (!mEnableClassifier) {
+ return;
+ }
- for (int i = 0; i < mStrokeClassifiersSize; i++) {
- mStrokeClassifiers.get(i).onTouchEvent(event);
+ // If the user is dragging down the notification, he might want to drag it down
+ // enough to see the content, read it for a while and then lift the finger to open
+ // the notification. This kind of motion scores very bad in the Classifier so the
+ // MotionEvents which are close to the current position of the finger are not
+ // sent to the classifiers until the finger moves far enough. When the finger if lifted
+ // up, the last MotionEvent which was far enough from the finger is set as the final
+ // MotionEvent and sent to the Classifiers.
+ if (mCurrentType == Classifier.NOTIFICATION_DRAG_DOWN) {
+ mBufferedEvents.add(MotionEvent.obtain(event));
+ Point pointEnd = new Point(event.getX() / mDpi, event.getY() / mDpi);
+
+ while (pointEnd.dist(new Point(mBufferedEvents.getFirst().getX() / mDpi,
+ mBufferedEvents.getFirst().getY() / mDpi)) > FINGER_DISTANCE) {
+ addTouchEvent(mBufferedEvents.getFirst());
+ mBufferedEvents.remove();
}
- for (int i = 0; i < mGestureClassifiersSize; i++) {
- mGestureClassifiers.get(i).onTouchEvent(event);
+ int action = event.getActionMasked();
+ if (action == MotionEvent.ACTION_UP) {
+ mBufferedEvents.getFirst().setAction(MotionEvent.ACTION_UP);
+ addTouchEvent(mBufferedEvents.getFirst());
+ mBufferedEvents.clear();
}
+ } else {
+ addTouchEvent(event);
+ }
+ }
- int size = mClassifierData.getEndingStrokes().size();
- for (int i = 0; i < size; i++) {
- Stroke stroke = mClassifierData.getEndingStrokes().get(i);
- float evaluation = 0.0f;
- for (int j = 0; j < mStrokeClassifiersSize; j++) {
- evaluation += mStrokeClassifiers.get(j).getFalseTouchEvaluation(
- mCurrentType, stroke);
- }
- mHistoryEvaluator.addStroke(evaluation);
- }
+ private void addTouchEvent(MotionEvent event) {
+ mClassifierData.update(event);
- int action = event.getActionMasked();
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- float evaluation = 0.0f;
- for (int i = 0; i < mGestureClassifiersSize; i++) {
- evaluation += mGestureClassifiers.get(i).getFalseTouchEvaluation(mCurrentType);
- }
- mHistoryEvaluator.addGesture(evaluation);
- setType(Classifier.GENERIC);
+ for (int i = 0; i < mStrokeClassifiersSize; i++) {
+ mStrokeClassifiers.get(i).onTouchEvent(event);
+ }
+
+ for (int i = 0; i < mGestureClassifiersSize; i++) {
+ mGestureClassifiers.get(i).onTouchEvent(event);
+ }
+
+ int size = mClassifierData.getEndingStrokes().size();
+ for (int i = 0; i < size; i++) {
+ Stroke stroke = mClassifierData.getEndingStrokes().get(i);
+ float evaluation = 0.0f;
+ for (int j = 0; j < mStrokeClassifiersSize; j++) {
+ evaluation += mStrokeClassifiers.get(j).getFalseTouchEvaluation(
+ mCurrentType, stroke);
}
+ mHistoryEvaluator.addStroke(evaluation);
+ }
- mClassifierData.cleanUp(event);
+ int action = event.getActionMasked();
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+ float evaluation = 0.0f;
+ for (int i = 0; i < mGestureClassifiersSize; i++) {
+ evaluation += mGestureClassifiers.get(i).getFalseTouchEvaluation(mCurrentType);
+ }
+ mHistoryEvaluator.addGesture(evaluation);
+ setType(Classifier.GENERIC);
}
+
+ mClassifierData.cleanUp(event);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Stroke.java b/packages/SystemUI/src/com/android/systemui/classifier/Stroke.java
index 49e6fb8b62c9..fb04d3e73a2d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/Stroke.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/Stroke.java
@@ -29,18 +29,16 @@ public class Stroke {
private long mStartTimeNano;
private long mEndTimeNano;
private float mLength;
- private float mXdpi;
- private float mYdpi;
+ private final float mDpi;
- public Stroke(long eventTimeNano, float xdpi, float ydpi) {
- mXdpi = xdpi;
- mYdpi = ydpi;
+ public Stroke(long eventTimeNano, float dpi) {
+ mDpi = dpi;
mStartTimeNano = mEndTimeNano = eventTimeNano;
}
public void addPoint(float x, float y, long eventTimeNano) {
mEndTimeNano = eventTimeNano;
- Point point = new Point(x / mXdpi, y / mYdpi, eventTimeNano - mStartTimeNano);
+ Point point = new Point(x / mDpi, y / mDpi, eventTimeNano - mStartTimeNano);
if (!mPoints.isEmpty()) {
mLength += mPoints.get(mPoints.size() - 1).dist(point);
}