1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)package org.chromium.chrome.browser.infobar; 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.animation.ObjectAnimator; 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.app.Activity; 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.graphics.Canvas; 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.view.Gravity; 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.view.MotionEvent; 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.view.View; 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.view.ViewGroup; 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.widget.FrameLayout; 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import android.widget.LinearLayout; 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import com.google.common.annotations.VisibleForTesting; 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import org.chromium.base.ApiCompatibilityUtils; 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import org.chromium.base.CalledByNative; 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import org.chromium.content.browser.DeviceUtils; 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import org.chromium.ui.UiUtils; 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import java.util.ArrayDeque; 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import java.util.ArrayList; 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import java.util.Iterator; 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)import java.util.LinkedList; 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)/** 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * A container for all the infobars of a specific tab. 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Note that infobars creation can be initiated from Java of from native code. 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * When initiated from native code, special code is needed to keep the Java and native infobar in 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * sync, see NativeInfoBar. 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)public class InfoBarContainer extends LinearLayout { 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private static final String TAG = "InfoBarContainer"; 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private static final long REATTACH_FADE_IN_MS = 250; 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public interface InfoBarAnimationListener { 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Notifies the subscriber when an animation is completed. 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void notifyAnimationFinished(int animationType); 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private static class InfoBarTransitionInfo { 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // InfoBar being animated. 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public InfoBar target; 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // View to replace the current View shown by the ContentWrapperView. 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public View toShow; 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Which type of animation needs to be performed. 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public int animationType; 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public InfoBarTransitionInfo(InfoBar bar, View view, int type) { 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert type >= AnimationHelper.ANIMATION_TYPE_SHOW; 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert type < AnimationHelper.ANIMATION_TYPE_BOUNDARY; 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) target = bar; 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) toShow = view; 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) animationType = type; 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private InfoBarAnimationListener mAnimationListener; 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Native InfoBarContainer pointer which will be set by nativeInit() 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private long mNativeInfoBarContainer; 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private final Activity mActivity; 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private final AutoLoginDelegate mAutoLoginDelegate; 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Whether the infobar are shown on top (below the location bar) or at the bottom of the screen. 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private final boolean mInfoBarsOnTop; 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The list of all infobars in this container, regardless of whether they've been shown yet. 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private final ArrayList<InfoBar> mInfoBars = new ArrayList<InfoBar>(); 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We only animate changing infobars one at a time. 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private final ArrayDeque<InfoBarTransitionInfo> mInfoBarTransitions; 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Animation currently moving InfoBars around. 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private AnimationHelper mAnimation; 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private final FrameLayout mAnimationSizer; 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // True when this container has been emptied and its native counterpart has been destroyed. 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private boolean mDestroyed = false; 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The id of the tab associated with us. Set to TabBase.INVALID_TAB_ID if no tab is associated. 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private int mTabId; 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Parent view that contains us. 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private ViewGroup mParentView; 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public InfoBarContainer(Activity activity, AutoLoginProcessor autoLoginProcessor, 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int tabId, ViewGroup parentView, long nativeWebContents) { 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) super(activity); 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setOrientation(LinearLayout.VERTICAL); 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimationListener = null; 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mInfoBarTransitions = new ArrayDeque<InfoBarTransitionInfo>(); 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAutoLoginDelegate = new AutoLoginDelegate(autoLoginProcessor, activity); 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mActivity = activity; 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mTabId = tabId; 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mParentView = parentView; 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimationSizer = new FrameLayout(activity); 111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimationSizer.setVisibility(INVISIBLE); 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // The tablet has the infobars below the location bar. On the phone they are at the bottom. 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mInfoBarsOnTop = DeviceUtils.isTablet(activity); 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setGravity(determineGravity()); 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Chromium's InfoBarContainer may add an InfoBar immediately during this initialization 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // call, so make sure everything in the InfoBarContainer is completely ready beforehand. 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mNativeInfoBarContainer = nativeInit(nativeWebContents, mAutoLoginDelegate); 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void setAnimationListener(InfoBarAnimationListener listener) { 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimationListener = listener; 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @VisibleForTesting 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public InfoBarAnimationListener getAnimationListener() { 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mAnimationListener; 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 130d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 131d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public boolean areInfoBarsOnTop() { 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mInfoBarsOnTop; 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 135d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 136d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @Override 137d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public boolean onInterceptTouchEvent(MotionEvent ev) { 138d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Trap any attempts to fiddle with the Views while we're animating. 139d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mAnimation != null; 140d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 141d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 142d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @Override 143d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public boolean onTouchEvent(MotionEvent event) { 144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Consume all motion events so they do not reach the ContentView. 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void addToParentView() { 149d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mParentView != null && mParentView.indexOfChild(this) == -1) { 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mParentView.addView(this, createLayoutParams()); 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private int determineGravity() { 155d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mInfoBarsOnTop ? Gravity.TOP : Gravity.BOTTOM; 156d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 158d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private FrameLayout.LayoutParams createLayoutParams() { 159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return new FrameLayout.LayoutParams( 160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, determineGravity()); 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public void removeFromParentView() { 164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (getParent() != null) { 165d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ((ViewGroup) getParent()).removeView(this); 166d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 167d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 168d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 169d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Called when the parent {@link android.view.ViewGroup} has changed for 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * this container. 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 173d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void onParentViewChanged(int tabId, ViewGroup parentView) { 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mTabId = tabId; 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mParentView = parentView; 176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 17733bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch removeFromParentView(); 17833bff6d6e5e82ca5f2abf842074e33f4944cc250Ben Murdoch addToParentView(); 179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 181d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @Override 182d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mAnimation == null || child != mAnimation.getTarget()) { 184d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return super.drawChild(canvas, child, drawingTime); 185d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 186d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // When infobars are on top, the new infobar Z-order is greater than the previous infobar, 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // which means it shows on top during the animation. We cannot change the Z-order in the 188d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // linear layout, it is driven by the insertion index. 189d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // So we simply clip the children to their bounds to make sure the new infobar does not 190d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // paint over. 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) boolean retVal; 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) canvas.save(); 193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) canvas.clipRect(mAnimation.getTarget().getClippingRect()); 194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) retVal = super.drawChild(canvas, child, drawingTime); 195d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) canvas.restore(); 196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return retVal; 197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 198d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 199d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @Override 200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) protected void onAttachedToWindow() { 201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) super.onAttachedToWindow(); 202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ObjectAnimator.ofFloat(this, "alpha", 0.f, 1.f).setDuration(REATTACH_FADE_IN_MS).start(); 203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setVisibility(VISIBLE); 204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @Override 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) protected void onDetachedFromWindow() { 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) super.onDetachedFromWindow(); 209d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setVisibility(INVISIBLE); 210d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 211d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public InfoBar findInfoBar(int nativeInfoBar) { 213d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (InfoBar infoBar : mInfoBars) { 214d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (infoBar.ownsNativeInfoBar(nativeInfoBar)) { 215d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return infoBar; 216d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 217d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 218d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return null; 219d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 221d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 222d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Adds an InfoBar to the view hierarchy. 223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param infoBar InfoBar to add to the View hierarchy. 224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @CalledByNative 226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void addInfoBar(InfoBar infoBar) { 227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert !mDestroyed; 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (infoBar == null) { 229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mInfoBars.contains(infoBar)) { 232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert false : "Trying to add an info bar that has already been added."; 233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 236d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We add the infobar immediately to mInfoBars but we wait for the animation to end to 237d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // notify it's been added, as tests rely on this notification but expects the infobar view 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // to be available when they get the notification. 239d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mInfoBars.add(infoBar); 240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) infoBar.setContext(mActivity); 241d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) infoBar.setInfoBarContainer(this); 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) enqueueInfoBarAnimation(infoBar, null, AnimationHelper.ANIMATION_TYPE_SHOW); 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Returns the latest InfoBarTransitionInfo that deals with the given InfoBar. 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param toFind InfoBar that we're looking for. 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public InfoBarTransitionInfo findLastTransitionForInfoBar(InfoBar toFind) { 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Iterator<InfoBarTransitionInfo> iterator = mInfoBarTransitions.descendingIterator(); 252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) while (iterator.hasNext()) { 253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InfoBarTransitionInfo info = iterator.next(); 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (info.target == toFind) return info; 255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return null; 257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Animates swapping out the current View in the {@code infoBar} with {@code toShow} without 261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * destroying or dismissing the entire InfoBar. 262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param infoBar InfoBar that is having its content replaced. 263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param toShow View representing the InfoBar's new contents. 264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void swapInfoBarViews(InfoBar infoBar, View toShow) { 266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert !mDestroyed; 267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!mInfoBars.contains(infoBar)) { 269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert false : "Trying to swap an InfoBar that is not in this container."; 270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 271d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InfoBarTransitionInfo transition = findLastTransitionForInfoBar(infoBar); 274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (transition != null && transition.toShow == toShow) { 275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert false : "Tried to enqueue the same swap twice in a row."; 276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) enqueueInfoBarAnimation(infoBar, toShow, AnimationHelper.ANIMATION_TYPE_SWAP); 280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Removes an InfoBar from the view hierarchy. 284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param infoBar InfoBar to remove from the View hierarchy. 285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void removeInfoBar(InfoBar infoBar) { 287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert !mDestroyed; 288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!mInfoBars.remove(infoBar)) { 290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert false : "Trying to remove an InfoBar that is not in this container."; 291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If an InfoBar is told to hide itself before it has a chance to be shown, don't bother 295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // with animating any of it. 296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) boolean collapseAnimations = false; 297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ArrayDeque<InfoBarTransitionInfo> transitionCopy = 298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) new ArrayDeque<InfoBarTransitionInfo>(mInfoBarTransitions); 299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (InfoBarTransitionInfo info : transitionCopy) { 300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (info.target == infoBar) { 301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (info.animationType == AnimationHelper.ANIMATION_TYPE_SHOW) { 302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We can assert that two attempts to show the same InfoBar won't be in the 303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // deque simultaneously because of the check in addInfoBar(). 304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert !collapseAnimations; 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) collapseAnimations = true; 306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (collapseAnimations) { 308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mInfoBarTransitions.remove(info); 309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!collapseAnimations) { 314d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) enqueueInfoBarAnimation(infoBar, null, AnimationHelper.ANIMATION_TYPE_HIDE); 315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 317d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 318d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Enqueue a new animation to run and kicks off the animation sequence. 320d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void enqueueInfoBarAnimation(InfoBar infoBar, View toShow, int animationType) { 322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InfoBarTransitionInfo info = new InfoBarTransitionInfo(infoBar, toShow, animationType); 323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mInfoBarTransitions.add(info); 324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) processPendingInfoBars(); 325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @Override 328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) protected void onLayout(boolean changed, int l, int t, int r, int b) { 329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Hide the infobars when the keyboard is showing. 330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) boolean isShowing = (getVisibility() == View.VISIBLE); 331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (UiUtils.isKeyboardShowing(mActivity, this)) { 332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (isShowing) { 333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setVisibility(View.INVISIBLE); 334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (!isShowing) { 337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) setVisibility(View.VISIBLE); 338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) super.onLayout(changed, l, t, r, b); 341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @return True when this container has been emptied and its native counterpart has been 345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * destroyed. 346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public boolean hasBeenDestroyed() { 348d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mDestroyed; 349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 350d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 351d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private void processPendingInfoBars() { 352d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mAnimation != null || mInfoBarTransitions.isEmpty()) return; 353d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 354d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Start animating what has to be animated. 355d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) InfoBarTransitionInfo info = mInfoBarTransitions.remove(); 356d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) View toShow = info.toShow; 357d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ContentWrapperView targetView; 358d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 359d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) addToParentView(); 360d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 361d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (info.animationType == AnimationHelper.ANIMATION_TYPE_SHOW) { 362d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) targetView = info.target.getContentWrapper(true); 363d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert mInfoBars.contains(info.target); 364d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) toShow = targetView.detachCurrentView(); 365d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) addView(targetView, mInfoBarsOnTop ? getChildCount() : 0, 366d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 367d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 368d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) targetView = info.target.getContentWrapper(false); 369d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 370d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 371d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Kick off the animation. 372d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimation = new AnimationHelper(this, targetView, info.target, toShow, info.animationType); 373d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimation.start(); 374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 375d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 376d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Called by the tab when it has started loading a new page. 377d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void onPageStarted(String url) { 378d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LinkedList<InfoBar> barsToRemove = new LinkedList<InfoBar>(); 379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 380d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (InfoBar infoBar : mInfoBars) { 381d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (infoBar.shouldExpire(url)) { 382d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) barsToRemove.add(infoBar); 383d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 384d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 385d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 386d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (InfoBar infoBar : barsToRemove) { 3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) infoBar.dismissJavaOnlyInfoBar(); 388d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 389d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 390d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 391d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 392d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Returns the id of the tab we are associated with. 393d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 394d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public int getTabId() { 395d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mTabId; 396d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 397d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 398d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void destroy() { 399d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mDestroyed = true; 400d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) removeAllViews(); 401d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mNativeInfoBarContainer != 0) { 402d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) nativeDestroy(mNativeInfoBarContainer); 403d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mInfoBarTransitions.clear(); 405d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 406d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 407d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 408d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @return all of the InfoBars held in this container. 409d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 410d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) @VisibleForTesting 411d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public ArrayList<InfoBar> getInfoBars() { 412d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mInfoBars; 413d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 414d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 415d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 416d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Dismisses all {@link AutoLoginInfoBar}s in this {@link InfoBarContainer} that are for 417d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * {@code accountName} and {@code authToken}. This also resets all {@link InfoBar}s that are 418d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * for a different request. 419d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param accountName The name of the account request is being accessed for. 420d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param authToken The authentication token access is being requested for. 421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param success Whether or not the authentication attempt was successful. 422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param result The resulting token for the auto login request (ignored if {@code success} is 423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * {@code false}. 424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void processAutoLogin(String accountName, String authToken, boolean success, 426d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) String result) { 427d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAutoLoginDelegate.dismissAutoLogins(accountName, authToken, success, result); 428d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 429d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 430d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 431d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Dismiss all auto logins infobars without processing any result. 432d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 433d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void dismissAutoLoginInfoBars() { 434d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAutoLoginDelegate.dismissAutoLogins("", "", false, ""); 435d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 436d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 437d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void prepareTransition(View toShow) { 438d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (toShow != null) { 439d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // In order to animate the addition of the infobar, we need a layout first. 440d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Attach the child to invisible layout so that we can get measurements for it without 441d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // moving everything in the real container. 442d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ViewGroup parent = (ViewGroup) toShow.getParent(); 443d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (parent != null) parent.removeView(toShow); 444d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 445d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert mAnimationSizer.getParent() == null; 446d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mParentView.addView(mAnimationSizer, createLayoutParams()); 447d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimationSizer.addView(toShow, 0, 448d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); 449d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimationSizer.requestLayout(); 450d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 451d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 452d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 453d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void startTransition() { 454d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mInfoBarsOnTop) { 455d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // We need to clip this view to its bounds while it is animated because the layout's 456d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // z-ordering puts it on top of other infobars as it's being animated. 457d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ApiCompatibilityUtils.postInvalidateOnAnimation(this); 458d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 459d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 460d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 461d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 462d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Finishes off whatever animation is running. 463d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 464d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public void finishTransition() { 465d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) assert mAnimation != null; 466d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 467d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If the InfoBar was hidden, get rid of its View entirely. 468d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mAnimation.getAnimationType() == AnimationHelper.ANIMATION_TYPE_HIDE) { 469d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) removeView(mAnimation.getTarget()); 470d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 471d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 472d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Reset all translations and put everything where they need to be. 473d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (int i = 0; i < getChildCount(); ++i) { 474d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) View view = getChildAt(i); 475d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) view.setTranslationY(0); 476d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 477d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) requestLayout(); 478d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 479d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // If there are no infobars shown, there is no need to keep the infobar container in the 480d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // view hierarchy. 481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (getChildCount() == 0) { 482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) removeFromParentView(); 483d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 484d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 485d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mAnimationSizer.getParent() != null) { 486d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ((ViewGroup) mAnimationSizer.getParent()).removeView(mAnimationSizer); 487d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 488d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 489d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Notify interested parties and move on to the next animation. 490d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (mAnimationListener != null) { 491d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimationListener.notifyAnimationFinished(mAnimation.getAnimationType()); 492d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 493d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) mAnimation = null; 494d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) processPendingInfoBars(); 495d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 496d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 497d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) /** 498d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * Searches a given view's child views for an instance of {@link InfoBarContainer}. 499d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * 500d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @param parentView View to be searched for 501d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * @return {@link InfoBarContainer} instance if it's one of the child views; 502d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) * otherwise {@code null}. 503d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) */ 504d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public static InfoBarContainer childViewOf(ViewGroup parentView) { 505d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (int i = 0; i < parentView.getChildCount(); i++) { 506d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (parentView.getChildAt(i) instanceof InfoBarContainer) { 507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return (InfoBarContainer) parentView.getChildAt(i); 508d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 509d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 510d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return null; 511d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public long getNative() { 514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return mNativeInfoBarContainer; 515d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 516d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private native long nativeInit(long webContentsPtr, AutoLoginDelegate autoLoginDelegate); 518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private native void nativeDestroy(long nativeInfoBarContainerAndroid); 520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 521