Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a76c5f0 authored by Julia Tuttle's avatar Julia Tuttle
Browse files

FalsingCollectorImpl: use Interactors under Flexiglass

The FalsingCollectorImpl needs to know whether the keyguard is showing
and whether it's occluded so it knows when it doesn't need to do
anything and when it should be registering for sensor updates.

When Flexiglass is disabled, the source of truth for these signals is
KeyguardStateController.

When Flexiglass is enabled, the KeyguardStateController doesn't update,
and the correct sources of truth for these signals are two different
Interactors -- but we're still using KeyguardStateController right now.

Therefore, modify FalsingCollectorImpl to use those Interactors when
Flexiglass is enabled.

Bug: 330492016
Fixes: 340255580
Test: atest FalsingCollectorImplTest
Flag: ACONFIG com.android.systemui.scene_container DEVELOPMENT
Change-Id: Ib1845853b26dd72470a35a42fa282f30e6375968
parent df75bbb3
Loading
Loading
Loading
Loading
+59 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -186,6 +193,8 @@ class FalsingCollectorImpl implements FalsingCollector {
        mSystemClock = systemClock;
        mUserInteractor = userInteractor;
        mCommunalInteractorLazy = communalInteractorLazy;
        mDeviceEntryInteractor = deviceEntryInteractor;
        mSceneContainerOcclusionInteractor = sceneContainerOcclusionInteractor;
    }

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

@@ -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");
@@ -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;
        }
@@ -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);
    }
@@ -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) {
+56 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);
@@ -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();
    }
@@ -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 =
@@ -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,
@@ -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);

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