Index: chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java |
index f4638c38711f444bf7f2b00cefa7cad6f4e9a8c6..40adf4b716ca7cbeaadef2f0571a29ac6ac60f86 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainerLayout.java |
@@ -21,7 +21,6 @@ import org.chromium.chrome.R; |
import org.chromium.chrome.browser.infobar.InfoBarContainer.InfoBarAnimationListener; |
import java.util.ArrayList; |
-import java.util.Collection; |
/** |
* Layout that displays infobars in a stack. Handles all the animations when adding or removing |
@@ -121,16 +120,6 @@ class InfoBarContainerLayout extends FrameLayout { |
} |
/** |
- * Removes multiple infobars simultaneously. This method (as opposed to calling removeInfoBar() |
- * multiple times) ensures that the animations will happen in the optimal order, i.e. back |
- * infobars disappear first. |
- */ |
- void removeInfoBars(Collection<Item> items) { |
- mItems.removeAll(items); |
- processPendingAnimations(); |
- } |
- |
- /** |
* Notifies that an infobar's View ({@link Item#getView}) has changed. If the |
* infobar is visible in the front of the stack, the infobar will fade out the old contents, |
* resize, then fade in the new contents. |
@@ -243,16 +232,18 @@ class InfoBarContainerLayout extends FrameLayout { |
* content fades in. |
*/ |
private class FrontInfoBarAppearingAnimation extends InfoBarAnimation { |
+ private Item mFrontItem; |
private InfoBarWrapper mFrontWrapper; |
private View mFrontContents; |
- FrontInfoBarAppearingAnimation(View frontContents) { |
- mFrontContents = frontContents; |
+ FrontInfoBarAppearingAnimation(Item frontItem) { |
+ mFrontItem = frontItem; |
} |
@Override |
void prepareAnimation() { |
- mFrontWrapper = new InfoBarWrapper(getContext()); |
+ mFrontContents = mFrontItem.getView(); |
+ mFrontWrapper = new InfoBarWrapper(getContext(), mFrontItem); |
mFrontWrapper.addView(mFrontContents); |
addWrapper(mFrontWrapper); |
} |
@@ -289,9 +280,12 @@ class InfoBarContainerLayout extends FrameLayout { |
private class BackInfoBarAppearingAnimation extends InfoBarAnimation { |
private InfoBarWrapper mAppearingWrapper; |
+ BackInfoBarAppearingAnimation(Item appearingItem) { |
+ mAppearingWrapper = new InfoBarWrapper(getContext(), appearingItem); |
+ } |
+ |
@Override |
void prepareAnimation() { |
- mAppearingWrapper = new InfoBarWrapper(getContext()); |
addWrapper(mAppearingWrapper); |
} |
@@ -318,14 +312,11 @@ class InfoBarContainerLayout extends FrameLayout { |
private InfoBarWrapper mNewFrontWrapper; |
private View mNewFrontContents; |
- FrontInfoBarDisappearingAndRevealingAnimation(View newFrontContents) { |
- mNewFrontContents = newFrontContents; |
- } |
- |
@Override |
void prepareAnimation() { |
mOldFrontWrapper = mInfoBarWrappers.get(0); |
mNewFrontWrapper = mInfoBarWrappers.get(1); |
+ mNewFrontContents = mNewFrontWrapper.getItem().getView(); |
mNewFrontWrapper.addView(mNewFrontContents); |
} |
@@ -366,7 +357,7 @@ class InfoBarContainerLayout extends FrameLayout { |
for (int i = 0; i < mInfoBarWrappers.size(); i++) { |
mInfoBarWrappers.get(i).setTranslationY(0); |
} |
- announceForAccessibility(mFrontItem.getAccessibilityText()); |
+ announceForAccessibility(mNewFrontWrapper.getItem().getAccessibilityText()); |
} |
@Override |
@@ -415,14 +406,11 @@ class InfoBarContainerLayout extends FrameLayout { |
private View mOldContents; |
private View mNewContents; |
- FrontInfoBarSwapContentsAnimation(View newContents) { |
- mNewContents = newContents; |
- } |
- |
@Override |
void prepareAnimation() { |
mFrontWrapper = mInfoBarWrappers.get(0); |
mOldContents = mFrontWrapper.getChildAt(0); |
+ mNewContents = mFrontWrapper.getItem().getView(); |
mFrontWrapper.addView(mNewContents); |
} |
@@ -447,8 +435,8 @@ class InfoBarContainerLayout extends FrameLayout { |
void onAnimationEnd() { |
mFrontWrapper.removeViewAt(0); |
InfoBarContainerLayout.this.setTranslationY(0f); |
- mFrontItem.setControlsEnabled(true); |
- announceForAccessibility(mFrontItem.getAccessibilityText()); |
+ mFrontWrapper.getItem().setControlsEnabled(true); |
+ announceForAccessibility(mFrontWrapper.getItem().getAccessibilityText()); |
} |
@Override |
@@ -589,13 +577,7 @@ class InfoBarContainerLayout extends FrameLayout { |
private final ArrayList<Item> mItems = new ArrayList<>(); |
/** |
- * The Item that is currently shown on the front (i.e. top) of the stack. Like mItems, this |
- * value is not meaningful during animations. |
- */ |
- private Item mFrontItem; |
- |
- /** |
- * The list of InfoBarWrapper views that are currently visible. |
+ * The currently visible InfoBarWrappers, in front to back order. |
*/ |
private final ArrayList<InfoBarWrapper> mInfoBarWrappers = new ArrayList<>(); |
@@ -618,51 +600,48 @@ class InfoBarContainerLayout extends FrameLayout { |
// removals happen before additions or swaps, and changes are made to back infobars before |
// front infobars. |
- int childCount = mInfoBarWrappers.size(); |
- int desiredChildCount = Math.min(mItems.size(), MAX_STACK_DEPTH); |
- boolean shouldRemoveFrontView = mFrontItem != null && !mItems.contains(mFrontItem); |
- |
- // First, check if we can remove any back infobars. |
- if (childCount > desiredChildCount + 1 |
- || (childCount == desiredChildCount + 1 && !shouldRemoveFrontView)) { |
- runAnimation(new InfoBarDisappearingAnimation()); |
- return; |
- } |
- |
- // Second, check if we should remove the front infobar. |
- if (shouldRemoveFrontView) { |
- // The second to front infobar, if any, will become the new front infobar. |
- if (!mItems.isEmpty() && childCount >= 2) { |
- mFrontItem = mItems.get(0); |
- runAnimation(new FrontInfoBarDisappearingAndRevealingAnimation( |
- mFrontItem.getView())); |
- return; |
- } else { |
- mFrontItem = null; |
- runAnimation(new InfoBarDisappearingAnimation()); |
- return; |
+ // First, remove any infobars that are no longer in mItems, if any. Check the back infobars |
+ // before the front. |
+ for (int i = mInfoBarWrappers.size() - 1; i >= 0; i--) { |
+ Item visibleItem = mInfoBarWrappers.get(i).getItem(); |
+ if (!mItems.contains(visibleItem)) { |
+ if (i == 0 && mInfoBarWrappers.size() >= 2) { |
+ // Remove the front infobar and reveal the second-to-front infobar. |
+ runAnimation(new FrontInfoBarDisappearingAndRevealingAnimation()); |
+ return; |
+ |
+ } else { |
+ // Move the infobar to the very back if it's not already there. |
+ InfoBarWrapper wrapper = mInfoBarWrappers.get(i); |
+ if (i != mInfoBarWrappers.size() - 1) { |
+ removeWrapper(wrapper); |
+ addWrapper(wrapper); |
+ } |
+ |
+ // Remove the backmost infobar (which may be the front infobar). |
+ runAnimation(new InfoBarDisappearingAnimation()); |
+ return; |
+ } |
} |
} |
- // Third, run swap animation on front infobar if needed. |
- if (mFrontItem != null && mItems.contains(mFrontItem)) { |
+ // Second, run swap animation on front infobar if needed. |
+ if (!mInfoBarWrappers.isEmpty()) { |
+ Item frontItem = mInfoBarWrappers.get(0).getItem(); |
View frontContents = mInfoBarWrappers.get(0).getChildAt(0); |
- if (frontContents != mFrontItem.getView()) { |
- runAnimation(new FrontInfoBarSwapContentsAnimation(mFrontItem.getView())); |
+ if (frontContents != frontItem.getView()) { |
+ runAnimation(new FrontInfoBarSwapContentsAnimation()); |
return; |
} |
} |
- // Fourth, check if we should add any infobars. |
- if (childCount < desiredChildCount) { |
- if (childCount == 0) { |
- mFrontItem = mItems.get(0); |
- runAnimation(new FrontInfoBarAppearingAnimation(mFrontItem.getView())); |
- return; |
- } else { |
- runAnimation(new BackInfoBarAppearingAnimation()); |
- return; |
- } |
+ // Third, check if we should add any infobars. |
+ int desiredChildCount = Math.min(mItems.size(), MAX_STACK_DEPTH); |
+ if (mInfoBarWrappers.size() < desiredChildCount) { |
+ Item itemToShow = mItems.get(mInfoBarWrappers.size()); |
+ runAnimation(mInfoBarWrappers.isEmpty() |
+ ? new FrontInfoBarAppearingAnimation(itemToShow) |
+ : new BackInfoBarAppearingAnimation(itemToShow)); |
} |
} |
@@ -722,7 +701,8 @@ class InfoBarContainerLayout extends FrameLayout { |
public boolean onInterceptTouchEvent(MotionEvent ev) { |
// Trap any attempts to fiddle with the infobars while we're animating. |
return super.onInterceptTouchEvent(ev) || mAnimation != null |
- || (mFrontItem != null && !mFrontItem.areControlsEnabled()); |
+ || (!mInfoBarWrappers.isEmpty() |
+ && !mInfoBarWrappers.get(0).getItem().areControlsEnabled()); |
} |
@Override |