diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java index 36319380ad50d..63d4d6becc27e 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java @@ -163,16 +163,12 @@ public class DozeScreenState implements DozeMachine.Part { // Delay screen state transitions even longer while animations are running. boolean shouldDelayTransitionEnteringDoze = newState == DOZE_AOD - && mParameters.shouldControlScreenOff() && !turningOn; + && mParameters.shouldDelayDisplayDozeTransition() && !turningOn; // Delay screen state transition longer if UDFPS is actively authenticating a fp boolean shouldDelayTransitionForUDFPS = newState == DOZE_AOD && mUdfpsController != null && mUdfpsController.isFingerDown(); - if (shouldDelayTransitionEnteringDoze || shouldDelayTransitionForUDFPS) { - mWakeLock.setAcquired(true); - } - if (!messagePending) { if (DEBUG) { Log.d(TAG, "Display state changed to " + screenState + " delayed by " @@ -180,6 +176,18 @@ public class DozeScreenState implements DozeMachine.Part { } if (shouldDelayTransitionEnteringDoze) { + if (justInitialized) { + // If we are delaying transitioning to doze and the display was not + // turned on we set it to 'on' first to make sure that the animation + // is visible before eventually moving it to doze state. + // The display might be off at this point for example on foldable devices + // when we switch displays and go to doze at the same time. + applyScreenState(Display.STATE_ON); + + // Restore pending screen state as it gets cleared by 'applyScreenState' + mPendingScreenState = screenState; + } + mHandler.postDelayed(mApplyPendingScreenState, ENTER_DOZE_DELAY); } else if (shouldDelayTransitionForUDFPS) { mDozeLog.traceDisplayStateDelayedByUdfps(mPendingScreenState); @@ -190,6 +198,10 @@ public class DozeScreenState implements DozeMachine.Part { } else if (DEBUG) { Log.d(TAG, "Pending display state change to " + screenState); } + + if (shouldDelayTransitionEnteringDoze || shouldDelayTransitionForUDFPS) { + mWakeLock.setAcquired(true); + } } else if (turningOff) { mDozeHost.prepareForGentleSleep(() -> applyScreenState(screenState)); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt index c8115e2c197a2..9a932bae833e8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt @@ -355,7 +355,8 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, } override fun onDraw(canvas: Canvas?) { - if (canvas == null || revealGradientWidth <= 0 || revealGradientHeight <= 0) { + if (canvas == null || revealGradientWidth <= 0 || revealGradientHeight <= 0 + || revealAmount == 0f) { if (revealAmount < 1f) { canvas?.drawColor(revealGradientEndColor) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 1b42b58a55aa8..d610b372702df 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -304,6 +304,14 @@ public class DozeParameters implements return mScreenOffAnimationController.shouldAnimateDozingChange(); } + /** + * When this method returns true then moving display state to power save mode will be + * delayed for a few seconds. This might be useful to play animations without reducing FPS. + */ + public boolean shouldDelayDisplayDozeTransition() { + return mScreenOffAnimationController.shouldDelayDisplayDozeTransition(); + } + /** * Whether we're capable of controlling the screen off animation if we want to. This isn't * possible if AOD isn't even enabled or if the flag is disabled. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt index e806ca0d9005d..091831f360222 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt @@ -179,6 +179,14 @@ class ScreenOffAnimationController @Inject constructor( fun shouldAnimateDozingChange(): Boolean = animations.all { it.shouldAnimateDozingChange() } + /** + * Returns true when moving display state to power save mode should be + * delayed for a few seconds. This might be useful to play animations in full quality, + * without reducing FPS. + */ + fun shouldDelayDisplayDozeTransition(): Boolean = + animations.any { it.shouldDelayDisplayDozeTransition() } + /** * Return true to animate large <-> small clock transition */ @@ -207,6 +215,7 @@ interface ScreenOffAnimation { fun shouldHideScrimOnWakeUp(): Boolean = false fun overrideNotificationsDozeAmount(): Boolean = false fun shouldShowAodIconsWhenShade(): Boolean = false + fun shouldDelayDisplayDozeTransition(): Boolean = false fun shouldAnimateAodIcons(): Boolean = true fun shouldAnimateDozingChange(): Boolean = true fun shouldAnimateClockChange(): Boolean = true diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java index f8b0535b7ec7d..72237b1ca6c6c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java @@ -123,7 +123,8 @@ public class ShadeControllerImpl implements ShadeController { + " canPanelBeCollapsed(): " + getNotificationPanelViewController().canPanelBeCollapsed()); if (getNotificationShadeWindowView() != null - && getNotificationPanelViewController().canPanelBeCollapsed()) { + && getNotificationPanelViewController().canPanelBeCollapsed() + && (flags & CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL) == 0) { // release focus immediately to kick off focus change transition mNotificationShadeWindowController.setNotificationShadeFocusable(false); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index fdced64bf1c0c..07ae33c42c213 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -268,6 +268,7 @@ public class StatusBar extends CoreStartable implements // Should match the values in PhoneWindowManager public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; + public static final String SYSTEM_DIALOG_REASON_DREAM = "dream"; static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot"; private static final String BANNER_ACTION_CANCEL = @@ -2635,8 +2636,17 @@ public class StatusBar extends CoreStartable implements if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) { int flags = CommandQueue.FLAG_EXCLUDE_NONE; String reason = intent.getStringExtra("reason"); - if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { - flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL; + if (reason != null) { + if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) { + flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL; + } + // Do not collapse notifications when starting dreaming if the notifications + // shade is used for the screen off animation. It might require expanded + // state for the scrims to be visible + if (reason.equals(SYSTEM_DIALOG_REASON_DREAM) + && mScreenOffAnimationController.shouldExpandNotifications()) { + flags |= CommandQueue.FLAG_EXCLUDE_NOTIFICATION_PANEL; + } } mShadeController.animateCollapsePanels(flags); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt index ea0dd72d673f5..6746b3e8883a9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt @@ -290,6 +290,9 @@ class UnlockedScreenOffAnimationController @Inject constructor( return true } + override fun shouldDelayDisplayDozeTransition(): Boolean = + dozeParameters.get().shouldControlUnlockedScreenOff() + fun addCallback(callback: Callback) { callbacks.add(callback) } diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt index 4f037a0f1acec..aaf35afe936d9 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt @@ -136,6 +136,8 @@ constructor( override fun shouldAnimateClockChange(): Boolean = !isAnimationPlaying() + override fun shouldDelayDisplayDozeTransition(): Boolean = shouldPlayAnimation() + /** Called when AOD status is changed */ override fun onAlwaysOnChanged(alwaysOn: Boolean) { alwaysOnEnabled = alwaysOn diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java index 3e19cc436dca6..cdffaecadd77a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenStateTest.java @@ -192,7 +192,7 @@ public class DozeScreenStateTest extends SysuiTestCase { public void test_holdsWakeLockWhenGoingToLowPowerDelayed() { // Transition to low power mode will be delayed to let // animations play at 60 fps. - when(mDozeParameters.shouldControlScreenOff()).thenReturn(true); + when(mDozeParameters.shouldDelayDisplayDozeTransition()).thenReturn(true); mHandlerFake.setMode(QUEUEING); mScreen.transitionTo(UNINITIALIZED, INITIALIZED); @@ -209,7 +209,7 @@ public class DozeScreenStateTest extends SysuiTestCase { public void test_releasesWakeLock_abortingLowPowerDelayed() { // Transition to low power mode will be delayed to let // animations play at 60 fps. - when(mDozeParameters.shouldControlScreenOff()).thenReturn(true); + when(mDozeParameters.shouldDelayDisplayDozeTransition()).thenReturn(true); mHandlerFake.setMode(QUEUEING); mScreen.transitionTo(UNINITIALIZED, INITIALIZED);