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

Commit 93d992d0 authored by Alejandro Nijamkin's avatar Alejandro Nijamkin
Browse files

[flexiglass] Lockscreen -> split shade transition touchups

Makes the transition look correct.

Fix: 373688433
Test: manually verified, see video on comment in bug
Flag: com.android.systemui.scene_container
Change-Id: I825df7f7d295017c7bca2bea943b846575e774d0
parent a545efde
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
@@ -99,12 +98,18 @@ fun SceneScope.NotificationLockscreenScrim(
        }
    }

    val isBouncerToLockscreen =
        layoutState.currentTransition?.isTransitioning(
            from = Scenes.Bouncer,
            to = Scenes.Lockscreen,
        ) ?: false

    Box(
        modifier
            .fillMaxSize()
            .element(Notifications.Elements.NotificationScrim)
            .element(viewModel.element.key)
            .graphicsLayer { alpha = alphaAnimatable.value }
            .background(MaterialTheme.colorScheme.surface)
            .background(viewModel.element.color(isBouncerToLockscreen))
    )
}

@@ -112,7 +117,7 @@ private fun shouldShowScrimFadeOut(
    currentTransition: TransitionState.Transition,
    shadeMode: ShadeMode,
): Boolean {
    return shadeMode == ShadeMode.Single &&
    return shadeMode != ShadeMode.Dual &&
        currentTransition.isInitiatedByUserInput &&
        (currentTransition.isTransitioning(from = Scenes.Shade, to = Scenes.Lockscreen) ||
            currentTransition.isTransitioning(from = Scenes.Bouncer, to = Scenes.Lockscreen))
+4 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ val SceneContainerTransitions = transitions {
    from(Scenes.Lockscreen, to = Scenes.Shade) { lockscreenToShadeTransition() }
    from(Scenes.Lockscreen, to = Scenes.Shade, key = ToSplitShade) {
        lockscreenToSplitShadeTransition()
        sharedElement(Shade.Elements.BackgroundScrim, enabled = false)
    }
    from(Scenes.Lockscreen, to = Scenes.Shade, key = SlightlyFasterShadeCollapse) {
        lockscreenToShadeTransition(durationScale = 0.9)
@@ -96,6 +97,9 @@ val SceneContainerTransitions = transitions {
        sharedElement(Notifications.Elements.NotificationStackPlaceholder, enabled = false)
        sharedElement(Notifications.Elements.HeadsUpNotificationPlaceholder, enabled = false)
    }
    from(Scenes.Shade, to = Scenes.Lockscreen, key = ToSplitShade) {
        reversed { lockscreenToSplitShadeTransition() }
    }
    from(Scenes.Communal, to = Scenes.Shade) { communalToShadeTransition() }
    from(Scenes.Communal, to = Scenes.Bouncer) { communalToBouncerTransition() }

+74 −2
Original line number Diff line number Diff line
@@ -16,14 +16,31 @@

package com.android.systemui.statusbar.notification.stack.ui.viewmodel

import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import com.android.app.tracing.coroutines.coroutineScopeTraced
import com.android.compose.animation.scene.ElementKey
import com.android.systemui.dump.DumpManager
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.notifications.ui.composable.Notifications
import com.android.systemui.res.R
import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.shade.ui.composable.Shade
import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
import com.android.systemui.util.kotlin.ActivatableFlowDumper
import com.android.systemui.util.kotlin.ActivatableFlowDumperImpl
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

class NotificationLockscreenScrimViewModel
@AssistedInject
@@ -35,7 +52,17 @@ constructor(
    ActivatableFlowDumper by ActivatableFlowDumperImpl(dumpManager, "NotificationScrollViewModel"),
    ExclusiveActivatable() {

    val shadeMode = shadeInteractor.shadeMode
    private val hydrator = Hydrator("NotificationLockscreenScrimViewModel.hydrator")

    val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode

    /** The [ElementKey] to use for the scrim. */
    val element: ElementViewModel by
        hydrator.hydratedStateOf(
            traceName = "elementKey",
            initialValue = element(shadeMode.value),
            source = shadeMode.map { element(it) },
        )

    /** Sets the alpha to apply to the NSSL for fade-in on lockscreen */
    fun setAlphaForLockscreenFadeIn(alpha: Float) {
@@ -43,11 +70,56 @@ constructor(
    }

    override suspend fun onActivated(): Nothing {
        activateFlowDumper()
        coroutineScopeTraced("NotificationLockscreenScrimViewModel") {
            launch { activateFlowDumper() }
            launch { hydrator.activate() }
            awaitCancellation()
        }
    }

    private fun element(shadeMode: ShadeMode): ElementViewModel {
        return if (shadeMode == ShadeMode.Single) {
            ElementViewModel(
                key = Notifications.Elements.NotificationScrim,
                color = { SingleShadeBackground },
            )
        } else {
            ElementViewModel(
                key = Shade.Elements.BackgroundScrim,
                color = { isBouncerToLockscreen ->
                    if (isBouncerToLockscreen) {
                        SplitShadeBouncerToLockscreenBackground
                    } else {
                        SplitShadeDefaultBackground
                    }
                },
            )
        }
    }

    /** Models the UI state of the scrim. */
    data class ElementViewModel(
        /** The [ElementKey] to use with an `element` modifier. */
        val key: ElementKey,
        /** A function that returns the color to use within a `background` modifier. */
        val color: @Composable (isBouncerToLockscreen: Boolean) -> Color,
    )

    @AssistedFactory
    interface Factory {
        fun create(): NotificationLockscreenScrimViewModel
    }

    companion object {
        private val SingleShadeBackground: Color
            @Composable @ReadOnlyComposable get() = MaterialTheme.colorScheme.surface

        private val SplitShadeBouncerToLockscreenBackground: Color
            @Composable @ReadOnlyComposable get() = MaterialTheme.colorScheme.surface

        private val SplitShadeDefaultBackground: Color
            @Composable
            @ReadOnlyComposable
            get() = colorResource(R.color.shade_scrim_background_dark)
    }
}