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:
Dave Mankoff
2021-03-30 14:08:01 -04:00
parent 0d4e510467
commit 58718c7f81
16 changed files with 148 additions and 84 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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));

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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);