From 8a5e237677cdc77b063b80d14a9094e350ea36ee Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Mon, 15 Mar 2021 13:26:04 -0400 Subject: [PATCH] Avoid falsing when the phone is unlocked. With this change, we completely avoid recording motion events when the phone is off the lock screen. We also also return false when asked if the last gesture was a false. Fixes: 182713255 Test: atest SystemUITests && manual Change-Id: I2e16aecb218dd3c862ffefc8c82f67523925ac5e --- .../classifier/BrightLineFalsingManager.java | 22 +++++++++++++++- .../classifier/FalsingCollectorImpl.java | 11 ++++++-- .../classifier/BrightLineClassifierTest.java | 25 ++++++++++++++++--- .../classifier/FalsingCollectorImplTest.java | 22 +++++++++++++++- 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index efb799294004c..45cefcc564bfc 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -31,6 +31,7 @@ import com.android.systemui.classifier.FalsingDataProvider.SessionListener; import com.android.systemui.dagger.qualifiers.TestHarness; import com.android.systemui.dock.DockManager; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ThresholdSensor; import java.io.FileDescriptor; @@ -67,6 +68,7 @@ public class BrightLineFalsingManager implements FalsingManager { private final SingleTapClassifier mSingleTapClassifier; private final DoubleTapClassifier mDoubleTapClassifier; private final HistoryTracker mHistoryTracker; + private final KeyguardStateController mKeyguardStateController; private final boolean mTestHarness; private final MetricsLogger mMetricsLogger; private int mIsFalseTouchCalls; @@ -113,7 +115,8 @@ public class BrightLineFalsingManager implements FalsingManager { DockManager dockManager, MetricsLogger metricsLogger, @Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set classifiers, SingleTapClassifier singleTapClassifier, DoubleTapClassifier doubleTapClassifier, - HistoryTracker historyTracker, @TestHarness boolean testHarness) { + HistoryTracker historyTracker, KeyguardStateController keyguardStateController, + @TestHarness boolean testHarness) { mDataProvider = falsingDataProvider; mDockManager = dockManager; mMetricsLogger = metricsLogger; @@ -121,6 +124,7 @@ public class BrightLineFalsingManager implements FalsingManager { mSingleTapClassifier = singleTapClassifier; mDoubleTapClassifier = doubleTapClassifier; mHistoryTracker = historyTracker; + mKeyguardStateController = keyguardStateController; mTestHarness = testHarness; mDataProvider.addSessionListener(mSessionListener); @@ -134,6 +138,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + if (skipFalsing()) { + return false; + } + boolean result; mDataProvider.setInteractionType(interactionType); @@ -195,6 +203,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTap(boolean robustCheck, double falsePenalty) { + if (skipFalsing()) { + return false; + } + FalsingClassifier.Result singleTapResult = mSingleTapClassifier.isTap(mDataProvider.getRecentMotionEvents()); mPriorResults = Collections.singleton(singleTapResult); @@ -233,6 +245,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseDoubleTap() { + if (skipFalsing()) { + return false; + } + FalsingClassifier.Result result = mDoubleTapClassifier.classifyGesture(); mPriorResults = Collections.singleton(result); if (result.isFalse()) { @@ -246,6 +262,10 @@ public class BrightLineFalsingManager implements FalsingManager { return result.isFalse(); } + private boolean skipFalsing() { + return !mKeyguardStateController.isShowing(); + } + @Override public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { // TODO: some of these classifiers might allow us to abort early, meaning we don't have to diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java index e090006cca4fd..b359860a0fd7f 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java @@ -27,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.SystemClock; @@ -48,6 +49,7 @@ class FalsingCollectorImpl implements FalsingCollector { private final HistoryTracker mHistoryTracker; private final ProximitySensor mProximitySensor; private final StatusBarStateController mStatusBarStateController; + private final KeyguardStateController mKeyguardStateController; private final SystemClock mSystemClock; private int mState; @@ -87,13 +89,14 @@ class FalsingCollectorImpl implements FalsingCollector { FalsingCollectorImpl(FalsingDataProvider falsingDataProvider, FalsingManager falsingManager, KeyguardUpdateMonitor keyguardUpdateMonitor, HistoryTracker historyTracker, ProximitySensor proximitySensor, StatusBarStateController statusBarStateController, - SystemClock systemClock) { + KeyguardStateController keyguardStateController, SystemClock systemClock) { mFalsingDataProvider = falsingDataProvider; mFalsingManager = falsingManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mHistoryTracker = historyTracker; mProximitySensor = proximitySensor; mStatusBarStateController = statusBarStateController; + mKeyguardStateController = keyguardStateController; mSystemClock = systemClock; @@ -255,6 +258,10 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void onTouchEvent(MotionEvent ev) { + if (!mKeyguardStateController.isShowing()) { + avoidGesture(); + return; + } // We delay processing down events to see if another component wants to process them. // If #avoidGesture is called after a MotionEvent.ACTION_DOWN, all following motion events // will be ignored by the collector until another MotionEvent.ACTION_DOWN is passed in. @@ -276,8 +283,8 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void avoidGesture() { + mAvoidGesture = true; if (mPendingDownEvent != null) { - mAvoidGesture = true; mPendingDownEvent.recycle(); mPendingDownEvent = null; } 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 b2328504272a7..d015f51055b5a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java @@ -35,6 +35,7 @@ import com.android.internal.logging.testing.FakeMetricsLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingDataProvider.GestureCompleteListener; import com.android.systemui.dock.DockManagerFake; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -71,7 +72,10 @@ public class BrightLineClassifierTest extends SysuiTestCase { private FalsingClassifier mClassifierB; private final List mMotionEventList = new ArrayList<>(); @Mock - private HistoryTracker mHistoryTracker;; + private HistoryTracker mHistoryTracker; + @Mock + private KeyguardStateController mKeyguardStateController; + private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); private final FalsingClassifier.Result mFalsedResult = FalsingClassifier.Result.falsed(1, ""); @@ -88,9 +92,10 @@ public class BrightLineClassifierTest extends SysuiTestCase { mClassifiers.add(mClassifierA); mClassifiers.add(mClassifierB); when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList); + when(mKeyguardStateController.isShowing()).thenReturn(true); mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager, mMetricsLogger, mClassifiers, mSingleTapClassfier, mDoubleTapClassifier, - mHistoryTracker, false); + mHistoryTracker, mKeyguardStateController, false); ArgumentCaptor gestureCompleteListenerCaptor = @@ -120,7 +125,7 @@ public class BrightLineClassifierTest extends SysuiTestCase { } @Test - public void testIsFalseTouch_ClassffiersPass() { + public void testIsFalseTouch_ClassifiersPass() { assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse(); } @@ -233,4 +238,18 @@ public class BrightLineClassifierTest extends SysuiTestCase { assertThat(mFakeExecutor.numPending()).isEqualTo(0); } + + @Test + public void testNoFalsingUnlocked() { + when(mKeyguardStateController.isShowing()).thenReturn(false); + + when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse(); + + when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseTap(false, 0)).isFalse(); + + when(mDoubleTapClassifier.classifyGesture()).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java index dc79b88818919..e6aeee7a9184b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java @@ -34,6 +34,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.FakeSystemClock; @@ -62,16 +63,19 @@ public class FalsingCollectorImplTest extends SysuiTestCase { private ProximitySensor mProximitySensor; @Mock private SysuiStatusBarStateController mStatusBarStateController; + @Mock + private KeyguardStateController mKeyguardStateController; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); + when(mKeyguardStateController.isShowing()).thenReturn(true); mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager, mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor, - mStatusBarStateController, new FakeSystemClock()); + mStatusBarStateController, mKeyguardStateController, new FakeSystemClock()); } @Test @@ -159,4 +163,20 @@ public class FalsingCollectorImplTest extends SysuiTestCase { mFalsingCollector.onTouchEvent(up); verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); } + + @Test + public void testAvoidUnlocked() { + MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); + MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); + + when(mKeyguardStateController.isShowing()).thenReturn(false); + + // Nothing passed initially + mFalsingCollector.onTouchEvent(down); + verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); + + // Up event would normally flush the up event. + mFalsingCollector.onTouchEvent(up); + verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); + } }