Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt +33 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.coroutines.collectValues import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.flags.fakeFeatureFlagsClassic Loading Loading @@ -148,6 +149,38 @@ class BouncerToGoneFlowsTest : SysuiTestCase() { } } } } @Test fun showAllNotifications_isTrue_whenLeaveShadeOpen() = testScope.runTest { val showAllNotifications by collectLastValue(underTest.showAllNotifications(500.milliseconds, PRIMARY_BOUNCER)) sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true) keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED)) keyguardTransitionRepository.sendTransitionStep(step(0.1f)) assertThat(showAllNotifications).isTrue() keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED)) assertThat(showAllNotifications).isFalse() } @Test fun showAllNotifications_isFalse_whenLeaveShadeIsNotOpen() = testScope.runTest { val showAllNotifications by collectLastValue(underTest.showAllNotifications(500.milliseconds, PRIMARY_BOUNCER)) sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(false) keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED)) keyguardTransitionRepository.sendTransitionStep(step(0.1f)) assertThat(showAllNotifications).isFalse() keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED)) assertThat(showAllNotifications).isFalse() } @Test @Test fun scrimBehindAlpha_doNotLeaveShadeOpen() = fun scrimBehindAlpha_doNotLeaveShadeOpen() = testScope.runTest { testScope.runTest { Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,10 @@ constructor( ) ) } } /** See [BouncerToGoneFlows#showAllNotifications] */ val showAllNotifications: Flow<Boolean> = bouncerToGoneFlows.showAllNotifications(TO_GONE_DURATION, ALTERNATE_BOUNCER) /** Scrim alpha values */ /** Scrim alpha values */ val scrimAlpha: Flow<ScrimAlpha> = val scrimAlpha: Flow<ScrimAlpha> = bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, ALTERNATE_BOUNCER) bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, ALTERNATE_BOUNCER) Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt +26 −0 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ import javax.inject.Inject import kotlin.time.Duration import kotlin.time.Duration import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map Loading Loading @@ -63,6 +64,31 @@ constructor( } } } } /** * When the shade is expanded, make sure that all notifications can be seen immediately during a * transition to GONE. This matters especially when the user has chosen to not show * notifications on the lockscreen and then pulls down the shade, which presents them with an * immediate auth prompt, followed by a notification animation. */ fun showAllNotifications(duration: Duration, from: KeyguardState): Flow<Boolean> { var leaveShadeOpen = false return animationFlow .setup( duration = duration, from = from, to = GONE, ) .sharedFlow( duration = duration, onStart = { leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() }, onStep = { if (leaveShadeOpen) 1f else 0f }, onFinish = { 0f }, onCancel = { 0f }, ) .map { it == 1f } .distinctUntilChanged() } private fun createScrimAlphaFlow( private fun createScrimAlphaFlow( duration: Duration, duration: Duration, fromState: KeyguardState, fromState: KeyguardState, Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,10 @@ constructor( private var leaveShadeOpen: Boolean = false private var leaveShadeOpen: Boolean = false private var willRunDismissFromKeyguard: Boolean = false private var willRunDismissFromKeyguard: Boolean = false /** See [BouncerToGoneFlows#showAllNotifications] */ val showAllNotifications: Flow<Boolean> = bouncerToGoneFlows.showAllNotifications(TO_GONE_DURATION, PRIMARY_BOUNCER) val notificationAlpha: Flow<Float> = val notificationAlpha: Flow<Float> = transitionAnimation.sharedFlow( transitionAnimation.sharedFlow( duration = 200.milliseconds, duration = 200.milliseconds, Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt +7 −2 Original line number Original line Diff line number Diff line Loading @@ -589,8 +589,13 @@ constructor( combine( combine( isOnLockscreen, isOnLockscreen, keyguardInteractor.statusBarState, keyguardInteractor.statusBarState, ) { isOnLockscreen, statusBarState -> merge( statusBarState == SHADE_LOCKED || !isOnLockscreen primaryBouncerToGoneTransitionViewModel.showAllNotifications, alternateBouncerToGoneTransitionViewModel.showAllNotifications, ) .onStart { emit(false) } ) { isOnLockscreen, statusBarState, showAllNotifications -> statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications } } return combineTransform( return combineTransform( Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt +33 −0 Original line number Original line Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectValues import com.android.systemui.coroutines.collectValues import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags import com.android.systemui.flags.fakeFeatureFlagsClassic import com.android.systemui.flags.fakeFeatureFlagsClassic Loading Loading @@ -148,6 +149,38 @@ class BouncerToGoneFlowsTest : SysuiTestCase() { } } } } @Test fun showAllNotifications_isTrue_whenLeaveShadeOpen() = testScope.runTest { val showAllNotifications by collectLastValue(underTest.showAllNotifications(500.milliseconds, PRIMARY_BOUNCER)) sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(true) keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED)) keyguardTransitionRepository.sendTransitionStep(step(0.1f)) assertThat(showAllNotifications).isTrue() keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED)) assertThat(showAllNotifications).isFalse() } @Test fun showAllNotifications_isFalse_whenLeaveShadeIsNotOpen() = testScope.runTest { val showAllNotifications by collectLastValue(underTest.showAllNotifications(500.milliseconds, PRIMARY_BOUNCER)) sysuiStatusBarStateController.setLeaveOpenOnKeyguardHide(false) keyguardTransitionRepository.sendTransitionStep(step(0f, TransitionState.STARTED)) keyguardTransitionRepository.sendTransitionStep(step(0.1f)) assertThat(showAllNotifications).isFalse() keyguardTransitionRepository.sendTransitionStep(step(1f, TransitionState.FINISHED)) assertThat(showAllNotifications).isFalse() } @Test @Test fun scrimBehindAlpha_doNotLeaveShadeOpen() = fun scrimBehindAlpha_doNotLeaveShadeOpen() = testScope.runTest { testScope.runTest { Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,10 @@ constructor( ) ) } } /** See [BouncerToGoneFlows#showAllNotifications] */ val showAllNotifications: Flow<Boolean> = bouncerToGoneFlows.showAllNotifications(TO_GONE_DURATION, ALTERNATE_BOUNCER) /** Scrim alpha values */ /** Scrim alpha values */ val scrimAlpha: Flow<ScrimAlpha> = val scrimAlpha: Flow<ScrimAlpha> = bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, ALTERNATE_BOUNCER) bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, ALTERNATE_BOUNCER) Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt +26 −0 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ import javax.inject.Inject import kotlin.time.Duration import kotlin.time.Duration import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map Loading Loading @@ -63,6 +64,31 @@ constructor( } } } } /** * When the shade is expanded, make sure that all notifications can be seen immediately during a * transition to GONE. This matters especially when the user has chosen to not show * notifications on the lockscreen and then pulls down the shade, which presents them with an * immediate auth prompt, followed by a notification animation. */ fun showAllNotifications(duration: Duration, from: KeyguardState): Flow<Boolean> { var leaveShadeOpen = false return animationFlow .setup( duration = duration, from = from, to = GONE, ) .sharedFlow( duration = duration, onStart = { leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() }, onStep = { if (leaveShadeOpen) 1f else 0f }, onFinish = { 0f }, onCancel = { 0f }, ) .map { it == 1f } .distinctUntilChanged() } private fun createScrimAlphaFlow( private fun createScrimAlphaFlow( duration: Duration, duration: Duration, fromState: KeyguardState, fromState: KeyguardState, Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt +4 −0 Original line number Original line Diff line number Diff line Loading @@ -60,6 +60,10 @@ constructor( private var leaveShadeOpen: Boolean = false private var leaveShadeOpen: Boolean = false private var willRunDismissFromKeyguard: Boolean = false private var willRunDismissFromKeyguard: Boolean = false /** See [BouncerToGoneFlows#showAllNotifications] */ val showAllNotifications: Flow<Boolean> = bouncerToGoneFlows.showAllNotifications(TO_GONE_DURATION, PRIMARY_BOUNCER) val notificationAlpha: Flow<Float> = val notificationAlpha: Flow<Float> = transitionAnimation.sharedFlow( transitionAnimation.sharedFlow( duration = 200.milliseconds, duration = 200.milliseconds, Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt +7 −2 Original line number Original line Diff line number Diff line Loading @@ -589,8 +589,13 @@ constructor( combine( combine( isOnLockscreen, isOnLockscreen, keyguardInteractor.statusBarState, keyguardInteractor.statusBarState, ) { isOnLockscreen, statusBarState -> merge( statusBarState == SHADE_LOCKED || !isOnLockscreen primaryBouncerToGoneTransitionViewModel.showAllNotifications, alternateBouncerToGoneTransitionViewModel.showAllNotifications, ) .onStart { emit(false) } ) { isOnLockscreen, statusBarState, showAllNotifications -> statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications } } return combineTransform( return combineTransform( Loading