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

Commit 412f9cc9 authored by Chandru S's avatar Chandru S
Browse files

Expose windowBlurRadius as a flow that is in sync with various bouncer transitions

All transitions to and away from the bouncer will provide an implementation of how the windowBlurRadius should change.
This will be used by WindowRootViewModel to apply the specified blur to the window root view.

Bug: 370555003
Flag: com.android.systemui.bouncer_ui_revamp
Test: Added unit tests
Change-Id: I002141d69a41b44099e434e38b4c80935b2b44a2
parent c1babf69
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -27,7 +27,9 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.shadeTestUtil
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -47,6 +49,8 @@ class AlternateBouncerToPrimaryBouncerTransitionViewModelTest : SysuiTestCase()
    private val keyguardTransitionRepository by lazy { kosmos.fakeKeyguardTransitionRepository }
    private val underTest by lazy { kosmos.alternateBouncerToPrimaryBouncerTransitionViewModel }

    private val shadeTestUtil by lazy { kosmos.shadeTestUtil }

    @Test
    fun deviceEntryParentViewDisappear() =
        testScope.runTest {
@@ -67,13 +71,44 @@ class AlternateBouncerToPrimaryBouncerTransitionViewModelTest : SysuiTestCase()
            values.forEach { assertThat(it).isEqualTo(0f) }
        }

    @Test
    fun blurRadiusGoesToMaximumWhenShadeIsExpanded() =
        testScope.runTest {
            val values by collectValues(underTest.windowBlurRadius)
            kosmos.bouncerWindowBlurTestUtil.shadeExpanded(true)

            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0f, 0f, 0.1f, 0.2f, 0.3f, 1f),
                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                checkInterpolatedValues = false,
                transitionFactory = ::step,
                actualValuesProvider = { values },
            )
        }

    @Test
    fun blurRadiusGoesFromMinToMaxWhenShadeIsNotExpanded() =
        testScope.runTest {
            val values by collectValues(underTest.windowBlurRadius)
            kosmos.bouncerWindowBlurTestUtil.shadeExpanded(false)

            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0f, 0f, 0.1f, 0.2f, 0.3f, 1f),
                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                transitionFactory = ::step,
                actualValuesProvider = { values },
            )
        }

    private fun step(value: Float, state: TransitionState = RUNNING): TransitionStep {
        return TransitionStep(
            from = KeyguardState.ALTERNATE_BOUNCER,
            to = KeyguardState.PRIMARY_BOUNCER,
            value = value,
            transitionState = state,
            ownerName = "AlternateBouncerToPrimaryBouncerTransitionViewModelTest"
            ownerName = "AlternateBouncerToPrimaryBouncerTransitionViewModelTest",
        )
    }
}
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.systemui.keyguard.ui.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith

@ExperimentalCoroutinesApi
@SmallTest
@RunWith(AndroidJUnit4::class)
class AodToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope
    private val underTest by lazy { kosmos.aodToPrimaryBouncerTransitionViewModel }

    @Test
    fun aodToPrimaryBouncerChangesBlurToMax() =
        testScope.runTest {
            val values by collectValues(underTest.windowBlurRadius)

            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0.0f, 0.0f, 0.3f, 0.4f, 0.5f, 1.0f),
                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                transitionFactory = { value, state ->
                    TransitionStep(
                        from = KeyguardState.AOD,
                        to = KeyguardState.PRIMARY_BOUNCER,
                        value = value,
                        transitionState = state,
                        ownerName = "AodToPrimaryBouncerTransitionViewModelTest",
                    )
                },
                actualValuesProvider = { values },
                checkInterpolatedValues = false,
            )
        }
}
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import android.util.MathUtils
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testScope
import com.android.systemui.shade.ShadeTestUtil
import com.android.systemui.shade.shadeTestUtil
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.TestScope

val Kosmos.bouncerWindowBlurTestUtil by
    Kosmos.Fixture {
        BouncerWindowBlurTestUtil(
            shadeTestUtil = shadeTestUtil,
            fakeKeyguardTransitionRepository = fakeKeyguardTransitionRepository,
            fakeKeyguardRepository = fakeKeyguardRepository,
            testScope = testScope,
        )
    }

class BouncerWindowBlurTestUtil(
    private val shadeTestUtil: ShadeTestUtil,
    private val fakeKeyguardTransitionRepository: FakeKeyguardTransitionRepository,
    private val fakeKeyguardRepository: FakeKeyguardRepository,
    private val testScope: TestScope,
) {

    suspend fun assertTransitionToBlurRadius(
        transitionProgress: List<Float>,
        startValue: Float,
        endValue: Float,
        actualValuesProvider: () -> List<Float>,
        transitionFactory: (value: Float, state: TransitionState) -> TransitionStep,
        checkInterpolatedValues: Boolean = true,
    ) {
        val transitionSteps =
            listOf(
                transitionFactory(transitionProgress.first(), STARTED),
                *transitionProgress.drop(1).map { transitionFactory(it, RUNNING) }.toTypedArray(),
            )
        fakeKeyguardTransitionRepository.sendTransitionSteps(transitionSteps, testScope)

        val interpolationFunction = { step: Float -> MathUtils.lerp(startValue, endValue, step) }

        if (checkInterpolatedValues) {
            assertThat(actualValuesProvider.invoke())
                .containsExactly(*transitionProgress.map(interpolationFunction).toTypedArray())
        } else {
            assertThat(actualValuesProvider.invoke()).contains(endValue)
        }
    }

    fun shadeExpanded(expanded: Boolean) {
        if (expanded) {
            shadeTestUtil.setQsExpansion(1f)
        } else {
            fakeKeyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
            shadeTestUtil.setQsExpansion(0f)
            shadeTestUtil.setLockscreenShadeExpansion(0f)
        }
    }
}
+16 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -70,13 +71,27 @@ class DozingToPrimaryBouncerTransitionViewModelTest : SysuiTestCase() {
            values.forEach { assertThat(it).isEqualTo(0f) }
        }

    @Test
    fun windowBlurRadiusGoesFromMinToMax() =
        testScope.runTest {
            val values by collectValues(underTest.windowBlurRadius)

            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                actualValuesProvider = { values },
                transitionFactory = ::step,
            )
        }

    private fun step(value: Float, state: TransitionState = RUNNING): TransitionStep {
        return TransitionStep(
            from = KeyguardState.DOZING,
            to = KeyguardState.PRIMARY_BOUNCER,
            value = value,
            transitionState = state,
            ownerName = "DozingToPrimaryBouncerTransitionViewModelTest"
            ownerName = "DozingToPrimaryBouncerTransitionViewModelTest",
        )
    }
}
+37 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
import com.android.systemui.flags.BrokenWithSceneContainer
import com.android.systemui.flags.Flags
import com.android.systemui.flags.andSceneContainer
@@ -31,6 +32,7 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
import com.android.systemui.kosmos.testScope
import com.android.systemui.scene.data.repository.sceneContainerRepository
import com.android.systemui.scene.shared.flag.SceneContainerFlag
@@ -128,7 +130,7 @@ class LockscreenToPrimaryBouncerTransitionViewModelTest(flags: FlagsParameteriza
                    emptyFlow(),
                    emptyFlow(),
                    false,
                    emptyFlow()
                    emptyFlow(),
                )
            runCurrent()
            // fade out
@@ -150,6 +152,39 @@ class LockscreenToPrimaryBouncerTransitionViewModelTest(flags: FlagsParameteriza
            Truth.assertThat(actual).isEqualTo(0f)
        }

    @Test
    @BrokenWithSceneContainer(330311871)
    fun blurRadiusIsMaxWhenShadeIsExpanded() =
        testScope.runTest {
            val values by collectValues(underTest.windowBlurRadius)
            kosmos.bouncerWindowBlurTestUtil.shadeExpanded(true)

            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
                startValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                actualValuesProvider = { values },
                transitionFactory = ::step,
                checkInterpolatedValues = false,
            )
        }

    @Test
    @BrokenWithSceneContainer(330311871)
    fun blurRadiusGoesFromMinToMaxWhenShadeIsNotExpanded() =
        testScope.runTest {
            val values by collectValues(underTest.windowBlurRadius)
            kosmos.bouncerWindowBlurTestUtil.shadeExpanded(false)

            kosmos.bouncerWindowBlurTestUtil.assertTransitionToBlurRadius(
                transitionProgress = listOf(0.0f, 0.2f, 0.3f, 0.65f, 0.7f, 1.0f),
                startValue = PrimaryBouncerTransition.MIN_BACKGROUND_BLUR_RADIUS,
                endValue = PrimaryBouncerTransition.MAX_BACKGROUND_BLUR_RADIUS,
                actualValuesProvider = { values },
                transitionFactory = ::step,
            )
        }

    private fun step(
        value: Float,
        state: TransitionState = TransitionState.RUNNING,
@@ -161,7 +196,7 @@ class LockscreenToPrimaryBouncerTransitionViewModelTest(flags: FlagsParameteriza
                else KeyguardState.PRIMARY_BOUNCER,
            value = value,
            transitionState = state,
            ownerName = "LockscreenToPrimaryBouncerTransitionViewModelTest"
            ownerName = "LockscreenToPrimaryBouncerTransitionViewModelTest",
        )
    }

Loading