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
This commit is contained in:
Dave Mankoff
2021-03-15 13:26:04 -04:00
parent 8a80ffbedb
commit 8a5e237677
4 changed files with 73 additions and 7 deletions

View File

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

View File

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

View File

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

View File

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