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

Commit c74e9ff4 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Force new fading elements to fade from 0 alpha

This CL makes sure that new elements that were never drawn in any scene
and that appear by fading always start at alpha = 0f. This ensures that
elements never appear instantly even if the transition making them
appear on screen start at progress >> 0f.

Bug: 290930950
Test: ElementTest
Flag: com.android.systemui.scene_container
Change-Id: I7e5f70fd9657d5b8c2dd29881828b973a7ac1e4d
parent b49ba446
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -66,6 +66,9 @@ internal class Element(val key: ElementKey) {
     */
    var lastTransition: TransitionState.Transition? = null

    /** Whether this element was ever drawn in a scene. */
    var wasDrawnInAnyScene = false

    override fun toString(): String {
        return "Element(key=$key)"
    }
@@ -389,6 +392,8 @@ internal class ElementNode(
    }

    override fun ContentDrawScope.draw() {
        element.wasDrawnInAnyScene = true

        val transition = elementTransition(element, currentTransitions)
        val drawScale = getDrawScale(layoutImpl, scene, element, transition, sceneState)
        if (drawScale == Scale.Default) {
@@ -726,6 +731,12 @@ private fun elementAlpha(
            )
            .fastCoerceIn(0f, 1f)

    // If the element is fading during this transition and that it is drawn for the first time, make
    // sure that it doesn't instantly appear on screen.
    if (!element.wasDrawnInAnyScene && alpha > 0f) {
        element.sceneStates.forEach { it.value.alphaBeforeInterruption = 0f }
    }

    val interruptedAlpha = interruptedAlpha(layoutImpl, transition, sceneState, alpha)
    sceneState.lastAlpha = interruptedAlpha
    return interruptedAlpha
+48 −0
Original line number Diff line number Diff line
@@ -1481,4 +1481,52 @@ class ElementTest {
        assertThat(fooInC.lastAlpha).isEqualTo(1f)
        assertThat(fooInB.lastAlpha).isEqualTo(Element.AlphaUnspecified)
    }

    @Test
    fun fadingElementsDontAppearInstantly() {
        val state =
            rule.runOnUiThread {
                MutableSceneTransitionLayoutStateImpl(
                    SceneA,
                    transitions { from(SceneA, to = SceneB) { fade(TestElements.Foo) } }
                )
            }

        lateinit var layoutImpl: SceneTransitionLayoutImpl
        rule.setContent {
            SceneTransitionLayoutForTesting(state, onLayoutImpl = { layoutImpl = it }) {
                scene(SceneA) {}
                scene(SceneB) { Box(Modifier.element(TestElements.Foo)) }
            }
        }

        // Start A => B at 60%.
        var interruptionProgress by mutableStateOf(1f)
        rule.runOnUiThread {
            state.startTransition(
                transition(
                    from = SceneA,
                    to = SceneB,
                    progress = { 0.6f },
                    interruptionProgress = { interruptionProgress },
                ),
                transitionKey = null
            )
        }
        rule.waitForIdle()

        // Alpha of Foo should be 0f at interruption progress 100%.
        val fooInB = layoutImpl.elements.getValue(TestElements.Foo).sceneStates.getValue(SceneB)
        assertThat(fooInB.lastAlpha).isEqualTo(0f)

        // Alpha of Foo should be 0.6f at interruption progress 0%.
        interruptionProgress = 0f
        rule.waitForIdle()
        assertThat(fooInB.lastAlpha).isEqualTo(0.6f)

        // Alpha of Foo should be 0.3f at interruption progress 50%.
        interruptionProgress = 0.5f
        rule.waitForIdle()
        assertThat(fooInB.lastAlpha).isEqualTo(0.3f)
    }
}