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

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

Smooth out tap-to-expand notification

In this case the SHADE_LOCKED state is being received prior
to expansion events, so wait for both events before issuing
a call to fade when closing the shade. And don't fade in
notifications if you do this while pulsing.

Also, move tests to multivalent directory

Test: atest SharedNotificationsViewModelTest
AodToLockscreenTransitionViewModelTest
Fixes: 325729047
Flag: ACONFIG com.android.systemui.migrate_clocks_to_blueprint
DEVELOPMENT

Change-Id: Id81c1b662cfb31388f0d9d478e50fc0bc832e59f
parent 8251f755
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.data.repository.fakeShadeRepository
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -42,6 +43,7 @@ class AodToLockscreenTransitionViewModelTest : SysuiTestCase() {
    val kosmos = testKosmos()
    val testScope = kosmos.testScope
    val repository = kosmos.fakeKeyguardTransitionRepository
    val shadeRepository = kosmos.fakeShadeRepository
    val fingerprintPropertyRepository = kosmos.fingerprintPropertyRepository
    val underTest = kosmos.aodToLockscreenTransitionViewModel

@@ -58,6 +60,38 @@ class AodToLockscreenTransitionViewModelTest : SysuiTestCase() {
            deviceEntryParentViewAlpha.forEach { assertThat(it).isEqualTo(1f) }
        }

    @Test
    fun notificationAlpha_whenShadeIsExpanded_equalsOne() =
        testScope.runTest {
            val alpha by collectLastValue(underTest.notificationAlpha)

            shadeRepository.setQsExpansion(0.5f)
            runCurrent()

            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
            assertThat(alpha).isEqualTo(1f)
            repository.sendTransitionStep(step(0.5f))
            assertThat(alpha).isEqualTo(1f)
            repository.sendTransitionStep(step(1f))
            assertThat(alpha).isEqualTo(1f)
        }

    @Test
    fun notificationAlpha_whenShadeIsNotExpanded_usesTransitionValue() =
        testScope.runTest {
            val alpha by collectLastValue(underTest.notificationAlpha)

            shadeRepository.setQsExpansion(0f)
            runCurrent()

            repository.sendTransitionStep(step(0f, TransitionState.STARTED))
            assertThat(alpha).isEqualTo(0f)
            repository.sendTransitionStep(step(0.5f))
            assertThat(alpha).isEqualTo(0.5f)
            repository.sendTransitionStep(step(1f))
            assertThat(alpha).isEqualTo(1f)
        }

    @Test
    fun lockscreenAlphaStartsFromViewStateAccessorAlpha() =
        testScope.runTest {
+1 −1
Original line number Diff line number Diff line
@@ -681,7 +681,7 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() {
    @Test
    fun shadeCollapseFadeIn() =
        testScope.runTest {
            val fadeIn by collectLastValue(underTest.shadeCollpaseFadeIn)
            val fadeIn by collectLastValue(underTest.shadeCollapseFadeIn)

            // Start on lockscreen without the shade
            underTest.setShadeCollapseFadeInComplete(false)
+20 −5
Original line number Diff line number Diff line
@@ -25,10 +25,13 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map

/**
 * Breaks down AOD->LOCKSCREEN transition into discrete steps for corresponding views to consume.
@@ -39,6 +42,7 @@ class AodToLockscreenTransitionViewModel
@Inject
constructor(
    deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
    shadeInteractor: ShadeInteractor,
    animationFlow: KeyguardTransitionAnimationFlow,
) : DeviceEntryIconTransition {

@@ -73,11 +77,22 @@ constructor(
    }

    val notificationAlpha: Flow<Float> =
        combine(
            shadeInteractor.shadeExpansion.map { it > 0f },
            shadeInteractor.qsExpansion.map { it > 0f },
            transitionAnimation.sharedFlow(
                duration = 500.milliseconds,
                onStep = { it },
                onCancel = { 1f },
        )
            ),
        ) { isShadeExpanded, isQsExpanded, alpha ->
            if (isShadeExpanded || isQsExpanded) {
                // One example of this happening is dragging a notification while pulsing on AOD
                1f
            } else {
                alpha
            }
        }

    val shortcutsAlpha: Flow<Float> =
        transitionAnimation.sharedFlow(
+2 −2
Original line number Diff line number Diff line
@@ -91,10 +91,10 @@ object SharedNotificationContainerBinder {
                    if (!sceneContainerFlags.flexiNotifsEnabled()) {
                        launch {
                            // Only temporarily needed, until flexi notifs go live
                            viewModel.shadeCollpaseFadeIn.collect { fadeIn ->
                            viewModel.shadeCollapseFadeIn.collect { fadeIn ->
                                if (fadeIn) {
                                    android.animation.ValueAnimator.ofFloat(0f, 1f).apply {
                                        duration = 350
                                        duration = 250
                                        addUpdateListener { animation ->
                                            controller.setMaxAlphaForExpansion(
                                                animation.getAnimatedFraction()
+21 −6
Original line number Diff line number Diff line
@@ -133,6 +133,21 @@ constructor(
            .distinctUntilChanged()
            .onStart { emit(false) }

    /**
     * Shade locked is a legacy concept, but necessary to mimic current functionality. Listen for
     * both SHADE_LOCKED and shade/qs expansion in order to determine lock state, as one can arrive
     * before the other.
     */
    private val isShadeLocked: Flow<Boolean> =
        combine(
                keyguardInteractor.statusBarState.map { it == SHADE_LOCKED },
                shadeInteractor.qsExpansion.map { it > 0f },
                shadeInteractor.shadeExpansion.map { it > 0f },
            ) { isShadeLocked, isQsExpanded, isShadeExpanded ->
                isShadeLocked && (isQsExpanded || isShadeExpanded)
            }
            .distinctUntilChanged()

    val shadeCollapseFadeInComplete = MutableStateFlow(false)

    val configurationBasedDimensions: Flow<ConfigurationBasedDimensions> =
@@ -190,7 +205,7 @@ constructor(
            )

    /** Are we purely on the glanceable hub without the shade/qs? */
    internal val isOnGlanceableHubWithoutShade: Flow<Boolean> =
    val isOnGlanceableHubWithoutShade: Flow<Boolean> =
        combine(
                communalInteractor.isIdleOnCommunal,
                // Shade with notifications
@@ -208,12 +223,12 @@ constructor(
            )

    /** Fade in only for use after the shade collapses */
    val shadeCollpaseFadeIn: Flow<Boolean> =
    val shadeCollapseFadeIn: Flow<Boolean> =
        flow {
                while (currentCoroutineContext().isActive) {
                    emit(false)
                    // Wait for shade to be fully expanded
                    keyguardInteractor.statusBarState.first { it == SHADE_LOCKED }
                    isShadeLocked.first { it }
                    // ... and then for it to be collapsed
                    isOnLockscreenWithoutShade.first { it }
                    emit(true)
@@ -330,16 +345,16 @@ constructor(
                // shade expansion or swipe to dismiss
                combineTransform(
                    isOnLockscreenWithoutShade,
                    shadeCollpaseFadeIn,
                    shadeCollapseFadeIn,
                    alphaForShadeAndQsExpansion,
                    keyguardInteractor.dismissAlpha,
                ) {
                    isOnLockscreenWithoutShade,
                    shadeCollpaseFadeIn,
                    shadeCollapseFadeIn,
                    alphaForShadeAndQsExpansion,
                    dismissAlpha ->
                    if (isOnLockscreenWithoutShade) {
                        if (!shadeCollpaseFadeIn && dismissAlpha != null) {
                        if (!shadeCollapseFadeIn && dismissAlpha != null) {
                            emit(dismissAlpha)
                        }
                    } else {
Loading