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

Commit 84d31328 authored by Luca Zuccarini's avatar Luca Zuccarini
Browse files

Make sure chip is hidden when launching from another source.

We can't assume that all launches occur from tapping the chip, so we
take the tap into account when deciding whether to show or not.

Fix: 405975193
Flag: com.android.systemui.status_bar_chips_return_animations
Test: atest CallChipViewModelTest + manual validation (Notify2 app, start a call, put the app in the background, launch from the app icon, make sure that the chip goes away).
Change-Id: I7e9a134c261f7b4eb6a82810bd76a0c811ea5074
parent f6d3e7a7
Loading
Loading
Loading
Loading
+75 −7
Original line number Diff line number Diff line
@@ -588,15 +588,26 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // Trigger a launch transition [InCall(isAppVisible=false) -> InCall(isAppVisible=true),
            // NoTransition].
            // Trigger a launch transition [InCall(isAppVisible=false), NoTransition ->
            // LaunchRequested].
            val clickBehavior =
                (latest as OngoingActivityChipModel.Active).clickBehavior
                    as OngoingActivityChipModel.ClickBehavior.ExpandAction
            clickBehavior.onClick(expandable)
            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()

            // System reacts to the tap [InCall(isAppVisible=false) -> InCall(isAppVisible=true),
            // LaunchRequested].
            kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, true)
            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 ->
            // Request the launch transition [InCall(isAppVisible=true), NoTransition ->
            // LaunchRequested].
            controller = factory.createController(forLaunch = true)
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
@@ -604,7 +615,7 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

            // Start the return transition [InCall(isAppVisible=true), LaunchRequested ->
            // Start the launch transition [InCall(isAppVisible=true), LaunchRequested ->
            // Launching].
            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
@@ -612,10 +623,10 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()

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

@@ -638,6 +649,63 @@ class CallChipViewModelTest(flags: FlagsParameterization) : SysuiTestCase() {
            assertThat(latest!!.transitionManager!!.controllerFactory).isNull()
        }

    @Test
    @EnableFlags(StatusBarChipsReturnAnimations.FLAG_NAME)
    @EnableChipsModernization
    fun chipWithReturnAnimation_updatesCorrectly_whenAppIsLaunchedAndClosedWithoutAnimation() =
        kosmos.runTest {
            val pendingIntent = mock<PendingIntent>()
            val intent = mock<Intent>()
            whenever(pendingIntent.intent).thenReturn(intent)
            val component = mock<ComponentName>()
            whenever(intent.component).thenReturn(component)

            val expandable = mock<Expandable>()
            val activityController = mock<ActivityTransitionAnimator.Controller>()
            whenever(
                    expandable.activityTransitionController(
                        anyOrNull(),
                        anyOrNull(),
                        any(),
                        anyOrNull(),
                        any(),
                    )
                )
                .thenReturn(activityController)

            val latest by collectLastValue(underTest.chip)

            // Start off with a call with visible app.
            addOngoingCallState(
                key = NOTIFICATION_KEY,
                startTimeMs = 345,
                contentIntent = pendingIntent,
                uid = NOTIFICATION_UID,
                isAppVisible = true,
            )
            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)

            // Close the app without a return transition (e.g. from gesture nav)
            // [InCall(isAppVisible=true) -> InCall(isAppVisible=false), NoTransition].
            kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, 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()

            // Launch the app from another source (e.g. the app icon) [InCall(isAppVisible=true) ->
            // InCall(isAppVisible=false), NoTransition].
            kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, true)
            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isTrue()
            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
        }

    @Test
    @DisableFlags(StatusBarChipsReturnAnimations.FLAG_NAME)
    fun chipLegacy_hasNoTransitionAnimationInformation() =
+8 −6
Original line number Diff line number Diff line
@@ -283,6 +283,7 @@ constructor(
                                Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP
                            )
                        } else {
                            transitionState.value = TransitionState.LaunchRequested
                            // When return animations are enabled, we use a long-lived registration
                            // with controllers created on-demand by the animation library instead
                            // of explicitly creating one at the time of the click. By not passing
@@ -449,12 +450,8 @@ constructor(
            // The call has just started and is visible. Hide the chip.
            if (oldState is OngoingCallModel.NoCall) return true

            // The state went from the app not being visible to visible. This happens when the chip
            // is tapped and a launch animation is about to start. Keep the chip showing.
            if (!(oldState as OngoingCallModel.InCall).isAppVisible) return false

            // The app was and remains visible, but the transition state has changed. A launch or
            // return animation has been requested or is ongoing. Keep the chip showing.
            // The transition state has changed. A launch or return animation has been requested or
            // is ongoing. Show the chip.
            if (
                newTransitionState is TransitionState.LaunchRequested ||
                    newTransitionState is TransitionState.Launching ||
@@ -464,6 +461,11 @@ constructor(
                return false
            }

            // The state went from the app not being visible to visible with no transition requested
            // or ongoing. This can happen when the app is opened by means other than tapping the
            // chip. Hide the chip.
            if (!(oldState as OngoingCallModel.InCall).isAppVisible) return true

            // The app was and remains visible, so we generally want to hide the chip. The only
            // exception is if a return transition has just ended. In this case, the transition
            // state changes shortly before the app visibility does. If we hide the chip between