diff options
author | 2025-03-12 12:48:41 -0700 | |
---|---|---|
committer | 2025-03-12 12:48:41 -0700 | |
commit | d859311070a0638715e4f455d26260d98ebdb789 (patch) | |
tree | 2baf2ac8ce083990aaebc4ca504c0ec1713904be | |
parent | 494322401f5fddbfd56492cde82add1b7044773f (diff) | |
parent | 6388882984c378ed319d8bba43dbec8d3330b07b (diff) |
Merge "Remove flicker at the beginning of chip return animation." into main
4 files changed, 39 insertions, 7 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt index 2fa9a02b9e87..8120c2d9f816 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt @@ -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]. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt index 03108deb0ecc..922afc7825c4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt index 58d38903f7cf..74b3f302cdc8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt @@ -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 { - if (contentDescription != null) { - this.contentDescription = contentDescription + 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, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt index 3876d9fa77a3..364e6656ee9d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt @@ -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, ) } |