Index: chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManager.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManager.java |
index dec1711f5190a8d5c5ea9f20fcea12d682bfb10b..b00505e370e954971846f15191e6bcdb4037ad7e 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManager.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelManager.java |
@@ -10,12 +10,14 @@ import org.chromium.base.VisibleForTesting; |
import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel.StateChangeReason; |
import org.chromium.ui.resources.dynamics.DynamicResourceLoader; |
+import java.util.Comparator; |
import java.util.HashSet; |
+import java.util.PriorityQueue; |
+import java.util.Queue; |
import java.util.Set; |
/** |
* Used to decide which panel should be showing on screen at any moment. |
- * NOTE(mdjones): Currently only supports two panels. |
*/ |
public class OverlayPanelManager { |
@@ -29,6 +31,9 @@ public class OverlayPanelManager { |
HIGH; |
} |
+ /** The initial size of the priority queue for suppressed panels. */ |
+ private static final int INITIAL_QUEUE_CAPACITY = 3; |
+ |
/** A map of panels that this class is managing. */ |
private final Set<OverlayPanel> mPanelSet; |
@@ -38,9 +43,8 @@ public class OverlayPanelManager { |
/** |
* If a panel was being shown and another panel with higher priority was requested to show, |
* the lower priority one is stored here. |
- * TODO(mdjones): This should be a list in the case that there are more than two panels. |
*/ |
- private OverlayPanel mSuppressedPanel; |
+ private Queue<OverlayPanel> mSuppressedPanels; |
/** When a panel is suppressed, this is the panel waiting for the close animation to finish. */ |
private OverlayPanel mPendingPanel; |
@@ -58,6 +62,15 @@ public class OverlayPanelManager { |
* Default constructor. |
*/ |
public OverlayPanelManager() { |
+ mSuppressedPanels = new PriorityQueue<>(INITIAL_QUEUE_CAPACITY, |
+ new Comparator<OverlayPanel>() { |
+ @Override |
+ public int compare(OverlayPanel p1, OverlayPanel p2) { |
+ // The head of the queue is the smallest element, so subtract p1's priority |
+ // from p2's priority. |
+ return p2.getPriority().ordinal() - p1.getPriority().ordinal(); |
+ } |
+ }); |
mPanelSet = new HashSet<>(); |
} |
@@ -79,8 +92,8 @@ public class OverlayPanelManager { |
} else if (panel.getPriority().ordinal() > mActivePanel.getPriority().ordinal()) { |
// If a panel with higher priority than the active one requests to be shown, suppress |
- // the active panel and show the requesting one. |
- // NOTE(mdjones): closePanel will trigger notifyPanelClosed. |
+ // the active panel and show the requesting one. closePanel will trigger |
+ // notifyPanelClosed. |
mPendingPanel = panel; |
mPendingReason = reason; |
mActivePanel.closePanel(StateChangeReason.SUPPRESS, true); |
@@ -88,7 +101,7 @@ public class OverlayPanelManager { |
} else if (panel.canBeSuppressed()) { |
// If a panel was showing and the requesting panel has a lower priority, suppress it |
// if possible. |
- mSuppressedPanel = panel; |
+ if (!mSuppressedPanels.contains(panel)) mSuppressedPanels.add(panel); |
} |
} |
@@ -107,7 +120,7 @@ public class OverlayPanelManager { |
if (reason == StateChangeReason.SUPPRESS) { |
if (mActivePanel == panel) { |
if (mActivePanel.canBeSuppressed()) { |
- mSuppressedPanel = mActivePanel; |
+ mSuppressedPanels.add(mActivePanel); |
} |
mActivePanel = mPendingPanel; |
mActivePanel.peekPanel(mPendingReason); |
@@ -118,12 +131,13 @@ public class OverlayPanelManager { |
// Normal close panel flow. |
if (panel == mActivePanel) { |
mActivePanel = null; |
- if (mSuppressedPanel != null) { |
- mActivePanel = mSuppressedPanel; |
+ if (!mSuppressedPanels.isEmpty()) { |
+ mActivePanel = mSuppressedPanels.poll(); |
mActivePanel.peekPanel(StateChangeReason.UNSUPPRESS); |
} |
+ } else { |
+ mSuppressedPanels.remove(panel); |
} |
- mSuppressedPanel = null; |
} |
} |
@@ -137,6 +151,14 @@ public class OverlayPanelManager { |
} |
/** |
+ * @return The size of the suppressed panel queue. |
+ */ |
+ @VisibleForTesting |
+ public int getSuppressedQueueSize() { |
+ return mSuppressedPanels.size(); |
+ } |
+ |
+ /** |
* Destroy all panels owned by this manager. |
*/ |
public void destroy() { |
@@ -145,7 +167,7 @@ public class OverlayPanelManager { |
} |
mPanelSet.clear(); |
mActivePanel = null; |
- mSuppressedPanel = null; |
+ mSuppressedPanels.clear(); |
// Clear references to held resources. |
mDynamicResourceLoader = null; |