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

Commit d49175bc authored by Matt Pietal's avatar Matt Pietal
Browse files

Fix errant bouncer/keyboard display over keyguard

Legacy logic attempts to infer whether the bouncer should show based
upon panel expansion events in a variety of scenarios.

Modify the logic a bit to require show() be called on the bouncer, in
order for any events to be forwarded.

Fixes: 260589442
Fixes: 260310219
Test: atest StatusBarKeyguardViewManager
Test: manual - Bouncer works for SIM, from AOD, from UDFPS, over
occluded activity, while unlocked, over dreams, with face auth,
tapping on notif

Change-Id: I4e5919d222c1c94731dc5bf050ff66a8376b38a9
parent 1a38ab1c
Loading
Loading
Loading
Loading
+47 −63
Original line number Diff line number Diff line
@@ -19,9 +19,6 @@ package com.android.systemui.statusbar.phone;
import static android.view.WindowInsets.Type.navigationBars;

import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_DISMISS_BOUNCER;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_SHOW_BOUNCER;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_COLLAPSING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;

@@ -140,6 +137,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
    private final BouncerView mPrimaryBouncerView;
    private final Lazy<com.android.systemui.shade.ShadeController> mShadeController;

    // Local cache of expansion events, to avoid duplicates
    private float mFraction = -1f;
    private boolean mTracking = false;

    private final PrimaryBouncerExpansionCallback mExpansionCallback =
            new PrimaryBouncerExpansionCallback() {
            private boolean mPrimaryBouncerAnimating;
@@ -440,80 +441,68 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
        hideBouncer(true /* destroyView */);
    }

    @Override
    public void onPanelExpansionChanged(ShadeExpansionChangeEvent event) {
        float fraction = event.getFraction();
        boolean tracking = event.getTracking();
    private boolean beginShowingBouncer(ShadeExpansionChangeEvent event) {
        // Avoid having the shade and the bouncer open at the same time over a dream.
        final boolean hideBouncerOverDream =
                mDreamOverlayStateController.isOverlayActive()
                        && (mNotificationPanelViewController.isExpanded()
                        || mNotificationPanelViewController.isExpanding());

        // We don't want to translate the bounce when:
        // • device is dozing and not pulsing
        // • Keyguard is occluded, because we're in a FLAG_SHOW_WHEN_LOCKED activity and need to
        //   conserve the original animation.
        // • The user quickly taps on the display and we show "swipe up to unlock."
        // • Keyguard will be dismissed by an action. a.k.a: FLAG_DISMISS_KEYGUARD_ACTIVITY
        // • Full-screen user switcher is displayed.
        if (mDozing && !mPulsing) {
        final boolean isUserTrackingStarted =
                event.getFraction() != KeyguardBouncer.EXPANSION_HIDDEN && event.getTracking();

        return mKeyguardStateController.isShowing()
                && !primaryBouncerIsOrWillBeShowing()
                && isUserTrackingStarted
                && !hideBouncerOverDream
                && !mKeyguardStateController.isOccluded()
                && !mKeyguardStateController.canDismissLockScreen()
                && !bouncerIsAnimatingAway()
                && !mNotificationPanelViewController.isUnlockHintRunning()
                && !(mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED);
    }

    @Override
    public void onPanelExpansionChanged(ShadeExpansionChangeEvent event) {
        float fraction = event.getFraction();
        boolean tracking = event.getTracking();

        if (mFraction == fraction && mTracking == tracking) {
            // Ignore duplicate events, as they will cause confusion with bouncer expansion
            return;
        } else if (mNotificationPanelViewController.isUnlockHintRunning()) {
        }
        mFraction = fraction;
        mTracking = tracking;

        /*
         * The bouncer may have received a call to show(), or the following will infer it from
         * device state and touch handling. The bouncer MUST have been notified that it is about to
         * show if any subsequent events are to be handled.
         */
        if (beginShowingBouncer(event)) {
            if (mPrimaryBouncer != null) {
                mPrimaryBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
                mPrimaryBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */);
            } else {
                mPrimaryBouncerInteractor.setPanelExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
                mPrimaryBouncerInteractor.show(/* isScrimmed= */false);
            }
        } else if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) {
            // Don't expand to the bouncer. Instead transition back to the lock screen (see
            // CentralSurfaces#showBouncerOrLockScreenIfKeyguard)
            return;
        } else if (mKeyguardStateController.isOccluded()
                && !mDreamOverlayStateController.isOverlayActive()) {
        }

        if (!primaryBouncerIsOrWillBeShowing()) {
            return;
        } else if (needsFullscreenBouncer()) {
            if (mPrimaryBouncer != null) {
                mPrimaryBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
            } else {
                mPrimaryBouncerInteractor.setPanelExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
        }
        } else if (mKeyguardStateController.isShowing() && !hideBouncerOverDream) {
            if (!isWakeAndUnlocking()
                    && !(mBiometricUnlockController.getMode() == MODE_DISMISS_BOUNCER)
                    && !(mBiometricUnlockController.getMode() == MODE_SHOW_BOUNCER)
                    && !isUnlockCollapsing()) {

        if (mKeyguardStateController.isShowing()) {
            if (mPrimaryBouncer != null) {
                mPrimaryBouncer.setExpansion(fraction);
            } else {
                mPrimaryBouncerInteractor.setPanelExpansion(fraction);
            }
            }
            if (fraction != KeyguardBouncer.EXPANSION_HIDDEN && tracking
                    && !mKeyguardStateController.canDismissLockScreen()
                    && !primaryBouncerIsShowing()
                    && !bouncerIsAnimatingAway()) {
                if (mPrimaryBouncer != null) {
                    mPrimaryBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */);
        } else {
                    mPrimaryBouncerInteractor.show(/* isScrimmed= */false);
                }
            }
        } else if (!mKeyguardStateController.isShowing()  && isPrimaryBouncerInTransit()) {
            // Keyguard is not visible anymore, but expansion animation was still running.
            // We need to hide the bouncer, otherwise it will be stuck in transit.
            if (mPrimaryBouncer != null) {
                mPrimaryBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
            } else {
                mPrimaryBouncerInteractor.setPanelExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
            }
        } else if (mPulsing && fraction == KeyguardBouncer.EXPANSION_VISIBLE) {
            // Panel expanded while pulsing but didn't translate the bouncer (because we are
            // unlocked.) Let's simply wake-up to dismiss the lock screen.
            mCentralSurfaces.wakeUpIfDozing(
                    SystemClock.uptimeMillis(),
                    mCentralSurfaces.getBouncerContainer(),
                    "BOUNCER_VISIBLE");
        }
    }

@@ -704,11 +693,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
        return mode == MODE_WAKE_AND_UNLOCK || mode == MODE_WAKE_AND_UNLOCK_PULSING;
    }

    private boolean isUnlockCollapsing() {
        int mode = mBiometricUnlockController.getMode();
        return mode == MODE_UNLOCK_COLLAPSING;
    }

    /**
     * Adds a {@param runnable} to be executed after Keyguard is gone.
     */
+16 −15
Original line number Diff line number Diff line
@@ -222,31 +222,32 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
    }

    @Test
    public void onPanelExpansionChanged_neverHidesFullscreenBouncer() {
        when(mPrimaryBouncer.isShowing()).thenReturn(true);
        when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
                KeyguardSecurityModel.SecurityMode.SimPuk);
        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
        verify(mPrimaryBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE));

        reset(mPrimaryBouncer);
        when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
                KeyguardSecurityModel.SecurityMode.SimPin);
    public void onPanelExpansionChanged_neverShowsDuringHintAnimation() {
        when(mNotificationPanelView.isUnlockHintRunning()).thenReturn(true);
        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
        verify(mPrimaryBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE));
        verify(mPrimaryBouncer, never()).setExpansion(anyFloat());
    }

    @Test
    public void onPanelExpansionChanged_neverShowsDuringHintAnimation() {
        when(mNotificationPanelView.isUnlockHintRunning()).thenReturn(true);
    public void onPanelExpansionChanged_propagatesToBouncerOnlyIfShowing() {
        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
        verify(mPrimaryBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_HIDDEN));
        verify(mPrimaryBouncer, never()).setExpansion(eq(0.5f));

        when(mPrimaryBouncer.isShowing()).thenReturn(true);
        mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                expansionEvent(/* fraction= */ 0.6f, /* expanded= */ false, /* tracking= */ true));
        verify(mPrimaryBouncer).setExpansion(eq(0.6f));
    }

    @Test
    public void onPanelExpansionChanged_propagatesToBouncer() {
    public void onPanelExpansionChanged_duplicateEventsAreIgnored() {
        when(mPrimaryBouncer.isShowing()).thenReturn(true);
        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
        verify(mPrimaryBouncer).setExpansion(eq(0.5f));

        reset(mPrimaryBouncer);
        mStatusBarKeyguardViewManager.onPanelExpansionChanged(EXPANSION_EVENT);
        verify(mPrimaryBouncer, never()).setExpansion(eq(0.5f));
    }

    @Test