Loading packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +59 −5 Original line number Diff line number Diff line Loading @@ -31,9 +31,12 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor; import com.android.systemui.dock.DockManager; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor; import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.policy.BatteryController; Loading Loading @@ -88,6 +91,8 @@ class FalsingCollectorImpl implements FalsingCollector { private final JavaAdapter mJavaAdapter; private final SystemClock mSystemClock; private final Lazy<SelectedUserInteractor> mUserInteractor; private final Lazy<DeviceEntryInteractor> mDeviceEntryInteractor; private final Lazy<SceneContainerOcclusionInteractor> mSceneContainerOcclusionInteractor; private int mState; private boolean mShowingAod; Loading Loading @@ -170,7 +175,9 @@ class FalsingCollectorImpl implements FalsingCollector { JavaAdapter javaAdapter, SystemClock systemClock, Lazy<SelectedUserInteractor> userInteractor, Lazy<CommunalInteractor> communalInteractorLazy) { Lazy<CommunalInteractor> communalInteractorLazy, Lazy<DeviceEntryInteractor> deviceEntryInteractor, Lazy<SceneContainerOcclusionInteractor> sceneContainerOcclusionInteractor) { mFalsingDataProvider = falsingDataProvider; mFalsingManager = falsingManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; Loading @@ -186,6 +193,8 @@ class FalsingCollectorImpl implements FalsingCollector { mSystemClock = systemClock; mUserInteractor = userInteractor; mCommunalInteractorLazy = communalInteractorLazy; mDeviceEntryInteractor = deviceEntryInteractor; mSceneContainerOcclusionInteractor = sceneContainerOcclusionInteractor; } @Override Loading @@ -196,7 +205,18 @@ class FalsingCollectorImpl implements FalsingCollector { mStatusBarStateController.addCallback(mStatusBarStateListener); mState = mStatusBarStateController.getState(); if (SceneContainerFlag.isEnabled()) { mJavaAdapter.alwaysCollectFlow( mDeviceEntryInteractor.get().isDeviceEntered(), this::isDeviceEnteredChanged ); mJavaAdapter.alwaysCollectFlow( mSceneContainerOcclusionInteractor.get().getInvisibleDueToOcclusion(), this::isInvisibleDueToOcclusionChanged ); } else { mKeyguardStateController.addCallback(mKeyguardStateControllerCallback); } mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback); Loading @@ -216,6 +236,14 @@ class FalsingCollectorImpl implements FalsingCollector { mDockManager.addListener(mDockEventListener); } public void isDeviceEnteredChanged(boolean unused) { updateSensorRegistration(); } public void isInvisibleDueToOcclusionChanged(boolean unused) { updateSensorRegistration(); } @Override public void onSuccessfulUnlock() { logDebug("REAL: onSuccessfulUnlock"); Loading Loading @@ -302,7 +330,7 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void onTouchEvent(MotionEvent ev) { logDebug("REAL: onTouchEvent(" + MotionEvent.actionToString(ev.getActionMasked()) + ")"); if (!mKeyguardStateController.isShowing()) { if (!isKeyguardShowing()) { avoidGesture(); return; } Loading Loading @@ -402,8 +430,8 @@ class FalsingCollectorImpl implements FalsingCollector { final boolean isKeyguard = mState == StatusBarState.KEYGUARD; final boolean isShadeOverOccludedKeyguard = mState == StatusBarState.SHADE && mKeyguardStateController.isShowing() && mKeyguardStateController.isOccluded(); && isKeyguardShowing() && isKeyguardOccluded(); return mScreenOn && !mShowingAod && (isKeyguard || isShadeOverOccludedKeyguard); } Loading Loading @@ -447,6 +475,32 @@ class FalsingCollectorImpl implements FalsingCollector { mFalsingManager.onProximityEvent(new ProximityEventImpl(proximityEvent)); } /** * Returns {@code true} if the keyguard is showing (whether or not the screen is on, whether or * not an activity is occluding the keyguard, and whether or not the shade is open on top of the * keyguard), or {@code false} if the user has dismissed the keyguard by authenticating or * swiping up. */ private boolean isKeyguardShowing() { if (SceneContainerFlag.isEnabled()) { return !mDeviceEntryInteractor.get().isDeviceEntered().getValue(); } else { return mKeyguardStateController.isShowing(); } } /** * Returns {@code true} if there is an activity display on top of ("occluding") the keyguard, or * {@code false} if an activity is not occluding the keyguard (including if the keyguard is not * showing at all). */ private boolean isKeyguardOccluded() { if (SceneContainerFlag.isEnabled()) { return mSceneContainerOcclusionInteractor.get().getInvisibleDueToOcclusion().getValue(); } else { return mKeyguardStateController.isOccluded(); } } static void logDebug(String msg) { if (DEBUG) { Loading packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java +56 −3 Original line number Diff line number Diff line Loading @@ -35,9 +35,13 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerFake; import com.android.systemui.flags.DisableSceneContainer; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; Loading @@ -50,6 +54,7 @@ import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.FakeSystemClock; import kotlinx.coroutines.flow.MutableStateFlow; import kotlinx.coroutines.flow.StateFlowKt; import org.junit.Before; Loading Loading @@ -89,6 +94,14 @@ public class FalsingCollectorImplTest extends SysuiTestCase { private SelectedUserInteractor mSelectedUserInteractor; @Mock private CommunalInteractor mCommunalInteractor; @Mock private DeviceEntryInteractor mDeviceEntryInteractor; private final MutableStateFlow<Boolean> mIsDeviceEntered = StateFlowKt.MutableStateFlow(false); @Mock private SceneContainerOcclusionInteractor mSceneContainerOcclusionInteractor; private final MutableStateFlow<Boolean> mIsInvisibleDueToOcclusion = StateFlowKt.MutableStateFlow(false); private final DockManagerFake mDockManager = new DockManagerFake(); private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock); Loading @@ -99,15 +112,21 @@ public class FalsingCollectorImplTest extends SysuiTestCase { when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); when(mKeyguardStateController.isShowing()).thenReturn(true); when(mKeyguardStateController.isOccluded()).thenReturn(false); when(mShadeInteractor.isQsExpanded()).thenReturn(StateFlowKt.MutableStateFlow(false)); when(mDeviceEntryInteractor.isDeviceEntered()).thenReturn(mIsDeviceEntered); when(mSceneContainerOcclusionInteractor.getInvisibleDueToOcclusion()).thenReturn( mIsInvisibleDueToOcclusion); mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager, mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor, mStatusBarStateController, mKeyguardStateController, () -> mShadeInteractor, mBatteryController, mDockManager, mFakeExecutor, mJavaAdapter, mFakeSystemClock, () -> mSelectedUserInteractor, () -> mCommunalInteractor () -> mCommunalInteractor, () -> mDeviceEntryInteractor, () -> mSceneContainerOcclusionInteractor ); mFalsingCollector.init(); } Loading Loading @@ -189,7 +208,8 @@ public class FalsingCollectorImplTest extends SysuiTestCase { } @Test public void testRegisterSensor_OccludingActivity() { @DisableSceneContainer public void testRegisterSensor_OccludingActivity_sceneContainerDisabled() { when(mKeyguardStateController.isOccluded()).thenReturn(true); ArgumentCaptor<StatusBarStateController.StateListener> stateListenerArgumentCaptor = Loading @@ -202,6 +222,21 @@ public class FalsingCollectorImplTest extends SysuiTestCase { verify(mProximitySensor).register(any(ThresholdSensor.Listener.class)); } @Test @EnableSceneContainer public void testRegisterSensor_OccludingActivity_sceneContainerEnabled() { mIsInvisibleDueToOcclusion.setValue(true); ArgumentCaptor<StatusBarStateController.StateListener> stateListenerArgumentCaptor = ArgumentCaptor.forClass(StatusBarStateController.StateListener.class); verify(mStatusBarStateController).addCallback(stateListenerArgumentCaptor.capture()); mFalsingCollector.onScreenTurningOn(); reset(mProximitySensor); stateListenerArgumentCaptor.getValue().onStateChanged(StatusBarState.SHADE); verify(mProximitySensor).register(any(ThresholdSensor.Listener.class)); } @Test public void testPassThroughEnterKeyEvent() { KeyEvent enterDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, Loading Loading @@ -280,7 +315,8 @@ public class FalsingCollectorImplTest extends SysuiTestCase { } @Test public void testAvoidUnlocked() { @DisableSceneContainer public void testAvoidUnlocked_sceneContainerDisabled() { MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); Loading @@ -295,6 +331,23 @@ public class FalsingCollectorImplTest extends SysuiTestCase { verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); } @Test @EnableSceneContainer public void testAvoidUnlocked_sceneContainerEnabled() { MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); mIsDeviceEntered.setValue(true); // Nothing passed initially mFalsingCollector.onTouchEvent(down); verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); // Up event would normally flush the up event, but doesn't. mFalsingCollector.onTouchEvent(up); verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); } @Test public void testGestureWhenDozing() { // We check the FalsingManager for taps during the transition to AoD (dozing=true, Loading Loading
packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +59 −5 Original line number Diff line number Diff line Loading @@ -31,9 +31,12 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor; import com.android.systemui.dock.DockManager; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor; import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.policy.BatteryController; Loading Loading @@ -88,6 +91,8 @@ class FalsingCollectorImpl implements FalsingCollector { private final JavaAdapter mJavaAdapter; private final SystemClock mSystemClock; private final Lazy<SelectedUserInteractor> mUserInteractor; private final Lazy<DeviceEntryInteractor> mDeviceEntryInteractor; private final Lazy<SceneContainerOcclusionInteractor> mSceneContainerOcclusionInteractor; private int mState; private boolean mShowingAod; Loading Loading @@ -170,7 +175,9 @@ class FalsingCollectorImpl implements FalsingCollector { JavaAdapter javaAdapter, SystemClock systemClock, Lazy<SelectedUserInteractor> userInteractor, Lazy<CommunalInteractor> communalInteractorLazy) { Lazy<CommunalInteractor> communalInteractorLazy, Lazy<DeviceEntryInteractor> deviceEntryInteractor, Lazy<SceneContainerOcclusionInteractor> sceneContainerOcclusionInteractor) { mFalsingDataProvider = falsingDataProvider; mFalsingManager = falsingManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; Loading @@ -186,6 +193,8 @@ class FalsingCollectorImpl implements FalsingCollector { mSystemClock = systemClock; mUserInteractor = userInteractor; mCommunalInteractorLazy = communalInteractorLazy; mDeviceEntryInteractor = deviceEntryInteractor; mSceneContainerOcclusionInteractor = sceneContainerOcclusionInteractor; } @Override Loading @@ -196,7 +205,18 @@ class FalsingCollectorImpl implements FalsingCollector { mStatusBarStateController.addCallback(mStatusBarStateListener); mState = mStatusBarStateController.getState(); if (SceneContainerFlag.isEnabled()) { mJavaAdapter.alwaysCollectFlow( mDeviceEntryInteractor.get().isDeviceEntered(), this::isDeviceEnteredChanged ); mJavaAdapter.alwaysCollectFlow( mSceneContainerOcclusionInteractor.get().getInvisibleDueToOcclusion(), this::isInvisibleDueToOcclusionChanged ); } else { mKeyguardStateController.addCallback(mKeyguardStateControllerCallback); } mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback); Loading @@ -216,6 +236,14 @@ class FalsingCollectorImpl implements FalsingCollector { mDockManager.addListener(mDockEventListener); } public void isDeviceEnteredChanged(boolean unused) { updateSensorRegistration(); } public void isInvisibleDueToOcclusionChanged(boolean unused) { updateSensorRegistration(); } @Override public void onSuccessfulUnlock() { logDebug("REAL: onSuccessfulUnlock"); Loading Loading @@ -302,7 +330,7 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void onTouchEvent(MotionEvent ev) { logDebug("REAL: onTouchEvent(" + MotionEvent.actionToString(ev.getActionMasked()) + ")"); if (!mKeyguardStateController.isShowing()) { if (!isKeyguardShowing()) { avoidGesture(); return; } Loading Loading @@ -402,8 +430,8 @@ class FalsingCollectorImpl implements FalsingCollector { final boolean isKeyguard = mState == StatusBarState.KEYGUARD; final boolean isShadeOverOccludedKeyguard = mState == StatusBarState.SHADE && mKeyguardStateController.isShowing() && mKeyguardStateController.isOccluded(); && isKeyguardShowing() && isKeyguardOccluded(); return mScreenOn && !mShowingAod && (isKeyguard || isShadeOverOccludedKeyguard); } Loading Loading @@ -447,6 +475,32 @@ class FalsingCollectorImpl implements FalsingCollector { mFalsingManager.onProximityEvent(new ProximityEventImpl(proximityEvent)); } /** * Returns {@code true} if the keyguard is showing (whether or not the screen is on, whether or * not an activity is occluding the keyguard, and whether or not the shade is open on top of the * keyguard), or {@code false} if the user has dismissed the keyguard by authenticating or * swiping up. */ private boolean isKeyguardShowing() { if (SceneContainerFlag.isEnabled()) { return !mDeviceEntryInteractor.get().isDeviceEntered().getValue(); } else { return mKeyguardStateController.isShowing(); } } /** * Returns {@code true} if there is an activity display on top of ("occluding") the keyguard, or * {@code false} if an activity is not occluding the keyguard (including if the keyguard is not * showing at all). */ private boolean isKeyguardOccluded() { if (SceneContainerFlag.isEnabled()) { return mSceneContainerOcclusionInteractor.get().getInvisibleDueToOcclusion().getValue(); } else { return mKeyguardStateController.isOccluded(); } } static void logDebug(String msg) { if (DEBUG) { Loading
packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java +56 −3 Original line number Diff line number Diff line Loading @@ -35,9 +35,13 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; import com.android.systemui.communal.domain.interactor.CommunalInteractor; import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor; import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManagerFake; import com.android.systemui.flags.DisableSceneContainer; import com.android.systemui.flags.EnableSceneContainer; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; Loading @@ -50,6 +54,7 @@ import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.FakeSystemClock; import kotlinx.coroutines.flow.MutableStateFlow; import kotlinx.coroutines.flow.StateFlowKt; import org.junit.Before; Loading Loading @@ -89,6 +94,14 @@ public class FalsingCollectorImplTest extends SysuiTestCase { private SelectedUserInteractor mSelectedUserInteractor; @Mock private CommunalInteractor mCommunalInteractor; @Mock private DeviceEntryInteractor mDeviceEntryInteractor; private final MutableStateFlow<Boolean> mIsDeviceEntered = StateFlowKt.MutableStateFlow(false); @Mock private SceneContainerOcclusionInteractor mSceneContainerOcclusionInteractor; private final MutableStateFlow<Boolean> mIsInvisibleDueToOcclusion = StateFlowKt.MutableStateFlow(false); private final DockManagerFake mDockManager = new DockManagerFake(); private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock); Loading @@ -99,15 +112,21 @@ public class FalsingCollectorImplTest extends SysuiTestCase { when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); when(mKeyguardStateController.isShowing()).thenReturn(true); when(mKeyguardStateController.isOccluded()).thenReturn(false); when(mShadeInteractor.isQsExpanded()).thenReturn(StateFlowKt.MutableStateFlow(false)); when(mDeviceEntryInteractor.isDeviceEntered()).thenReturn(mIsDeviceEntered); when(mSceneContainerOcclusionInteractor.getInvisibleDueToOcclusion()).thenReturn( mIsInvisibleDueToOcclusion); mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager, mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor, mStatusBarStateController, mKeyguardStateController, () -> mShadeInteractor, mBatteryController, mDockManager, mFakeExecutor, mJavaAdapter, mFakeSystemClock, () -> mSelectedUserInteractor, () -> mCommunalInteractor () -> mCommunalInteractor, () -> mDeviceEntryInteractor, () -> mSceneContainerOcclusionInteractor ); mFalsingCollector.init(); } Loading Loading @@ -189,7 +208,8 @@ public class FalsingCollectorImplTest extends SysuiTestCase { } @Test public void testRegisterSensor_OccludingActivity() { @DisableSceneContainer public void testRegisterSensor_OccludingActivity_sceneContainerDisabled() { when(mKeyguardStateController.isOccluded()).thenReturn(true); ArgumentCaptor<StatusBarStateController.StateListener> stateListenerArgumentCaptor = Loading @@ -202,6 +222,21 @@ public class FalsingCollectorImplTest extends SysuiTestCase { verify(mProximitySensor).register(any(ThresholdSensor.Listener.class)); } @Test @EnableSceneContainer public void testRegisterSensor_OccludingActivity_sceneContainerEnabled() { mIsInvisibleDueToOcclusion.setValue(true); ArgumentCaptor<StatusBarStateController.StateListener> stateListenerArgumentCaptor = ArgumentCaptor.forClass(StatusBarStateController.StateListener.class); verify(mStatusBarStateController).addCallback(stateListenerArgumentCaptor.capture()); mFalsingCollector.onScreenTurningOn(); reset(mProximitySensor); stateListenerArgumentCaptor.getValue().onStateChanged(StatusBarState.SHADE); verify(mProximitySensor).register(any(ThresholdSensor.Listener.class)); } @Test public void testPassThroughEnterKeyEvent() { KeyEvent enterDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, Loading Loading @@ -280,7 +315,8 @@ public class FalsingCollectorImplTest extends SysuiTestCase { } @Test public void testAvoidUnlocked() { @DisableSceneContainer public void testAvoidUnlocked_sceneContainerDisabled() { MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); Loading @@ -295,6 +331,23 @@ public class FalsingCollectorImplTest extends SysuiTestCase { verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); } @Test @EnableSceneContainer public void testAvoidUnlocked_sceneContainerEnabled() { MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); mIsDeviceEntered.setValue(true); // Nothing passed initially mFalsingCollector.onTouchEvent(down); verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); // Up event would normally flush the up event, but doesn't. mFalsingCollector.onTouchEvent(up); verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); } @Test public void testGestureWhenDozing() { // We check the FalsingManager for taps during the transition to AoD (dozing=true, Loading