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

Commit ec6f9d71 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor bubble lookup and code organization." into main

parents d59304db 36cec9b1
Loading
Loading
Loading
Loading
+37 −38
Original line number Diff line number Diff line
@@ -477,24 +477,23 @@ public class BubbleController implements ConfigurationChangeListener,
            @Override
            public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
                    boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
                for (Bubble b : mBubbleData.getBubbles()) {
                    if (task.taskId == b.getTaskId()) {
                final int taskId = task.taskId;
                Bubble bubble = mBubbleData.getBubbleInStackWithTaskId(taskId);
                if (bubble != null) {
                    ProtoLog.d(WM_SHELL_BUBBLES,
                            "onActivityRestartAttempt - taskId=%d selecting matching bubble=%s",
                                task.taskId, b.getKey());
                        mBubbleData.setSelectedBubbleAndExpandStack(b);
                            taskId, bubble.getKey());
                    mBubbleData.setSelectedBubbleAndExpandStack(bubble);
                    return;
                }
                }
                for (Bubble b : mBubbleData.getOverflowBubbles()) {
                    if (task.taskId == b.getTaskId()) {

                bubble = mBubbleData.getOverflowBubbleWithTaskId(taskId);
                if (bubble != null) {
                    ProtoLog.d(WM_SHELL_BUBBLES, "onActivityRestartAttempt - taskId=%d "
                                    + "selecting matching overflow bubble=%s",
                                task.taskId, b.getKey());
                        promoteBubbleFromOverflow(b);
                            taskId, bubble.getKey());
                    promoteBubbleFromOverflow(bubble);
                    mBubbleData.setExpanded(true);
                        return;
                    }
                }
            }
        });
@@ -1296,8 +1295,8 @@ public class BubbleController implements ConfigurationChangeListener,
     * @param timestamp the timestamp of the removal
     */
    public void dragBubbleToDismiss(String bubbleKey, long timestamp) {
        String selectedBubbleKey = mBubbleData.getSelectedBubbleKey();
        Bubble bubbleToDismiss = mBubbleData.getAnyBubbleWithkey(bubbleKey);
        final String selectedBubbleKey = mBubbleData.getSelectedBubbleKey();
        final Bubble bubbleToDismiss = mBubbleData.getAnyBubbleWithKey(bubbleKey);
        if (bubbleToDismiss != null) {
            mBubbleData.dismissBubbleWithKey(
                    bubbleKey, Bubbles.DISMISS_USER_GESTURE_FROM_LAUNCHER, timestamp);
@@ -1330,11 +1329,11 @@ public class BubbleController implements ConfigurationChangeListener,

    @VisibleForTesting
    public boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey) {
        boolean isSuppressedBubble = (mBubbleData.hasAnyBubbleWithKey(key)
                && !mBubbleData.getAnyBubbleWithkey(key).showInShade());
        final boolean isSuppressedBubble = (mBubbleData.hasAnyBubbleWithKey(key)
                && !mBubbleData.getAnyBubbleWithKey(key).showInShade());

        boolean isSuppressedSummary = mBubbleData.isSummarySuppressed(groupKey);
        boolean isSummary = key.equals(mBubbleData.getSummaryKey(groupKey));
        final boolean isSuppressedSummary = mBubbleData.isSummarySuppressed(groupKey);
        final boolean isSummary = key.equals(mBubbleData.getSummaryKey(groupKey));
        return (isSummary && isSuppressedSummary) || isSuppressedBubble;
    }

@@ -1362,8 +1361,6 @@ public class BubbleController implements ConfigurationChangeListener,
    public void expandStackAndSelectBubbleFromLauncher(String key, int topOnScreen) {
        mBubblePositioner.setBubbleBarTopOnScreen(topOnScreen);

        boolean wasExpanded = (mLayerView != null && mLayerView.isExpanded());

        if (BubbleOverflow.KEY.equals(key)) {
            mBubbleData.setSelectedBubbleFromLauncher(mBubbleData.getOverflow());
            mLayerView.showExpandedView(mBubbleData.getOverflow());
@@ -1371,10 +1368,11 @@ public class BubbleController implements ConfigurationChangeListener,
            return;
        }

        Bubble b = mBubbleData.getAnyBubbleWithkey(key);
        final Bubble b = mBubbleData.getAnyBubbleWithKey(key);
        if (b == null) {
            return;
        }
        final boolean wasExpanded = (mLayerView != null && mLayerView.isExpanded());
        if (mBubbleData.hasBubbleInStackWithKey(b.getKey())) {
            // already in the stack
            mBubbleData.setSelectedBubbleFromLauncher(b);
@@ -1748,31 +1746,32 @@ public class BubbleController implements ConfigurationChangeListener,
    public void updateBubble(BubbleEntry notif, boolean suppressFlyout, boolean showInShade) {
        // If this is an interruptive notif, mark that it's interrupted
        mSysuiProxy.setNotificationInterruption(notif.getKey());
        boolean isNonInterruptiveNotExpanding = !notif.getRanking().isTextChanged()
        final boolean isNonInterruptiveNotExpanding = !notif.getRanking().isTextChanged()
                && (notif.getBubbleMetadata() != null
                && !notif.getBubbleMetadata().getAutoExpandBubble());
        final Bubble bubble;
        if (isNonInterruptiveNotExpanding
                && mBubbleData.hasOverflowBubbleWithKey(notif.getKey())) {
            // Update the bubble but don't promote it out of overflow
            Bubble b = mBubbleData.getOverflowBubbleWithKey(notif.getKey());
            bubble = mBubbleData.getOverflowBubbleWithKey(notif.getKey());
            if (notif.isBubble()) {
                notif.setFlagBubble(false);
            }
            updateNotNotifyingEntry(b, notif, showInShade);
            updateNotNotifyingEntry(bubble, notif, showInShade);
        } else if (mBubbleData.hasAnyBubbleWithKey(notif.getKey())
                && isNonInterruptiveNotExpanding) {
            Bubble b = mBubbleData.getAnyBubbleWithkey(notif.getKey());
            if (b != null) {
                updateNotNotifyingEntry(b, notif, showInShade);
            bubble = mBubbleData.getAnyBubbleWithKey(notif.getKey());
            if (bubble != null) {
                updateNotNotifyingEntry(bubble, notif, showInShade);
            }
        } else if (mBubbleData.isSuppressedWithLocusId(notif.getLocusId())) {
            // Update the bubble but don't promote it out of overflow
            Bubble b = mBubbleData.getSuppressedBubbleWithKey(notif.getKey());
            if (b != null) {
                updateNotNotifyingEntry(b, notif, showInShade);
            bubble = mBubbleData.getSuppressedBubbleWithKey(notif.getKey());
            if (bubble != null) {
                updateNotNotifyingEntry(bubble, notif, showInShade);
            }
        } else {
            Bubble bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */);
            bubble = mBubbleData.getOrCreateBubble(notif, null /* persistedBubble */);
            if (notif.shouldSuppressNotificationList()) {
                // If we're suppressing notifs for DND, we don't want the bubbles to randomly
                // expand when DND turns off so flip the flag.
@@ -2323,12 +2322,12 @@ public class BubbleController implements ConfigurationChangeListener,
            BubbleEntry summary, @Nullable List<BubbleEntry> children, IntConsumer removeCallback) {
        if (children != null) {
            for (int i = 0; i < children.size(); i++) {
                BubbleEntry child = children.get(i);
                final BubbleEntry child = children.get(i);
                if (mBubbleData.hasAnyBubbleWithKey(child.getKey())) {
                    // Suppress the bubbled child
                    // As far as group manager is concerned, once a child is no longer shown
                    // in the shade, it is essentially removed.
                    Bubble bubbleChild = mBubbleData.getAnyBubbleWithkey(child.getKey());
                    final Bubble bubbleChild = mBubbleData.getAnyBubbleWithKey(child.getKey());
                    if (bubbleChild != null) {
                        bubbleChild.setSuppressNotification(true);
                        bubbleChild.setShowDot(false /* show */);
+53 −69
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.content.Intent;
import android.content.LocusId;
import android.content.pm.ShortcutInfo;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -48,6 +47,7 @@ import com.android.wm.shell.shared.bubbles.RemovedBubble;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -667,7 +667,7 @@ public class BubbleData {

    /** Removes all bubbles for the given user. */
    public void removeBubblesForUser(int userId) {
        List<Bubble> removedBubbles = filterAllBubbles(bubble ->
        final List<Bubble> removedBubbles = filterAllBubbles(bubble ->
                userId == bubble.getUser().getIdentifier());
        for (Bubble b : removedBubbles) {
            doRemove(b.getKey(), Bubbles.DISMISS_USER_ACCOUNT_REMOVED);
@@ -1162,7 +1162,7 @@ public class BubbleData {

    @VisibleForTesting(visibility = PRIVATE)
    @Nullable
    Bubble getAnyBubbleWithkey(String key) {
    Bubble getAnyBubbleWithKey(String key) {
        Bubble b = getBubbleInStackWithKey(key);
        if (b == null) {
            b = getOverflowBubbleWithKey(key);
@@ -1173,77 +1173,45 @@ public class BubbleData {
        return b;
    }

    /** @return any bubble (in the stack or the overflow) that matches the provided shortcutId. */
    /** @return the bubble in the stack that matches the provided taskId. */
    @Nullable
    Bubble getAnyBubbleWithShortcutId(String shortcutId) {
        if (TextUtils.isEmpty(shortcutId)) {
            return null;
        }
        for (int i = 0; i < mBubbles.size(); i++) {
            Bubble bubble = mBubbles.get(i);
            String bubbleShortcutId = bubble.getShortcutInfo() != null
                    ? bubble.getShortcutInfo().getId()
                    : bubble.getMetadataShortcutId();
            if (shortcutId.equals(bubbleShortcutId)) {
                return bubble;
            }
        }

        for (int i = 0; i < mOverflowBubbles.size(); i++) {
            Bubble bubble = mOverflowBubbles.get(i);
            String bubbleShortcutId = bubble.getShortcutInfo() != null
                    ? bubble.getShortcutInfo().getId()
                    : bubble.getMetadataShortcutId();
            if (shortcutId.equals(bubbleShortcutId)) {
                return bubble;
            }
        }
        return null;
    Bubble getBubbleInStackWithTaskId(int taskId) {
        return getBubbleWithPredicate(mBubbles, b -> b.getTaskId() == taskId);
    }

    @VisibleForTesting(visibility = PRIVATE)
    /** @return the bubble in the stack that matches the provided key. */
    @Nullable
    @VisibleForTesting(visibility = PRIVATE)
    public Bubble getBubbleInStackWithKey(String key) {
        for (int i = 0; i < mBubbles.size(); i++) {
            Bubble bubble = mBubbles.get(i);
            if (bubble.getKey().equals(key)) {
                return bubble;
            }
        }
        return null;
        return getBubbleWithPredicate(mBubbles, b -> b.getKey().equals(key));
    }

    /** @return the bubble in the stack that matches the provided locusId. */
    @Nullable
    private Bubble getBubbleInStackWithLocusId(LocusId locusId) {
        if (locusId == null) return null;
        for (int i = 0; i < mBubbles.size(); i++) {
            Bubble bubble = mBubbles.get(i);
            if (locusId.equals(bubble.getLocusId())) {
                return bubble;
            }
        }
    private Bubble getBubbleInStackWithLocusId(@Nullable LocusId locusId) {
        if (locusId == null) {
            return null;
        }
        return getBubbleWithPredicate(mBubbles, b -> locusId.equals(b.getLocusId()));
    }

    /** @return the bubble in the stack that matches the provided icon view. */
    @Nullable
    Bubble getBubbleWithView(View view) {
        for (int i = 0; i < mBubbles.size(); i++) {
            Bubble bubble = mBubbles.get(i);
            if (bubble.getIconView() != null && bubble.getIconView().equals(view)) {
                return bubble;
            }
    Bubble getBubbleInStackWithView(View view) {
        return getBubbleWithPredicate(mBubbles, b ->
                b.getIconView() != null && b.getIconView().equals(view));
    }
        return null;

    /** @return the overflow bubble that matches the provided taskId. */
    @Nullable
    Bubble getOverflowBubbleWithTaskId(int taskId) {
        return getBubbleWithPredicate(mOverflowBubbles, b -> b.getTaskId() == taskId);
    }

    /** @return the overflow bubble that matches the provided key. */
    @Nullable
    public Bubble getOverflowBubbleWithKey(String key) {
        for (int i = 0; i < mOverflowBubbles.size(); i++) {
            Bubble bubble = mOverflowBubbles.get(i);
            if (bubble.getKey().equals(key)) {
                return bubble;
            }
        }
        return null;
        return getBubbleWithPredicate(mOverflowBubbles, b -> b.getKey().equals(key));
    }

    /**
@@ -1255,12 +1223,7 @@ public class BubbleData {
    @Nullable
    @VisibleForTesting(visibility = PRIVATE)
    public Bubble getSuppressedBubbleWithKey(String key) {
        for (Bubble b : mSuppressedBubbles.values()) {
            if (b.getKey().equals(key)) {
                return b;
            }
        }
        return null;
        return getBubbleWithPredicate(mSuppressedBubbles.values(), b -> b.getKey().equals(key));
    }

    /**
@@ -1269,11 +1232,32 @@ public class BubbleData {
     * @param key notification key
     * @return bubble that matches or null
     */
    @Nullable
    @VisibleForTesting(visibility = PRIVATE)
    public Bubble getPendingBubbleWithKey(String key) {
        for (Bubble b : mPendingBubbles.values()) {
            if (b.getKey().equals(key)) {
                return b;
        return getBubbleWithPredicate(mPendingBubbles.values(), b -> b.getKey().equals(key));
    }

    @Nullable
    private static Bubble getBubbleWithPredicate(@NonNull final List<Bubble> bubbles,
            @NonNull final Predicate<Bubble> predicate) {
        // Uses an indexed for loop for optimized performance when iterating over ArrayLists.
        for (int i = 0; i < bubbles.size(); i++) {
            final Bubble bubble = bubbles.get(i);
            if (predicate.test(bubble)) {
                return bubble;
            }
        }
        return null;
    }

    @Nullable
    private static Bubble getBubbleWithPredicate(@NonNull final Collection<Bubble> bubbles,
            @NonNull final Predicate<Bubble> predicate) {
        // Uses an enhanced for loop for general collections, which may not support indexed access.
        for (final Bubble bubble : bubbles) {
            if (predicate.test(bubble)) {
                return bubble;
            }
        }
        return null;
@@ -1284,7 +1268,7 @@ public class BubbleData {
     * bubbles (i.e. pending, suppressed, active, and overflowed).
     */
    private List<Bubble> filterAllBubbles(Predicate<Bubble> predicate) {
        ArrayList<Bubble> matchingBubbles = new ArrayList<>();
        final ArrayList<Bubble> matchingBubbles = new ArrayList<>();
        for (Bubble b : mPendingBubbles.values()) {
            if (predicate.test(b)) {
                matchingBubbles.add(b);
+2 −2
Original line number Diff line number Diff line
@@ -497,7 +497,7 @@ public class BubbleStackView extends FrameLayout
                                view /* bubble */,
                                mDismissView.getHeight() /* translationYBy */,
                                () -> dismissBubbleIfExists(
                                        mBubbleData.getBubbleWithView(view)) /* after */);
                                        mBubbleData.getBubbleInStackWithView(view)) /* after */);
                    }

                    mDismissView.hide();
@@ -558,7 +558,7 @@ public class BubbleStackView extends FrameLayout
                return;
            }

            final Bubble clickedBubble = mBubbleData.getBubbleWithView(view);
            final Bubble clickedBubble = mBubbleData.getBubbleInStackWithView(view);

            // If the bubble has since left us, ignore the click.
            if (clickedBubble == null) {
+7 −5
Original line number Diff line number Diff line
@@ -33,11 +33,13 @@ import com.android.wm.shell.transition.Transitions;
 */
public class BubblesTransitionObserver implements Transitions.TransitionObserver {

    private BubbleController mBubbleController;
    private BubbleData mBubbleData;
    @NonNull
    private final BubbleController mBubbleController;
    @NonNull
    private final BubbleData mBubbleData;

    public BubblesTransitionObserver(BubbleController controller,
            BubbleData bubbleData) {
    public BubblesTransitionObserver(@NonNull BubbleController controller,
            @NonNull BubbleData bubbleData) {
        mBubbleController = controller;
        mBubbleData = bubbleData;
    }
@@ -57,7 +59,7 @@ public class BubblesTransitionObserver implements Transitions.TransitionObserver
                    || mBubbleData.getSelectedBubble() == null) {
                continue;
            }
            int expandedId = mBubbleData.getSelectedBubble().getTaskId();
            final int expandedId = mBubbleData.getSelectedBubble().getTaskId();
            // If the task id that's opening is the same as the expanded bubble, skip collapsing
            // because it is our bubble that is opening.
            if (expandedId != INVALID_TASK_ID && expandedId != taskInfo.taskId) {