diff options
19 files changed, 168 insertions, 92 deletions
diff --git a/packages/SystemUI/docs/falsing.md b/packages/SystemUI/docs/falsing.md index 09215ac813b5..0a60270499ca 100644 --- a/packages/SystemUI/docs/falsing.md +++ b/packages/SystemUI/docs/falsing.md @@ -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. - -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 gesture fails to validate as a simple tap. + +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 diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java index 1fde6c9df90a..4142e517243f 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java @@ -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); + + /** + * Does basic checking to see if gesture looks like a tap. + * + * 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 gesure was not a valid tap. + * Returns true if the FalsingManager thinks the last gesture was not a valid 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 + * 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. diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index 5bdc7a4b1936..e2c62ed55eb2 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -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)); diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java index e7c9d1863ce2..b6d529d3a129 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/DoubleTapClassifier.java @@ -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; diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java index d39f12488595..e557773fe295 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java index 9c29f27a2e15..1723291e26f8 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java index 68a9e5f0d489..bd6fbfbd282e 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java index 52e05a4fd6c5..3467838bd02a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java @@ -34,6 +34,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.R; import com.android.systemui.globalactions.GlobalActionsDialogLite; import com.android.systemui.plugins.ActivityStarter; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.qs.dagger.QSScope; import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.phone.MultiUserSwitch; @@ -62,6 +63,7 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme private final QuickQSPanelController mQuickQSPanelController; private final TunerService mTunerService; private final MetricsLogger mMetricsLogger; + private final FalsingManager mFalsingManager; private final SettingsButton mSettingsButton; private final TextView mBuildText; private final View mEdit; @@ -83,8 +85,9 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme private final View.OnClickListener mSettingsOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { - // Don't do anything until view are unhidden - if (!mExpanded) { + // Don't do anything until views are unhidden. Don't do anything if the tap looks + // suspicious. + if (!mExpanded || mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { return; } @@ -132,7 +135,7 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme DeviceProvisionedController deviceProvisionedController, UserTracker userTracker, QSPanelController qsPanelController, QSDetailDisplayer qsDetailDisplayer, QuickQSPanelController quickQSPanelController, - TunerService tunerService, MetricsLogger metricsLogger, + TunerService tunerService, MetricsLogger metricsLogger, FalsingManager falsingManager, @Named(PM_LITE_ENABLED) boolean showPMLiteButton, GlobalActionsDialogLite globalActionsDialog) { super(view); @@ -146,6 +149,7 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme mQuickQSPanelController = quickQSPanelController; mTunerService = tunerService; mMetricsLogger = metricsLogger; + mFalsingManager = falsingManager; mSettingsButton = mView.findViewById(R.id.settings_button); mBuildText = mView.findViewById(R.id.build); @@ -184,9 +188,13 @@ public class QSFooterViewController extends ViewController<QSFooterView> impleme return false; }); - mEdit.setOnClickListener(view -> - mActivityStarter.postQSRunnableDismissingKeyguard(() -> - mQsPanelController.showEdit(view))); + mEdit.setOnClickListener(view -> { + if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { + return; + } + mActivityStarter.postQSRunnableDismissingKeyguard(() -> + mQsPanelController.showEdit(view)); + }); mMultiUserSwitch.setQSDetailDisplayer(mQsDetailDisplayer); mQsPanelController.setFooterPageIndicator(mPageIndicator); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index 1cb268365441..375c79f0aaf5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -279,7 +279,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); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java index 3f7b8aff7c51..edd97afce2ca 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java @@ -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; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index 207a89482b17..2ada28123f5f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationTapHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationTapHelper.java index 66df936dd556..95ecd3f4ab4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationTapHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationTapHelper.java @@ -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; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index f1f34dc10421..7e433e88c60a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -681,6 +681,9 @@ public class StatusBar extends SystemUI implements DemoMode, new FalsingManager.FalsingBeliefListener() { @Override public void onFalse() { + // Hides quick settings. + mNotificationPanelViewController.resetViews(true); + // Hides bouncer and quick-quick settings. mStatusBarKeyguardViewManager.reset(true); } }; diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java index 923cae89401d..a7f9fe4e0a2c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java @@ -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); diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java index f726cbead1f0..2ceee6dc56d8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/DoubleTapClassifierTest.java @@ -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); diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java index 15241073d191..e3c800e441e0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/SingleTapClassifierTest.java @@ -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(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java index 650ee50f13af..21fec913f88c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java @@ -38,6 +38,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.testing.FakeMetricsLogger; import com.android.systemui.Dependency; import com.android.systemui.R; +import com.android.systemui.classifier.FalsingManagerFake; import com.android.systemui.globalactions.GlobalActionsDialogLite; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.settings.UserTracker; @@ -121,7 +122,7 @@ public class QSFooterViewControllerTest extends LeakCheckedTest { mController = new QSFooterViewController(mView, mUserManager, mUserInfoController, mActivityStarter, mDeviceProvisionedController, mUserTracker, mQSPanelController, new QSDetailDisplayer(), mQuickQSPanelController, mFakeTunerService, - mMetricsLogger, false, mGlobalActionsDialog); + mMetricsLogger, new FalsingManagerFake(), false, mGlobalActionsDialog); mController.init(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java index 0f9ca7b57328..2d6ed7c2e4a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java @@ -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(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java index 4ed27463eecd..b70c6dd1242d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationTapHelperTest.java @@ -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); |