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

Commit 0c76ea59 authored by Josh Tsuji's avatar Josh Tsuji Committed by Android (Google) Code Review
Browse files

Merge changes Ic62b7358,Ic3f7e62a into tm-qpr-dev

* changes:
  Fix scrim turning opaque during occlusion animation.
  Delay keyguard hiding until after occlusion animation ends.
parents 04cbb0e2 55816370
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ import android.view.animation.AnimationUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.jank.InteractionJankMonitor.Configuration;
@@ -322,6 +323,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
    // true if the keyguard is hidden by another window
    private boolean mOccluded = false;

    /**
     * Whether the {@link #mOccludeAnimationController} is currently playing the occlusion
     * animation.
     */
    private boolean mOccludeAnimationPlaying = false;

    private boolean mWakeAndUnlocking = false;

    /**
@@ -836,15 +843,22 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
    /**
     * Animation launch controller for activities that occlude the keyguard.
     */
    private final ActivityLaunchAnimator.Controller mOccludeAnimationController =
    @VisibleForTesting
    final ActivityLaunchAnimator.Controller mOccludeAnimationController =
            new ActivityLaunchAnimator.Controller() {
                @Override
                public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {}
                public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {
                    mOccludeAnimationPlaying = true;
                }

                @Override
                public void onLaunchAnimationCancelled(@Nullable Boolean newKeyguardOccludedState) {
                    Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: "
                            + mOccluded);
                    mOccludeAnimationPlaying = false;

                    // Ensure keyguard state is set correctly if we're cancelled.
                    mCentralSurfaces.updateIsKeyguard();
                }

                @Override
@@ -853,6 +867,12 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
                        mCentralSurfaces.instantCollapseNotificationPanel();
                    }

                    mOccludeAnimationPlaying = false;

                    // Hide the keyguard now that we're done launching the occluding activity over
                    // it.
                    mCentralSurfaces.updateIsKeyguard();

                    mInteractionJankMonitor.end(CUJ_LOCKSCREEN_OCCLUSION);
                }

@@ -1767,6 +1787,10 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
        return mShowing && !mOccluded;
    }

    public boolean isOccludeAnimationPlaying() {
        return mOccludeAnimationPlaying;
    }

    /**
     * Notify us when the keyguard is occluded by another window
     */
+4 −1
Original line number Diff line number Diff line
@@ -2980,7 +2980,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
            //  * When phone is unlocked: we still don't want to execute hiding of the keyguard
            //    as the animation could prepare 'fake AOD' interface (without actually
            //    transitioning to keyguard state) and this might reset the view states
            if (!mScreenOffAnimationController.isKeyguardHideDelayed()) {
            if (!mScreenOffAnimationController.isKeyguardHideDelayed()
                    // If we're animating occluded, there's an activity launching over the keyguard
                    // UI. Wait to hide it until after the animation concludes.
                    && !mKeyguardViewMediator.isOccludeAnimationPlaying()) {
                return hideKeyguardImpl(forceStateChange);
            }
        }
+13 −1
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.scrim.ScrimView;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -204,6 +205,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
    private final ScreenOffAnimationController mScreenOffAnimationController;
    private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
    private KeyguardViewMediator mKeyguardViewMediator;

    private GradientColors mColors;
    private boolean mNeedsDrawableColorUpdate;
@@ -273,7 +275,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
            @Main Executor mainExecutor,
            ScreenOffAnimationController screenOffAnimationController,
            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
            KeyguardViewMediator keyguardViewMediator) {
        mScrimStateListener = lightBarController::setScrimState;
        mDefaultScrimAlpha = BUSY_SCRIM_ALPHA;

@@ -312,6 +315,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
            }
        });
        mColors = new GradientColors();

        mKeyguardViewMediator = keyguardViewMediator;
    }

    /**
@@ -807,6 +812,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
                        mBehindTint,
                        interpolatedFraction);
            }

            // If we're unlocked but still playing the occlude animation, remain at the keyguard
            // alpha temporarily.
            if (mKeyguardViewMediator.isOccludeAnimationPlaying()
                    || mState.mLaunchingAffordanceWithPreview) {
                mNotificationsAlpha = KEYGUARD_SCRIM_ALPHA;
            }
        } else if (mState == ScrimState.AUTH_SCRIMMED_SHADE) {
            float behindFraction = getInterpolatedFraction();
            behindFraction = (float) Math.pow(behindFraction, 0.8f);
+25 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -112,6 +113,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {

    private FalsingCollectorFake mFalsingCollector;

    private @Mock CentralSurfaces mCentralSurfaces;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
@@ -258,6 +261,26 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
        verify(mKeyguardStateController).notifyKeyguardGoingAway(false);
    }

    @Test
    public void testUpdateIsKeyguardAfterOccludeAnimationEnds() {
        mViewMediator.mOccludeAnimationController.onLaunchAnimationEnd(
                false /* isExpandingFullyAbove */);

        // Since the updateIsKeyguard call is delayed during the animation, ensure it's called once
        // it ends.
        verify(mCentralSurfaces).updateIsKeyguard();
    }

    @Test
    public void testUpdateIsKeyguardAfterOccludeAnimationIsCancelled() {
        mViewMediator.mOccludeAnimationController.onLaunchAnimationCancelled(
                null /* newKeyguardOccludedState */);

        // Since the updateIsKeyguard call is delayed during the animation, ensure it's called if
        // it's cancelled.
        verify(mCentralSurfaces).updateIsKeyguard();
    }

    private void createAndStartViewMediator() {
        mViewMediator = new KeyguardViewMediator(
                mContext,
@@ -287,5 +310,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
                mNotificationShadeWindowControllerLazy,
                () -> mActivityLaunchAnimator);
        mViewMediator.start();

        mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null, null);
    }
}
+56 −4
Original line number Diff line number Diff line
@@ -235,6 +235,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
    @Mock private NavigationBarController mNavigationBarController;
    @Mock private AccessibilityFloatingMenuController mAccessibilityFloatingMenuController;
    @Mock private SysuiColorExtractor mColorExtractor;
    private WakefulnessLifecycle mWakefulnessLifecycle;
    @Mock private ColorExtractor.GradientColors mGradientColors;
    @Mock private PulseExpansionHandler mPulseExpansionHandler;
    @Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
@@ -366,10 +367,10 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
            return null;
        }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());

        WakefulnessLifecycle wakefulnessLifecycle =
        mWakefulnessLifecycle =
                new WakefulnessLifecycle(mContext, mIWallpaperManager, mDumpManager);
        wakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
        wakefulnessLifecycle.dispatchFinishedWakingUp();
        mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
        mWakefulnessLifecycle.dispatchFinishedWakingUp();

        when(mGradientColors.supportsDarkText()).thenReturn(true);
        when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
@@ -428,7 +429,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
                mBatteryController,
                mColorExtractor,
                new ScreenLifecycle(mDumpManager),
                wakefulnessLifecycle,
                mWakefulnessLifecycle,
                mStatusBarStateController,
                Optional.of(mBubbles),
                mDeviceProvisionedController,
@@ -507,6 +508,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
        mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController;
        mCentralSurfaces.mBarService = mBarService;
        mCentralSurfaces.mStackScroller = mStackScroller;
        mCentralSurfaces.mGestureWakeLock = mPowerManager.newWakeLock(
                PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "sysui:GestureWakeLock");
        mCentralSurfaces.startKeyguard();
        mInitController.executePostInitTasks();
        notificationLogger.setUpWithContainer(mNotificationListContainer);
@@ -1125,6 +1128,55 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
        assertThat(onDismissActionCaptor.getValue().onDismiss()).isFalse();
    }

    @Test
    public void testKeyguardHideDelayedIfOcclusionAnimationRunning() {
        // Show the keyguard and verify we've done so.
        setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
        verify(mStatusBarStateController).setState(StatusBarState.KEYGUARD);

        // Request to hide the keyguard, but while the occlude animation is playing. We should delay
        // this hide call, since we're playing the occlude animation over the keyguard and thus want
        // it to remain visible.
        when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(true);
        setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
        verify(mStatusBarStateController, never()).setState(StatusBarState.SHADE);

        // Once the animation ends, verify that the keyguard is actually hidden.
        when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
        setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
        verify(mStatusBarStateController).setState(StatusBarState.SHADE);
    }

    @Test
    public void testKeyguardHideNotDelayedIfOcclusionAnimationNotRunning() {
        // Show the keyguard and verify we've done so.
        setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
        verify(mStatusBarStateController).setState(StatusBarState.KEYGUARD);

        // Hide the keyguard while the occlusion animation is not running. Verify that we
        // immediately hide the keyguard.
        when(mKeyguardViewMediator.isOccludeAnimationPlaying()).thenReturn(false);
        setKeyguardShowingAndOccluded(false /* showing */, true /* occluded */);
        verify(mStatusBarStateController).setState(StatusBarState.SHADE);
    }

    /**
     * Configures the appropriate mocks and then calls {@link CentralSurfacesImpl#updateIsKeyguard}
     * to reconfigure the keyguard to reflect the requested showing/occluded states.
     */
    private void setKeyguardShowingAndOccluded(boolean showing, boolean occluded) {
        when(mStatusBarStateController.isKeyguardRequested()).thenReturn(showing);
        when(mKeyguardStateController.isOccluded()).thenReturn(occluded);

        // If we want to show the keyguard, make sure that we think we're awake and not unlocking.
        if (showing) {
            when(mBiometricUnlockController.isWakeAndUnlock()).thenReturn(false);
            mWakefulnessLifecycle.dispatchStartedWakingUp(PowerManager.WAKE_REASON_UNKNOWN);
        }

        mCentralSurfaces.updateIsKeyguard(false /* forceStateChange */);
    }

    private void setDeviceState(int state) {
        ArgumentCaptor<DeviceStateManager.DeviceStateCallback> callbackCaptor =
                ArgumentCaptor.forClass(DeviceStateManager.DeviceStateCallback.class);
Loading