diff options
2 files changed, 75 insertions, 7 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt index 0641c610aaff..f7756d82a956 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt @@ -701,6 +701,32 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { assertThat(fadeIn).isEqualTo(false) } + @Test + fun shadeCollapseFadeIn_doesNotRunIfTransitioningToAod() = + testScope.runTest { + val fadeIn by collectLastValue(underTest.shadeCollapseFadeIn) + + // Start on lockscreen without the shade + underTest.setShadeCollapseFadeInComplete(false) + showLockscreen() + assertThat(fadeIn).isEqualTo(false) + + // ... then the shade expands + showLockscreenWithShadeExpanded() + assertThat(fadeIn).isEqualTo(false) + + // ... then user hits power to go to AOD + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + testScope, + ) + // ... followed by a shade collapse + showLockscreen() + // ... does not trigger a fade in + assertThat(fadeIn).isEqualTo(false) + } + private suspend fun TestScope.showLockscreen() { shadeRepository.setLockscreenShadeExpansion(0f) shadeRepository.setQsExpansion(0f) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt index a15d829ade07..b4c88c5f9e79 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt @@ -79,6 +79,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.transformWhile import kotlinx.coroutines.isActive /** View-model for the shared notification container, used by both the shade and keyguard spaces */ @@ -89,7 +90,7 @@ constructor( private val interactor: SharedNotificationContainerInteractor, @Application applicationScope: CoroutineScope, private val keyguardInteractor: KeyguardInteractor, - keyguardTransitionInteractor: KeyguardTransitionInteractor, + private val keyguardTransitionInteractor: KeyguardTransitionInteractor, private val shadeInteractor: ShadeInteractor, communalInteractor: CommunalInteractor, private val alternateBouncerToGoneTransitionViewModel: @@ -222,19 +223,60 @@ constructor( initialValue = false, ) + /** + * Fade in if the user swipes the shade back up, not if collapsed by going to AOD. This is + * needed due to the lack of a SHADE state with existing keyguard transitions. + */ + private fun awaitCollapse(): Flow<Boolean> { + var aodTransitionIsComplete = true + return combine( + isOnLockscreenWithoutShade, + keyguardTransitionInteractor + .isInTransitionWhere( + fromStatePredicate = { it == LOCKSCREEN }, + toStatePredicate = { it == AOD } + ) + .onStart { emit(false) }, + ::Pair + ) + .transformWhile { (isOnLockscreenWithoutShade, aodTransitionIsRunning) -> + // Wait until the AOD transition is complete before terminating + if (!aodTransitionIsComplete && !aodTransitionIsRunning) { + aodTransitionIsComplete = true + emit(false) // do not fade in + false + } else if (aodTransitionIsRunning) { + aodTransitionIsComplete = false + true + } else if (isOnLockscreenWithoutShade) { + // Shade is closed, fade in and terminate + emit(true) + false + } else { + true + } + } + } + /** Fade in only for use after the shade collapses */ val shadeCollapseFadeIn: Flow<Boolean> = flow { while (currentCoroutineContext().isActive) { + // Ensure shade is collapsed + isShadeLocked.first { !it } emit(false) // Wait for shade to be fully expanded isShadeLocked.first { it } - // ... and then for it to be collapsed - isOnLockscreenWithoutShade.first { it } - emit(true) - // ... and then for the animation to complete - shadeCollapseFadeInComplete.first { it } - shadeCollapseFadeInComplete.value = false + // ... and then for it to be collapsed OR a transition to AOD begins. + // If AOD, do not fade in (a fade out occurs instead). + awaitCollapse().collect { doFadeIn -> + if (doFadeIn) { + emit(true) + // ... and then for the animation to complete + shadeCollapseFadeInComplete.first { it } + shadeCollapseFadeInComplete.value = false + } + } } } .stateIn( |