From bdd96de69a92fed9360ba8521d618b6274553447 Mon Sep 17 00:00:00 2001 From: Liran Binyamin Date: Wed, 3 Jul 2024 17:07:09 -0400 Subject: [PATCH] Send the bubble removal timestamp to wm shell The removal and update of bubbles happen in different processes, so it's possible for race conditions to allow users to remove bubbles without knowing that an update exists. Passing the removal timestamp allows wm shell to determine whether the removal happened before or after the latest update was received for the bubble. This largely mitigates the race but does not solve it completely. Will file a separate bug to track that. Flag: com.android.wm.shell.enable_bubble_bar Bug: 351026092 Test: Manual - Note the issue here is a race condition so requires code changes to force repro it - Locally I added an artificial delay between the time the - bubble is removed and until the removal is sent to wmshell - Create bubbles and expand the bubble bar - Dismiss bubble by dragging it to dismiss - Send an update to the same bubble before removal is processed in wmshell - Verify bubble is added back - Verify bubble is not removed when the removal is processed in wmshell Change-Id: I05ddc692fe30709125e380351b223d20a0778264 --- .../launcher3/taskbar/bubbles/BubbleBarController.java | 7 +++++++ .../taskbar/bubbles/BubbleBarViewController.java | 9 ++++++++- quickstep/src/com/android/quickstep/SystemUiProxy.java | 6 ++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java index a3832cdf8b..7426dc7259 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java @@ -356,6 +356,13 @@ public class BubbleBarController extends IBubblesListener.Stub { } } + // if a bubble was updated upstream, but removed before the update was received, add it back + if (update.updatedBubble != null && !mBubbles.containsKey(update.updatedBubble.getKey())) { + mBubbles.put(update.updatedBubble.getKey(), update.updatedBubble); + mBubbleBarViewController.addBubble( + update.updatedBubble, isExpanding, suppressAnimation); + } + if (update.addedBubble != null && isCollapsed) { // If we're collapsed, the most recently added bubble will be selected. bubbleToSelect = update.addedBubble; diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java index ad815094bb..23c747eda0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java @@ -89,6 +89,8 @@ public class BubbleBarViewController { private BubbleBarViewAnimator mBubbleBarViewAnimator; + private TimeSource mTimeSource = System::currentTimeMillis; + @Nullable private BubbleBarBoundsChangeListener mBoundsChangeListener; @@ -576,7 +578,7 @@ public class BubbleBarViewController { * @param bubble dismissed bubble item */ public void onDismissBubbleWhileDragging(@NonNull BubbleBarItem bubble) { - mSystemUiProxy.dragBubbleToDismiss(bubble.getKey()); + mSystemUiProxy.dragBubbleToDismiss(bubble.getKey(), mTimeSource.currentTimeMillis()); } /** @@ -601,6 +603,11 @@ public class BubbleBarViewController { void onBoundsChanged(); } + /** Interface for getting the current timestamp. */ + interface TimeSource { + long currentTimeMillis(); + } + /** Dumps the state of BubbleBarViewController. */ public void dump(PrintWriter pw) { pw.println("Bubble bar view controller state:"); diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 433baa9581..ec035a9145 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -831,12 +831,14 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { /** * Tells SysUI to dismiss the bubble with the provided key. + * * @param key the key of the bubble to dismiss. + * @param timestamp the timestamp when the removal happened. */ - public void dragBubbleToDismiss(String key) { + public void dragBubbleToDismiss(String key, long timestamp) { if (mBubbles == null) return; try { - mBubbles.dragBubbleToDismiss(key); + mBubbles.dragBubbleToDismiss(key, timestamp); } catch (RemoteException e) { Log.w(TAG, "Failed call dragBubbleToDismiss"); }