Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e157a0d4 authored by mpodolian's avatar mpodolian
Browse files

Combined Bubble Bar location and adding a bubble into single update.

Combined Bubble Bar location update and adding a new bubble into a
single IPC call update for the Bubble Bar.

Test: atest BubbleDataTest
Test: Manual. Have a shortcut and app icons in the taskbar.
Drag and drop both items over the bubble drop zone.
Observe that items are added to the Bubble Bar.
Bubble Bar location is updated.
Flag: com.android.wm.shell.enable_create_any_bubble
Bug: 388894910

Change-Id: I2493d97baaecc3b7e6c781c2079b51192619aa97
parent 25399261
Loading
Loading
Loading
Loading
+42 −20
Original line number Diff line number Diff line
@@ -792,16 +792,22 @@ 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);
@@ -1523,18 +1530,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);
        }
    }

@@ -1564,19 +1572,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);
        }
    }

@@ -1944,11 +1952,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,
@@ -2283,7 +2302,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",
@@ -2292,7 +2312,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();

+34 −1
Original line number Diff line number Diff line
@@ -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();
    }

@@ -512,6 +532,17 @@ public class BubbleData {
        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.
     * @see Bubble#inflate(BubbleViewInfoTask.Callback, Context, BubbleExpandedViewManager,
@@ -519,7 +550,8 @@ public class BubbleData {
     * 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();
    }

+36 −0
Original line number Diff line number Diff line
@@ -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
@@ -1366,6 +1382,20 @@ public class BubbleDataTest extends ShellTestCase {
        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
    public void testShowOverflowChanged_hasOverflowBubbles() {
        assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
@@ -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();