summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/LongTapClassifier.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/TapClassifier.java67
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java56
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java20
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java11
11 files changed, 273 insertions, 55 deletions
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 c50340cfd247..e52a57f761c7 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -82,6 +82,18 @@ public interface FalsingManager {
boolean isFalseTap(@Penalty int penalty);
/**
+ * Returns true if the FalsingManager thinks the last gesture was not a valid long tap.
+ *
+ * Use this method to validate a long tap for launching an action, like long press on a UMO
+ *
+ * The only parameter, penalty, indicates how much this should affect future gesture
+ * classifications if this long tap looks like a false.
+ * As long taps are hard to confirm as false or otherwise,
+ * a low penalty value is encouraged unless context indicates otherwise.
+ */
+ boolean isFalseLongTap(@Penalty int penalty);
+
+ /**
* Returns true if the last two gestures do not look like a double tap.
*
* Only works on data that has already been reported to the FalsingManager. Be sure that
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 2245d8462c31..beaccbaf9a70 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -34,6 +34,8 @@ import com.android.internal.logging.MetricsLogger;
import com.android.systemui.classifier.FalsingDataProvider.SessionListener;
import com.android.systemui.classifier.HistoryTracker.BeliefListener;
import com.android.systemui.dagger.qualifiers.TestHarness;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -65,6 +67,7 @@ public class BrightLineFalsingManager implements FalsingManager {
private static final double FALSE_BELIEF_THRESHOLD = 0.9;
private final FalsingDataProvider mDataProvider;
+ private final LongTapClassifier mLongTapClassifier;
private final SingleTapClassifier mSingleTapClassifier;
private final DoubleTapClassifier mDoubleTapClassifier;
private final HistoryTracker mHistoryTracker;
@@ -73,6 +76,7 @@ public class BrightLineFalsingManager implements FalsingManager {
private final boolean mTestHarness;
private final MetricsLogger mMetricsLogger;
private int mIsFalseTouchCalls;
+ private FeatureFlags mFeatureFlags;
private static final Queue<String> RECENT_INFO_LOG =
new ArrayDeque<>(RECENT_INFO_LOG_SIZE + 1);
private static final Queue<DebugSwipeRecord> RECENT_SWIPES =
@@ -175,19 +179,23 @@ public class BrightLineFalsingManager implements FalsingManager {
public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
MetricsLogger metricsLogger,
@Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set<FalsingClassifier> classifiers,
- SingleTapClassifier singleTapClassifier, DoubleTapClassifier doubleTapClassifier,
- HistoryTracker historyTracker, KeyguardStateController keyguardStateController,
+ SingleTapClassifier singleTapClassifier, LongTapClassifier longTapClassifier,
+ DoubleTapClassifier doubleTapClassifier, HistoryTracker historyTracker,
+ KeyguardStateController keyguardStateController,
AccessibilityManager accessibilityManager,
- @TestHarness boolean testHarness) {
+ @TestHarness boolean testHarness,
+ FeatureFlags featureFlags) {
mDataProvider = falsingDataProvider;
mMetricsLogger = metricsLogger;
mClassifiers = classifiers;
mSingleTapClassifier = singleTapClassifier;
+ mLongTapClassifier = longTapClassifier;
mDoubleTapClassifier = doubleTapClassifier;
mHistoryTracker = historyTracker;
mKeyguardStateController = keyguardStateController;
mAccessibilityManager = accessibilityManager;
mTestHarness = testHarness;
+ mFeatureFlags = featureFlags;
mDataProvider.addSessionListener(mSessionListener);
mDataProvider.addGestureCompleteListener(mGestureFinalizedListener);
@@ -313,6 +321,58 @@ public class BrightLineFalsingManager implements FalsingManager {
}
@Override
+ public boolean isFalseLongTap(@Penalty int penalty) {
+ if (!mFeatureFlags.isEnabled(Flags.FALSING_FOR_LONG_TAPS)) {
+ return false;
+ }
+
+ checkDestroyed();
+
+ if (skipFalsing(GENERIC)) {
+ mPriorResults = getPassedResult(1);
+ logDebug("Skipped falsing");
+ 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 longTapResult =
+ mLongTapClassifier.isTap(mDataProvider.getRecentMotionEvents().isEmpty()
+ ? mDataProvider.getPriorMotionEvents()
+ : mDataProvider.getRecentMotionEvents(), falsePenalty);
+ mPriorResults = Collections.singleton(longTapResult);
+
+ if (!longTapResult.isFalse()) {
+ if (mDataProvider.isJustUnlockedWithFace()) {
+ // Immediately pass if a face is detected.
+ mPriorResults = getPassedResult(1);
+ logDebug("False Long Tap: false (face detected)");
+ } else {
+ mPriorResults = getPassedResult(0.1);
+ logDebug("False Long Tap: false (default)");
+ }
+ return false;
+ } else {
+ logDebug("False Long Tap: " + longTapResult.isFalse() + " (simple)");
+ return longTapResult.isFalse();
+ }
+ }
+
+ @Override
public boolean isFalseDoubleTap() {
checkDestroyed();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 5d04b5f77479..c4723e895ee7 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -139,6 +139,11 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
}
@Override
+ public boolean isFalseLongTap(int penalty) {
+ return mInternalFalsingManager.isFalseLongTap(penalty);
+ }
+
+ @Override
public boolean isFalseDoubleTap() {
return mInternalFalsingManager.isFalseDoubleTap();
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
index 7b7f17e1568b..5302af9db836 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingModule.java
@@ -40,6 +40,7 @@ import dagger.multibindings.ElementsIntoSet;
public interface FalsingModule {
String BRIGHT_LINE_GESTURE_CLASSIFERS = "bright_line_gesture_classifiers";
String SINGLE_TAP_TOUCH_SLOP = "falsing_single_tap_touch_slop";
+ String LONG_TAP_TOUCH_SLOP = "falsing_long_tap_slop";
String DOUBLE_TAP_TOUCH_SLOP = "falsing_double_tap_touch_slop";
String DOUBLE_TAP_TIMEOUT_MS = "falsing_double_tap_timeout_ms";
@@ -81,4 +82,11 @@ public interface FalsingModule {
static float providesSingleTapTouchSlop(ViewConfiguration viewConfiguration) {
return viewConfiguration.getScaledTouchSlop();
}
+
+ /** */
+ @Provides
+ @Named(LONG_TAP_TOUCH_SLOP)
+ static float providesLongTapTouchSlop(ViewConfiguration viewConfiguration) {
+ return viewConfiguration.getScaledTouchSlop() * 1.25f;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/LongTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/LongTapClassifier.java
new file mode 100644
index 000000000000..1963e69c1547
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/LongTapClassifier.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.classifier;
+
+import static com.android.systemui.classifier.FalsingModule.LONG_TAP_TOUCH_SLOP;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * Falsing classifier that accepts or rejects a gesture as a long tap.
+ */
+public class LongTapClassifier extends TapClassifier{
+
+ @Inject
+ LongTapClassifier(FalsingDataProvider dataProvider,
+ @Named(LONG_TAP_TOUCH_SLOP) float touchSlop) {
+ super(dataProvider, touchSlop);
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java
index bd6fbfbd282e..7a7401dfdd22 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/SingleTapClassifier.java
@@ -18,57 +18,17 @@ package com.android.systemui.classifier;
import static com.android.systemui.classifier.FalsingModule.SINGLE_TAP_TOUCH_SLOP;
-import android.view.MotionEvent;
-
-import java.util.List;
-
import javax.inject.Inject;
import javax.inject.Named;
/**
- * Falsing classifier that accepts or rejects a single gesture as a tap.
+ * Falsing classifier that accepts or rejects a gesture as a single tap.
*/
-public class SingleTapClassifier extends FalsingClassifier {
- private final float mTouchSlop;
+public class SingleTapClassifier extends TapClassifier {
@Inject
SingleTapClassifier(FalsingDataProvider dataProvider,
@Named(SINGLE_TAP_TOUCH_SLOP) float touchSlop) {
- super(dataProvider);
- mTouchSlop = touchSlop;
- }
-
- @Override
- Result calculateFalsingResult(
- @Classifier.InteractionType int interactionType,
- double historyBelief, double historyConfidence) {
- 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, double falsePenalty) {
- if (motionEvents.isEmpty()) {
- return falsed(0, "no motion events");
- }
- float downX = motionEvents.get(0).getX();
- float downY = motionEvents.get(0).getY();
-
- for (MotionEvent event : motionEvents) {
- String reason;
- if (Math.abs(event.getX() - downX) >= mTouchSlop) {
- reason = "dX too big for a tap: "
- + Math.abs(event.getX() - downX)
- + "vs "
- + mTouchSlop;
- 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(falsePenalty, reason);
- }
- }
- return Result.passed(0);
+ super(dataProvider, touchSlop);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TapClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/TapClassifier.java
new file mode 100644
index 000000000000..e24cfaa0ff8f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TapClassifier.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.classifier;
+
+import android.view.MotionEvent;
+
+import java.util.List;
+
+/**
+ * Falsing classifier that accepts or rejects a gesture as a tap.
+ */
+public abstract class TapClassifier extends FalsingClassifier{
+ private final float mTouchSlop;
+
+ TapClassifier(FalsingDataProvider dataProvider,
+ float touchSlop) {
+ super(dataProvider);
+ mTouchSlop = touchSlop;
+ }
+
+ @Override
+ Result calculateFalsingResult(
+ @Classifier.InteractionType int interactionType,
+ double historyBelief, double historyConfidence) {
+ 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, double falsePenalty) {
+ if (motionEvents.isEmpty()) {
+ return falsed(0, "no motion events");
+ }
+ float downX = motionEvents.get(0).getX();
+ float downY = motionEvents.get(0).getY();
+
+ for (MotionEvent event : motionEvents) {
+ String reason;
+ if (Math.abs(event.getX() - downX) >= mTouchSlop) {
+ reason = "dX too big for a tap: "
+ + Math.abs(event.getX() - downX)
+ + "vs "
+ + mTouchSlop;
+ 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(falsePenalty, reason);
+ }
+ }
+ return Result.passed(0);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index f51e28196627..42f2dab1e065 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -349,6 +349,9 @@ object Flags {
// 2000 - device controls
@Keep val USE_APP_PANELS = UnreleasedFlag(2000, true)
+ // 2100 - Falsing Manager
+ @JvmField val FALSING_FOR_LONG_TAPS = ReleasedFlag(2100)
+
// Pay no attention to the reflection behind the curtain.
// ========================== Curtain ==========================
// | |
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 6bc7308a6a40..f8579fff488b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java
@@ -39,6 +39,8 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingDataProvider.GestureFinalizedListener;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -66,6 +68,8 @@ public class BrightLineClassifierTest extends SysuiTestCase {
@Mock
private SingleTapClassifier mSingleTapClassfier;
@Mock
+ private LongTapClassifier mLongTapClassifier;
+ @Mock
private DoubleTapClassifier mDoubleTapClassifier;
@Mock
private FalsingClassifier mClassifierA;
@@ -80,6 +84,7 @@ public class BrightLineClassifierTest extends SysuiTestCase {
private AccessibilityManager mAccessibilityManager;
private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+ private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
private final FalsingClassifier.Result mFalsedResult =
FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
@@ -94,6 +99,7 @@ public class BrightLineClassifierTest extends SysuiTestCase {
when(mClassifierB.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
when(mSingleTapClassfier.isTap(any(List.class), anyDouble())).thenReturn(mPassedResult);
+ when(mLongTapClassifier.isTap(any(List.class), anyDouble())).thenReturn(mFalsedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
mClassifiers.add(mClassifierA);
@@ -101,9 +107,9 @@ public class BrightLineClassifierTest extends SysuiTestCase {
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
when(mKeyguardStateController.isShowing()).thenReturn(true);
mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
- mMetricsLogger, mClassifiers, mSingleTapClassfier, mDoubleTapClassifier,
- mHistoryTracker, mKeyguardStateController, mAccessibilityManager,
- false);
+ mMetricsLogger, mClassifiers, mSingleTapClassfier, mLongTapClassifier,
+ mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
+ mAccessibilityManager, false, mFakeFeatureFlags);
ArgumentCaptor<GestureFinalizedListener> gestureCompleteListenerCaptor =
@@ -113,6 +119,7 @@ public class BrightLineClassifierTest extends SysuiTestCase {
gestureCompleteListenerCaptor.capture());
mGestureFinalizedListener = gestureCompleteListenerCaptor.getValue();
+ mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true);
}
@Test
@@ -212,7 +219,7 @@ public class BrightLineClassifierTest extends SysuiTestCase {
}
@Test
- public void testIsFalseTap_EmptyRecentEvents() {
+ public void testIsFalseSingleTap_EmptyRecentEvents() {
// Ensure we look at prior events if recent events has already been emptied.
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(new ArrayList<>());
when(mFalsingDataProvider.getPriorMotionEvents()).thenReturn(mMotionEventList);
@@ -223,7 +230,7 @@ public class BrightLineClassifierTest extends SysuiTestCase {
@Test
- public void testIsFalseTap_RobustCheck_NoFaceAuth() {
+ public void testIsFalseSingleTap_RobustCheck_NoFaceAuth() {
when(mSingleTapClassfier.isTap(mMotionEventList, 0)).thenReturn(mPassedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
@@ -233,13 +240,50 @@ public class BrightLineClassifierTest extends SysuiTestCase {
}
@Test
- public void testIsFalseTap_RobustCheck_FaceAuth() {
+ public void testIsFalseSingleTap_RobustCheck_FaceAuth() {
when(mSingleTapClassfier.isTap(mMotionEventList, 0)).thenReturn(mPassedResult);
when(mFalsingDataProvider.isJustUnlockedWithFace()).thenReturn(true);
assertThat(mBrightLineFalsingManager.isFalseTap(NO_PENALTY)).isFalse();
}
@Test
+ public void testIsFalseLongTap_EmptyRecentEvents() {
+ // Ensure we look at prior events if recent events has already been emptied.
+ when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(new ArrayList<>());
+ when(mFalsingDataProvider.getPriorMotionEvents()).thenReturn(mMotionEventList);
+
+ mBrightLineFalsingManager.isFalseLongTap(0);
+ verify(mLongTapClassifier).isTap(mMotionEventList, 0);
+ }
+
+ @Test
+ public void testIsFalseLongTap_FalseLongTap_NotFlagged() {
+ mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, false);
+ when(mLongTapClassifier.isTap(mMotionEventList, 0)).thenReturn(mFalsedResult);
+ assertThat(mBrightLineFalsingManager.isFalseLongTap(NO_PENALTY)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseLongTap_FalseLongTap() {
+ when(mLongTapClassifier.isTap(mMotionEventList, 0)).thenReturn(mFalsedResult);
+ assertThat(mBrightLineFalsingManager.isFalseLongTap(NO_PENALTY)).isTrue();
+ }
+
+ @Test
+ public void testIsFalseLongTap_RobustCheck_NoFaceAuth() {
+ when(mLongTapClassifier.isTap(mMotionEventList, 0)).thenReturn(mPassedResult);
+ when(mFalsingDataProvider.isJustUnlockedWithFace()).thenReturn(false);
+ assertThat(mBrightLineFalsingManager.isFalseLongTap(NO_PENALTY)).isFalse();
+ }
+
+ @Test
+ public void testIsFalseLongTap_RobustCheck_FaceAuth() {
+ when(mLongTapClassifier.isTap(mMotionEventList, 0)).thenReturn(mPassedResult);
+ when(mFalsingDataProvider.isJustUnlockedWithFace()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseLongTap(NO_PENALTY)).isFalse();
+ }
+
+ @Test
public void testIsFalseDoubleTap() {
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mPassedResult);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
index b811aab6d35f..4281ee0f139f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java
@@ -32,6 +32,8 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.flags.FakeFeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -57,6 +59,8 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
@Mock
private SingleTapClassifier mSingleTapClassifier;
@Mock
+ private LongTapClassifier mLongTapClassifier;
+ @Mock
private DoubleTapClassifier mDoubleTapClassifier;
@Mock
private FalsingClassifier mClassifierA;
@@ -71,6 +75,7 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
private final FalsingClassifier.Result mPassedResult = FalsingClassifier.Result.passed(1);
private final FalsingClassifier.Result mFalsedResult =
FalsingClassifier.Result.falsed(1, getClass().getSimpleName(), "");
+ private final FakeFeatureFlags mFakeFeatureFlags = new FakeFeatureFlags();
@Before
public void setup() {
@@ -78,15 +83,17 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
when(mClassifierA.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
when(mSingleTapClassifier.isTap(any(List.class), anyDouble())).thenReturn(mFalsedResult);
+ when(mLongTapClassifier.isTap(any(List.class), anyDouble())).thenReturn(mFalsedResult);
when(mDoubleTapClassifier.classifyGesture(anyInt(), anyDouble(), anyDouble()))
.thenReturn(mFalsedResult);
mClassifiers.add(mClassifierA);
when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList);
when(mKeyguardStateController.isShowing()).thenReturn(true);
mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider,
- mMetricsLogger, mClassifiers, mSingleTapClassifier, mDoubleTapClassifier,
- mHistoryTracker, mKeyguardStateController, mAccessibilityManager,
- false);
+ mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier,
+ mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController,
+ mAccessibilityManager, false, mFakeFeatureFlags);
+ mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true);
}
@Test
@@ -105,6 +112,13 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
@Test
+ public void testA11yDisablesLongTap() {
+ assertThat(mBrightLineFalsingManager.isFalseLongTap(1)).isTrue();
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
+ assertThat(mBrightLineFalsingManager.isFalseLongTap(1)).isFalse();
+ }
+
+ @Test
public void testA11yDisablesDoubleTap() {
assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isTrue();
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java
index 34c83bd41a02..d47e88fc9385 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -39,6 +39,7 @@ public class FalsingManagerFake implements FalsingManager {
private boolean mShouldEnforceBouncer;
private boolean mIsReportingEnabled;
private boolean mIsFalseRobustTap;
+ private boolean mIsFalseLongTap;
private boolean mDestroyed;
private boolean mIsProximityNear;
@@ -87,6 +88,10 @@ public class FalsingManagerFake implements FalsingManager {
mIsProximityNear = proxNear;
}
+ public void setFalseLongTap(boolean falseLongTap) {
+ mIsFalseLongTap = falseLongTap;
+ }
+
@Override
public boolean isSimpleTap() {
checkDestroyed();
@@ -100,6 +105,12 @@ public class FalsingManagerFake implements FalsingManager {
}
@Override
+ public boolean isFalseLongTap(int penalty) {
+ checkDestroyed();
+ return mIsFalseLongTap;
+ }
+
+ @Override
public boolean isFalseDoubleTap() {
checkDestroyed();
return mIsFalseDoubleTap;