Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +42 −20 Original line number Original line Diff line number Diff line Loading @@ -792,16 +792,22 @@ public class BubbleController implements ConfigurationChangeListener, */ */ public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, @BubbleBarLocation.UpdateSource int source) { @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()) { if (isShowingAsBubbleBar()) { BubbleBarLocation previousLocation = mBubblePositioner.getBubbleBarLocation(); BubbleBarLocation previousLocation = mBubblePositioner.getBubbleBarLocation(); mBubblePositioner.setBubbleBarLocation(bubbleBarLocation); mBubblePositioner.setBubbleBarLocation(bubbleBarLocation); if (mLayerView != null && !mLayerView.isExpandedViewDragged()) { if (mLayerView != null && !mLayerView.isExpandedViewDragged()) { mLayerView.updateExpandedView(); mLayerView.updateExpandedView(); } } BubbleBarUpdate bubbleBarUpdate = new BubbleBarUpdate(); bubbleBarUpdate.bubbleBarLocation = bubbleBarLocation; mBubbleStateListener.onBubbleStateChange(bubbleBarUpdate); logBubbleBarLocationIfChanged(bubbleBarLocation, previousLocation, source); logBubbleBarLocationIfChanged(bubbleBarLocation, previousLocation, source); } } } } Loading Loading @@ -874,7 +880,8 @@ public class BubbleController implements ConfigurationChangeListener, } } @Override @Override public void onItemDroppedOverBubbleBarDragZone(BubbleBarLocation location, Intent itemIntent) { public void onItemDroppedOverBubbleBarDragZone(@NonNull BubbleBarLocation location, Intent itemIntent) { hideBubbleBarExpandedViewDropTarget(); hideBubbleBarExpandedViewDropTarget(); ShortcutInfo shortcutInfo = (ShortcutInfo) itemIntent ShortcutInfo shortcutInfo = (ShortcutInfo) itemIntent .getExtra(DragAndDropConstants.EXTRA_SHORTCUT_INFO); .getExtra(DragAndDropConstants.EXTRA_SHORTCUT_INFO); Loading Loading @@ -1521,18 +1528,19 @@ public class BubbleController implements ConfigurationChangeListener, public void expandStackAndSelectBubble(ShortcutInfo info, public void expandStackAndSelectBubble(ShortcutInfo info, @Nullable BubbleBarLocation bubbleBarLocation) { @Nullable BubbleBarLocation bubbleBarLocation) { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (bubbleBarLocation != null) { BubbleBarLocation updateLocation = isShowingAsBubbleBar() ? bubbleBarLocation : null; //TODO (b/388894910) combine location update with the setSelectedBubbleAndExpandStack & if (updateLocation != null) { // fix bubble bar flicking updateExpandedViewForBubbleBarLocation(updateLocation, setBubbleBarLocation(bubbleBarLocation, BubbleBarLocation.UpdateSource.APP_ICON_DRAG); BubbleBarLocation.UpdateSource.APP_ICON_DRAG); } } Bubble b = mBubbleData.getOrCreateBubble(info); // Removes from overflow Bubble b = mBubbleData.getOrCreateBubble(info); // Removes from overflow ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - shortcut=%s", info); ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - shortcut=%s", info); if (b.isInflated()) { if (b.isInflated()) { mBubbleData.setSelectedBubbleAndExpandStack(b); mBubbleData.setSelectedBubbleAndExpandStack(b, updateLocation); } else { } else { b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false, updateLocation); } } } } Loading Loading @@ -1562,19 +1570,19 @@ public class BubbleController implements ConfigurationChangeListener, public void expandStackAndSelectBubble(PendingIntent pendingIntent, UserHandle user, public void expandStackAndSelectBubble(PendingIntent pendingIntent, UserHandle user, @Nullable BubbleBarLocation bubbleBarLocation) { @Nullable BubbleBarLocation bubbleBarLocation) { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (bubbleBarLocation != null) { BubbleBarLocation updateLocation = isShowingAsBubbleBar() ? bubbleBarLocation : null; //TODO (b/388894910) combine location update with the setSelectedBubbleAndExpandStack & if (updateLocation != null) { // fix bubble bar flicking updateExpandedViewForBubbleBarLocation(updateLocation, setBubbleBarLocation(bubbleBarLocation, BubbleBarLocation.UpdateSource.APP_ICON_DRAG); BubbleBarLocation.UpdateSource.APP_ICON_DRAG); } } Bubble b = mBubbleData.getOrCreateBubble(pendingIntent, user); Bubble b = mBubbleData.getOrCreateBubble(pendingIntent, user); ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - pendingIntent=%s", ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - pendingIntent=%s", pendingIntent); pendingIntent); if (b.isInflated()) { if (b.isInflated()) { mBubbleData.setSelectedBubbleAndExpandStack(b); mBubbleData.setSelectedBubbleAndExpandStack(b, updateLocation); } else { } else { b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false, updateLocation); } } } } Loading Loading @@ -1940,11 +1948,22 @@ public class BubbleController implements ConfigurationChangeListener, @VisibleForTesting @VisibleForTesting public void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade) { 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 // Lazy init stack view when a bubble is created ensureBubbleViewsAndWindowCreated(); ensureBubbleViewsAndWindowCreated(); bubble.setInflateSynchronously(mInflateSynchronously); bubble.setInflateSynchronously(mInflateSynchronously); bubble.inflate( bubble.inflate( b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade), b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade, bubbleBarLocation), mContext, mContext, mExpandedViewManager, mExpandedViewManager, mBubbleTaskViewFactory, mBubbleTaskViewFactory, Loading Loading @@ -2278,7 +2297,8 @@ public class BubbleController implements ConfigurationChangeListener, ProtoLog.d(WM_SHELL_BUBBLES, "mBubbleDataListener#applyUpdate:" ProtoLog.d(WM_SHELL_BUBBLES, "mBubbleDataListener#applyUpdate:" + " added=%s removed=%b updated=%s orderChanged=%b expansionChanged=%b" + " added=%s removed=%b updated=%s orderChanged=%b expansionChanged=%b" + " expanded=%b selectionChanged=%b selected=%s" + " 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.addedBubble != null ? update.addedBubble.getKey() : "null", !update.removedBubbles.isEmpty(), !update.removedBubbles.isEmpty(), update.updatedBubble != null ? update.updatedBubble.getKey() : "null", update.updatedBubble != null ? update.updatedBubble.getKey() : "null", Loading @@ -2287,7 +2307,9 @@ public class BubbleController implements ConfigurationChangeListener, update.selectedBubble != null ? update.selectedBubble.getKey() : "null", update.selectedBubble != null ? update.selectedBubble.getKey() : "null", update.suppressedBubble != null ? update.suppressedBubble.getKey() : "null", update.suppressedBubble != null ? update.suppressedBubble.getKey() : "null", update.unsuppressedBubble != null ? update.unsuppressedBubble.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(); ensureBubbleViewsAndWindowCreated(); Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +34 −1 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubbles.DismissReason; import com.android.wm.shell.bubbles.Bubbles.DismissReason; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellMainThread; 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.BubbleBarUpdate; import com.android.wm.shell.shared.bubbles.RemovedBubble; import com.android.wm.shell.shared.bubbles.RemovedBubble; Loading Loading @@ -91,6 +92,8 @@ public class BubbleData { @Nullable Bubble suppressedBubble; @Nullable Bubble suppressedBubble; @Nullable Bubble unsuppressedBubble; @Nullable Bubble unsuppressedBubble; @Nullable String suppressedSummaryGroup; @Nullable String suppressedSummaryGroup; @Nullable BubbleBarLocation mBubbleBarLocation; // Pair with Bubble and @DismissReason Integer // Pair with Bubble and @DismissReason Integer final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); Loading @@ -116,6 +119,7 @@ public class BubbleData { || unsuppressedBubble != null || unsuppressedBubble != null || suppressedSummaryChanged || suppressedSummaryChanged || suppressedSummaryGroup != null || suppressedSummaryGroup != null || mBubbleBarLocation != null || showOverflowChanged; || showOverflowChanged; } } Loading Loading @@ -169,6 +173,7 @@ public class BubbleData { } } bubbleBarUpdate.showOverflowChanged = showOverflowChanged; bubbleBarUpdate.showOverflowChanged = showOverflowChanged; bubbleBarUpdate.showOverflow = !overflowBubbles.isEmpty(); bubbleBarUpdate.showOverflow = !overflowBubbles.isEmpty(); bubbleBarUpdate.bubbleBarLocation = mBubbleBarLocation; return bubbleBarUpdate; return bubbleBarUpdate; } } Loading Loading @@ -396,8 +401,23 @@ public class BubbleData { * {@link #setExpanded(boolean)} immediately after, which will generate 2 separate updates. * {@link #setExpanded(boolean)} immediately after, which will generate 2 separate updates. */ */ public void setSelectedBubbleAndExpandStack(BubbleViewProvider bubble) { 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); setSelectedBubbleInternal(bubble); setExpandedInternal(true); setExpandedInternal(true); mStateChange.mBubbleBarLocation = bubbleBarLocation; dispatchPendingChanges(); dispatchPendingChanges(); } } Loading Loading @@ -512,6 +532,17 @@ public class BubbleData { return bubbleToReturn; return bubbleToReturn; } } /** * 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. * When this method is called it is expected that all info in the bubble has completed loading. * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleExpandedViewManager, * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleExpandedViewManager, Loading @@ -519,7 +550,8 @@ public class BubbleData { * com.android.wm.shell.bubbles.bar.BubbleBarLayerView, * com.android.wm.shell.bubbles.bar.BubbleBarLayerView, * com.android.launcher3.icons.BubbleIconFactory, boolean) * 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 mPendingBubbles.remove(bubble.getKey()); // No longer pending once we're here Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey()); Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey()); suppressFlyout |= !bubble.isTextChanged(); suppressFlyout |= !bubble.isTextChanged(); Loading Loading @@ -567,6 +599,7 @@ public class BubbleData { doSuppress(bubble); doSuppress(bubble); } } } } mStateChange.mBubbleBarLocation = bubbleBarLocation; dispatchPendingChanges(); dispatchPendingChanges(); } } Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java +36 −0 Original line number Original line Diff line number Diff line Loading @@ -572,6 +572,22 @@ public class BubbleDataTest extends ShellTestCase { assertThat(update.shouldShowEducation).isTrue(); 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 * Verifies that the update shouldn't show the user education, if the education is required but * the bubble should auto-expand * the bubble should auto-expand Loading Loading @@ -1366,6 +1382,20 @@ public class BubbleDataTest extends ShellTestCase { assertExpandedChangedTo(true); assertExpandedChangedTo(true); } } @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 @Test public void testShowOverflowChanged_hasOverflowBubbles() { public void testShowOverflowChanged_hasOverflowBubbles() { assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); Loading Loading @@ -1450,6 +1480,12 @@ public class BubbleDataTest extends ShellTestCase { assertWithMessage("selectedBubble").that(update.selectedBubble).isEqualTo(bubble); 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) { private void assertExpandedChangedTo(boolean expected) { BubbleData.Update update = mUpdateCaptor.getValue(); BubbleData.Update update = mUpdateCaptor.getValue(); assertWithMessage("expandedChanged").that(update.expandedChanged).isTrue(); assertWithMessage("expandedChanged").that(update.expandedChanged).isTrue(); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +42 −20 Original line number Original line Diff line number Diff line Loading @@ -792,16 +792,22 @@ public class BubbleController implements ConfigurationChangeListener, */ */ public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation, @BubbleBarLocation.UpdateSource int source) { @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()) { if (isShowingAsBubbleBar()) { BubbleBarLocation previousLocation = mBubblePositioner.getBubbleBarLocation(); BubbleBarLocation previousLocation = mBubblePositioner.getBubbleBarLocation(); mBubblePositioner.setBubbleBarLocation(bubbleBarLocation); mBubblePositioner.setBubbleBarLocation(bubbleBarLocation); if (mLayerView != null && !mLayerView.isExpandedViewDragged()) { if (mLayerView != null && !mLayerView.isExpandedViewDragged()) { mLayerView.updateExpandedView(); mLayerView.updateExpandedView(); } } BubbleBarUpdate bubbleBarUpdate = new BubbleBarUpdate(); bubbleBarUpdate.bubbleBarLocation = bubbleBarLocation; mBubbleStateListener.onBubbleStateChange(bubbleBarUpdate); logBubbleBarLocationIfChanged(bubbleBarLocation, previousLocation, source); logBubbleBarLocationIfChanged(bubbleBarLocation, previousLocation, source); } } } } Loading Loading @@ -874,7 +880,8 @@ public class BubbleController implements ConfigurationChangeListener, } } @Override @Override public void onItemDroppedOverBubbleBarDragZone(BubbleBarLocation location, Intent itemIntent) { public void onItemDroppedOverBubbleBarDragZone(@NonNull BubbleBarLocation location, Intent itemIntent) { hideBubbleBarExpandedViewDropTarget(); hideBubbleBarExpandedViewDropTarget(); ShortcutInfo shortcutInfo = (ShortcutInfo) itemIntent ShortcutInfo shortcutInfo = (ShortcutInfo) itemIntent .getExtra(DragAndDropConstants.EXTRA_SHORTCUT_INFO); .getExtra(DragAndDropConstants.EXTRA_SHORTCUT_INFO); Loading Loading @@ -1521,18 +1528,19 @@ public class BubbleController implements ConfigurationChangeListener, public void expandStackAndSelectBubble(ShortcutInfo info, public void expandStackAndSelectBubble(ShortcutInfo info, @Nullable BubbleBarLocation bubbleBarLocation) { @Nullable BubbleBarLocation bubbleBarLocation) { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (bubbleBarLocation != null) { BubbleBarLocation updateLocation = isShowingAsBubbleBar() ? bubbleBarLocation : null; //TODO (b/388894910) combine location update with the setSelectedBubbleAndExpandStack & if (updateLocation != null) { // fix bubble bar flicking updateExpandedViewForBubbleBarLocation(updateLocation, setBubbleBarLocation(bubbleBarLocation, BubbleBarLocation.UpdateSource.APP_ICON_DRAG); BubbleBarLocation.UpdateSource.APP_ICON_DRAG); } } Bubble b = mBubbleData.getOrCreateBubble(info); // Removes from overflow Bubble b = mBubbleData.getOrCreateBubble(info); // Removes from overflow ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - shortcut=%s", info); ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - shortcut=%s", info); if (b.isInflated()) { if (b.isInflated()) { mBubbleData.setSelectedBubbleAndExpandStack(b); mBubbleData.setSelectedBubbleAndExpandStack(b, updateLocation); } else { } else { b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false, updateLocation); } } } } Loading Loading @@ -1562,19 +1570,19 @@ public class BubbleController implements ConfigurationChangeListener, public void expandStackAndSelectBubble(PendingIntent pendingIntent, UserHandle user, public void expandStackAndSelectBubble(PendingIntent pendingIntent, UserHandle user, @Nullable BubbleBarLocation bubbleBarLocation) { @Nullable BubbleBarLocation bubbleBarLocation) { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) return; if (bubbleBarLocation != null) { BubbleBarLocation updateLocation = isShowingAsBubbleBar() ? bubbleBarLocation : null; //TODO (b/388894910) combine location update with the setSelectedBubbleAndExpandStack & if (updateLocation != null) { // fix bubble bar flicking updateExpandedViewForBubbleBarLocation(updateLocation, setBubbleBarLocation(bubbleBarLocation, BubbleBarLocation.UpdateSource.APP_ICON_DRAG); BubbleBarLocation.UpdateSource.APP_ICON_DRAG); } } Bubble b = mBubbleData.getOrCreateBubble(pendingIntent, user); Bubble b = mBubbleData.getOrCreateBubble(pendingIntent, user); ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - pendingIntent=%s", ProtoLog.v(WM_SHELL_BUBBLES, "expandStackAndSelectBubble - pendingIntent=%s", pendingIntent); pendingIntent); if (b.isInflated()) { if (b.isInflated()) { mBubbleData.setSelectedBubbleAndExpandStack(b); mBubbleData.setSelectedBubbleAndExpandStack(b, updateLocation); } else { } else { b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); b.enable(Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false); inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false, updateLocation); } } } } Loading Loading @@ -1940,11 +1948,22 @@ public class BubbleController implements ConfigurationChangeListener, @VisibleForTesting @VisibleForTesting public void inflateAndAdd(Bubble bubble, boolean suppressFlyout, boolean showInShade) { 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 // Lazy init stack view when a bubble is created ensureBubbleViewsAndWindowCreated(); ensureBubbleViewsAndWindowCreated(); bubble.setInflateSynchronously(mInflateSynchronously); bubble.setInflateSynchronously(mInflateSynchronously); bubble.inflate( bubble.inflate( b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade), b -> mBubbleData.notificationEntryUpdated(b, suppressFlyout, showInShade, bubbleBarLocation), mContext, mContext, mExpandedViewManager, mExpandedViewManager, mBubbleTaskViewFactory, mBubbleTaskViewFactory, Loading Loading @@ -2278,7 +2297,8 @@ public class BubbleController implements ConfigurationChangeListener, ProtoLog.d(WM_SHELL_BUBBLES, "mBubbleDataListener#applyUpdate:" ProtoLog.d(WM_SHELL_BUBBLES, "mBubbleDataListener#applyUpdate:" + " added=%s removed=%b updated=%s orderChanged=%b expansionChanged=%b" + " added=%s removed=%b updated=%s orderChanged=%b expansionChanged=%b" + " expanded=%b selectionChanged=%b selected=%s" + " 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.addedBubble != null ? update.addedBubble.getKey() : "null", !update.removedBubbles.isEmpty(), !update.removedBubbles.isEmpty(), update.updatedBubble != null ? update.updatedBubble.getKey() : "null", update.updatedBubble != null ? update.updatedBubble.getKey() : "null", Loading @@ -2287,7 +2307,9 @@ public class BubbleController implements ConfigurationChangeListener, update.selectedBubble != null ? update.selectedBubble.getKey() : "null", update.selectedBubble != null ? update.selectedBubble.getKey() : "null", update.suppressedBubble != null ? update.suppressedBubble.getKey() : "null", update.suppressedBubble != null ? update.suppressedBubble.getKey() : "null", update.unsuppressedBubble != null ? update.unsuppressedBubble.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(); ensureBubbleViewsAndWindowCreated(); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +34 −1 Original line number Original line Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.wm.shell.R; import com.android.wm.shell.bubbles.Bubbles.DismissReason; import com.android.wm.shell.bubbles.Bubbles.DismissReason; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellBackgroundThread; import com.android.wm.shell.shared.annotations.ShellMainThread; 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.BubbleBarUpdate; import com.android.wm.shell.shared.bubbles.RemovedBubble; import com.android.wm.shell.shared.bubbles.RemovedBubble; Loading Loading @@ -91,6 +92,8 @@ public class BubbleData { @Nullable Bubble suppressedBubble; @Nullable Bubble suppressedBubble; @Nullable Bubble unsuppressedBubble; @Nullable Bubble unsuppressedBubble; @Nullable String suppressedSummaryGroup; @Nullable String suppressedSummaryGroup; @Nullable BubbleBarLocation mBubbleBarLocation; // Pair with Bubble and @DismissReason Integer // Pair with Bubble and @DismissReason Integer final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>(); Loading @@ -116,6 +119,7 @@ public class BubbleData { || unsuppressedBubble != null || unsuppressedBubble != null || suppressedSummaryChanged || suppressedSummaryChanged || suppressedSummaryGroup != null || suppressedSummaryGroup != null || mBubbleBarLocation != null || showOverflowChanged; || showOverflowChanged; } } Loading Loading @@ -169,6 +173,7 @@ public class BubbleData { } } bubbleBarUpdate.showOverflowChanged = showOverflowChanged; bubbleBarUpdate.showOverflowChanged = showOverflowChanged; bubbleBarUpdate.showOverflow = !overflowBubbles.isEmpty(); bubbleBarUpdate.showOverflow = !overflowBubbles.isEmpty(); bubbleBarUpdate.bubbleBarLocation = mBubbleBarLocation; return bubbleBarUpdate; return bubbleBarUpdate; } } Loading Loading @@ -396,8 +401,23 @@ public class BubbleData { * {@link #setExpanded(boolean)} immediately after, which will generate 2 separate updates. * {@link #setExpanded(boolean)} immediately after, which will generate 2 separate updates. */ */ public void setSelectedBubbleAndExpandStack(BubbleViewProvider bubble) { 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); setSelectedBubbleInternal(bubble); setExpandedInternal(true); setExpandedInternal(true); mStateChange.mBubbleBarLocation = bubbleBarLocation; dispatchPendingChanges(); dispatchPendingChanges(); } } Loading Loading @@ -512,6 +532,17 @@ public class BubbleData { return bubbleToReturn; return bubbleToReturn; } } /** * 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. * When this method is called it is expected that all info in the bubble has completed loading. * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleExpandedViewManager, * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleExpandedViewManager, Loading @@ -519,7 +550,8 @@ public class BubbleData { * com.android.wm.shell.bubbles.bar.BubbleBarLayerView, * com.android.wm.shell.bubbles.bar.BubbleBarLayerView, * com.android.launcher3.icons.BubbleIconFactory, boolean) * 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 mPendingBubbles.remove(bubble.getKey()); // No longer pending once we're here Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey()); Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey()); suppressFlyout |= !bubble.isTextChanged(); suppressFlyout |= !bubble.isTextChanged(); Loading Loading @@ -567,6 +599,7 @@ public class BubbleData { doSuppress(bubble); doSuppress(bubble); } } } } mStateChange.mBubbleBarLocation = bubbleBarLocation; dispatchPendingChanges(); dispatchPendingChanges(); } } Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java +36 −0 Original line number Original line Diff line number Diff line Loading @@ -572,6 +572,22 @@ public class BubbleDataTest extends ShellTestCase { assertThat(update.shouldShowEducation).isTrue(); 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 * Verifies that the update shouldn't show the user education, if the education is required but * the bubble should auto-expand * the bubble should auto-expand Loading Loading @@ -1366,6 +1382,20 @@ public class BubbleDataTest extends ShellTestCase { assertExpandedChangedTo(true); assertExpandedChangedTo(true); } } @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 @Test public void testShowOverflowChanged_hasOverflowBubbles() { public void testShowOverflowChanged_hasOverflowBubbles() { assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); assertThat(mBubbleData.getOverflowBubbles()).isEmpty(); Loading Loading @@ -1450,6 +1480,12 @@ public class BubbleDataTest extends ShellTestCase { assertWithMessage("selectedBubble").that(update.selectedBubble).isEqualTo(bubble); 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) { private void assertExpandedChangedTo(boolean expected) { BubbleData.Update update = mUpdateCaptor.getValue(); BubbleData.Update update = mUpdateCaptor.getValue(); assertWithMessage("expandedChanged").that(update.expandedChanged).isTrue(); assertWithMessage("expandedChanged").that(update.expandedChanged).isTrue(); Loading