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

Commit b714bfda authored by Matt Pietal's avatar Matt Pietal
Browse files

Support smooth notification reveal...

...when the user has chosen not to see notifs on
the lockscreen, pulls down the shade, is prompted
to unlock, and then unlocks. There is a built-in
notif animation for this. Immediately set max
notifications to reveal all when unlocked in this
way.

Fixes: 329195944
Test: atest BouncerToGoneFlowsTest
Flag: ACONFIG com.android.systemui.migrate_clocks_to_blueprint
TEAMFOOD

Change-Id: I3a618e756b69b1f4e1bce371d3f97bf202d83b00
parent ebba16b2
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.domain.interactor.mockPrimaryBouncerInteractor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.Flags
import com.android.systemui.flags.fakeFeatureFlagsClassic
@@ -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
    fun scrimBehindAlpha_doNotLeaveShadeOpen() =
        testScope.runTest {
+4 −0
Original line number Diff line number Diff line
@@ -81,6 +81,10 @@ constructor(
        )
    }

    /** See [BouncerToGoneFlows#showAllNotifications] */
    val showAllNotifications: Flow<Boolean> =
        bouncerToGoneFlows.showAllNotifications(TO_GONE_DURATION, ALTERNATE_BOUNCER)

    /** Scrim alpha values */
    val scrimAlpha: Flow<ScrimAlpha> =
        bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, ALTERNATE_BOUNCER)
+26 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import javax.inject.Inject
import kotlin.time.Duration
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map

@@ -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(
        duration: Duration,
        fromState: KeyguardState,
+4 −0
Original line number Diff line number Diff line
@@ -60,6 +60,10 @@ constructor(
    private var leaveShadeOpen: 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> =
        transitionAnimation.sharedFlow(
            duration = 200.milliseconds,
+7 −2
Original line number Diff line number Diff line
@@ -589,8 +589,13 @@ constructor(
            combine(
                isOnLockscreen,
                keyguardInteractor.statusBarState,
            ) { isOnLockscreen, statusBarState ->
                statusBarState == SHADE_LOCKED || !isOnLockscreen
                merge(
                        primaryBouncerToGoneTransitionViewModel.showAllNotifications,
                        alternateBouncerToGoneTransitionViewModel.showAllNotifications,
                    )
                    .onStart { emit(false) }
            ) { isOnLockscreen, statusBarState, showAllNotifications ->
                statusBarState == SHADE_LOCKED || !isOnLockscreen || showAllNotifications
            }

        return combineTransform(