Separate out FalsingManager#isFalseTap
Method no longer takes `robustCheck` parameter. Instead, FalsingManager#isSimpleTap is added for basic checking, and FalsingManager#isTap does robust checking by default. FalsingManager#isTap takes an enum value for penalty instead of a double, making the value more understandable. Bug: 172655679 Test: atest SystemUITests && manual Change-Id: Ib4a99f87bcd6acee67a98420f460c98d44fa6360
This commit is contained in:
@@ -70,17 +70,17 @@ target. Match the methods with the gesture you expect the device owner to use.
|
||||
|
||||
### Single Tap
|
||||
|
||||
`FalsingManager#isFalseTap(boolean robustCheck, double falsePenalty)`. This
|
||||
method tells the `FalsingManager` that you want to validate a single tap. It
|
||||
`FalsingManager#isSimpleTape()`. This method
|
||||
performs a only very basic checking, checking that observed `MotionEvent`s are
|
||||
all within some small x & y region ("touch slop"). Useful for only the most simple of scenarios,
|
||||
you probably want `FalsingManager#isFalseTap` method for most cases.
|
||||
|
||||
`FalsingManager#isFalseTap(@Penalty int penalty)`. This
|
||||
method tells the `FalsingManager` that you want to thoroughly validate a single tap. It
|
||||
returns true if it thinks the tap should be rejected (i.e. the tap looks more
|
||||
like a swipe) and false otherwise.
|
||||
|
||||
`robustCheck` determines what heuristics are used. If set to false, the method
|
||||
performs a only very basic checking, checking that observed `MotionEvent`s are
|
||||
all within some small x & y region ("touch slop").
|
||||
|
||||
When `robustCheck` is set to true, several more advanced rules are additionally
|
||||
applied:
|
||||
It runs through the following heuristics to validate a tap:
|
||||
|
||||
1. If the device recognizes a face (i.e. face-auth) the tap is **accepted**.
|
||||
2. If the tap is the _second_ tap in recent history and looks like a valid Double Tap
|
||||
@@ -90,19 +90,18 @@ applied:
|
||||
4. Otherwise the tap is **accepted**.
|
||||
|
||||
All the above rules are applied only after first confirming the gesture does
|
||||
in fact look like a basic tap.
|
||||
in fact look like a simple tap.
|
||||
|
||||
`falsePenalty` is a measure of how much the `HistoryTracker`'s belief should be
|
||||
`penalty` is a measure of how much the `HistoryTracker`'s belief should be
|
||||
penalized in the event that the tap is rejected. This value is only used if
|
||||
`robustCheck` is set to true.
|
||||
the gesture fails to validate as a simple tap.
|
||||
|
||||
A value of `0` means no change in belief. A value of `1` means a _very_ strong
|
||||
confidence in a false tap. In general, as a single tap on the screen is not
|
||||
verifiable, a small value should be supplied - on the order of `0.1`. Pass `0`
|
||||
if you don't want to penalize belief at all. Pass a higher value
|
||||
the earlier in the UX flow your interaction occurs. Once an owner is farther
|
||||
along in a UX flow (multiple taps or swipes), its safer to assume that a single
|
||||
accidental tap should cause less of a penalty.
|
||||
The `@FalsingManager.Penalty` values are fairly straightforward, but note that you
|
||||
should generally be choosing `LOW_PENALTY`. It is inherently difficult to know if a
|
||||
tap is truly false or not, so a single mis-tap should apply only a small penalty.
|
||||
If the owner is further along in a UX flow, and is still mis-tapping, it may make more
|
||||
sense to increase the penalty as mis-taps should be less likely to occur after
|
||||
several successful gestures.
|
||||
|
||||
### Double Tap
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.plugins;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.net.Uri;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@@ -24,6 +25,8 @@ import com.android.systemui.util.sensors.ThresholdSensor;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Interface that decides whether a touch on the phone was accidental. i.e. Pocket Dialing.
|
||||
@@ -34,6 +37,20 @@ import java.io.PrintWriter;
|
||||
public interface FalsingManager {
|
||||
int VERSION = 6;
|
||||
|
||||
int NO_PENALTY = 0;
|
||||
int LOW_PENALTY = 1;
|
||||
int MODERATE_PENALTY = 2;
|
||||
int HIGH_PENALTY = 3;
|
||||
|
||||
@IntDef({
|
||||
NO_PENALTY,
|
||||
LOW_PENALTY,
|
||||
MODERATE_PENALTY,
|
||||
HIGH_PENALTY
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Penalty {}
|
||||
|
||||
void onSuccessfulUnlock();
|
||||
|
||||
boolean isUnlockingDisabled();
|
||||
@@ -41,23 +58,31 @@ public interface FalsingManager {
|
||||
/** Returns true if the gesture should be rejected. */
|
||||
boolean isFalseTouch(int interactionType);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the FalsingManager thinks the last gesure was not a valid tap.
|
||||
* Does basic checking to see if gesture looks like a tap.
|
||||
*
|
||||
* The first parameter, robustCheck, distinctly changes behavior. When set to false,
|
||||
* this method simply looks at the last gesture and returns whether it is a tap or not, (as
|
||||
* opposed to a swipe or other non-tap gesture). When set to true, a more thorough analysis
|
||||
* is performed that can include historical interactions and other contextual cues to see
|
||||
* Only does the most basic of checks. No penalty is applied if this method returns false.
|
||||
*
|
||||
* For more robust analysis, use {@link #isFalseTap(int)}.
|
||||
*/
|
||||
boolean isSimpleTap();
|
||||
|
||||
/**
|
||||
* Returns true if the FalsingManager thinks the last gesture was not a valid tap.
|
||||
*
|
||||
* This method runs a more thorough analysis than the similar {@link #isSimpleTap()},
|
||||
* that can include historical interactions and other contextual cues to see
|
||||
* if the tap looks accidental.
|
||||
*
|
||||
* Set robustCheck to true if you want to validate a tap for launching an action, like opening
|
||||
* a notification. Set to false if you simply want to know if the last gesture looked like a
|
||||
* tap.
|
||||
* Use this method to validate a tap for launching an action, like opening
|
||||
* a notification.
|
||||
*
|
||||
* The second parameter, falsePenalty, indicates how much this should affect future gesture
|
||||
* classifications if this tap looks like a false.
|
||||
* The only parameter, penalty, indicates how much this should affect future gesture
|
||||
* classifications if this tap looks like a false. As single taps are hard to confirm as false
|
||||
* or otherwise, a low penalty value is encouraged unless context indicates otherwise.
|
||||
*/
|
||||
boolean isFalseTap(boolean robustCheck, double falsePenalty);
|
||||
boolean isFalseTap(@Penalty int penalty);
|
||||
|
||||
/**
|
||||
* Returns true if the last two gestures do not look like a double tap.
|
||||
|
||||
@@ -218,18 +218,43 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFalseTap(boolean robustCheck, double falsePenalty) {
|
||||
public boolean isSimpleTap() {
|
||||
FalsingClassifier.Result result = mSingleTapClassifier.isTap(
|
||||
mDataProvider.getRecentMotionEvents(), 0);
|
||||
mPriorResults = Collections.singleton(result);
|
||||
|
||||
return !result.isFalse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFalseTap(@Penalty int penalty) {
|
||||
if (skipFalsing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double falsePenalty = 0;
|
||||
switch(penalty) {
|
||||
case NO_PENALTY:
|
||||
falsePenalty = 0;
|
||||
break;
|
||||
case LOW_PENALTY:
|
||||
falsePenalty = 0.1;
|
||||
break;
|
||||
case MODERATE_PENALTY:
|
||||
falsePenalty = 0.3;
|
||||
break;
|
||||
case HIGH_PENALTY:
|
||||
falsePenalty = 0.6;
|
||||
break;
|
||||
}
|
||||
|
||||
FalsingClassifier.Result singleTapResult =
|
||||
mSingleTapClassifier.isTap(mDataProvider.getRecentMotionEvents().isEmpty()
|
||||
? mDataProvider.getPriorMotionEvents()
|
||||
: mDataProvider.getRecentMotionEvents());
|
||||
: mDataProvider.getRecentMotionEvents(), falsePenalty);
|
||||
mPriorResults = Collections.singleton(singleTapResult);
|
||||
|
||||
if (!singleTapResult.isFalse() && robustCheck) {
|
||||
if (!singleTapResult.isFalse()) {
|
||||
if (mDataProvider.isJustUnlockedWithFace()) {
|
||||
// Immediately pass if a face is detected.
|
||||
mPriorResults = Collections.singleton(FalsingClassifier.Result.passed(1));
|
||||
|
||||
@@ -66,13 +66,13 @@ public class DoubleTapClassifier extends FalsingClassifier {
|
||||
public boolean isDoubleTap(List<MotionEvent> firstEvents, List<MotionEvent> secondEvents,
|
||||
StringBuilder reason) {
|
||||
|
||||
Result firstTap = mSingleTapClassifier.isTap(firstEvents);
|
||||
Result firstTap = mSingleTapClassifier.isTap(firstEvents, 0.5);
|
||||
if (firstTap.isFalse()) {
|
||||
reason.append("First gesture is not a tap. ").append(firstTap.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
Result secondTap = mSingleTapClassifier.isTap(secondEvents);
|
||||
Result secondTap = mSingleTapClassifier.isTap(secondEvents, 0.5);
|
||||
if (secondTap.isFalse()) {
|
||||
reason.append("Second gesture is not a tap. ").append(secondTap.getReason());
|
||||
return false;
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.List;
|
||||
*/
|
||||
public class FalsingManagerFake implements FalsingManager {
|
||||
private boolean mIsFalseTouch;
|
||||
private boolean mIsFalseTap;
|
||||
private boolean mIsSimpleTap;
|
||||
private boolean mIsFalseDoubleTap;
|
||||
private boolean mIsUnlockingDisabled;
|
||||
private boolean mIsClassiferEnabled;
|
||||
@@ -67,12 +67,12 @@ public class FalsingManagerFake implements FalsingManager {
|
||||
return mIsFalseTouch;
|
||||
}
|
||||
|
||||
public void setFalseRobustTap(boolean falseRobustTap) {
|
||||
public void setFalseTap(boolean falseRobustTap) {
|
||||
mIsFalseRobustTap = falseRobustTap;
|
||||
}
|
||||
|
||||
public void setFalseTap(boolean falseTap) {
|
||||
mIsFalseTap = falseTap;
|
||||
public void setSimpleTap(boolean isSimpleTape) {
|
||||
mIsSimpleTap = isSimpleTape;
|
||||
}
|
||||
|
||||
public void setFalseDoubleTap(boolean falseDoubleTap) {
|
||||
@@ -80,8 +80,13 @@ public class FalsingManagerFake implements FalsingManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFalseTap(boolean robustCheck, double falsePenalty) {
|
||||
return robustCheck ? mIsFalseRobustTap : mIsFalseTap;
|
||||
public boolean isSimpleTap() {
|
||||
return mIsSimpleTap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFalseTap(@Penalty int penalty) {
|
||||
return mIsFalseRobustTap;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -131,8 +131,13 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFalseTap(boolean robustCheck, double falsePenalty) {
|
||||
return mInternalFalsingManager.isFalseTap(robustCheck, falsePenalty);
|
||||
public boolean isSimpleTap() {
|
||||
return mInternalFalsingManager.isSimpleTap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFalseTap(@Penalty int penalty) {
|
||||
return mInternalFalsingManager.isFalseTap(penalty);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,11 +42,11 @@ public class SingleTapClassifier extends FalsingClassifier {
|
||||
Result calculateFalsingResult(
|
||||
@Classifier.InteractionType int interactionType,
|
||||
double historyBelief, double historyConfidence) {
|
||||
return isTap(getRecentMotionEvents());
|
||||
return isTap(getRecentMotionEvents(), 0.5);
|
||||
}
|
||||
|
||||
/** Given a list of {@link android.view.MotionEvent}'s, returns true if the look like a tap. */
|
||||
public Result isTap(List<MotionEvent> motionEvents) {
|
||||
public Result isTap(List<MotionEvent> motionEvents, double falsePenalty) {
|
||||
if (motionEvents.isEmpty()) {
|
||||
return falsed(0, "no motion events");
|
||||
}
|
||||
@@ -60,13 +60,13 @@ public class SingleTapClassifier extends FalsingClassifier {
|
||||
+ Math.abs(event.getX() - downX)
|
||||
+ "vs "
|
||||
+ mTouchSlop;
|
||||
return falsed(0.5, reason);
|
||||
return falsed(falsePenalty, reason);
|
||||
} else if (Math.abs(event.getY() - downY) >= mTouchSlop) {
|
||||
reason = "dY too big for a tap: "
|
||||
+ Math.abs(event.getY() - downY)
|
||||
+ " vs "
|
||||
+ mTouchSlop;
|
||||
return falsed(0.5, reason);
|
||||
return falsed(falsePenalty, reason);
|
||||
}
|
||||
}
|
||||
return Result.passed(0);
|
||||
|
||||
@@ -276,7 +276,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile, Lifecy
|
||||
mUiEventLogger.logWithInstanceId(QSEvent.QS_ACTION_CLICK, 0, getMetricsSpec(),
|
||||
getInstanceId());
|
||||
mQSLogger.logTileClick(mTileSpec, mStatusBarStateController.getState(), mState.state);
|
||||
if (!mFalsingManager.isFalseTap(true, 0.1)) {
|
||||
if (!mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||
mHandler.sendEmptyMessage(H.CLICK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ public class ActivatableNotificationViewController
|
||||
result = mNotificationTapHelper.onTouchEvent(ev, mView.getActualHeight());
|
||||
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||
// If this is a false tap, capture the even so it doesn't result in a click.
|
||||
return mFalsingManager.isFalseTap(true, 0.1);
|
||||
return mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -881,7 +881,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
// Other parts of the system may intercept and handle all the falsing.
|
||||
// Otherwise, if we see motion and follow-on events, try to classify them as a tap.
|
||||
if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
|
||||
mFalsingManager.isFalseTap(true, 0.3);
|
||||
mFalsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY);
|
||||
}
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public class NotificationTapHelper {
|
||||
mTrackTouch = event.getY() <= maxTouchableHeight;
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mTrackTouch && mFalsingManager.isFalseTap(false, 0)) {
|
||||
if (mTrackTouch && !mFalsingManager.isSimpleTap()) {
|
||||
makeInactive();
|
||||
mTrackTouch = false;
|
||||
}
|
||||
@@ -78,10 +78,10 @@ public class NotificationTapHelper {
|
||||
|
||||
// 1) See if we have confidence that we can activate after a single tap.
|
||||
// 2) Else, see if it looks like a tap at all and check for a double-tap.
|
||||
if (!mFalsingManager.isFalseTap(true, 0)) {
|
||||
if (!mFalsingManager.isFalseTap(FalsingManager.NO_PENALTY)) {
|
||||
makeInactive();
|
||||
return mDoubleTapListener.onDoubleTap();
|
||||
} else if (!mFalsingManager.isFalseTap(false, 0)) {
|
||||
} else if (mFalsingManager.isSimpleTap()) {
|
||||
if (mSlideBackListener != null && mSlideBackListener.onSlideBack()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.systemui.classifier;
|
||||
|
||||
import static com.android.systemui.plugins.FalsingManager.HIGH_PENALTY;
|
||||
import static com.android.systemui.plugins.FalsingManager.NO_PENALTY;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -55,8 +58,6 @@ import java.util.Set;
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
private static final long DOUBLE_TAP_TIMEOUT_MS = 1000;
|
||||
|
||||
private BrightLineFalsingManager mBrightLineFalsingManager;
|
||||
@Mock
|
||||
private FalsingDataProvider mFalsingDataProvider;
|
||||
@@ -91,7 +92,7 @@ public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
.thenReturn(mPassedResult);
|
||||
when(mClassifierB.classifyGesture(anyInt(), anyDouble(), anyDouble()))
|
||||
.thenReturn(mPassedResult);
|
||||
when(mSingleTapClassfier.isTap(any(List.class))).thenReturn(mPassedResult);
|
||||
when(mSingleTapClassfier.isTap(any(List.class), anyDouble())).thenReturn(mPassedResult);
|
||||
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
|
||||
.thenReturn(mPassedResult);
|
||||
mClassifiers.add(mClassifierA);
|
||||
@@ -170,13 +171,13 @@ public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testIsFalseTap_BasicCheck() {
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mFalsedResult);
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList, 0)).thenReturn(mFalsedResult);
|
||||
|
||||
assertThat(mBrightLineFalsingManager.isFalseTap(false, 0)).isTrue();
|
||||
assertThat(mBrightLineFalsingManager.isSimpleTap()).isFalse();
|
||||
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mPassedResult);
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList, 0)).thenReturn(mPassedResult);
|
||||
|
||||
assertThat(mBrightLineFalsingManager.isFalseTap(false, 0)).isFalse();
|
||||
assertThat(mBrightLineFalsingManager.isSimpleTap()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -185,26 +186,26 @@ public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(new ArrayList<>());
|
||||
when(mFalsingDataProvider.getPriorMotionEvents()).thenReturn(mMotionEventList);
|
||||
|
||||
mBrightLineFalsingManager.isFalseTap(false, 0);
|
||||
verify(mSingleTapClassfier).isTap(mMotionEventList);
|
||||
mBrightLineFalsingManager.isFalseTap(0);
|
||||
verify(mSingleTapClassfier).isTap(mMotionEventList, 0);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testIsFalseTap_RobustCheck_NoFaceAuth() {
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mPassedResult);
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList, 0)).thenReturn(mPassedResult);
|
||||
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
|
||||
.thenReturn(mFalsedResult);
|
||||
when(mHistoryTracker.falseBelief()).thenReturn(1.0);
|
||||
mFalsingDataProvider.setJustUnlockedWithFace(false);
|
||||
assertThat(mBrightLineFalsingManager.isFalseTap(true, 0)).isTrue();
|
||||
assertThat(mBrightLineFalsingManager.isFalseTap(NO_PENALTY)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsFalseTap_RobustCheck_FaceAuth() {
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mPassedResult);
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList, 0)).thenReturn(mPassedResult);
|
||||
when(mFalsingDataProvider.isJustUnlockedWithFace()).thenReturn(true);
|
||||
assertThat(mBrightLineFalsingManager.isFalseTap(true, 0)).isFalse();
|
||||
assertThat(mBrightLineFalsingManager.isFalseTap(NO_PENALTY)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -230,7 +231,7 @@ public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testHistory_singleTap() {
|
||||
// When trying to classify single taps, we don't immediately add results to history.
|
||||
mBrightLineFalsingManager.isFalseTap(false, 0);
|
||||
mBrightLineFalsingManager.isFalseTap(HIGH_PENALTY);
|
||||
mGestureFinalizedListener.onGestureFinalized(1000);
|
||||
verify(mHistoryTracker).addResults(anyCollection(), eq(1000L));
|
||||
}
|
||||
@@ -238,9 +239,9 @@ public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testHistory_multipleSingleTaps() {
|
||||
// When trying to classify single taps, we don't immediately add results to history.
|
||||
mBrightLineFalsingManager.isFalseTap(false, 0);
|
||||
mBrightLineFalsingManager.isFalseTap(HIGH_PENALTY);
|
||||
mGestureFinalizedListener.onGestureFinalized(1000);
|
||||
mBrightLineFalsingManager.isFalseTap(false, 0);
|
||||
mBrightLineFalsingManager.isFalseTap(HIGH_PENALTY);
|
||||
mGestureFinalizedListener.onGestureFinalized(2000);
|
||||
verify(mHistoryTracker).addResults(anyCollection(), eq(1000L));
|
||||
verify(mHistoryTracker).addResults(anyCollection(), eq(2000L));
|
||||
@@ -249,10 +250,10 @@ public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testHistory_doubleTap() {
|
||||
// When trying to classify single taps, we don't immediately add results to history.
|
||||
mBrightLineFalsingManager.isFalseTap(false, 0);
|
||||
mBrightLineFalsingManager.isFalseTap(HIGH_PENALTY);
|
||||
mGestureFinalizedListener.onGestureFinalized(1000);
|
||||
// Before checking for double tap, we may check for single-tap on the second gesture.
|
||||
mBrightLineFalsingManager.isFalseTap(false, 0);
|
||||
mBrightLineFalsingManager.isFalseTap(HIGH_PENALTY);
|
||||
mBrightLineFalsingManager.isFalseDoubleTap();
|
||||
mGestureFinalizedListener.onGestureFinalized(2000);
|
||||
|
||||
@@ -270,8 +271,8 @@ public class BrightLineClassifierTest extends SysuiTestCase {
|
||||
.thenReturn(mFalsedResult);
|
||||
assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse();
|
||||
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mFalsedResult);
|
||||
assertThat(mBrightLineFalsingManager.isFalseTap(false, 0)).isFalse();
|
||||
when(mSingleTapClassfier.isTap(mMotionEventList, 0)).thenReturn(mFalsedResult);
|
||||
assertThat(mBrightLineFalsingManager.isSimpleTap()).isFalse();
|
||||
|
||||
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
|
||||
.thenReturn(mFalsedResult);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.classifier;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyDouble;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -78,7 +79,7 @@ public class DoubleTapClassifierTest extends ClassifierTest {
|
||||
|
||||
@Test
|
||||
public void testSingleTap() {
|
||||
when(mSingleTapClassifier.isTap(anyList())).thenReturn(mFalsedResult);
|
||||
when(mSingleTapClassifier.isTap(anyList(), anyDouble())).thenReturn(mFalsedResult);
|
||||
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
|
||||
addMotionEvent(0, 1, MotionEvent.ACTION_UP, TOUCH_SLOP, 1);
|
||||
|
||||
@@ -88,7 +89,7 @@ public class DoubleTapClassifierTest extends ClassifierTest {
|
||||
|
||||
@Test
|
||||
public void testDoubleTap() {
|
||||
when(mSingleTapClassifier.isTap(anyList())).thenReturn(mPassedResult);
|
||||
when(mSingleTapClassifier.isTap(anyList(), anyDouble())).thenReturn(mPassedResult);
|
||||
|
||||
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
|
||||
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, 1);
|
||||
@@ -104,7 +105,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
|
||||
|
||||
@Test
|
||||
public void testBadFirstTap() {
|
||||
when(mSingleTapClassifier.isTap(anyList())).thenReturn(mPassedResult, mFalsedResult);
|
||||
when(mSingleTapClassifier.isTap(anyList(), anyDouble()))
|
||||
.thenReturn(mPassedResult, mFalsedResult);
|
||||
|
||||
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
|
||||
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, 1);
|
||||
@@ -120,7 +122,8 @@ public class DoubleTapClassifierTest extends ClassifierTest {
|
||||
|
||||
@Test
|
||||
public void testBadSecondTap() {
|
||||
when(mSingleTapClassifier.isTap(anyList())).thenReturn(mFalsedResult, mPassedResult);
|
||||
when(mSingleTapClassifier.isTap(anyList(), anyDouble()))
|
||||
.thenReturn(mFalsedResult, mPassedResult);
|
||||
|
||||
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
|
||||
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, 1);
|
||||
@@ -136,7 +139,7 @@ public class DoubleTapClassifierTest extends ClassifierTest {
|
||||
|
||||
@Test
|
||||
public void testBadTouchSlop() {
|
||||
when(mSingleTapClassifier.isTap(anyList())).thenReturn(mFalsedResult);
|
||||
when(mSingleTapClassifier.isTap(anyList(), anyDouble())).thenReturn(mFalsedResult);
|
||||
|
||||
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
|
||||
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, 1);
|
||||
@@ -152,7 +155,7 @@ public class DoubleTapClassifierTest extends ClassifierTest {
|
||||
|
||||
@Test
|
||||
public void testBadTouchSlow() {
|
||||
when(mSingleTapClassifier.isTap(anyList())).thenReturn(mFalsedResult);
|
||||
when(mSingleTapClassifier.isTap(anyList(), anyDouble())).thenReturn(mFalsedResult);
|
||||
|
||||
addMotionEvent(0, 0, MotionEvent.ACTION_DOWN, 1, 1);
|
||||
addMotionEvent(0, 1, MotionEvent.ACTION_UP, 1, 1);
|
||||
|
||||
@@ -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()).isFalse();
|
||||
assertThat(mClassifier.isTap(mMotionEvents, 0.5).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()).isTrue();
|
||||
assertThat(mClassifier.isTap(mMotionEvents, 0.5).isFalse()).isTrue();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -150,12 +150,12 @@ public class QSTileImplTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testClick_falsing() {
|
||||
mFalsingManager.setFalseRobustTap(true);
|
||||
mFalsingManager.setFalseTap(true);
|
||||
mTile.click();
|
||||
mTestableLooper.processAllMessages();
|
||||
assertThat(mTile.mClicked).isFalse();
|
||||
|
||||
mFalsingManager.setFalseRobustTap(false);
|
||||
mFalsingManager.setFalseTap(false);
|
||||
mTile.click();
|
||||
mTestableLooper.processAllMessages();
|
||||
assertThat(mTile.mClicked).isTrue();
|
||||
|
||||
@@ -63,7 +63,8 @@ public class NotificationTapHelperTest extends SysuiTestCase {
|
||||
when(mResources.getDimension(R.dimen.double_tap_slop))
|
||||
.thenReturn((float) ViewConfiguration.get(mContext).getScaledTouchSlop() - 1);
|
||||
|
||||
mFalsingManager.setFalseRobustTap(true); // Test double tapping most of the time.
|
||||
mFalsingManager.setSimpleTap(true);
|
||||
mFalsingManager.setFalseTap(true); // Test double tapping most of the time.
|
||||
|
||||
mNotificationTapHelper = new NotificationTapHelper.Factory(mFalsingManager, mFakeExecutor)
|
||||
.create(mActivationListener, mDoubleTapListener, mSlideBackListener);
|
||||
@@ -158,7 +159,7 @@ public class NotificationTapHelperTest extends SysuiTestCase {
|
||||
1,
|
||||
0);
|
||||
|
||||
mFalsingManager.setFalseTap(true);
|
||||
mFalsingManager.setSimpleTap(false);
|
||||
mNotificationTapHelper.onTouchEvent(evDownA);
|
||||
mNotificationTapHelper.onTouchEvent(evUpA);
|
||||
verify(mActivationListener, never()).onActiveChanged(true);
|
||||
|
||||
Reference in New Issue
Block a user