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

Commit 63888829 authored by Luca Zuccarini's avatar Luca Zuccarini
Browse files

Remove flicker at the beginning of chip return animation.

See comments in the code for details.

Bug: 202516970
Flag: com.android.systemui.status_bar_chips_return_animations
Test: atest CallChipViewModelTest
Change-Id: I27fa8dee5631bedae4208630a4117efbf2109347
parent 9f10b43f
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -528,6 +528,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            )
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isTrue()
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
            val factory = latest!!.transitionManager!!.controllerFactory
            assertThat(factory!!.component).isEqualTo(component)

@@ -538,6 +539,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isTrue()

            // Start the return transition [InCall(isAppVisible=true), ReturnRequested ->
            // Returning].
@@ -545,12 +547,14 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // End the return transition [InCall(isAppVisible=true), Returning -> NoTransition].
            controller.onTransitionAnimationEnd(isExpandingFullyAbove = false)
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // Settle the return transition [InCall(isAppVisible=true) ->
            // InCall(isAppVisible=false), NoTransition].
@@ -558,6 +562,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // Trigger a launch transition [InCall(isAppVisible=false) -> InCall(isAppVisible=true),
            // NoTransition].
@@ -565,6 +570,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // Request the return transition [InCall(isAppVisible=true), NoTransition ->
            // LaunchRequested].
@@ -572,6 +578,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // Start the return transition [InCall(isAppVisible=true), LaunchRequested ->
            // Launching].
@@ -579,12 +586,14 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // End the return transition [InCall(isAppVisible=true), Launching -> NoTransition].
            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // End the call with the app visible [InCall(isAppVisible=true) -> NoCall,
            // NoTransition].
+9 −3
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ constructor(
                                        oldTransitionState = oldTransitionState,
                                        newTransitionState = newTransitionState,
                                    ),
                                transitionState = newTransitionState,
                            )
                    }
                }
@@ -177,6 +178,7 @@ constructor(
        state: OngoingCallModel.InCall,
        systemClock: SystemClock,
        isHidden: Boolean,
        transitionState: TransitionState = TransitionState.NoTransition,
    ): OngoingActivityChipModel.Active {
        val key = state.notificationKey
        val contentDescription = getContentDescription(state.appName)
@@ -209,7 +211,7 @@ constructor(
                onClickListenerLegacy = getOnClickListener(state.intent),
                clickBehavior = getClickBehavior(state.intent),
                isHidden = isHidden,
                transitionManager = getTransitionManager(state),
                transitionManager = getTransitionManager(state, transitionState),
            )
        } else {
            val startTimeInElapsedRealtime =
@@ -222,7 +224,7 @@ constructor(
                onClickListenerLegacy = getOnClickListener(state.intent),
                clickBehavior = getClickBehavior(state.intent),
                isHidden = isHidden,
                transitionManager = getTransitionManager(state),
                transitionManager = getTransitionManager(state, transitionState),
            )
        }
    }
@@ -285,7 +287,8 @@ constructor(
    }

    private fun getTransitionManager(
        state: OngoingCallModel
        state: OngoingCallModel,
        transitionState: TransitionState = TransitionState.NoTransition,
    ): OngoingActivityChipModel.TransitionManager? {
        if (!StatusBarChipsReturnAnimations.isEnabled) return null
        return if (state is OngoingCallModel.NoCall) {
@@ -301,6 +304,9 @@ constructor(
                    registerTransition = {
                        activityStarter.registerTransition(cookie, factory, scope)
                    },
                    // Make the chip invisible at the beginning of the return transition to avoid
                    // it flickering.
                    hideChipForTransition = transitionState is TransitionState.ReturnRequested,
                )
            } else {
                // Without a component we can't instantiate a controller factory, and without a
+15 −4
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.layout
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.dimensionResource
@@ -84,11 +85,21 @@ fun OngoingActivityChip(
        shape =
            RoundedCornerShape(dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius)),
        modifier =
            modifier.height(dimensionResource(R.dimen.ongoing_appops_chip_height)).semantics {
            modifier
                .height(dimensionResource(R.dimen.ongoing_appops_chip_height))
                .semantics {
                    if (contentDescription != null) {
                        this.contentDescription = contentDescription
                    }
            },
                }
                .graphicsLayer(
                    alpha =
                        if (model.transitionManager?.hideChipForTransition == true) {
                            0f
                        } else {
                            1f
                        }
                ),
        borderStroke = borderStroke,
        onClick = onClick,
        useModifierBasedImplementation = StatusBarChipsReturnAnimations.isEnabled,
+6 −0
Original line number Diff line number Diff line
@@ -301,5 +301,11 @@ sealed class OngoingActivityChipModel {
        val registerTransition: () -> Unit = {},
        /** Used to remove the existing registration for this chip, if any. */
        val unregisterTransition: () -> Unit = {},
        /**
         * Whether the chip should be made invisible (0 opacity) while still being composed. This is
         * necessary to avoid flickers at the beginning of return transitions, when the chip must
         * not be visible but must be composed in order for the animation to start.
         */
        val hideChipForTransition: Boolean = false,
    )
}