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

Commit 8d9b0a72 authored by Beverly's avatar Beverly
Browse files

Make AlteBouncerWindowVM and AltBouncerVM rely on same transition

Previously AlternateBouncerWindowViewModel and AlternateBouncerViewModel
were relying on different sources of truth for whether the device
was transitioning to the AlternateBouncer which could cause race
conditions, especially when animations are disabled.

Fixes: 333925071
Flag: ACONFIG com.android.systemui.device_entry_udfps_refactor TRUNKFOOD
Test: atest AlternateBouncerViewModelTest
Change-Id: Ic272f7b83582c4afd5aed01c60cc4651c8dcafc5
parent 0e75605d
Loading
Loading
Loading
Loading
+3 −35
Original line number Original line Diff line number Diff line
@@ -18,61 +18,29 @@
package com.android.systemui.keyguard.ui.viewmodel
package com.android.systemui.keyguard.ui.viewmodel


import android.graphics.Color
import android.graphics.Color
import com.android.systemui.keyguard.domain.interactor.FromAlternateBouncerTransitionInteractor.Companion.TRANSITION_DURATION_MS
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.wm.shell.animation.Interpolators
import javax.inject.Inject
import javax.inject.Inject
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.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge


@ExperimentalCoroutinesApi
@ExperimentalCoroutinesApi
class AlternateBouncerViewModel
class AlternateBouncerViewModel
@Inject
@Inject
constructor(
constructor(
    private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
    private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
    animationFlow: KeyguardTransitionAnimationFlow,
    keyguardTransitionInteractor: KeyguardTransitionInteractor,
) {
) {
    // When we're fully transitioned to the AlternateBouncer, the alpha of the scrim should be:
    // When we're fully transitioned to the AlternateBouncer, the alpha of the scrim should be:
    private val alternateBouncerScrimAlpha = .66f
    private val alternateBouncerScrimAlpha = .66f
    private val toAlternateBouncerTransition =
        animationFlow
            .setup(
                duration = TRANSITION_DURATION_MS,
                from = null,
                to = ALTERNATE_BOUNCER,
            )
            .sharedFlow(
                duration = TRANSITION_DURATION_MS,
                onStep = { it },
                onFinish = { 1f },
                // Reset on cancel
                onCancel = { 0f },
                interpolator = Interpolators.FAST_OUT_SLOW_IN,
            )
    private val fromAlternateBouncerTransition =
        animationFlow
            .setup(
                TRANSITION_DURATION_MS,
                from = ALTERNATE_BOUNCER,
                to = null,
            )
            .sharedFlow(
                duration = TRANSITION_DURATION_MS,
                onStep = { 1f - it },
                // Reset on cancel
                onCancel = { 0f },
                interpolator = Interpolators.FAST_OUT_SLOW_IN,
            )


    /** Progress to a fully transitioned alternate bouncer. 1f represents fully transitioned. */
    /** Progress to a fully transitioned alternate bouncer. 1f represents fully transitioned. */
    val transitionToAlternateBouncerProgress =
    val transitionToAlternateBouncerProgress =
        merge(fromAlternateBouncerTransition, toAlternateBouncerTransition)
        keyguardTransitionInteractor.transitionValue(ALTERNATE_BOUNCER)


    val forcePluginOpen: Flow<Boolean> =
    val forcePluginOpen: Flow<Boolean> =
        transitionToAlternateBouncerProgress.map { it > 0f }.distinctUntilChanged()
        transitionToAlternateBouncerProgress.map { it > 0f }.distinctUntilChanged()
+4 −5
Original line number Original line Diff line number Diff line
@@ -32,7 +32,6 @@ import com.android.systemui.util.mockito.any
import com.google.common.collect.Range
import com.google.common.collect.Range
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
@@ -67,7 +66,7 @@ class AlternateBouncerViewModelTest : SysuiTestCase() {
    fun transitionToAlternateBouncer_scrimAlphaUpdate() =
    fun transitionToAlternateBouncer_scrimAlphaUpdate() =
        testScope.runTest {
        testScope.runTest {
            val scrimAlphas by collectValues(underTest.scrimAlpha)
            val scrimAlphas by collectValues(underTest.scrimAlpha)
            runCurrent()
            assertThat(scrimAlphas.size).isEqualTo(1) // initial value is 0f


            transitionRepository.sendTransitionSteps(
            transitionRepository.sendTransitionSteps(
                listOf(
                listOf(
@@ -79,7 +78,7 @@ class AlternateBouncerViewModelTest : SysuiTestCase() {
                testScope,
                testScope,
            )
            )


            assertThat(scrimAlphas.size).isEqualTo(4)
            assertThat(scrimAlphas.size).isEqualTo(5)
            scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
            scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
        }
        }


@@ -87,7 +86,7 @@ class AlternateBouncerViewModelTest : SysuiTestCase() {
    fun transitionFromAlternateBouncer_scrimAlphaUpdate() =
    fun transitionFromAlternateBouncer_scrimAlphaUpdate() =
        testScope.runTest {
        testScope.runTest {
            val scrimAlphas by collectValues(underTest.scrimAlpha)
            val scrimAlphas by collectValues(underTest.scrimAlpha)
            runCurrent()
            assertThat(scrimAlphas.size).isEqualTo(1) // initial value is 0f


            transitionRepository.sendTransitionSteps(
            transitionRepository.sendTransitionSteps(
                listOf(
                listOf(
@@ -98,7 +97,7 @@ class AlternateBouncerViewModelTest : SysuiTestCase() {
                ),
                ),
                testScope,
                testScope,
            )
            )
            assertThat(scrimAlphas.size).isEqualTo(4)
            assertThat(scrimAlphas.size).isEqualTo(5)
            scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
            scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
        }
        }


+2 −2
Original line number Original line Diff line number Diff line
@@ -18,7 +18,7 @@


package com.android.systemui.keyguard.ui.viewmodel
package com.android.systemui.keyguard.ui.viewmodel


import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.kosmos.Kosmos.Fixture
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
import com.android.systemui.statusbar.phone.statusBarKeyguardViewManager
@@ -27,6 +27,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
val Kosmos.alternateBouncerViewModel by Fixture {
val Kosmos.alternateBouncerViewModel by Fixture {
    AlternateBouncerViewModel(
    AlternateBouncerViewModel(
        statusBarKeyguardViewManager = statusBarKeyguardViewManager,
        statusBarKeyguardViewManager = statusBarKeyguardViewManager,
        animationFlow = keyguardTransitionAnimationFlow,
        keyguardTransitionInteractor = keyguardTransitionInteractor,
    )
    )
}
}