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

Commit 707ccac7 authored by Danny Burakov's avatar Danny Burakov
Browse files

[Dual Shade] Blur the Quick Settings shade when the bouncer is open.

Fix: 441698959
Test: Manually tested by opening the bouncer over Quick Settings shade.
Test: Added unit tests.
Flag: com.android.systemui.scene_container
Change-Id: I25e9c3bae85fa95e1475bd78aa34ce149b56365b
parent 730784ab
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -39,10 +39,13 @@ import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.blur
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
@@ -155,6 +158,15 @@ constructor(
        val contentAlphaFromBrightnessMirror by
            animateFloatAsState(if (showBrightnessMirror) 0f else 1f)

        val targetBlurRadiusPx: Float by
            remember(layoutState) {
                derivedStateOf {
                    contentViewModel.calculateTargetBlurRadius(layoutState.transitionState)
                }
            }
        val animatedBlurRadiusPx: Float by
            animateFloatAsState(targetValue = targetBlurRadiusPx, label = "NSOverlay-blurRadius")

        // Set the bounds to null when the QuickSettings overlay disappears.
        DisposableEffectWithLifecycle(Unit) {
            onDispose {
@@ -169,6 +181,7 @@ constructor(
            modifier =
                modifier
                    .graphicsLayer { alpha = contentAlphaFromBrightnessMirror }
                    .blur(with(LocalDensity.current) { animatedBlurRadiusPx.toDp() })
                    .thenIf(showBrightnessMirror) { Modifier.gesturesDisabled() }
        ) {
            OverlayShade(
+59 −0
Original line number Diff line number Diff line
@@ -23,12 +23,14 @@ import android.platform.test.annotations.EnableFlags
import androidx.compose.ui.geometry.Rect
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.systemui.Flags.FLAG_NOTIFICATION_SHADE_BLUR
import com.android.systemui.SysuiTestCase
import com.android.systemui.authentication.data.repository.FakeAuthenticationRepository
import com.android.systemui.authentication.domain.interactor.AuthenticationResult
import com.android.systemui.authentication.domain.interactor.authenticationInteractor
import com.android.systemui.flags.EnableSceneContainer
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.collectLastValue
import com.android.systemui.kosmos.runCurrent
@@ -256,6 +258,63 @@ class QuickSettingsShadeOverlayContentViewModelTest : SysuiTestCase() {
            assertThat(underTest.isTransparencyEnabled).isFalse()
        }

    @Test
    @EnableFlags(FLAG_NOTIFICATION_SHADE_BLUR)
    fun calculateTargetBlurRadius() =
        kosmos.runTest {
            // Only bouncer shown: no blur.
            fakeWindowRootViewBlurRepository.isBlurSupported.value = true
            assertThat(
                    underTest.calculateTargetBlurRadius(
                        transitionState =
                            TransitionState.Idle(
                                currentScene = Scenes.Lockscreen,
                                currentOverlays = setOf(Overlays.Bouncer),
                            )
                    )
                )
                .isEqualTo(0f)

            // Quick Settings shade and bouncer shown: apply blur.
            assertThat(
                    underTest.calculateTargetBlurRadius(
                        transitionState =
                            TransitionState.Idle(
                                currentScene = Scenes.Lockscreen,
                                currentOverlays =
                                    setOf(Overlays.Bouncer, Overlays.QuickSettingsShade),
                            )
                    )
                )
                .isEqualTo(blurConfig.maxBlurRadiusPx)

            // No bouncer shown: no blur.
            assertThat(
                    underTest.calculateTargetBlurRadius(
                        transitionState =
                            TransitionState.Idle(
                                currentScene = Scenes.Lockscreen,
                                currentOverlays = setOf(Overlays.QuickSettingsShade),
                            )
                    )
                )
                .isEqualTo(0)

            // Blur not supported: no blur.
            fakeWindowRootViewBlurRepository.isBlurSupported.value = false
            assertThat(
                    underTest.calculateTargetBlurRadius(
                        transitionState =
                            TransitionState.Idle(
                                currentScene = Scenes.Lockscreen,
                                currentOverlays =
                                    setOf(Overlays.Bouncer, Overlays.QuickSettingsShade),
                            )
                    )
                )
                .isEqualTo(0f)
        }

    private fun Kosmos.lockDevice() {
        val currentScene by collectLastValue(sceneInteractor.currentScene)
        powerInteractor.setAsleepForTest()
+19 −0
Original line number Diff line number Diff line
@@ -21,11 +21,13 @@ import android.graphics.Rect
import android.media.AudioManager
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.settingslib.volume.shared.model.AudioStream
import com.android.systemui.Flags
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.desktop.domain.interactor.DesktopInteractor
import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel
import com.android.systemui.keyguard.ui.transitions.BlurConfig
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.qs.flags.QsDetailedView
@@ -33,6 +35,7 @@ import com.android.systemui.qs.panels.ui.viewmodel.toolbar.ToolbarViewModel
import com.android.systemui.qs.tiles.dialog.AudioDetailsViewModel
import com.android.systemui.res.R
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Overlays
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.shade.ShadeDisplayAware
import com.android.systemui.shade.domain.interactor.ShadeInteractor
@@ -80,6 +83,7 @@ constructor(
    val notificationStackAppearanceInteractor: NotificationStackAppearanceInteractor,
    @Assisted private val volumeSliderCoroutineScope: CoroutineScope?,
    val toolbarViewModelFactory: ToolbarViewModel.Factory,
    private val blurConfig: BlurConfig,
    windowRootViewBlurInteractor: WindowRootViewBlurInteractor,
) : ExclusiveActivatable() {

@@ -118,6 +122,21 @@ constructor(
                },
        )

    /**
     * Calculates the blur radius to apply to the overlay.
     *
     * @param transitionState The current transition state of the scene (from its `ContentScope`)
     * @return The blur radius to apply to the scene UI, in pixels.
     */
    fun calculateTargetBlurRadius(transitionState: TransitionState): Float {
        return when {
            !isTransparencyEnabled -> 0f
            Overlays.QuickSettingsShade !in transitionState.currentOverlays -> 0f
            Overlays.Bouncer in transitionState.currentOverlays -> blurConfig.maxBlurRadiusPx
            else -> 0f
        }
    }

    private val showVolumeSlider =
        QsDetailedView.isEnabled &&
            shadeContext.resources.getBoolean(R.bool.config_enableDesktopAudioTileDetailsView)
+2 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.qs.ui.viewmodel
import android.content.applicationContext
import com.android.systemui.desktop.domain.interactor.desktopInteractor
import com.android.systemui.development.ui.viewmodel.buildNumberViewModelFactory
import com.android.systemui.keyguard.ui.transitions.blurConfig
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.testDispatcher
import com.android.systemui.qs.panels.ui.viewmodel.toolbar.toolbarViewModelFactory
@@ -51,6 +52,7 @@ val Kosmos.quickSettingsShadeOverlayContentViewModelFactory:
                    buildNumberViewModelFactory = buildNumberViewModelFactory,
                    volumeSliderCoroutineScope = volumeSliderCoroutineScope,
                    toolbarViewModelFactory = toolbarViewModelFactory,
                    blurConfig = blurConfig,
                    windowRootViewBlurInteractor = windowRootViewBlurInteractor,
                )
            }