Handle suppressed bubbles

Hide or show bubble based on suppression signals from shell.
If this is the only bubble, hides or shows the bubble bar.

Bug: 273316505
Test: have a single bubble in the bubble bar, suppress the bubble,
  observe that bubble is hidden and bubble bar is not shown,
  unsuppress the bubble, check that bubble bar and bubble is shown
  again, perform check with transient and persistent taskbar
Test: have multiple bubbles, suppress one bubble, check that this bubble
  is not shown, but the bubble bar remains visible with other bubbles,
  perform the check with transient and persistent taskbar
Test: have a single bubble in bubble bar that is suppressed, receive
  notifications to trigger new bubbles, observe bubble bar is shown for
  new bubbles, check that after unsuppressing bubble, it is added back,
  perform the checks with tranient and persistent taskbar
Test: suppress a bubble and rotate the device to trigger launcher
  recreation, check that after unsuppress, the bubble is added back

Flag: com.android.wm.shell.enable_bubble_bar

Change-Id: I17e5cec750a2666feecc62213a3e8fc204ee510a
This commit is contained in:
Ats Jenk
2024-12-11 11:39:48 -08:00
parent 29ccf8703b
commit bcc12470b7
2 changed files with 43 additions and 10 deletions

View File

@@ -77,6 +77,8 @@ public class TaskbarSharedState {
public List<BubbleInfo> bubbleInfoItems;
public List<BubbleInfo> suppressedBubbleInfoItems;
/** Returns whether there are a saved bubbles. */
public boolean hasSavedBubbles() {
return bubbleInfoItems != null && !bubbleInfoItems.isEmpty();

View File

@@ -107,6 +107,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
private final Context mContext;
private final BubbleBarView mBarView;
private final ArrayMap<String, BubbleBarBubble> mBubbles = new ArrayMap<>();
private final ArrayMap<String, BubbleBarBubble> mSuppressedBubbles = new ArrayMap<>();
private static final Executor BUBBLE_STATE_EXECUTOR = Executors.newSingleThreadExecutor(
new SimpleThreadFactory("BubbleStateUpdates-", THREAD_PRIORITY_BACKGROUND));
@@ -188,6 +189,10 @@ public class BubbleBarController extends IBubblesListener.Stub {
}
});
mSharedState.bubbleInfoItems = Arrays.asList(bubbleInfoItems);
mSharedState.suppressedBubbleInfoItems = new ArrayList<>(mSuppressedBubbles.size());
for (int i = 0; i < mSuppressedBubbles.size(); i++) {
mSharedState.suppressedBubbleInfoItems.add(mSuppressedBubbles.valueAt(i).getInfo());
}
}
/** Initializes controllers. */
@@ -290,7 +295,11 @@ public class BubbleBarController extends IBubblesListener.Stub {
if (sharedState.bubbleBarLocation != null) {
updateBubbleBarLocationInternal(sharedState.bubbleBarLocation);
}
List<BubbleInfo> bubbleInfos = sharedState.bubbleInfoItems;
restoreSavedBubbles(sharedState.bubbleInfoItems);
restoreSuppressed(sharedState.suppressedBubbleInfoItems);
}
private void restoreSavedBubbles(List<BubbleInfo> bubbleInfos) {
if (bubbleInfos == null || bubbleInfos.isEmpty()) return;
// Iterate in reverse because new bubbles are added in front and the list is in order.
for (int i = bubbleInfos.size() - 1; i >= 0; i--) {
@@ -304,6 +313,18 @@ public class BubbleBarController extends IBubblesListener.Stub {
}
}
private void restoreSuppressed(List<BubbleInfo> bubbleInfos) {
if (bubbleInfos == null || bubbleInfos.isEmpty()) return;
for (BubbleInfo bubbleInfo : bubbleInfos.reversed()) {
BubbleBarBubble bb = mBubbleCreator.populateBubble(mContext, bubbleInfo,
mBarView, /* existingBubble= */
null);
if (bb != null) {
mSuppressedBubbles.put(bb.getKey(), bb);
}
}
}
private void applyViewChanges(BubbleBarViewUpdate update) {
final boolean isCollapsed = (update.expandedChanged && !update.expanded)
|| (!update.expandedChanged && !mBubbleBarViewController.isExpanded());
@@ -375,9 +396,7 @@ 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);
addBubbleInternally(update.updatedBubble, isExpanding, suppressAnimation);
}
if (update.addedBubble != null && isCollapsed) {
@@ -405,6 +424,24 @@ public class BubbleBarController extends IBubblesListener.Stub {
mBubbleBarViewController.showOverflow(true);
}
if (update.suppressedBubbleKey != null) {
BubbleBarBubble bb = mBubbles.remove(update.suppressedBubbleKey);
if (bb != null) {
mSuppressedBubbles.put(update.suppressedBubbleKey, bb);
mBubbleBarViewController.removeBubble(bb);
}
}
if (update.unsuppressedBubbleKey != null) {
BubbleBarBubble bb = mSuppressedBubbles.remove(update.unsuppressedBubbleKey);
if (bb != null) {
// Unsuppressing an existing bubble should not cause the bar to expand or animate
addBubbleInternally(bb, /* isExpanding= */ false, /* suppressAnimation= */ true);
if (mBubbleBarViewController.isHiddenForNoBubbles()) {
mBubbleBarViewController.setHiddenForBubbles(false);
}
}
}
// Update the visibility if this is the initial state or if there are no bubbles.
// If this is the initial bubble, the bubble bar will become visible as part of the
// animation.
@@ -439,12 +476,6 @@ public class BubbleBarController extends IBubblesListener.Stub {
mBubbleBarViewController.reorderBubbles(newOrder);
}
}
if (update.suppressedBubbleKey != null) {
// TODO: (b/273316505) handle suppression
}
if (update.unsuppressedBubbleKey != null) {
// TODO: (b/273316505) handle suppression
}
if (update.selectedBubbleKey != null) {
if (mSelectedBubble == null
|| !update.selectedBubbleKey.equals(mSelectedBubble.getKey())) {