From afa8d3986898f20c2f459668b3082a68f137fc8b Mon Sep 17 00:00:00 2001 From: Luca Zuccarini Date: Mon, 19 Jun 2023 11:03:44 +0000 Subject: [PATCH] Hide animated ghost when underlying view is detached from window. This mirrors the behavior that we have when the view is made INVISIBLE/GONE. The need for this change is that a view can be detached with its visibility remaining VISIBLE, in which case the updated location of the animated ghost become (0,0), which makes the transition look jumpy and broken. Note that this also disables dismiss animations for the MediaOutputDialog when the "Stop casting" button is tapped, since we know that the notification will go away but can't rely on the timing of it. Disabling the animation makes the dialog fade away in place instead, so it has a reliable transition. Fix: 232542592 Flag: N/A Test: see before/after videos in the bug Change-Id: Ieba6a2f5681ad7143c2f14b59f0309f658d66ce9 --- .../animation/GhostedViewLaunchAnimatorController.kt | 3 +-- .../android/systemui/media/dialog/MediaOutputDialog.java | 9 +++++++-- .../systemui/media/dialog/MediaOutputDialogFactory.kt | 7 ++++--- .../systemui/media/dialog/MediaOutputDialogTest.java | 3 ++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt index 23e3a01c2686b..1a03ede98d121 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt @@ -34,7 +34,6 @@ import android.view.ViewGroup import android.view.ViewGroupOverlay import android.widget.FrameLayout import com.android.internal.jank.InteractionJankMonitor -import java.lang.IllegalArgumentException import java.util.LinkedList import kotlin.math.min import kotlin.math.roundToInt @@ -240,7 +239,7 @@ constructor( val ghostView = this.ghostView ?: return val backgroundView = this.backgroundView!! - if (!state.visible) { + if (!state.visible || !ghostedView.isAttachedToWindow) { if (ghostView.visibility == View.VISIBLE) { // Making the ghost view invisible will make the ghosted view visible, so order is // important here. diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java index 19b32e93274bd..f3865f52e8632 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java @@ -28,6 +28,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; +import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastSender; import com.android.systemui.dagger.SysUISingleton; @@ -36,11 +37,14 @@ import com.android.systemui.dagger.SysUISingleton; */ @SysUISingleton public class MediaOutputDialog extends MediaOutputBaseDialog { - final UiEventLogger mUiEventLogger; + private final DialogLaunchAnimator mDialogLaunchAnimator; + private final UiEventLogger mUiEventLogger; MediaOutputDialog(Context context, boolean aboveStatusbar, BroadcastSender broadcastSender, - MediaOutputController mediaOutputController, UiEventLogger uiEventLogger) { + MediaOutputController mediaOutputController, DialogLaunchAnimator dialogLaunchAnimator, + UiEventLogger uiEventLogger) { super(context, broadcastSender, mediaOutputController); + mDialogLaunchAnimator = dialogLaunchAnimator; mUiEventLogger = uiEventLogger; mAdapter = new MediaOutputAdapter(mMediaOutputController); if (!aboveStatusbar) { @@ -138,6 +142,7 @@ public class MediaOutputDialog extends MediaOutputBaseDialog { } } else { mMediaOutputController.releaseSession(); + mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations(); dismiss(); } } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt index 802488668f16a..4c168ecb81af3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt @@ -28,11 +28,11 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.broadcast.BroadcastSender +import com.android.systemui.flags.FeatureFlags import com.android.systemui.media.nearby.NearbyMediaDevicesManager import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection -import com.android.systemui.flags.FeatureFlags import com.android.systemui.settings.UserTracker +import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection import java.util.Optional import javax.inject.Inject @@ -71,7 +71,8 @@ class MediaOutputDialogFactory @Inject constructor( dialogLaunchAnimator, nearbyMediaDevicesManagerOptional, audioManager, powerExemptionManager, keyGuardManager, featureFlags, userTracker) val dialog = - MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, uiEventLogger) + MediaOutputDialog(context, aboveStatusBar, broadcastSender, controller, + dialogLaunchAnimator, uiEventLogger) mediaOutputDialog = dialog // Show the dialog. diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java index f3aee48cfb56c..a14ff2f72f1fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java @@ -356,6 +356,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { }); verify(mockMediaOutputController).releaseSession(); + verify(mDialogLaunchAnimator).disableAllCurrentDialogsExitAnimations(); } @Test @@ -371,7 +372,7 @@ public class MediaOutputDialogTest extends SysuiTestCase { @NonNull private MediaOutputDialog makeTestDialog(MediaOutputController controller) { return new MediaOutputDialog(mContext, false, mBroadcastSender, - controller, mUiEventLogger); + controller, mDialogLaunchAnimator, mUiEventLogger); } private void withTestDialog(MediaOutputController controller, Consumer c) {