Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/infobar/InfoBarContainer.java

Issue 1613513004: Prevent Contextual Search from breaking InfoBarContainer visibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Logs Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.infobar; 5 package org.chromium.chrome.browser.infobar;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.view.Gravity; 8 import android.view.Gravity;
9 import android.view.View;
9 import android.view.ViewGroup; 10 import android.view.ViewGroup;
11 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
10 import android.widget.FrameLayout; 12 import android.widget.FrameLayout;
11 13
12 import org.chromium.base.ObserverList; 14 import org.chromium.base.ObserverList;
13 import org.chromium.base.VisibleForTesting; 15 import org.chromium.base.VisibleForTesting;
14 import org.chromium.base.annotations.CalledByNative; 16 import org.chromium.base.annotations.CalledByNative;
15 import org.chromium.chrome.browser.banners.SwipableOverlayView; 17 import org.chromium.chrome.browser.banners.SwipableOverlayView;
18 import org.chromium.chrome.browser.tab.EmptyTabObserver;
16 import org.chromium.chrome.browser.tab.Tab; 19 import org.chromium.chrome.browser.tab.Tab;
20 import org.chromium.chrome.browser.tab.TabObserver;
17 import org.chromium.content.browser.ContentViewCore; 21 import org.chromium.content.browser.ContentViewCore;
18 import org.chromium.content_public.browser.WebContents; 22 import org.chromium.content_public.browser.WebContents;
23 import org.chromium.ui.UiUtils;
19 import org.chromium.ui.base.DeviceFormFactor; 24 import org.chromium.ui.base.DeviceFormFactor;
20 25
21 import java.util.ArrayList; 26 import java.util.ArrayList;
22 27
23 28
24 /** 29 /**
25 * A container for all the infobars of a specific tab. 30 * A container for all the infobars of a specific tab.
26 * Note that infobars creation can be initiated from Java of from native code. 31 * Note that infobars creation can be initiated from Java of from native code.
27 * When initiated from native code, special code is needed to keep the Java and native infobar in 32 * When initiated from native code, special code is needed to keep the Java and native infobar in
28 * sync, see NativeInfoBar. 33 * sync, see NativeInfoBar.
29 */ 34 */
30 public class InfoBarContainer extends SwipableOverlayView { 35 public class InfoBarContainer extends SwipableOverlayView {
31 private static final String TAG = "InfoBarContainer"; 36 private static final String TAG = "InfoBarContainer";
32 37
33 /** Top margin, including the toolbar and tabstrip height and 48dp of web co ntents. */ 38 /** Top margin, including the toolbar and tabstrip height and 48dp of web co ntents. */
34 private static final int TOP_MARGIN_PHONE_DP = 104; 39 private static final int TOP_MARGIN_PHONE_DP = 104;
35 private static final int TOP_MARGIN_TABLET_DP = 144; 40 private static final int TOP_MARGIN_TABLET_DP = 144;
36 41
42 /** Length of the animation to fade the InfoBarContainer back into View. */
43 private static final long REATTACH_FADE_IN_MS = 250;
44
37 /** Whether or not the InfoBarContainer is allowed to hide when the user scr olls. */ 45 /** Whether or not the InfoBarContainer is allowed to hide when the user scr olls. */
38 private static boolean sIsAllowedToAutoHide = true; 46 private static boolean sIsAllowedToAutoHide = true;
39 47
40 /** 48 /**
41 * A listener for the InfoBar animations. 49 * A listener for the InfoBar animations.
42 */ 50 */
43 public interface InfoBarAnimationListener { 51 public interface InfoBarAnimationListener {
44 public static final int ANIMATION_TYPE_SHOW = 0; 52 public static final int ANIMATION_TYPE_SHOW = 0;
45 public static final int ANIMATION_TYPE_SWAP = 1; 53 public static final int ANIMATION_TYPE_SWAP = 1;
46 public static final int ANIMATION_TYPE_HIDE = 2; 54 public static final int ANIMATION_TYPE_HIDE = 2;
(...skipping 18 matching lines...) Expand all
65 73
66 /** 74 /**
67 * Called when an {@link InfoBar} is about to be removed (before the ani mation). 75 * Called when an {@link InfoBar} is about to be removed (before the ani mation).
68 * @param container The notifying {@link InfoBarContainer} 76 * @param container The notifying {@link InfoBarContainer}
69 * @param infoBar An {@link InfoBar} being removed 77 * @param infoBar An {@link InfoBar} being removed
70 * @param isLast Whether the infobar container is going to be empty 78 * @param isLast Whether the infobar container is going to be empty
71 */ 79 */
72 void onRemoveInfoBar(InfoBarContainer container, InfoBar infoBar, boolea n isLast); 80 void onRemoveInfoBar(InfoBarContainer container, InfoBar infoBar, boolea n isLast);
73 } 81 }
74 82
83 /** Toggles visibility of the InfoBarContainer when the keyboard appears. */
84 private OnGlobalLayoutListener mGlobalLayoutListener = new OnGlobalLayoutLis tener() {
newt (away) 2016/01/22 21:43:46 Just realized a downside of using a global layout
gone 2016/01/22 22:11:41 Android doesn't like that: 01-22 14:10:17.992 290
85 @Override
86 public void onGlobalLayout() {
87 // Hide the View when the keyboard is showing.
88 boolean isShowing = (getVisibility() == View.VISIBLE);
89 if (UiUtils.isKeyboardShowing(getContext(), InfoBarContainer.this)) {
90 if (isShowing) {
91 setVisibility(View.GONE);
92 }
93 } else {
94 if (!isShowing && !mIsObscured) {
95 setVisibility(View.VISIBLE);
96 }
97 }
98 }
99 };
100
101 /** Resets the state of the InfoBarContainer when the user navigates. */
102 private final TabObserver mTabObserver = new EmptyTabObserver() {
103 @Override
104 public void onDidNavigateMainFrame(Tab tab, String url, String baseUrl,
105 boolean isNavigationToDifferentPage, boolean isFragmentNavigatio n,
106 int statusCode) {
107 setIsObscuredByOtherView(false);
108 }
109 };
110
75 private final InfoBarContainerLayout mLayout; 111 private final InfoBarContainerLayout mLayout;
76 112
77 /** Native InfoBarContainer pointer which will be set by nativeInit(). */ 113 /** Native InfoBarContainer pointer which will be set by nativeInit(). */
78 private final long mNativeInfoBarContainer; 114 private final long mNativeInfoBarContainer;
79 115
80 private final Context mContext;
81
82 /** The list of all InfoBars in this container, regardless of whether they'v e been shown yet. */ 116 /** The list of all InfoBars in this container, regardless of whether they'v e been shown yet. */
83 private final ArrayList<InfoBar> mInfoBars = new ArrayList<InfoBar>(); 117 private final ArrayList<InfoBar> mInfoBars = new ArrayList<InfoBar>();
84 118
85 /** True when this container has been emptied and its native counterpart has been destroyed. */ 119 /** True when this container has been emptied and its native counterpart has been destroyed. */
86 private boolean mDestroyed = false; 120 private boolean mDestroyed = false;
87 121
88 /** The id of the tab associated with us. Set to Tab.INVALID_TAB_ID if no ta b is associated. */ 122 /** The id of the tab associated with us. Set to Tab.INVALID_TAB_ID if no ta b is associated. */
89 private int mTabId; 123 private int mTabId;
90 124
91 /** Parent view that contains the InfoBarContainerLayout. */ 125 /** Parent view that contains the InfoBarContainerLayout. */
92 private ViewGroup mParentView; 126 private ViewGroup mParentView;
93 127
128 /** Whether or not another View is occupying the same space as this one. */
129 private boolean mIsObscured;
130
94 private final ObserverList<InfoBarContainerObserver> mObservers = 131 private final ObserverList<InfoBarContainerObserver> mObservers =
95 new ObserverList<InfoBarContainerObserver>(); 132 new ObserverList<InfoBarContainerObserver>();
96 133
97 public InfoBarContainer(Context context, int tabId, ViewGroup parentView, Ta b tab) { 134 public InfoBarContainer(Context context, int tabId, ViewGroup parentView, Ta b tab) {
98 super(context, null); 135 super(context, null);
99 tab.addObserver(getTabObserver()); 136 tab.addObserver(mTabObserver);
100 137
101 // TODO(newt): move this workaround into the infobar views if/when they' re scrollable. 138 // TODO(newt): move this workaround into the infobar views if/when they' re scrollable.
102 // Workaround for http://crbug.com/407149. See explanation in onMeasure( ) below. 139 // Workaround for http://crbug.com/407149. See explanation in onMeasure( ) below.
103 setVerticalScrollBarEnabled(false); 140 setVerticalScrollBarEnabled(false);
104 141
105 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( 142 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
106 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, Gravity.BO TTOM); 143 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, Gravity.BO TTOM);
107 int topMarginDp = DeviceFormFactor.isTablet(context) 144 int topMarginDp = DeviceFormFactor.isTablet(context)
108 ? TOP_MARGIN_TABLET_DP : TOP_MARGIN_PHONE_DP; 145 ? TOP_MARGIN_TABLET_DP : TOP_MARGIN_PHONE_DP;
109 lp.topMargin = Math.round(topMarginDp * getResources().getDisplayMetrics ().density); 146 lp.topMargin = Math.round(topMarginDp * getResources().getDisplayMetrics ().density);
110 setLayoutParams(lp); 147 setLayoutParams(lp);
111 148
112 mContext = context;
113 mTabId = tabId; 149 mTabId = tabId;
114 mParentView = parentView; 150 mParentView = parentView;
115 151
116 mLayout = new InfoBarContainerLayout(context); 152 mLayout = new InfoBarContainerLayout(context);
117 addView(mLayout, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, 153 addView(mLayout, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
118 LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL)); 154 LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL));
119 155
120 // Chromium's InfoBarContainer may add an InfoBar immediately during thi s initialization 156 // Chromium's InfoBarContainer may add an InfoBar immediately during thi s initialization
121 // call, so make sure everything in the InfoBarContainer is completely r eady beforehand. 157 // call, so make sure everything in the InfoBarContainer is completely r eady beforehand.
122 mNativeInfoBarContainer = nativeInit(); 158 mNativeInfoBarContainer = nativeInit();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 /** 190 /**
155 * Returns true if any animations are pending or in progress. 191 * Returns true if any animations are pending or in progress.
156 */ 192 */
157 @VisibleForTesting 193 @VisibleForTesting
158 public boolean isAnimating() { 194 public boolean isAnimating() {
159 return mLayout.isAnimating(); 195 return mLayout.isAnimating();
160 } 196 }
161 197
162 private void addToParentView() { 198 private void addToParentView() {
163 super.addToParentView(mParentView); 199 super.addToParentView(mParentView);
200 if (mParentView != null) {
201 mParentView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalL ayoutListener);
202 }
164 } 203 }
165 204
166 /** 205 /**
167 * Called when the parent {@link android.view.ViewGroup} has changed for 206 * Called when the parent {@link android.view.ViewGroup} has changed for
168 * this container. 207 * this container.
169 */ 208 */
170 public void onParentViewChanged(int tabId, ViewGroup parentView) { 209 public void onParentViewChanged(int tabId, ViewGroup parentView) {
171 mTabId = tabId; 210 mTabId = tabId;
172 mParentView = parentView; 211 mParentView = parentView;
173 212
174 removeFromParentView(); 213 removeFromParentView();
175 addToParentView(); 214 addToParentView();
176 } 215 }
177 216
217 @Override
218 public boolean removeFromParentView() {
219 if (mParentView != null) {
220 mParentView.getViewTreeObserver().removeOnGlobalLayoutListener(mGlob alLayoutListener);
221 }
222 return super.removeFromParentView();
223 }
224
178 /** 225 /**
179 * Adds an InfoBar to the view hierarchy. 226 * Adds an InfoBar to the view hierarchy.
180 * @param infoBar InfoBar to add to the View hierarchy. 227 * @param infoBar InfoBar to add to the View hierarchy.
181 */ 228 */
182 @CalledByNative 229 @CalledByNative
183 private void addInfoBar(InfoBar infoBar) { 230 private void addInfoBar(InfoBar infoBar) {
184 assert !mDestroyed; 231 assert !mDestroyed;
185 if (infoBar == null) { 232 if (infoBar == null) {
186 return; 233 return;
187 } 234 }
188 if (mInfoBars.contains(infoBar)) { 235 if (mInfoBars.contains(infoBar)) {
189 assert false : "Trying to add an info bar that has already been adde d."; 236 assert false : "Trying to add an info bar that has already been adde d.";
190 return; 237 return;
191 } 238 }
192 addToParentView(); 239 addToParentView();
193 240
194 // We notify observers immediately (before the animation starts). 241 // We notify observers immediately (before the animation starts).
195 for (InfoBarContainerObserver observer : mObservers) { 242 for (InfoBarContainerObserver observer : mObservers) {
196 observer.onAddInfoBar(this, infoBar, mInfoBars.isEmpty()); 243 observer.onAddInfoBar(this, infoBar, mInfoBars.isEmpty());
197 } 244 }
198 245
199 // We add the infobar immediately to mInfoBars but we wait for the anima tion to end to 246 // We add the infobar immediately to mInfoBars but we wait for the anima tion to end to
200 // notify it's been added, as tests rely on this notification but expect s the infobar view 247 // notify it's been added, as tests rely on this notification but expect s the infobar view
201 // to be available when they get the notification. 248 // to be available when they get the notification.
202 mInfoBars.add(infoBar); 249 mInfoBars.add(infoBar);
203 infoBar.setContext(mContext); 250 infoBar.setContext(getContext());
204 infoBar.setInfoBarContainer(this); 251 infoBar.setInfoBarContainer(this);
205 infoBar.createView(); 252 infoBar.createView();
206 253
207 mLayout.addInfoBar(infoBar); 254 mLayout.addInfoBar(infoBar);
208 } 255 }
209 256
210 /** 257 /**
211 * Notifies that an infobar's View ({@link InfoBar#getView}) has changed. If the infobar is 258 * Notifies that an infobar's View ({@link InfoBar#getView}) has changed. If the infobar is
212 * visible, a view swapping animation will be run. 259 * visible, a view swapping animation will be run.
213 */ 260 */
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 301
255 /** 302 /**
256 * @return all of the InfoBars held in this container. 303 * @return all of the InfoBars held in this container.
257 */ 304 */
258 @VisibleForTesting 305 @VisibleForTesting
259 public ArrayList<InfoBar> getInfoBarsForTesting() { 306 public ArrayList<InfoBar> getInfoBarsForTesting() {
260 return mInfoBars; 307 return mInfoBars;
261 } 308 }
262 309
263 /** 310 /**
311 * Tells this class that a View with higher priority is occupying the same s pace.
312 *
313 * Causes this View to hide itself until the obscuring View goes away.
314 *
315 * @param isObscured Whether this View is obscured by another one.
316 */
317 public void setIsObscuredByOtherView(boolean isObscured) {
318 mIsObscured = isObscured;
319 if (isObscured) {
320 setVisibility(View.GONE);
321 } else {
322 setVisibility(View.VISIBLE);
323 }
324 }
325
326 /**
264 * Sets whether the InfoBarContainer is allowed to auto-hide when the user s crolls the page. 327 * Sets whether the InfoBarContainer is allowed to auto-hide when the user s crolls the page.
265 * Expected to be called when Touch Exploration is enabled. 328 * Expected to be called when Touch Exploration is enabled.
266 * @param isAllowed Whether auto-hiding is allowed. 329 * @param isAllowed Whether auto-hiding is allowed.
267 */ 330 */
268 public static void setIsAllowedToAutoHide(boolean isAllowed) { 331 public static void setIsAllowedToAutoHide(boolean isAllowed) {
269 sIsAllowedToAutoHide = isAllowed; 332 sIsAllowedToAutoHide = isAllowed;
270 } 333 }
271 334
272 @Override 335 @Override
273 protected boolean isAllowedToAutoHide() { 336 protected boolean isAllowedToAutoHide() {
274 return sIsAllowedToAutoHide; 337 return sIsAllowedToAutoHide;
275 } 338 }
276 339
340 @Override
341 protected void onAttachedToWindow() {
342 super.onAttachedToWindow();
343 if (!mIsObscured) {
344 setVisibility(VISIBLE);
345 setAlpha(0f);
346 animate().alpha(1f).setDuration(REATTACH_FADE_IN_MS);
347 }
348 }
349
277 private native long nativeInit(); 350 private native long nativeInit();
278 private native void nativeSetWebContents( 351 private native void nativeSetWebContents(
279 long nativeInfoBarContainerAndroid, WebContents webContents); 352 long nativeInfoBarContainerAndroid, WebContents webContents);
280 private native void nativeDestroy(long nativeInfoBarContainerAndroid); 353 private native void nativeDestroy(long nativeInfoBarContainerAndroid);
281 } 354 }
OLDNEW
« no previous file with comments | « chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManager.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698