Add more logging for falsing.

Makes the FalsingManager slightly less stateful (passing the
interaction type directly to the classifiers as needed). It also
includes more logging than we had before, listing all the failed
classifiers for a gesture, along with the HistoryTracker's
belief and confidence.

Logs are now delayed one gesture. Instead of immediately logging when
a falsing call is made, it waits until the gesture is marked as
complete. This confers two advantages:

1) If multiple calls to #isFalseGesture (and similar) are made, we
   don't log multiple times. We only log the result once.

2) It allows us to log the effects on the HistoryTracker, as that only
   updates itself when the gesture is marked as completed.

Bug: 172655679
Test: atest SystemUITests && manual
Change-Id: I653ac2abb03a91ff000b46075e58137b04226023
This commit is contained in:
Dave Mankoff
2021-03-17 13:31:34 -04:00
parent fa304e1f71
commit 4124a204c6
24 changed files with 336 additions and 370 deletions

View File

@@ -109,7 +109,7 @@ public class KeyguardPatternViewController
// Treat single-sized patterns as erroneous taps.
if (pattern.size() == 1) {
mFalsingCollector.updateFalseConfidence(FalsingClassifier.Result.falsed(
0.7, "empty pattern input"));
0.7, getClass().getSimpleName(), "empty pattern input"));
}
mLockPatternView.enableInput();
onPatternChecked(userId, false, 0, false /* not valid - too short */);

View File

@@ -42,7 +42,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Queue;
import java.util.Set;
import java.util.StringJoiner;
@@ -94,9 +93,17 @@ public class BrightLineFalsingManager implements FalsingManager {
}
};
private final BeliefListener mBeliefListener = belief -> {
if (belief > FALSE_BELIEF_THRESHOLD) {
mFalsingBeliefListeners.forEach(FalsingBeliefListener::onFalse);
private final BeliefListener mBeliefListener = new BeliefListener() {
@Override
public void onBeliefChanged(double belief) {
logInfo(String.format(
"{belief=%s confidence=%s}",
mHistoryTracker.falseBelief(),
mHistoryTracker.falseConfidence()));
if (belief > FALSE_BELIEF_THRESHOLD) {
mFalsingBeliefListeners.forEach(FalsingBeliefListener::onFalse);
logInfo("Triggering False Event (Threshold: " + FALSE_BELIEF_THRESHOLD + ")");
}
}
};
@@ -105,13 +112,23 @@ public class BrightLineFalsingManager implements FalsingManager {
@Override
public void onGestureComplete(long completionTimeMs) {
if (mPriorResults != null) {
mPriorResults.forEach(result -> {
if (result.isFalse()) {
String reason = result.getReason();
if (reason != null) {
logInfo(reason);
}
}
});
mHistoryTracker.addResults(mPriorResults, completionTimeMs);
mPriorResults = null;
} else {
// Gestures that were not classified get treated as a false.
mHistoryTracker.addResults(
Collections.singleton(
FalsingClassifier.Result.falsed(.8, "unclassified")),
FalsingClassifier.Result.falsed(
.8, getClass().getSimpleName(), "unclassified")),
completionTimeMs);
}
}
@@ -154,30 +171,13 @@ public class BrightLineFalsingManager implements FalsingManager {
boolean result;
mDataProvider.setInteractionType(interactionType);
if (!mTestHarness && !mDataProvider.isJustUnlockedWithFace() && !mDockManager.isDocked()) {
Stream<FalsingClassifier.Result> results =
mClassifiers.stream().map(falsingClassifier -> {
FalsingClassifier.Result classifierResult =
falsingClassifier.classifyGesture(
mHistoryTracker.falseBelief(),
mHistoryTracker.falseConfidence());
if (classifierResult.isFalse()) {
logInfo(String.format(
(Locale) null,
"{classifier=%s, interactionType=%d}",
falsingClassifier.getClass().getName(),
mDataProvider.getInteractionType()));
String reason = classifierResult.getReason();
if (reason != null) {
logInfo(reason);
}
} else {
logDebug(falsingClassifier.getClass().getName() + ": false");
}
return classifierResult;
});
mClassifiers.stream().map(falsingClassifier ->
falsingClassifier.classifyGesture(
interactionType,
mHistoryTracker.falseBelief(),
mHistoryTracker.falseConfidence()));
mPriorResults = new ArrayList<>();
final boolean[] localResult = {false};
results.forEach(classifierResult -> {
@@ -190,13 +190,13 @@ public class BrightLineFalsingManager implements FalsingManager {
mPriorResults = Collections.singleton(FalsingClassifier.Result.passed(1));
}
logDebug("Is false touch? " + result);
logDebug("False Gesture: " + result);
if (Build.IS_ENG || Build.IS_USERDEBUG) {
// Copy motion events, as the passed in list gets emptied out elsewhere in the code.
RECENT_SWIPES.add(new DebugSwipeRecord(
result,
mDataProvider.getInteractionType(),
interactionType,
mDataProvider.getRecentMotionEvents().stream().map(
motionEvent -> new XYDt(
(int) motionEvent.getX(),
@@ -220,37 +220,36 @@ public class BrightLineFalsingManager implements FalsingManager {
FalsingClassifier.Result singleTapResult =
mSingleTapClassifier.isTap(mDataProvider.getRecentMotionEvents());
mPriorResults = Collections.singleton(singleTapResult);
if (singleTapResult.isFalse()) {
logInfo(String.format(
(Locale) null, "{classifier=%s}", mSingleTapClassifier.getClass().getName()));
String reason = singleTapResult.getReason();
if (reason != null) {
logInfo(reason);
}
return true;
}
if (robustCheck) {
if (!singleTapResult.isFalse() && robustCheck) {
if (mDataProvider.isJustUnlockedWithFace()) {
// Immediately pass if a face is detected.
mPriorResults = Collections.singleton(FalsingClassifier.Result.passed(1));
logDebug("False Single Tap: false (face detected)");
return false;
} else if (!isFalseDoubleTap()) {
// We must check double tapping before other heuristics. This is because
// the double tap will fail if there's only been one tap. We don't want that
// failure to be recorded in mPriorResults.
logDebug("False Single Tap: false (double tapped)");
return false;
} else if (mHistoryTracker.falseBelief() > TAP_CONFIDENCE_THRESHOLD) {
mPriorResults = Collections.singleton(
FalsingClassifier.Result.falsed(0, "bad history"));
FalsingClassifier.Result.falsed(
0, getClass().getSimpleName(), "bad history"));
logDebug("False Single Tap: true (bad history)");
return true;
} else {
mPriorResults = Collections.singleton(FalsingClassifier.Result.passed(0.1));
logDebug("False Single Tap: false (default)");
return false;
}
} else {
logDebug("False Single Tap: " + singleTapResult.isFalse() + " (simple)");
return singleTapResult.isFalse();
}
return false;
}
@Override
@@ -259,16 +258,12 @@ public class BrightLineFalsingManager implements FalsingManager {
return false;
}
FalsingClassifier.Result result = mDoubleTapClassifier.classifyGesture();
FalsingClassifier.Result result = mDoubleTapClassifier.classifyGesture(
Classifier.GENERIC,
mHistoryTracker.falseBelief(),
mHistoryTracker.falseConfidence());
mPriorResults = Collections.singleton(result);
if (result.isFalse()) {
logInfo(String.format(
(Locale) null, "{classifier=%s}", mDoubleTapClassifier.getClass().getName()));
String reason = result.getReason();
if (reason != null) {
logInfo(reason);
}
}
logDebug("False Double Tap: " + result.isFalse());
return result.isFalse();
}

View File

@@ -62,15 +62,16 @@ class DiagonalClassifier extends FalsingClassifier {
VERTICAL_ANGLE_RANGE);
}
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
float angle = getAngle();
if (angle == Float.MAX_VALUE) { // Unknown angle
return Result.passed(0);
}
if (getInteractionType() == LEFT_AFFORDANCE
|| getInteractionType() == RIGHT_AFFORDANCE) {
if (interactionType == LEFT_AFFORDANCE || interactionType == RIGHT_AFFORDANCE) {
return Result.passed(0);
}
@@ -86,7 +87,7 @@ class DiagonalClassifier extends FalsingClassifier {
|| angleBetween(angle, minAngle - NINETY_DEG, maxAngle - NINETY_DEG)
|| angleBetween(angle, minAngle + ONE_HUNDRED_EIGHTY_DEG,
maxAngle + ONE_HUNDRED_EIGHTY_DEG);
return falsed ? Result.falsed(0.5f, getReason()) : Result.passed(0.5);
return falsed ? falsed(0.5f, getReason()) : Result.passed(0.5);
}
private String getReason() {

View File

@@ -136,8 +136,6 @@ class DistanceClassifier extends FalsingClassifier {
float dX = getLastMotionEvent().getX() - getFirstMotionEvent().getX();
float dY = getLastMotionEvent().getY() - getFirstMotionEvent().getY();
logInfo("dX: " + dX + " dY: " + dY + " xV: " + vX + " yV: " + vY);
return new DistanceVectors(dX, dY, vX, vY);
}
@@ -147,9 +145,10 @@ class DistanceClassifier extends FalsingClassifier {
}
@Override
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
return !getPassedFlingThreshold()
? Result.falsed(0.5, getReason()) : Result.passed(0.5);
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
return !getPassedFlingThreshold() ? falsed(0.5, getReason()) : Result.passed(0.5);
}
String getReason() {
@@ -172,7 +171,7 @@ class DistanceClassifier extends FalsingClassifier {
Result isLongSwipe() {
boolean longSwipe = getPassedDistanceThreshold();
logDebug("Is longSwipe? " + longSwipe);
return longSwipe ? Result.passed(0.5) : Result.falsed(0.5, getReason());
return longSwipe ? Result.passed(0.5) : falsed(0.5, getReason());
}
private boolean getPassedDistanceThreshold() {

View File

@@ -46,18 +46,20 @@ public class DoubleTapClassifier extends FalsingClassifier {
}
@Override
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
List<MotionEvent> secondTapEvents = getRecentMotionEvents();
List<MotionEvent> firstTapEvents = getPriorMotionEvents();
StringBuilder reason = new StringBuilder();
if (firstTapEvents == null) {
return Result.falsed(0, "Only one gesture recorded");
return falsed(0, "Only one gesture recorded");
}
return !isDoubleTap(firstTapEvents, secondTapEvents, reason)
? Result.falsed(0.5, reason.toString()) : Result.passed(0.5);
? falsed(0.5, reason.toString()) : Result.passed(0.5);
}
/** Returns true if the two supplied lists of {@link MotionEvent}s look like a double-tap. */

View File

@@ -35,6 +35,14 @@ public abstract class FalsingClassifier {
mDataProvider.addMotionEventListener(mMotionEventListener);
}
protected String getFalsingContext() {
return getClass().getSimpleName();
}
protected Result falsed(double confidence, String reason) {
return Result.falsed(confidence, getFalsingContext(), reason);
}
List<MotionEvent> getRecentMotionEvents() {
return mDataProvider.getRecentMotionEvents();
}
@@ -87,10 +95,6 @@ public abstract class FalsingClassifier {
return mDataProvider.getYdpi();
}
final @Classifier.InteractionType int getInteractionType() {
return mDataProvider.getInteractionType();
}
void cleanup() {
mDataProvider.removeMotionEventListener(mMotionEventListener);
}
@@ -101,42 +105,32 @@ public abstract class FalsingClassifier {
* Useful for classifiers that need to see every MotionEvent, but most can probably
* use {@link #getRecentMotionEvents()} instead, which will return a list of MotionEvents.
*/
void onTouchEvent(MotionEvent motionEvent) {};
void onTouchEvent(MotionEvent motionEvent) {}
/**
* Called when a ProximityEvent occurs (change in near/far).
*/
void onProximityEvent(ProximitySensor.ThresholdSensorEvent proximityEvent) {};
void onProximityEvent(ProximitySensor.ThresholdSensorEvent proximityEvent) {}
/**
* The phone screen has turned on and we need to begin falsing detection.
*/
void onSessionStarted() {};
void onSessionStarted() {}
/**
* The phone screen has turned off and falsing data can be discarded.
*/
void onSessionEnded() {};
void onSessionEnded() {}
/**
* Returns whether a gesture looks like a false touch.
* Returns whether a gesture looks like a false touch, taking history into consideration.
*
* See also {@link #classifyGesture(double, double)}.
* See {@link HistoryTracker#falseBelief()} and {@link HistoryTracker#falseConfidence()}.
*/
Result classifyGesture() {
return calculateFalsingResult(0.5, 0);
}
/**
* Returns whether a gesture looks like a false touch, with the option to consider history.
*
* Unlike the parameter-less version of this method, this method allows the classifier to take
* history into account, penalizing or boosting confidence in a gesture based on recent results.
*
* See also {@link #classifyGesture()}.
*/
Result classifyGesture(double historyBelief, double historyConfidence) {
return calculateFalsingResult(historyBelief, historyConfidence);
Result classifyGesture(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
return calculateFalsingResult(interactionType, historyBelief, historyConfidence);
}
/**
@@ -144,7 +138,9 @@ public abstract class FalsingClassifier {
*
* When passed a historyConfidence of 0, the history belief should be wholly ignored.
*/
abstract Result calculateFalsingResult(double historyBelief, double historyConfidence);
abstract Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence);
/** */
public static void logDebug(String msg) {
@@ -167,14 +163,16 @@ public abstract class FalsingClassifier {
public static class Result {
private final boolean mFalsed;
private final double mConfidence;
private final String mContext;
private final String mReason;
/**
* See {@link #falsed(double, String)} abd {@link #passed(double)}.
* See {@link #falsed(double, String, String)} abd {@link #passed(double)}.
*/
private Result(boolean falsed, double confidence, String reason) {
private Result(boolean falsed, double confidence, String context, String reason) {
mFalsed = falsed;
mConfidence = confidence;
mContext = context;
mReason = reason;
}
@@ -187,21 +185,21 @@ public abstract class FalsingClassifier {
}
public String getReason() {
return mReason;
return String.format("{context=%s reason=%s}", mContext, mReason);
}
/**
* Construct a "falsed" result indicating that a gesture should be treated as accidental.
*/
public static Result falsed(double confidence, String reason) {
return new Result(true, confidence, reason);
public static Result falsed(double confidence, String context, String reason) {
return new Result(true, confidence, context, reason);
}
/**
* Construct a "passed" result indicating that a gesture should be allowed.
*/
public static Result passed(double confidence) {
return new Result(false, confidence, null);
return new Result(false, confidence, null, null);
}
}
}

View File

@@ -127,7 +127,6 @@ class FalsingCollectorImpl implements FalsingCollector {
@Override
public void onNotificationStartDraggingDown() {
updateInteractionType(Classifier.NOTIFICATION_DRAG_DOWN);
}
@Override
@@ -140,7 +139,6 @@ class FalsingCollectorImpl implements FalsingCollector {
@Override
public void onQsDown() {
updateInteractionType(Classifier.QUICK_SETTINGS);
}
@Override
@@ -159,7 +157,6 @@ class FalsingCollectorImpl implements FalsingCollector {
@Override
public void onTrackingStarted(boolean secure) {
updateInteractionType(secure ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
}
@Override
@@ -176,8 +173,6 @@ class FalsingCollectorImpl implements FalsingCollector {
@Override
public void onAffordanceSwipingStarted(boolean rightCorner) {
updateInteractionType(
rightCorner ? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE);
}
@Override
@@ -186,7 +181,6 @@ class FalsingCollectorImpl implements FalsingCollector {
@Override
public void onStartExpandingFromPulse() {
updateInteractionType(Classifier.PULSE_EXPAND);
}
@Override
@@ -237,7 +231,6 @@ class FalsingCollectorImpl implements FalsingCollector {
@Override
public void onNotificationStartDismissing() {
updateInteractionType(Classifier.NOTIFICATION_DISMISS);
}
@Override
@@ -302,11 +295,6 @@ class FalsingCollectorImpl implements FalsingCollector {
mHistoryTracker.addResults(Collections.singleton(result), mSystemClock.uptimeMillis());
}
private void updateInteractionType(@Classifier.InteractionType int type) {
logDebug("InteractionType: " + type);
mFalsingDataProvider.setInteractionType(type);
}
private boolean shouldSessionBeActive() {
return mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
}

View File

@@ -47,8 +47,6 @@ public class FalsingDataProvider {
private final List<MotionEventListener> mMotionEventListeners = new ArrayList<>();
private final List<GestureCompleteListener> mGestureCompleteListeners = new ArrayList<>();
private @Classifier.InteractionType int mInteractionType;
private TimeLimitedMotionEventBuffer mRecentMotionEvents =
new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
private List<MotionEvent> mPriorMotionEvents;
@@ -137,21 +135,6 @@ public class FalsingDataProvider {
return mPriorMotionEvents;
}
/**
* interactionType is defined by {@link com.android.systemui.classifier.Classifier}.
*/
public final void setInteractionType(@Classifier.InteractionType int interactionType) {
if (mInteractionType != interactionType) {
mInteractionType = interactionType;
mDirty = true;
}
}
/** Return the interaction type that is being compared against for falsing. */
public final int getInteractionType() {
return mInteractionType;
}
/**
* Get the first recorded {@link MotionEvent} of the most recent gesture.
*

View File

@@ -56,14 +56,15 @@ class PointerCountClassifier extends FalsingClassifier {
}
@Override
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
int interactionType = getInteractionType();
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
int allowedPointerCount =
(interactionType == QUICK_SETTINGS || interactionType == NOTIFICATION_DRAG_DOWN)
? MAX_ALLOWED_POINTERS_SWIPE_DOWN : MAX_ALLOWED_POINTERS;
return mMaxPointerCount > allowedPointerCount
? Result.falsed(1, getReason(allowedPointerCount)) : Result.passed(0);
? falsed(1, getReason(allowedPointerCount)) : Result.passed(0);
}
private String getReason(int allowedPointerCount) {

View File

@@ -112,28 +112,31 @@ class ProximityClassifier extends FalsingClassifier {
}
@Override
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
if (getInteractionType() == QUICK_SETTINGS) {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
if (interactionType == QUICK_SETTINGS) {
return Result.passed(0);
}
logInfo("Percent of gesture in proximity: " + mPercentNear);
if (mPercentNear > mPercentCoveredThreshold) {
Result longSwipeResult = mDistanceClassifier.isLongSwipe();
return longSwipeResult.isFalse()
? Result.falsed(0.5, getReason(longSwipeResult)) : Result.passed(0.5);
? falsed(
0.5, getReason(longSwipeResult, mPercentNear, mPercentCoveredThreshold))
: Result.passed(0.5);
}
return Result.passed(0.5);
}
private String getReason(Result longSwipeResult) {
private static String getReason(Result longSwipeResult, float percentNear,
float percentCoveredThreshold) {
return String.format(
(Locale) null,
"{percentInProximity=%f, threshold=%f, distanceClassifier=%s}",
mPercentNear,
mPercentCoveredThreshold,
percentNear,
percentCoveredThreshold,
longSwipeResult.getReason());
}

View File

@@ -39,14 +39,16 @@ public class SingleTapClassifier extends FalsingClassifier {
}
@Override
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
return isTap(getRecentMotionEvents());
}
/** Given a list of {@link android.view.MotionEvent}'s, returns true if the look like a tap. */
public Result isTap(List<MotionEvent> motionEvents) {
if (motionEvents.isEmpty()) {
return Result.falsed(0, "no motion events");
return falsed(0, "no motion events");
}
float downX = motionEvents.get(0).getX();
float downY = motionEvents.get(0).getY();
@@ -58,13 +60,13 @@ public class SingleTapClassifier extends FalsingClassifier {
+ Math.abs(event.getX() - downX)
+ "vs "
+ mTouchSlop;
return Result.falsed(0.5, reason);
return falsed(0.5, reason);
} else if (Math.abs(event.getY() - downY) >= mTouchSlop) {
reason = "dY too big for a tap: "
+ Math.abs(event.getY() - downY)
+ " vs "
+ mTouchSlop;
return Result.falsed(0.5, reason);
return falsed(0.5, reason);
}
}
return Result.passed(0);

View File

@@ -38,13 +38,15 @@ public class TypeClassifier extends FalsingClassifier {
}
@Override
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
boolean vertical = isVertical();
boolean up = isUp();
boolean right = isRight();
boolean wrongDirection = true;
switch (getInteractionType()) {
switch (interactionType) {
case QUICK_SETTINGS:
case PULSE_EXPAND:
case NOTIFICATION_DRAG_DOWN:
@@ -68,10 +70,11 @@ public class TypeClassifier extends FalsingClassifier {
break;
}
return wrongDirection ? Result.falsed(1, getReason()) : Result.passed(0.5);
return wrongDirection ? falsed(1, getReason(interactionType)) : Result.passed(0.5);
}
private String getReason() {
return String.format("{vertical=%s, up=%s, right=%s}", isVertical(), isUp(), isRight());
private String getReason(int interactionType) {
return String.format("{interaction=%s, vertical=%s, up=%s, right=%s}",
interactionType, isVertical(), isUp(), isRight());
}
}

View File

@@ -84,7 +84,9 @@ class ZigZagClassifier extends FalsingClassifier {
}
@Override
Result calculateFalsingResult(double historyBelief, double historyConfidence) {
Result calculateFalsingResult(
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
List<MotionEvent> motionEvents = getRecentMotionEvents();
// Rotate horizontal gestures to be horizontal between their first and last point.
// Rotate vertical gestures to be vertical between their first and last point.
@@ -156,7 +158,7 @@ class ZigZagClassifier extends FalsingClassifier {
logDebug("Straightness Deviance: (" + devianceX + "," + devianceY + ") vs "
+ "(" + maxXDeviance + "," + maxYDeviance + ")");
return devianceX > maxXDeviance || devianceY > maxYDeviance
? Result.falsed(0.5, getReason()) : Result.passed(0.5);
? falsed(0.5, getReason()) : Result.passed(0.5);
}
private String getReason() {

View File

@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyCollection;
import static org.mockito.ArgumentMatchers.anyDouble;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -78,17 +79,21 @@ public class BrightLineClassifierTest extends SysuiTestCase {
private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
private final FalsingClassifier.Result mFalsedResult = FalsingClassifier.Result.falsed(1, "");
private final FalsingClassifier.Result mFalsedResult =
FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
private GestureCompleteListener mGestureCompleteListener;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mPassedResult);
when(mClassifierB.classifyGesture(anyDouble(), anyDouble())).thenReturn(mPassedResult);
when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
when(mClassifierB.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
when(mSingleTapClassfier.isTap(any(List.class))).thenReturn(mPassedResult);
when(mDoubleTapClassifier.classifyGesture()).thenReturn(mPassedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
mClassifiers.add(mClassifierA);
mClassifiers.add(mClassifierB);
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
@@ -131,20 +136,23 @@ public class BrightLineClassifierTest extends SysuiTestCase {
@Test
public void testIsFalseTouch_ClassifierARejects() {
when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mFalsedResult);
when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isTrue();
}
@Test
public void testIsFalseTouch_ClassifierBRejects() {
when(mClassifierB.classifyGesture(anyDouble(), anyDouble())).thenReturn(mFalsedResult);
when(mClassifierB.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isTrue();
}
@Test
public void testIsFalseTouch_FaceAuth() {
// Even when the classifiers report a false, we should allow.
when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mPassedResult);
when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
when(mFalsingDataProvider.isJustUnlockedWithFace()).thenReturn(true);
assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
@@ -153,7 +161,8 @@ public class BrightLineClassifierTest extends SysuiTestCase {
@Test
public void testIsFalseTouch_Docked() {
// Even when the classifiers report a false, we should allow.
when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mPassedResult);
when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
mDockManager.setIsDocked(true);
assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
@@ -173,7 +182,8 @@ public class BrightLineClassifierTest extends SysuiTestCase {
@Test
public void testIsFalseTap_RobustCheck_NoFaceAuth() {
when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mPassedResult);
when(mDoubleTapClassifier.classifyGesture()).thenReturn(mFalsedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
when(mHistoryTracker.falseBelief()).thenReturn(1.0);
mFalsingDataProvider.setJustUnlockedWithFace(false);
assertThat(mBrightLineFalsingManager.isFalseTap(true, 0)).isTrue();
@@ -188,11 +198,13 @@ public class BrightLineClassifierTest extends SysuiTestCase {
@Test
public void testIsFalseDoubleTap() {
when(mDoubleTapClassifier.classifyGesture()).thenReturn(mPassedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse();
when(mDoubleTapClassifier.classifyGesture()).thenReturn(mFalsedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isTrue();
}
@@ -243,13 +255,15 @@ public class BrightLineClassifierTest extends SysuiTestCase {
public void testNoFalsingUnlocked() {
when(mKeyguardStateController.isShowing()).thenReturn(false);
when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mFalsedResult);
when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mFalsedResult);
assertThat(mBrightLineFalsingManager.isFalseTap(false, 0)).isFalse();
when(mDoubleTapClassifier.classifyGesture()).thenReturn(mFalsedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse();
}
}

View File

@@ -16,8 +16,6 @@
package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.UNLOCK;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
@@ -45,7 +43,6 @@ public class ClassifierTest extends LeakCheckedTest {
displayMetrics.heightPixels = 1000;
mFakeBatteryController = new FakeBatteryController(getLeakCheck());
mDataProvider = new FalsingDataProvider(displayMetrics, mFakeBatteryController);
mDataProvider.setInteractionType(UNLOCK);
}
@After

View File

@@ -16,11 +16,12 @@
package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.GENERIC;
import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -69,106 +70,104 @@ public class DiagonalClassifierTest extends ClassifierTest {
@Test
public void testPass_UnknownAngle() {
when(mDataProvider.getAngle()).thenReturn(Float.MAX_VALUE);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testPass_VerticalSwipe() {
when(mDataProvider.getAngle()).thenReturn(UP_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(DOWN_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testPass_MostlyVerticalSwipe() {
when(mDataProvider.getAngle()).thenReturn(UP_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(UP_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(DOWN_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(DOWN_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS * 2);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testPass_BarelyVerticalSwipe() {
when(mDataProvider.getAngle()).thenReturn(
UP_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(
UP_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(
DOWN_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(
DOWN_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS * 2);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testPass_HorizontalSwipe() {
when(mDataProvider.getAngle()).thenReturn(RIGHT_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(LEFT_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testPass_MostlyHorizontalSwipe() {
when(mDataProvider.getAngle()).thenReturn(RIGHT_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(RIGHT_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(LEFT_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(LEFT_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testPass_BarelyHorizontalSwipe() {
when(mDataProvider.getAngle()).thenReturn(
RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(
LEFT_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(
LEFT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - 2 * FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getAngle()).thenReturn(
RIGHT_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS + 2 * FIVE_DEG_IN_RADIANS * 2);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testPass_AffordanceSwipe() {
when(mDataProvider.getInteractionType()).thenReturn(LEFT_AFFORDANCE);
when(mDataProvider.getAngle()).thenReturn(
RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(LEFT_AFFORDANCE, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.getInteractionType()).thenReturn(RIGHT_AFFORDANCE);
when(mDataProvider.getAngle()).thenReturn(
LEFT_IN_RADIANS - FORTY_FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(RIGHT_AFFORDANCE, 0.5, 0).isFalse()).isFalse();
// This classifier may return false for other angles, but these are the only
// two that actually matter, as affordances generally only travel in these two directions.
@@ -182,37 +181,37 @@ public class DiagonalClassifierTest extends ClassifierTest {
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.getAngle()).thenReturn(
RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.getAngle()).thenReturn(
UP_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.getAngle()).thenReturn(
LEFT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.getAngle()).thenReturn(
DOWN_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
// Vertical Swipes
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.getAngle()).thenReturn(
RIGHT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.getAngle()).thenReturn(
UP_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.getAngle()).thenReturn(
LEFT_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS + FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.getAngle()).thenReturn(
DOWN_IN_RADIANS + FORTY_FIVE_DEG_IN_RADIANS - FIVE_DEG_IN_RADIANS);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse()).isTrue();
}
}

View File

@@ -16,8 +16,7 @@
package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static com.google.common.truth.Truth.assertThat;
import android.testing.AndroidTestingRunner;
@@ -51,32 +50,32 @@ public class DistanceClassifierTest extends ClassifierTest {
@Test
public void testPass_noPointer() {
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
public void testPass_fling() {
mClassifier.onTouchEvent(appendDownEvent(1, 1));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mClassifier.onTouchEvent(appendMoveEvent(1, 40));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mClassifier.onTouchEvent(appendUpEvent(1, 80));
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@Test
public void testFail_flingShort() {
mClassifier.onTouchEvent(appendDownEvent(1, 1));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mClassifier.onTouchEvent(appendMoveEvent(1, 2));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mClassifier.onTouchEvent(appendUpEvent(1, 10));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -84,26 +83,26 @@ public class DistanceClassifierTest extends ClassifierTest {
// These events, in testing, result in a fling that falls just short of the threshold.
mClassifier.onTouchEvent(appendDownEvent(1, 1, 1));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mClassifier.onTouchEvent(appendMoveEvent(1, 15, 2));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mClassifier.onTouchEvent(appendMoveEvent(1, 16, 3));
mClassifier.onTouchEvent(appendMoveEvent(1, 17, 300));
mClassifier.onTouchEvent(appendMoveEvent(1, 18, 301));
mClassifier.onTouchEvent(appendUpEvent(1, 19, 501));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
public void testPass_swipe() {
mClassifier.onTouchEvent(appendDownEvent(1, 1));
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mClassifier.onTouchEvent(appendMoveEvent(1, mDataProvider.getYdpi() * 3, 3));
mClassifier.onTouchEvent(appendUpEvent(1, mDataProvider.getYdpi() * 3, 300));
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
}

View File

@@ -16,8 +16,8 @@
package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.when;
@@ -52,7 +52,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
private SingleTapClassifier mSingleTapClassifier;
private DoubleTapClassifier mClassifier;
private final FalsingClassifier.Result mFalsedResult = FalsingClassifier.Result.falsed(1, "");
private final FalsingClassifier.Result mFalsedResult =
FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
@Before
@@ -81,8 +82,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, TOUCH_SLOP, 1);
boolean result = mClassifier.classifyGesture().isFalse();
assertThat("Single tap recognized as a valid double tap", result, is(true));
boolean result = mClassifier.classifyGesture(0, 0.5, 1).isFalse();
assertThat(result).isTrue();
}
@Test
@@ -97,8 +98,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
addMotionEvent(2, 2, MotionEvent.ACTION_DOWN, TOUCH_SLOP, TOUCH_SLOP);
addMotionEvent(2, 3, MotionEvent.ACTION_UP, TOUCH_SLOP, TOUCH_SLOP);
FalsingClassifier.Result result = mClassifier.classifyGesture();
assertThat(result.getReason(), result.isFalse(), is(false));
FalsingClassifier.Result result = mClassifier.classifyGesture(0, 0.5, 1);
assertThat(result.isFalse()).isFalse();
}
@Test
@@ -113,8 +114,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
addMotionEvent(2, 2, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(2, 3, MotionEvent.ACTION_UP, 1, 1);
boolean result = mClassifier.classifyGesture().isFalse();
assertThat("Bad first touch allowed", result, is(true));
boolean result = mClassifier.classifyGesture(0, 0.5, 1).isFalse();
assertThat(result).isTrue();
}
@Test
@@ -129,8 +130,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
addMotionEvent(2, 2, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(2, 3, MotionEvent.ACTION_UP, 1, 1);
boolean result = mClassifier.classifyGesture().isFalse();
assertThat("Bad second touch allowed", result, is(true));
boolean result = mClassifier.classifyGesture(0, 0.5, 1).isFalse();
assertThat(result).isTrue();
}
@Test
@@ -145,8 +146,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
addMotionEvent(2, 2, MotionEvent.ACTION_DOWN, TOUCH_SLOP + 1, TOUCH_SLOP);
addMotionEvent(2, 3, MotionEvent.ACTION_UP, TOUCH_SLOP, TOUCH_SLOP + 1);
boolean result = mClassifier.classifyGesture().isFalse();
assertThat("Sloppy second touch allowed", result, is(true));
boolean result = mClassifier.classifyGesture(0, 0.5, 1).isFalse();
assertThat(result).isTrue();
}
@Test
@@ -163,8 +164,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
addMotionEvent(DOUBLE_TAP_TIMEOUT_MS + 1, DOUBLE_TAP_TIMEOUT_MS + 2,
MotionEvent.ACTION_UP, 1, 1);
boolean result = mClassifier.classifyGesture().isFalse();
assertThat("Slow second tap allowed", result, is(true));
boolean result = mClassifier.classifyGesture(0, 0.5, 1).isFalse();
assertThat(result).isTrue();
}
private void addMotionEvent(long downMs, long eventMs, int action, int x, int y) {

View File

@@ -121,7 +121,8 @@ public class HistoryTrackerTest extends SysuiTestCase {
private void addResult(boolean falsed, double confidence) {
mHistoryTracker.addResults(Collections.singletonList(
falsed
? FalsingClassifier.Result.falsed(confidence, "test")
? FalsingClassifier.Result.falsed(
confidence, getClass().getSimpleName(), "test")
: FalsingClassifier.Result.passed(confidence)),
mSystemClock.uptimeMillis());
}

View File

@@ -18,8 +18,10 @@ package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyDouble;
import static org.mockito.ArgumentMatchers.anyInt;
import android.testing.AndroidTestingRunner;
import android.view.MotionEvent;
@@ -50,13 +52,15 @@ public class PointerCountClassifierTest extends ClassifierTest {
@Test
public void testPass_noPointer() {
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()).isFalse())
.isFalse();
}
@Test
public void testPass_singlePointer() {
mClassifier.onTouchEvent(appendDownEvent(1, 1));
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()).isFalse())
.isFalse();
}
@Test
@@ -72,7 +76,8 @@ public class PointerCountClassifierTest extends ClassifierTest {
0, 0);
mClassifier.onTouchEvent(motionEvent);
motionEvent.recycle();
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(Classifier.GENERIC, 0.5, 1).isFalse())
.isTrue();
}
@Test
@@ -88,7 +93,6 @@ public class PointerCountClassifierTest extends ClassifierTest {
0, 0);
mClassifier.onTouchEvent(motionEvent);
motionEvent.recycle();
getDataProvider().setInteractionType(QUICK_SETTINGS);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse()).isFalse();
}
}

View File

@@ -51,14 +51,13 @@ public class ProximityClassifierTest extends ClassifierTest {
private FalsingClassifier mClassifier;
private final FalsingClassifier.Result mFalsedResult =
FalsingClassifier.Result.falsed(1, "test");
FalsingClassifier.Result.falsed(1, getClass().getSimpleName() , "test");
private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
@Before
public void setup() {
super.setup();
MockitoAnnotations.initMocks(this);
when(mDataProvider.getInteractionType()).thenReturn(GENERIC);
when(mDistanceClassifier.isLongSwipe()).thenReturn(mFalsedResult);
mClassifier = new ProximityClassifier(
mDistanceClassifier, mDataProvider, new DeviceConfigProxyFake());
@@ -73,7 +72,7 @@ public class ProximityClassifierTest extends ClassifierTest {
public void testPass_uncovered() {
touchDown();
touchUp(10);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(false));
}
@Test
@@ -82,17 +81,16 @@ public class ProximityClassifierTest extends ClassifierTest {
mClassifier.onProximityEvent(createSensorEvent(true, 1));
mClassifier.onProximityEvent(createSensorEvent(false, 2));
touchUp(20);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(false));
}
@Test
public void testPass_quickSettings() {
touchDown();
when(mDataProvider.getInteractionType()).thenReturn(QUICK_SETTINGS);
mClassifier.onProximityEvent(createSensorEvent(true, 1));
mClassifier.onProximityEvent(createSensorEvent(false, 11));
touchUp(10);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse(), is(false));
}
@Test
@@ -101,7 +99,7 @@ public class ProximityClassifierTest extends ClassifierTest {
mClassifier.onProximityEvent(createSensorEvent(true, 1));
mClassifier.onProximityEvent(createSensorEvent(false, 11));
touchUp(10);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(true));
}
@Test
@@ -112,7 +110,7 @@ public class ProximityClassifierTest extends ClassifierTest {
mClassifier.onProximityEvent(createSensorEvent(true, 96));
mClassifier.onProximityEvent(createSensorEvent(false, 100));
touchUp(100);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(true));
}
@Test
@@ -122,7 +120,7 @@ public class ProximityClassifierTest extends ClassifierTest {
mClassifier.onProximityEvent(createSensorEvent(false, 11));
touchUp(10);
when(mDistanceClassifier.isLongSwipe()).thenReturn(mPassedResult);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(GENERIC, 0.5, 0).isFalse(), is(false));
}
private void touchDown() {

View File

@@ -16,8 +16,8 @@
package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -70,14 +70,14 @@ public class SingleTapClassifierTest extends ClassifierTest {
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, TOUCH_SLOP, 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
mMotionEvents.clear();
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, -TOUCH_SLOP + 2, 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@@ -86,14 +86,14 @@ public class SingleTapClassifierTest extends ClassifierTest {
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, TOUCH_SLOP);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
mMotionEvents.clear();
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, -TOUCH_SLOP + 2);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@@ -102,14 +102,14 @@ public class SingleTapClassifierTest extends ClassifierTest {
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, TOUCH_SLOP + 1, 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mMotionEvents.clear();
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, -TOUCH_SLOP - 1, 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@@ -118,14 +118,14 @@ public class SingleTapClassifierTest extends ClassifierTest {
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, TOUCH_SLOP + 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
mMotionEvents.clear();
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, -TOUCH_SLOP - 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -134,7 +134,7 @@ public class SingleTapClassifierTest extends ClassifierTest {
addMotionEvent(0, 1, MotionEvent.ACTION_MOVE, 1, TOUCH_SLOP + 1);
addMotionEvent(0, 2, MotionEvent.ACTION_UP, 1, 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -142,12 +142,12 @@ public class SingleTapClassifierTest extends ClassifierTest {
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, 1);
assertThat(mClassifier.isTap(mMotionEvents).isFalse(), is(false));
assertThat(mClassifier.isTap(mMotionEvents).isFalse()).isFalse();
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, TOUCH_SLOP + 1);
assertThat(mClassifier.isTap(mMotionEvents).isFalse(), is(true));
assertThat(mClassifier.isTap(mMotionEvents).isFalse()).isTrue();
}

View File

@@ -25,8 +25,8 @@ import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.UNLOCK;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -56,248 +56,225 @@ public class TypeClassifierTest extends ClassifierTest {
@Test
public void testPass_QuickSettings() {
when(mDataProvider.getInteractionType()).thenReturn(QUICK_SETTINGS);
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(false); // right should cause no effect.
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_QuickSettings() {
when(mDataProvider.getInteractionType()).thenReturn(QUICK_SETTINGS);
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(QUICK_SETTINGS, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_PulseExpand() {
when(mDataProvider.getInteractionType()).thenReturn(PULSE_EXPAND);
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(false); // right should cause no effect.
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(PULSE_EXPAND, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(PULSE_EXPAND, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_PulseExpand() {
when(mDataProvider.getInteractionType()).thenReturn(PULSE_EXPAND);
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(PULSE_EXPAND, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(PULSE_EXPAND, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_NotificationDragDown() {
when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DRAG_DOWN);
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(false); // right should cause no effect.
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DRAG_DOWN, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DRAG_DOWN, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_NotificationDragDown() {
when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DRAG_DOWN);
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DRAG_DOWN, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DRAG_DOWN, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_NotificationDismiss() {
when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DISMISS);
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_NotificationDismiss() {
when(mDataProvider.getInteractionType()).thenReturn(NOTIFICATION_DISMISS);
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(NOTIFICATION_DISMISS, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_Unlock() {
when(mDataProvider.getInteractionType()).thenReturn(UNLOCK);
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false); // right should cause no effect.
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(UNLOCK, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(UNLOCK, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_Unlock() {
when(mDataProvider.getInteractionType()).thenReturn(UNLOCK);
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(UNLOCK, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(UNLOCK, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(UNLOCK, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_BouncerUnlock() {
when(mDataProvider.getInteractionType()).thenReturn(BOUNCER_UNLOCK);
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false); // right should cause no effect.
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(BOUNCER_UNLOCK, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(BOUNCER_UNLOCK, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_BouncerUnlock() {
when(mDataProvider.getInteractionType()).thenReturn(BOUNCER_UNLOCK);
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(BOUNCER_UNLOCK, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(BOUNCER_UNLOCK, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(BOUNCER_UNLOCK, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_LeftAffordance() {
when(mDataProvider.getInteractionType()).thenReturn(LEFT_AFFORDANCE);
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
when(mDataProvider.isVertical()).thenReturn(false); // vertical should cause no effect.
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(LEFT_AFFORDANCE, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isVertical()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(LEFT_AFFORDANCE, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_LeftAffordance() {
when(mDataProvider.getInteractionType()).thenReturn(LEFT_AFFORDANCE);
when(mDataProvider.isRight()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(LEFT_AFFORDANCE, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isRight()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(LEFT_AFFORDANCE, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isRight()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(LEFT_AFFORDANCE, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_RightAffordance() {
when(mDataProvider.getInteractionType()).thenReturn(RIGHT_AFFORDANCE);
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false);
when(mDataProvider.isVertical()).thenReturn(false); // vertical should cause no effect.
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(RIGHT_AFFORDANCE, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isVertical()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(RIGHT_AFFORDANCE, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_RightAffordance() {
when(mDataProvider.getInteractionType()).thenReturn(RIGHT_AFFORDANCE);
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(RIGHT_AFFORDANCE, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(RIGHT_AFFORDANCE, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(RIGHT_AFFORDANCE, 0.5, 0).isFalse()).isTrue();
}
}

View File

@@ -16,8 +16,7 @@
package com.android.systemui.classifier;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static com.google.common.truth.Truth.assertThat;
import android.testing.AndroidTestingRunner;
@@ -51,11 +50,11 @@ public class ZigZagClassifierTest extends ClassifierTest {
@Test
public void testPass_fewTouchesVertical() {
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
appendMoveEvent(0, 0);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
appendMoveEvent(0, 100);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@Test
@@ -63,16 +62,16 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(0, 100);
appendMoveEvent(0, 200);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@Test
public void testPass_fewTouchesHorizontal() {
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
appendMoveEvent(0, 0);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
appendMoveEvent(100, 0);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@Test
@@ -80,7 +79,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(100, 0);
appendMoveEvent(200, 0);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@@ -89,7 +88,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(0, 100);
appendMoveEvent(0, 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -97,7 +96,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(100, 0);
appendMoveEvent(1, 0);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -105,7 +104,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(10, 10);
appendMoveEvent(20, 20);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@Test
@@ -115,7 +114,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(5, 100);
appendMoveEvent(-5, 200);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@Test
@@ -125,7 +124,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(100, 5);
appendMoveEvent(200, -5);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
}
@Test
@@ -135,7 +134,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(6, 10);
appendMoveEvent(-6, 20);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -145,7 +144,7 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(10, 5);
appendMoveEvent(20, -5);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -153,25 +152,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(100, 5);
appendMoveEvent(200, 10);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(100, 0);
appendMoveEvent(200, 10);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(100, -10);
appendMoveEvent(200, 10);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(100, -10);
appendMoveEvent(200, 50);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -179,25 +178,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(10, 50);
appendMoveEvent(8, 100);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(1, 800);
appendMoveEvent(2, 900);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-10, 600);
appendMoveEvent(30, 700);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(40, 100);
appendMoveEvent(0, 101);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -205,25 +204,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(-10, 50);
appendMoveEvent(-24, 100);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-20, 800);
appendMoveEvent(-20, 900);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(30, 600);
appendMoveEvent(-10, 700);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-80, 100);
appendMoveEvent(-10, 101);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -231,25 +230,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(-120, 10);
appendMoveEvent(-200, 20);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-20, 8);
appendMoveEvent(-40, 2);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-500, -2);
appendMoveEvent(-600, 70);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-80, 100);
appendMoveEvent(-100, 1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -257,25 +256,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(-120, -10);
appendMoveEvent(-200, -20);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-20, -8);
appendMoveEvent(-40, -2);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-500, 2);
appendMoveEvent(-600, -70);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-80, -100);
appendMoveEvent(-100, -1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -283,25 +282,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(-12, -20);
appendMoveEvent(-20, -40);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-20, -130);
appendMoveEvent(-40, -260);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(1, -100);
appendMoveEvent(-6, -200);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-80, -100);
appendMoveEvent(-10, -110);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -309,25 +308,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(12, -20);
appendMoveEvent(20, -40);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(20, -130);
appendMoveEvent(40, -260);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(-1, -100);
appendMoveEvent(6, -200);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(80, -100);
appendMoveEvent(10, -110);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test
@@ -335,25 +334,25 @@ public class ZigZagClassifierTest extends ClassifierTest {
appendMoveEvent(0, 0);
appendMoveEvent(120, -20);
appendMoveEvent(200, -40);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(200, -13);
appendMoveEvent(400, -30);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(100, 10);
appendMoveEvent(600, -20);
assertThat(mClassifier.classifyGesture().isFalse(), is(false));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isFalse();
resetDataProvider();
appendMoveEvent(0, 0);
appendMoveEvent(80, -100);
appendMoveEvent(100, -1);
assertThat(mClassifier.classifyGesture().isFalse(), is(true));
assertThat(mClassifier.classifyGesture(0, 0.5, 1).isFalse()).isTrue();
}
@Test