diff options
3 files changed, 112 insertions, 21 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index 8cf2370df48d..c7a0401c2b88 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -793,15 +793,21 @@ public class BubbleController implements ConfigurationChangeListener, public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, @BubbleBarLocation.UpdateSource int source) { if (isShowingAsBubbleBar()) { + updateExpandedViewForBubbleBarLocation(bubbleBarLocation, source); + BubbleBarUpdate bubbleBarUpdate = new BubbleBarUpdate(); + bubbleBarUpdate.bubbleBarLocation = bubbleBarLocation; + mBubbleStateListener.onBubbleStateChange(bubbleBarUpdate); + } + } + + private void updateExpandedViewForBubbleBarLocation(BubbleBarLocation bubbleBarLocation, + @BubbleBarLocation.UpdateSource int source) { + if (isShowingAsBubbleBar()) { BubbleBarLocation previousLocation = mBubblePositioner.getBubbleBarLocation(); mBubblePositioner.setBubbleBarLocation(bubbleBarLocation); if (mLayerView != null && !mLayerView.isExpandedViewDragged()) { mLayerView.updateExpandedView(); } - BubbleBarUpdate bubbleBarUpdate = new BubbleBarUpdate(); - bubbleBarUpdate.bubbleBarLocation = bubbleBarLocation; - mBubbleStateListener.onBubbleStateChange(bubbleBarUpdate); - logBubbleBarLocationIfChanged(bubbleBarLocation, previousLocation, source); } } @@ -874,7 +880,8 @@ public class BubbleController implements ConfigurationChangeListener, } @Override - public void onItemDroppedOverBubbleBarDragZone(BubbleBarLocation location, Intent itemIntent) { + public void onItemDroppedOverBubbleBarDragZone(@NonNull BubbleBarLocation location, + Intent itemIntent) { hideBubbleBarExpandedViewDropTarget(); ShortcutInfo shortcutInfo = (ShortcutInfo) itemIntent .getExtra(DragAndDropConstants.EXTRA_SHORTCUT_INFO); @@ -1521,18 +1528,19 @@ public class BubbleController implements ConfigurationChangeListener, public void expandStackAndSelectBubble(ShortcutInfo info, @Nullable BubbleBarLocation bubbleBarLocation) { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; - if (bubbleBarLocation != null) { - //TODO (b/388894910) combine location update with the setSelectedBubbleAndExpandStack & - // fix bubble bar flicking - setBubbleBarLocation(bubbleBarLocation, BubbleBarLocation.UpdateSource.APP_ICON_DRAG); + BubbleBarLocation updateLocation = isShowingAsBubbleBar() ? bubbleBarLocation : null; + if (updateLocation != null) { + updateExpandedViewForBubbleBarLocation(updateLocation, + BubbleBarLocation.UpdateSource.APP_ICON_DRAG); } Bubble b = mBubbleData.getOrCreateBubble(info); // Removes from overflow ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - shortcut=%s", info); if (b.isInflated()) { - mBubbleData.setSelectedBubbleAndExpandStack(b); + mBubbleData.setSelectedBubbleAndExpandStack(b, updateLocation); } else { b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); - inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); + inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false, + updateLocation); } } @@ -1562,19 +1570,19 @@ public class BubbleController implements ConfigurationChangeListener, public void expandStackAndSelectBubble(PendingIntent pendingIntent, UserHandle user, @Nullable BubbleBarLocation bubbleBarLocation) { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; - if (bubbleBarLocation != null) { - //TODO (b/388894910) combine location update with the setSelectedBubbleAndExpandStack & - // fix bubble bar flicking - setBubbleBarLocation(bubbleBarLocation, BubbleBarLocation.UpdateSource.APP_ICON_DRAG); + BubbleBarLocation updateLocation = isShowingAsBubbleBar() ? bubbleBarLocation : null; + if (updateLocation != null) { + updateExpandedViewForBubbleBarLocation(updateLocation, + BubbleBarLocation.UpdateSource.APP_ICON_DRAG); } Bubble b = mBubbleData.getOrCreateBubble(pendingIntent, user); ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - pendingIntent=%s", pendingIntent); if (b.isInflated()) { - mBubbleData.setSelectedBubbleAndExpandStack(b); + mBubbleData.setSelectedBubbleAndExpandStack(b, updateLocation); } else { b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); - inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); + inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false, updateLocation); } } @@ -1940,11 +1948,22 @@ public class BubbleController implements ConfigurationChangeListener, @VisibleForTesting public void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade) { + inflateAndAdd(bubble, suppressFlyout, showInShade, /* bubbleBarLocation= */ null); + } + + /** + * Inflates and adds a bubble. Updates Bubble Bar location if bubbles + * are shown in the Bubble Bar and the location is not null. + */ + @VisibleForTesting + public void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade, + @Nullable BubbleBarLocation bubbleBarLocation) { // Lazy init stack view when a bubble is created ensureBubbleViewsAndWindowCreated(); bubble.setInflateSynchronously(mInflateSynchronously); bubble.inflate( - b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade), + b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade, + bubbleBarLocation), mContext, mExpandedViewManager, mBubbleTaskViewFactory, @@ -2278,7 +2297,8 @@ public class BubbleController implements ConfigurationChangeListener, ProtoLog.d(WM_SHELL_BUBBLES, "mBubbleDataListener#applyUpdate:" + " added=%s removed=%b updated=%s orderChanged=%b expansionChanged=%b" + " expanded=%b selectionChanged=%b selected=%s" - + " suppressed=%s unsupressed=%s shouldShowEducation=%b showOverflowChanged=%b", + + " suppressed=%s unsupressed=%s shouldShowEducation=%b showOverflowChanged=%b" + + " bubbleBarLocation=%s", update.addedBubble != null ? update.addedBubble.getKey() : "null", !update.removedBubbles.isEmpty(), update.updatedBubble != null ? update.updatedBubble.getKey() : "null", @@ -2287,7 +2307,9 @@ public class BubbleController implements ConfigurationChangeListener, update.selectedBubble != null ? update.selectedBubble.getKey() : "null", update.suppressedBubble != null ? update.suppressedBubble.getKey() : "null", update.unsuppressedBubble != null ? update.unsuppressedBubble.getKey() : "null", - update.shouldShowEducation, update.showOverflowChanged); + update.shouldShowEducation, update.showOverflowChanged, + update.mBubbleBarLocation != null ? update.mBubbleBarLocation.toString() + : "null"); ensureBubbleViewsAndWindowCreated(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java index f97133a4c3d1..abcdb7e70cec 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java @@ -43,6 +43,7 @@ import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubbles.DismissReason; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellMainThread; +import com.android.wm.shell.shared.bubbles.BubbleBarLocation; import com.android.wm.shell.shared.bubbles.BubbleBarUpdate; import com.android.wm.shell.shared.bubbles.RemovedBubble; @@ -91,6 +92,8 @@ public class BubbleData { @Nullable Bubble suppressedBubble; @Nullable Bubble unsuppressedBubble; @Nullable String suppressedSummaryGroup; + @Nullable + BubbleBarLocation mBubbleBarLocation; // Pair with Bubble and @DismissReason Integer final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); @@ -116,6 +119,7 @@ public class BubbleData { || unsuppressedBubble != null || suppressedSummaryChanged || suppressedSummaryGroup != null + || mBubbleBarLocation != null || showOverflowChanged; } @@ -169,6 +173,7 @@ public class BubbleData { } bubbleBarUpdate.showOverflowChanged = showOverflowChanged; bubbleBarUpdate.showOverflow = !overflowBubbles.isEmpty(); + bubbleBarUpdate.bubbleBarLocation = mBubbleBarLocation; return bubbleBarUpdate; } @@ -396,8 +401,23 @@ public class BubbleData { * {@link #setExpanded(boolean)} immediately after, which will generate 2 separate updates. */ public void setSelectedBubbleAndExpandStack(BubbleViewProvider bubble) { + setSelectedBubbleAndExpandStack(bubble, /* bubbleBarLocation = */ null); + } + + /** + * Sets the selected bubble and expands it. Also updates bubble bar location if the + * bubbleBarLocation is not {@code null} + * + * <p>This dispatches a single state update for 3 changes and should be used instead of + * calling {@link BubbleController#setBubbleBarLocation(BubbleBarLocation, int)} followed by + * {@link #setSelectedBubbleAndExpandStack(BubbleViewProvider)} immediately after, which will + * generate 2 separate updates. + */ + public void setSelectedBubbleAndExpandStack(BubbleViewProvider bubble, + @Nullable BubbleBarLocation bubbleBarLocation) { setSelectedBubbleInternal(bubble); setExpandedInternal(true); + mStateChange.mBubbleBarLocation = bubbleBarLocation; dispatchPendingChanges(); } @@ -513,13 +533,25 @@ public class BubbleData { } /** + * Calls {@link #notificationEntryUpdated(Bubble, boolean, boolean, BubbleBarLocation)} passing + * {@code null} for bubbleBarLocation. + * + * @see #notificationEntryUpdated(Bubble, boolean, boolean, BubbleBarLocation) + */ + void notificationEntryUpdated(Bubble bubble, boolean suppressFlyout, boolean showInShade) { + notificationEntryUpdated(bubble, suppressFlyout, showInShade, /* bubbleBarLocation = */ + null); + } + + /** * When this method is called it is expected that all info in the bubble has completed loading. * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleExpandedViewManager, * BubbleTaskViewFactory, BubblePositioner, BubbleLogger, BubbleStackView, * com.android.wm.shell.bubbles.bar.BubbleBarLayerView, * com.android.launcher3.icons.BubbleIconFactory, boolean) */ - void notificationEntryUpdated(Bubble bubble, boolean suppressFlyout, boolean showInShade) { + void notificationEntryUpdated(Bubble bubble, boolean suppressFlyout, boolean showInShade, + @Nullable BubbleBarLocation bubbleBarLocation) { mPendingBubbles.remove(bubble.getKey()); // No longer pending once we're here Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey()); suppressFlyout |= !bubble.isTextChanged(); @@ -567,6 +599,7 @@ public class BubbleData { doSuppress(bubble); } } + mStateChange.mBubbleBarLocation = bubbleBarLocation; dispatchPendingChanges(); } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java index ffcc3446d436..7a7d88b80ce3 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java @@ -572,6 +572,22 @@ public class BubbleDataTest extends ShellTestCase { assertThat(update.shouldShowEducation).isTrue(); } + /** Verifies that the update should contain the bubble bar location. */ + @Test + public void test_shouldUpdateBubbleBarLocation() { + // Setup + mBubbleData.setListener(mListener); + + // Test + mBubbleData.notificationEntryUpdated(mBubbleA1, /* suppressFlyout */ true, /* showInShade */ + true, BubbleBarLocation.LEFT); + + // Verify + verifyUpdateReceived(); + BubbleData.Update update = mUpdateCaptor.getValue(); + assertThat(update.mBubbleBarLocation).isEqualTo(BubbleBarLocation.LEFT); + } + /** * Verifies that the update shouldn't show the user education, if the education is required but * the bubble should auto-expand @@ -1367,6 +1383,20 @@ public class BubbleDataTest extends ShellTestCase { } @Test + public void setSelectedBubbleAndExpandStackWithLocation() { + sendUpdatedEntryAtTime(mEntryA1, 1000); + sendUpdatedEntryAtTime(mEntryA2, 2000); + mBubbleData.setListener(mListener); + + mBubbleData.setSelectedBubbleAndExpandStack(mBubbleA1, BubbleBarLocation.LEFT); + + verifyUpdateReceived(); + assertSelectionChangedTo(mBubbleA1); + assertExpandedChangedTo(true); + assertLocationChangedTo(BubbleBarLocation.LEFT); + } + + @Test public void testShowOverflowChanged_hasOverflowBubbles() { assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); sendUpdatedEntryAtTime(mEntryA1, 1000); @@ -1450,6 +1480,12 @@ public class BubbleDataTest extends ShellTestCase { assertWithMessage("selectedBubble").that(update.selectedBubble).isEqualTo(bubble); } + private void assertLocationChangedTo(BubbleBarLocation location) { + BubbleData.Update update = mUpdateCaptor.getValue(); + assertWithMessage("locationChanged").that(update.mBubbleBarLocation) + .isEqualTo(location); + } + private void assertExpandedChangedTo(boolean expected) { BubbleData.Update update = mUpdateCaptor.getValue(); assertWithMessage("expandedChanged").that(update.expandedChanged).isTrue(); |