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
This commit is contained in:
Luca Zuccarini
2023-06-19 11:03:44 +00:00
parent 920307da3a
commit afa8d39868
4 changed files with 14 additions and 8 deletions

View File

@@ -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.

View File

@@ -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();
}
}

View File

@@ -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.

View File

@@ -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<MediaOutputDialog> c) {