Loading packages/SystemUI/multivalentTests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt +11 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import androidx.test.filters.SmallTest import com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.shade.display.PendingDisplayChangeController import com.android.systemui.unfold.FoldAodAnimationController import com.android.systemui.unfold.FullscreenLightRevealAnimation import com.android.systemui.unfold.SysUIUnfoldComponent Loading Loading @@ -57,6 +58,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { private lateinit var fullscreenLightRevealAnimation: FullscreenLightRevealAnimation @Mock private lateinit var fullScreenLightRevealAnimations: Set<FullscreenLightRevealAnimation> @Mock private lateinit var pendingDisplayChangeController: PendingDisplayChangeController @Captor private lateinit var readyCaptor: ArgumentCaptor<Runnable> Loading @@ -78,7 +81,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { screenOnCoordinator = ScreenOnCoordinator( Optional.of(unfoldComponent), testHandler testHandler, pendingDisplayChangeController, ) } Loading Loading @@ -128,7 +132,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { // Recreate with empty unfoldComponent screenOnCoordinator = ScreenOnCoordinator( Optional.empty(), testHandler testHandler, pendingDisplayChangeController, ) screenOnCoordinator.onScreenTurningOn(reason = SCREEN_TURNING_ON_REASON_UNKNOWN, runnable) waitHandlerIdle() Loading @@ -142,7 +147,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { // Recreate with empty unfoldComponent screenOnCoordinator = ScreenOnCoordinator( Optional.empty(), testHandler testHandler, pendingDisplayChangeController, ) screenOnCoordinator.onScreenTurningOn(reason = SCREEN_TURNING_ON_REASON_UNKNOWN, runnable) Loading @@ -156,7 +162,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { // Recreate with empty unfoldComponent screenOnCoordinator = ScreenOnCoordinator( Optional.empty(), testHandler testHandler, pendingDisplayChangeController, ) screenOnCoordinator.onScreenTurningOn(reason = SCREEN_TURNING_ON_REASON_UNKNOWN, runnable) // No need to wait for the handler to be idle, as it shouldn't be used Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.shade; import static android.service.dreams.Flags.FLAG_DREAMS_V2; import static com.android.window.flags.Flags.FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; Loading Loading @@ -274,6 +275,31 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isTrue(); } @EnableFlags(FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH) @Test public void attach_pendingDisplayChange_wallpaperVisible() { mNotificationShadeWindowController.attach(); clearInvocations(mWindowManager); mNotificationShadeWindowController.setPendingDisplayChange(true); verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture()); assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isTrue(); } @EnableFlags(FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH) @Test public void attach_pendingDisplayChangeFinished_wallpaperNotVisible() { mNotificationShadeWindowController.attach(); mNotificationShadeWindowController.setPendingDisplayChange(true); clearInvocations(mWindowManager); mNotificationShadeWindowController.setPendingDisplayChange(false); verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture()); assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isFalse(); } @Test public void setBouncerShowing_isFocusable_whenNeedsInput() { mNotificationShadeWindowController.setKeyguardNeedsInput(true); Loading packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/PendingDisplayChangeControllerTest.kt 0 → 100644 +173 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.shade.display import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH import com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN import com.android.systemui.SysuiTestCase import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.verifyCurrent import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.power.shared.model.ScreenPowerState import com.android.systemui.statusbar.notificationShadeWindowController import com.android.systemui.testKosmos import kotlinx.coroutines.test.advanceTimeBy import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.inOrder import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @SmallTest @RunWith(AndroidJUnit4::class) @EnableFlags(com.android.window.flags.Flags.FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH) class PendingDisplayChangeControllerTest : SysuiTestCase() { private val kosmos = testKosmos() private val powerRepository = kosmos.fakePowerRepository private lateinit var underTest: PendingDisplayChangeController @Test fun onScreenTurningOnWithDisplaySwitching_notifiesShadeWindowController() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) verifyCurrent(notificationShadeWindowController).setPendingDisplayChange(true) } @Test fun onScreenTurningOnWithDisplaySwitching_notifiesScreenTurningOnComplete() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, onScreenTurningOnComplete) verifyCurrent(onScreenTurningOnComplete).run() } @Test fun onScreenTurningWithoutDisplaySwitching_notifiesScreenTurningOnComplete() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_UNKNOWN, onScreenTurningOnComplete) verifyCurrent(onScreenTurningOnComplete).run() } @Test fun onScreenTurningWithoutDisplaySwitching_doesNotSetPendingScreenState() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_UNKNOWN, onScreenTurningOnComplete) runCurrent() verify(notificationShadeWindowController, never()).setPendingDisplayChange(anyBoolean()) } @Test fun onScreenTurningOnWithDisplaySwitching_screenTurnedOn_resetsPendingDisplayChange() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) runCurrent() clearInvocations(notificationShadeWindowController) powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) verifyCurrent(notificationShadeWindowController).setPendingDisplayChange(false) } @Test fun onScreenTurningOnWithDisplaySwitching_screenTurningOnTimeout_resetsPendingDisplayChange() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) runCurrent() clearInvocations(notificationShadeWindowController) testScope.advanceTimeBy(15.seconds) verify(notificationShadeWindowController).setPendingDisplayChange(false) } @Test fun onScreenTurningOnWithDisplaySwitching_beforeTurningOnTimeout_noPendingDisplayChange() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) runCurrent() clearInvocations(notificationShadeWindowController) testScope.advanceTimeBy(100.milliseconds) verifyNoInteractions(notificationShadeWindowController) } @Test fun onScreenTurningOnWithDisplaySwitching_previousOneIsStillInProgress_processesBoth() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete1 = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, onScreenTurningOnComplete1) runCurrent() val onScreenTurningOnComplete2 = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, onScreenTurningOnComplete2) runCurrent() powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) verifyCurrent(onScreenTurningOnComplete1).run() verifyCurrent(onScreenTurningOnComplete2).run() inOrder(notificationShadeWindowController) { verify(notificationShadeWindowController).setPendingDisplayChange(true) verify(notificationShadeWindowController).setPendingDisplayChange(false) verify(notificationShadeWindowController).setPendingDisplayChange(true) verify(notificationShadeWindowController).setPendingDisplayChange(false) } } private fun Kosmos.createAndStartController() { underTest = PendingDisplayChangeController( testScope.backgroundScope, testScope.backgroundScope, { notificationShadeWindowController }, powerInteractor ).also { it.start() } runCurrent() } } No newline at end of file packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt +8 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.os.Trace import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.shade.display.EnsureWallpaperDrawnOnDisplaySwitch import com.android.systemui.shade.display.PendingDisplayChangeController import com.android.systemui.unfold.SysUIUnfoldComponent import com.android.systemui.util.concurrency.PendingTasksContainer import com.android.systemui.util.kotlin.getOrNull Loading @@ -40,6 +42,7 @@ class ScreenOnCoordinator constructor( unfoldComponent: Optional<SysUIUnfoldComponent>, @Main private val mainHandler: Handler, private val pendingDisplayChangeController: PendingDisplayChangeController ) { private val foldAodAnimationController = Loading @@ -63,6 +66,11 @@ constructor( it.onScreenTurningOn(pendingTasks.registerTask(it::class.java.simpleName)) } if (EnsureWallpaperDrawnOnDisplaySwitch.isEnabled) { pendingDisplayChangeController.onScreenTurningOn(reason, pendingTasks.registerTask("pending-display-change-controller")); } pendingTasks.onTasksComplete { if (Flags.enableBackgroundKeyguardOndrawnCallback()) { // called by whatever thread completes the last task registered. Loading packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +15 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.systemui.res.R; import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.scene.ui.view.WindowRootViewComponent; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.display.EnsureWallpaperDrawnOnDisplaySwitch; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.shade.ui.viewmodel.NotificationShadeWindowModel; import com.android.systemui.statusbar.NotificationShadeWindowController; Loading Loading @@ -402,7 +403,9 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW final boolean keyguardOrAod = state.keyguardShowing || (state.dozing && mDozeParameters.getAlwaysOn()); if ((keyguardOrAod && !state.mediaBackdropShowing && !state.lightRevealScrimOpaque) || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()) { || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind() || (EnsureWallpaperDrawnOnDisplaySwitch.isEnabled() && state.pendingDisplayChange) ) { // Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a // solid backdrop. Also, show it if we are currently animating between the // keyguard and the surface behind the keyguard - we want to use the wallpaper as a Loading Loading @@ -655,6 +658,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW state.qsExpanded, state.headsUpNotificationShowing, state.lightRevealScrimOpaque, state.pendingDisplayChange, state.isSwitchingUsers, state.forceWindowCollapsed, state.forceDozeBrightness, Loading Loading @@ -896,6 +900,16 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW apply(mCurrentState); } @Override public void setPendingDisplayChange(boolean pendingDisplayChange) { if (EnsureWallpaperDrawnOnDisplaySwitch.isUnexpectedlyInLegacyMode() || mCurrentState.pendingDisplayChange == pendingDisplayChange) { return; } mCurrentState.pendingDisplayChange = pendingDisplayChange; apply(mCurrentState); } /** * @param state The {@link StatusBarStateController} of the status bar. */ Loading Loading
packages/SystemUI/multivalentTests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt +11 −4 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import androidx.test.filters.SmallTest import com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN import com.android.systemui.Flags import com.android.systemui.SysuiTestCase import com.android.systemui.shade.display.PendingDisplayChangeController import com.android.systemui.unfold.FoldAodAnimationController import com.android.systemui.unfold.FullscreenLightRevealAnimation import com.android.systemui.unfold.SysUIUnfoldComponent Loading Loading @@ -57,6 +58,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { private lateinit var fullscreenLightRevealAnimation: FullscreenLightRevealAnimation @Mock private lateinit var fullScreenLightRevealAnimations: Set<FullscreenLightRevealAnimation> @Mock private lateinit var pendingDisplayChangeController: PendingDisplayChangeController @Captor private lateinit var readyCaptor: ArgumentCaptor<Runnable> Loading @@ -78,7 +81,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { screenOnCoordinator = ScreenOnCoordinator( Optional.of(unfoldComponent), testHandler testHandler, pendingDisplayChangeController, ) } Loading Loading @@ -128,7 +132,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { // Recreate with empty unfoldComponent screenOnCoordinator = ScreenOnCoordinator( Optional.empty(), testHandler testHandler, pendingDisplayChangeController, ) screenOnCoordinator.onScreenTurningOn(reason = SCREEN_TURNING_ON_REASON_UNKNOWN, runnable) waitHandlerIdle() Loading @@ -142,7 +147,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { // Recreate with empty unfoldComponent screenOnCoordinator = ScreenOnCoordinator( Optional.empty(), testHandler testHandler, pendingDisplayChangeController, ) screenOnCoordinator.onScreenTurningOn(reason = SCREEN_TURNING_ON_REASON_UNKNOWN, runnable) Loading @@ -156,7 +162,8 @@ class ScreenOnCoordinatorTest : SysuiTestCase() { // Recreate with empty unfoldComponent screenOnCoordinator = ScreenOnCoordinator( Optional.empty(), testHandler testHandler, pendingDisplayChangeController, ) screenOnCoordinator.onScreenTurningOn(reason = SCREEN_TURNING_ON_REASON_UNKNOWN, runnable) // No need to wait for the handler to be idle, as it shouldn't be used Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +26 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.shade; import static android.service.dreams.Flags.FLAG_DREAMS_V2; import static com.android.window.flags.Flags.FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; Loading Loading @@ -274,6 +275,31 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isTrue(); } @EnableFlags(FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH) @Test public void attach_pendingDisplayChange_wallpaperVisible() { mNotificationShadeWindowController.attach(); clearInvocations(mWindowManager); mNotificationShadeWindowController.setPendingDisplayChange(true); verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture()); assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isTrue(); } @EnableFlags(FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH) @Test public void attach_pendingDisplayChangeFinished_wallpaperNotVisible() { mNotificationShadeWindowController.attach(); mNotificationShadeWindowController.setPendingDisplayChange(true); clearInvocations(mWindowManager); mNotificationShadeWindowController.setPendingDisplayChange(false); verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture()); assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isFalse(); } @Test public void setBouncerShowing_isFocusable_whenNeedsInput() { mNotificationShadeWindowController.setKeyguardNeedsInput(true); Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/shade/display/PendingDisplayChangeControllerTest.kt 0 → 100644 +173 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.shade.display import android.platform.test.annotations.EnableFlags import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH import com.android.internal.policy.IKeyguardService.SCREEN_TURNING_ON_REASON_UNKNOWN import com.android.systemui.SysuiTestCase import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.runTest import com.android.systemui.kosmos.testScope import com.android.systemui.kosmos.runCurrent import com.android.systemui.kosmos.verifyCurrent import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.power.domain.interactor.powerInteractor import com.android.systemui.power.shared.model.ScreenPowerState import com.android.systemui.statusbar.notificationShadeWindowController import com.android.systemui.testKosmos import kotlinx.coroutines.test.advanceTimeBy import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyBoolean import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.inOrder import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoInteractions import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @SmallTest @RunWith(AndroidJUnit4::class) @EnableFlags(com.android.window.flags.Flags.FLAG_ENSURE_WALLPAPER_DRAWN_ON_DISPLAY_SWITCH) class PendingDisplayChangeControllerTest : SysuiTestCase() { private val kosmos = testKosmos() private val powerRepository = kosmos.fakePowerRepository private lateinit var underTest: PendingDisplayChangeController @Test fun onScreenTurningOnWithDisplaySwitching_notifiesShadeWindowController() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) verifyCurrent(notificationShadeWindowController).setPendingDisplayChange(true) } @Test fun onScreenTurningOnWithDisplaySwitching_notifiesScreenTurningOnComplete() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, onScreenTurningOnComplete) verifyCurrent(onScreenTurningOnComplete).run() } @Test fun onScreenTurningWithoutDisplaySwitching_notifiesScreenTurningOnComplete() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_UNKNOWN, onScreenTurningOnComplete) verifyCurrent(onScreenTurningOnComplete).run() } @Test fun onScreenTurningWithoutDisplaySwitching_doesNotSetPendingScreenState() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_UNKNOWN, onScreenTurningOnComplete) runCurrent() verify(notificationShadeWindowController, never()).setPendingDisplayChange(anyBoolean()) } @Test fun onScreenTurningOnWithDisplaySwitching_screenTurnedOn_resetsPendingDisplayChange() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) runCurrent() clearInvocations(notificationShadeWindowController) powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) verifyCurrent(notificationShadeWindowController).setPendingDisplayChange(false) } @Test fun onScreenTurningOnWithDisplaySwitching_screenTurningOnTimeout_resetsPendingDisplayChange() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) runCurrent() clearInvocations(notificationShadeWindowController) testScope.advanceTimeBy(15.seconds) verify(notificationShadeWindowController).setPendingDisplayChange(false) } @Test fun onScreenTurningOnWithDisplaySwitching_beforeTurningOnTimeout_noPendingDisplayChange() = kosmos.runTest { createAndStartController() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, mock<Runnable>()) runCurrent() clearInvocations(notificationShadeWindowController) testScope.advanceTimeBy(100.milliseconds) verifyNoInteractions(notificationShadeWindowController) } @Test fun onScreenTurningOnWithDisplaySwitching_previousOneIsStillInProgress_processesBoth() = kosmos.runTest { createAndStartController() val onScreenTurningOnComplete1 = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, onScreenTurningOnComplete1) runCurrent() val onScreenTurningOnComplete2 = mock<Runnable>() underTest.onScreenTurningOn(SCREEN_TURNING_ON_REASON_DISPLAY_SWITCH, onScreenTurningOnComplete2) runCurrent() powerRepository.setScreenPowerState(ScreenPowerState.SCREEN_ON) verifyCurrent(onScreenTurningOnComplete1).run() verifyCurrent(onScreenTurningOnComplete2).run() inOrder(notificationShadeWindowController) { verify(notificationShadeWindowController).setPendingDisplayChange(true) verify(notificationShadeWindowController).setPendingDisplayChange(false) verify(notificationShadeWindowController).setPendingDisplayChange(true) verify(notificationShadeWindowController).setPendingDisplayChange(false) } } private fun Kosmos.createAndStartController() { underTest = PendingDisplayChangeController( testScope.backgroundScope, testScope.backgroundScope, { notificationShadeWindowController }, powerInteractor ).also { it.start() } runCurrent() } } No newline at end of file
packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt +8 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ import android.os.Trace import com.android.systemui.Flags import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.shade.display.EnsureWallpaperDrawnOnDisplaySwitch import com.android.systemui.shade.display.PendingDisplayChangeController import com.android.systemui.unfold.SysUIUnfoldComponent import com.android.systemui.util.concurrency.PendingTasksContainer import com.android.systemui.util.kotlin.getOrNull Loading @@ -40,6 +42,7 @@ class ScreenOnCoordinator constructor( unfoldComponent: Optional<SysUIUnfoldComponent>, @Main private val mainHandler: Handler, private val pendingDisplayChangeController: PendingDisplayChangeController ) { private val foldAodAnimationController = Loading @@ -63,6 +66,11 @@ constructor( it.onScreenTurningOn(pendingTasks.registerTask(it::class.java.simpleName)) } if (EnsureWallpaperDrawnOnDisplaySwitch.isEnabled) { pendingDisplayChangeController.onScreenTurningOn(reason, pendingTasks.registerTask("pending-display-change-controller")); } pendingTasks.onTasksComplete { if (Flags.enableBackgroundKeyguardOndrawnCallback()) { // called by whatever thread completes the last task registered. Loading
packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +15 −1 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import com.android.systemui.res.R; import com.android.systemui.scene.shared.flag.SceneContainerFlag; import com.android.systemui.scene.ui.view.WindowRootViewComponent; import com.android.systemui.settings.UserTracker; import com.android.systemui.shade.display.EnsureWallpaperDrawnOnDisplaySwitch; import com.android.systemui.shade.domain.interactor.ShadeInteractor; import com.android.systemui.shade.ui.viewmodel.NotificationShadeWindowModel; import com.android.systemui.statusbar.NotificationShadeWindowController; Loading Loading @@ -402,7 +403,9 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW final boolean keyguardOrAod = state.keyguardShowing || (state.dozing && mDozeParameters.getAlwaysOn()); if ((keyguardOrAod && !state.mediaBackdropShowing && !state.lightRevealScrimOpaque) || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()) { || mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind() || (EnsureWallpaperDrawnOnDisplaySwitch.isEnabled() && state.pendingDisplayChange) ) { // Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a // solid backdrop. Also, show it if we are currently animating between the // keyguard and the surface behind the keyguard - we want to use the wallpaper as a Loading Loading @@ -655,6 +658,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW state.qsExpanded, state.headsUpNotificationShowing, state.lightRevealScrimOpaque, state.pendingDisplayChange, state.isSwitchingUsers, state.forceWindowCollapsed, state.forceDozeBrightness, Loading Loading @@ -896,6 +900,16 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW apply(mCurrentState); } @Override public void setPendingDisplayChange(boolean pendingDisplayChange) { if (EnsureWallpaperDrawnOnDisplaySwitch.isUnexpectedlyInLegacyMode() || mCurrentState.pendingDisplayChange == pendingDisplayChange) { return; } mCurrentState.pendingDisplayChange = pendingDisplayChange; apply(mCurrentState); } /** * @param state The {@link StatusBarStateController} of the status bar. */ Loading