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

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: Final comments 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;
10 import android.view.View.OnLayoutChangeListener;
9 import android.view.ViewGroup; 11 import android.view.ViewGroup;
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 OnLayoutChangeListener mParentLayoutListener = new OnLayoutChangeLis tener() {
85 @Override
86 public void onLayoutChange(View v, int left, int top, int right, int bot tom, int oldLeft,
87 int oldTop, int oldRight, int oldBottom) {
88 // This check is posted because this is triggered during the layout pass of the parent.
89 // Setting the visibility on this View (its child) immediately resul ts in Android giving
90 // warnings about triggering another layout (via setVisibility) duri ng the current one.
91 post(new Runnable() {
92 @Override
93 public void run() {
94 // Hide the View when the keyboard is showing.
95 boolean isShowing = (getVisibility() == View.VISIBLE);
96 if (UiUtils.isKeyboardShowing(getContext(), InfoBarContainer .this)) {
97 if (isShowing) {
98 setVisibility(View.GONE);
99 }
100 } else {
101 if (!isShowing && !mIsObscured) {
102 setVisibility(View.VISIBLE);
103 }
104 }
105 }
106 });
107 }
108 };
109
110 /** Resets the state of the InfoBarContainer when the user navigates. */
111 private final TabObserver mTabObserver = new EmptyTabObserver() {
112 @Override
113 public void onDidNavigateMainFrame(Tab tab, String url, String baseUrl,
114 boolean isNavigationToDifferentPage, boolean isFragmentNavigatio n,
115 int statusCode) {
116 setIsObscuredByOtherView(false);
117 }
118 };
119
75 private final InfoBarContainerLayout mLayout; 120 private final InfoBarContainerLayout mLayout;
76 121
77 /** Native InfoBarContainer pointer which will be set by nativeInit(). */ 122 /** Native InfoBarContainer pointer which will be set by nativeInit(). */
78 private final long mNativeInfoBarContainer; 123 private final long mNativeInfoBarContainer;
79 124
80 private final Context mContext;
81
82 /** The list of all InfoBars in this container, regardless of whether they'v e been shown yet. */ 125 /** 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>(); 126 private final ArrayList<InfoBar> mInfoBars = new ArrayList<InfoBar>();
84 127
85 /** True when this container has been emptied and its native counterpart has been destroyed. */ 128 /** True when this container has been emptied and its native counterpart has been destroyed. */
86 private boolean mDestroyed = false; 129 private boolean mDestroyed = false;
87 130
88 /** The id of the tab associated with us. Set to Tab.INVALID_TAB_ID if no ta b is associated. */ 131 /** The id of the tab associated with us. Set to Tab.INVALID_TAB_ID if no ta b is associated. */
89 private int mTabId; 132 private int mTabId;
90 133
91 /** Parent view that contains the InfoBarContainerLayout. */ 134 /** Parent view that contains the InfoBarContainerLayout. */
92 private ViewGroup mParentView; 135 private ViewGroup mParentView;
93 136
137 /** Whether or not another View is occupying the same space as this one. */
138 private boolean mIsObscured;
139
94 private final ObserverList<InfoBarContainerObserver> mObservers = 140 private final ObserverList<InfoBarContainerObserver> mObservers =
95 new ObserverList<InfoBarContainerObserver>(); 141 new ObserverList<InfoBarContainerObserver>();
96 142
97 public InfoBarContainer(Context context, int tabId, ViewGroup parentView, Ta b tab) { 143 public InfoBarContainer(Context context, int tabId, ViewGroup parentView, Ta b tab) {
98 super(context, null); 144 super(context, null);
99 tab.addObserver(getTabObserver()); 145 tab.addObserver(mTabObserver);
100 146
101 // TODO(newt): move this workaround into the infobar views if/when they' re scrollable. 147 // 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. 148 // Workaround for http://crbug.com/407149. See explanation in onMeasure( ) below.
103 setVerticalScrollBarEnabled(false); 149 setVerticalScrollBarEnabled(false);
104 150
105 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( 151 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
106 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, Gravity.BO TTOM); 152 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, Gravity.BO TTOM);
107 int topMarginDp = DeviceFormFactor.isTablet(context) 153 int topMarginDp = DeviceFormFactor.isTablet(context)
108 ? TOP_MARGIN_TABLET_DP : TOP_MARGIN_PHONE_DP; 154 ? TOP_MARGIN_TABLET_DP : TOP_MARGIN_PHONE_DP;
109 lp.topMargin = Math.round(topMarginDp * getResources().getDisplayMetrics ().density); 155 lp.topMargin = Math.round(topMarginDp * getResources().getDisplayMetrics ().density);
110 setLayoutParams(lp); 156 setLayoutParams(lp);
111 157
112 mContext = context;
113 mTabId = tabId; 158 mTabId = tabId;
114 mParentView = parentView; 159 mParentView = parentView;
115 160
116 mLayout = new InfoBarContainerLayout(context); 161 mLayout = new InfoBarContainerLayout(context);
117 addView(mLayout, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, 162 addView(mLayout, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
118 LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL)); 163 LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL));
119 164
120 // Chromium's InfoBarContainer may add an InfoBar immediately during thi s initialization 165 // 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. 166 // call, so make sure everything in the InfoBarContainer is completely r eady beforehand.
122 mNativeInfoBarContainer = nativeInit(); 167 mNativeInfoBarContainer = nativeInit();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 /** 199 /**
155 * Returns true if any animations are pending or in progress. 200 * Returns true if any animations are pending or in progress.
156 */ 201 */
157 @VisibleForTesting 202 @VisibleForTesting
158 public boolean isAnimating() { 203 public boolean isAnimating() {
159 return mLayout.isAnimating(); 204 return mLayout.isAnimating();
160 } 205 }
161 206
162 private void addToParentView() { 207 private void addToParentView() {
163 super.addToParentView(mParentView); 208 super.addToParentView(mParentView);
209 if (mParentView != null) {
210 mParentView.addOnLayoutChangeListener(mParentLayoutListener);
211 }
164 } 212 }
165 213
166 /** 214 /**
167 * Called when the parent {@link android.view.ViewGroup} has changed for 215 * Called when the parent {@link android.view.ViewGroup} has changed for
168 * this container. 216 * this container.
169 */ 217 */
170 public void onParentViewChanged(int tabId, ViewGroup parentView) { 218 public void onParentViewChanged(int tabId, ViewGroup parentView) {
171 mTabId = tabId; 219 mTabId = tabId;
172 mParentView = parentView; 220 mParentView = parentView;
173 221
174 removeFromParentView(); 222 removeFromParentView();
175 addToParentView(); 223 addToParentView();
176 } 224 }
177 225
226 @Override
227 public boolean removeFromParentView() {
228 if (mParentView != null) {
229 mParentView.addOnLayoutChangeListener(mParentLayoutListener);
230 }
231 return super.removeFromParentView();
232 }
233
178 /** 234 /**
179 * Adds an InfoBar to the view hierarchy. 235 * Adds an InfoBar to the view hierarchy.
180 * @param infoBar InfoBar to add to the View hierarchy. 236 * @param infoBar InfoBar to add to the View hierarchy.
181 */ 237 */
182 @CalledByNative 238 @CalledByNative
183 private void addInfoBar(InfoBar infoBar) { 239 private void addInfoBar(InfoBar infoBar) {
184 assert !mDestroyed; 240 assert !mDestroyed;
185 if (infoBar == null) { 241 if (infoBar == null) {
186 return; 242 return;
187 } 243 }
188 if (mInfoBars.contains(infoBar)) { 244 if (mInfoBars.contains(infoBar)) {
189 assert false : "Trying to add an info bar that has already been adde d."; 245 assert false : "Trying to add an info bar that has already been adde d.";
190 return; 246 return;
191 } 247 }
192 addToParentView(); 248 addToParentView();
193 249
194 // We notify observers immediately (before the animation starts). 250 // We notify observers immediately (before the animation starts).
195 for (InfoBarContainerObserver observer : mObservers) { 251 for (InfoBarContainerObserver observer : mObservers) {
196 observer.onAddInfoBar(this, infoBar, mInfoBars.isEmpty()); 252 observer.onAddInfoBar(this, infoBar, mInfoBars.isEmpty());
197 } 253 }
198 254
199 // We add the infobar immediately to mInfoBars but we wait for the anima tion to end to 255 // 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 256 // 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. 257 // to be available when they get the notification.
202 mInfoBars.add(infoBar); 258 mInfoBars.add(infoBar);
203 infoBar.setContext(mContext); 259 infoBar.setContext(getContext());
204 infoBar.setInfoBarContainer(this); 260 infoBar.setInfoBarContainer(this);
205 infoBar.createView(); 261 infoBar.createView();
206 262
207 mLayout.addInfoBar(infoBar); 263 mLayout.addInfoBar(infoBar);
208 } 264 }
209 265
210 /** 266 /**
211 * Notifies that an infobar's View ({@link InfoBar#getView}) has changed. If the infobar is 267 * Notifies that an infobar's View ({@link InfoBar#getView}) has changed. If the infobar is
212 * visible, a view swapping animation will be run. 268 * visible, a view swapping animation will be run.
213 */ 269 */
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 310
255 /** 311 /**
256 * @return all of the InfoBars held in this container. 312 * @return all of the InfoBars held in this container.
257 */ 313 */
258 @VisibleForTesting 314 @VisibleForTesting
259 public ArrayList<InfoBar> getInfoBarsForTesting() { 315 public ArrayList<InfoBar> getInfoBarsForTesting() {
260 return mInfoBars; 316 return mInfoBars;
261 } 317 }
262 318
263 /** 319 /**
320 * Tells this class that a View with higher priority is occupying the same s pace.
321 *
322 * Causes this View to hide itself until the obscuring View goes away.
323 *
324 * @param isObscured Whether this View is obscured by another one.
325 */
326 public void setIsObscuredByOtherView(boolean isObscured) {
327 mIsObscured = isObscured;
328 if (isObscured) {
329 setVisibility(View.GONE);
330 } else {
331 setVisibility(View.VISIBLE);
332 }
333 }
334
335 /**
264 * Sets whether the InfoBarContainer is allowed to auto-hide when the user s crolls the page. 336 * 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. 337 * Expected to be called when Touch Exploration is enabled.
266 * @param isAllowed Whether auto-hiding is allowed. 338 * @param isAllowed Whether auto-hiding is allowed.
267 */ 339 */
268 public static void setIsAllowedToAutoHide(boolean isAllowed) { 340 public static void setIsAllowedToAutoHide(boolean isAllowed) {
269 sIsAllowedToAutoHide = isAllowed; 341 sIsAllowedToAutoHide = isAllowed;
270 } 342 }
271 343
272 @Override 344 @Override
273 protected boolean isAllowedToAutoHide() { 345 protected boolean isAllowedToAutoHide() {
274 return sIsAllowedToAutoHide; 346 return sIsAllowedToAutoHide;
275 } 347 }
276 348
349 @Override
350 protected void onAttachedToWindow() {
351 super.onAttachedToWindow();
352 if (!mIsObscured) {
353 setVisibility(VISIBLE);
354 setAlpha(0f);
355 animate().alpha(1f).setDuration(REATTACH_FADE_IN_MS);
356 }
357 }
358
277 private native long nativeInit(); 359 private native long nativeInit();
278 private native void nativeSetWebContents( 360 private native void nativeSetWebContents(
279 long nativeInfoBarContainerAndroid, WebContents webContents); 361 long nativeInfoBarContainerAndroid, WebContents webContents);
280 private native void nativeDestroy(long nativeInfoBarContainerAndroid); 362 private native void nativeDestroy(long nativeInfoBarContainerAndroid);
281 } 363 }
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