1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser.toolbar.top;
6 
7 import android.graphics.Rect;
8 import android.graphics.drawable.Drawable;
9 import android.view.View;
10 import android.view.View.OnClickListener;
11 import android.view.View.OnLongClickListener;
12 
13 import androidx.annotation.Nullable;
14 import androidx.annotation.VisibleForTesting;
15 
16 import org.chromium.base.Callback;
17 import org.chromium.base.supplier.ObservableSupplier;
18 import org.chromium.base.supplier.OneShotCallback;
19 import org.chromium.base.supplier.OneshotSupplier;
20 import org.chromium.base.supplier.Supplier;
21 import org.chromium.chrome.R;
22 import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
23 import org.chromium.chrome.browser.layouts.LayoutStateProvider;
24 import org.chromium.chrome.browser.omnibox.LocationBar;
25 import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
26 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
27 import org.chromium.chrome.browser.toolbar.ButtonData;
28 import org.chromium.chrome.browser.toolbar.ButtonDataProvider;
29 import org.chromium.chrome.browser.toolbar.TabCountProvider;
30 import org.chromium.chrome.browser.toolbar.ThemeColorProvider;
31 import org.chromium.chrome.browser.toolbar.ToolbarDataProvider;
32 import org.chromium.chrome.browser.toolbar.ToolbarProgressBar;
33 import org.chromium.chrome.browser.toolbar.ToolbarTabController;
34 import org.chromium.chrome.browser.toolbar.menu_button.MenuButton;
35 import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator;
36 import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper;
37 import org.chromium.chrome.browser.user_education.UserEducationHelper;
38 import org.chromium.chrome.features.start_surface.StartSurface;
39 import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration;
40 import org.chromium.chrome.features.start_surface.StartSurfaceState;
41 import org.chromium.components.browser_ui.widget.ClipDrawableProgressBar;
42 import org.chromium.ui.resources.ResourceManager;
43 
44 import java.util.List;
45 
46 /**
47  * A coordinator for the top toolbar component.
48  */
49 public class TopToolbarCoordinator implements Toolbar {
50     /**
51      * Observes toolbar URL expansion progress change.
52      */
53     public interface UrlExpansionObserver {
54         /**
55          * Notified when toolbar URL expansion progress fraction changes.
56          *
57          * @param fraction The toolbar expansion progress. 0 indicates that the URL bar is not
58          *                   expanded. 1 indicates that the URL bar is expanded to the maximum
59          *                   width.
60          */
onUrlExpansionProgressChanged(float fraction)61         void onUrlExpansionProgressChanged(float fraction);
62     }
63 
64     public static final int TAB_SWITCHER_MODE_NORMAL_ANIMATION_DURATION_MS = 200;
65     public static final int TAB_SWITCHER_MODE_GTS_ANIMATION_DURATION_MS = 150;
66 
67     private final ToolbarLayout mToolbarLayout;
68 
69     /**
70      * The coordinator for the tab switcher mode toolbar (phones only). This will be lazily created
71      * after ToolbarLayout is inflated.
72      */
73     private @Nullable TabSwitcherModeTTCoordinatorPhone mTabSwitcherModeCoordinatorPhone;
74     /**
75      * The coordinator for the start surface mode toolbar (phones only) if the StartSurface is
76      * enabled. This will be lazily created after ToolbarLayout is inflated.
77      */
78     private @Nullable StartSurfaceToolbarCoordinator mStartSurfaceToolbarCoordinator;
79 
80     private OptionalBrowsingModeButtonController mOptionalButtonController;
81 
82     private MenuButtonCoordinator mMenuButtonCoordinator;
83     private ObservableSupplier<AppMenuButtonHelper> mAppMenuButtonHelperSupplier;
84     private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier;
85 
86     private Callback<ClipDrawableProgressBar.DrawingInfo> mProgressDrawInfoCallback;
87     private ToolbarControlContainer mControlContainer;
88     private Supplier<ResourceManager> mResourceManagerSupplier;
89 
90     /**
91      * Creates a new {@link TopToolbarCoordinator}.
92      * @param controlContainer The {@link ToolbarControlContainer} for the containing activity.
93      * @param toolbarLayout The {@link ToolbarLayout}.
94      * @param userEducationHelper Helper class for showing in-product help text bubbles.
95      * @param buttonDataProviders List of classes that wish to display an optional button in the
96      *         browsing mode toolbar.
97      * @param layoutStateProviderSupplier Supplier of the {@link LayoutStateProvider}.
98      * @param normalThemeColorProvider The {@link ThemeColorProvider} for normal mode.
99      * @param overviewThemeColorProvider The {@link ThemeColorProvider} for overview mode.
100      * @param tabModelSelectorSupplier Supplier of the {@link TabModelSelector}.
101      * @param homeButtonVisibilitySupplier Supplier of the visibility change of Home button.
102      * @param identityDiscStateSupplier Supplier of the state change of identity disc button.
103      * @param invalidatorCallback Callback that will be invoked  when the toolbar attempts to
104      *        invalidate the drawing surface.  This will give the object that registers as the host
105      *        for the {@link Invalidator} a chance to defer the actual invalidate to sync drawing.
106      * @param identityDiscButtonSupplier Supplier of Identity Disc button.
107      * @param startSurfaceSupplier Supplier of the StartSurface.
108      * @param resourceManagerSupplier A supplier of a resource manager for native textures.
109      */
TopToolbarCoordinator(ToolbarControlContainer controlContainer, ToolbarLayout toolbarLayout, ToolbarDataProvider toolbarDataProvider, ToolbarTabController tabController, UserEducationHelper userEducationHelper, List<ButtonDataProvider> buttonDataProviders, OneshotSupplier<LayoutStateProvider> layoutStateProviderSupplier, ThemeColorProvider normalThemeColorProvider, ThemeColorProvider overviewThemeColorProvider, MenuButtonCoordinator browsingModeMenuButtonCoordinator, MenuButtonCoordinator overviewModeMenuButtonCoordinator, ObservableSupplier<AppMenuButtonHelper> appMenuButtonHelperSupplier, ObservableSupplier<TabModelSelector> tabModelSelectorSupplier, ObservableSupplier<Boolean> homeButtonVisibilitySupplier, ObservableSupplier<Boolean> identityDiscStateSupplier, Callback<Runnable> invalidatorCallback, Supplier<ButtonData> identityDiscButtonSupplier, OneshotSupplier<StartSurface> startSurfaceSupplier, Runnable tabOrModelChangeRunnable, Supplier<ResourceManager> resourceManagerSupplier)110     public TopToolbarCoordinator(ToolbarControlContainer controlContainer,
111             ToolbarLayout toolbarLayout, ToolbarDataProvider toolbarDataProvider,
112             ToolbarTabController tabController, UserEducationHelper userEducationHelper,
113             List<ButtonDataProvider> buttonDataProviders,
114             OneshotSupplier<LayoutStateProvider> layoutStateProviderSupplier,
115             ThemeColorProvider normalThemeColorProvider,
116             ThemeColorProvider overviewThemeColorProvider,
117             MenuButtonCoordinator browsingModeMenuButtonCoordinator,
118             MenuButtonCoordinator overviewModeMenuButtonCoordinator,
119             ObservableSupplier<AppMenuButtonHelper> appMenuButtonHelperSupplier,
120             ObservableSupplier<TabModelSelector> tabModelSelectorSupplier,
121             ObservableSupplier<Boolean> homeButtonVisibilitySupplier,
122             ObservableSupplier<Boolean> identityDiscStateSupplier,
123             Callback<Runnable> invalidatorCallback, Supplier<ButtonData> identityDiscButtonSupplier,
124             OneshotSupplier<StartSurface> startSurfaceSupplier, Runnable tabOrModelChangeRunnable,
125             Supplier<ResourceManager> resourceManagerSupplier) {
126         mControlContainer = controlContainer;
127         mToolbarLayout = toolbarLayout;
128         mMenuButtonCoordinator = browsingModeMenuButtonCoordinator;
129         mOptionalButtonController = new OptionalBrowsingModeButtonController(buttonDataProviders,
130                 userEducationHelper, mToolbarLayout, () -> toolbarDataProvider.getTab());
131         mResourceManagerSupplier = resourceManagerSupplier;
132         mProgressDrawInfoCallback = (info) -> {
133             if (controlContainer == null) return;
134             controlContainer.getProgressBarDrawingInfo(info);
135         };
136 
137         mTabModelSelectorSupplier = tabModelSelectorSupplier;
138 
139         if (mToolbarLayout instanceof ToolbarPhone) {
140             if (StartSurfaceConfiguration.isStartSurfaceEnabled()) {
141                 mStartSurfaceToolbarCoordinator = new StartSurfaceToolbarCoordinator(
142                         controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
143                         userEducationHelper, layoutStateProviderSupplier, identityDiscStateSupplier,
144                         overviewThemeColorProvider, overviewModeMenuButtonCoordinator,
145                         identityDiscButtonSupplier);
146             } else {
147                 mTabSwitcherModeCoordinatorPhone = new TabSwitcherModeTTCoordinatorPhone(
148                         controlContainer.getRootView().findViewById(R.id.tab_switcher_toolbar_stub),
149                         overviewModeMenuButtonCoordinator);
150             }
151         }
152         controlContainer.setToolbar(this);
153         mToolbarLayout.initialize(toolbarDataProvider, tabController, mMenuButtonCoordinator,
154                 tabOrModelChangeRunnable);
155 
156         mToolbarLayout.setThemeColorProvider(normalThemeColorProvider);
157         mAppMenuButtonHelperSupplier = appMenuButtonHelperSupplier;
158         new OneShotCallback<>(mAppMenuButtonHelperSupplier, this::setAppMenuButtonHelper);
159         homeButtonVisibilitySupplier.addObserver((show) -> mToolbarLayout.onHomeButtonUpdate(show));
160         mToolbarLayout.setInvalidatorCallback(invalidatorCallback);
161     }
162 
163     /**
164      * @param appMenuButtonHelper The helper for managing menu button interactions.
165      */
setAppMenuButtonHelper(AppMenuButtonHelper appMenuButtonHelper)166     public void setAppMenuButtonHelper(AppMenuButtonHelper appMenuButtonHelper) {
167         mToolbarLayout.setAppMenuButtonHelper(appMenuButtonHelper);
168     }
169 
170     /**
171      * Initialize the coordinator with the components that have native initialization dependencies.
172      * <p>
173      * Calling this must occur after the native library have completely loaded.
174      *
175      * @param layoutUpdater A {@link Runnable} used to request layout update upon scene change.
176      * @param tabSwitcherClickHandler The click handler for the tab switcher button.
177      * @param tabSwitcherLongClickHandler The long click handler for the tab switcher button.
178      * @param newTabClickHandler The click handler for the new tab button.
179      * @param bookmarkClickHandler The click handler for the bookmarks button.
180      * @param customTabsBackClickHandler The click handler for the custom tabs back button.
181      * @param browserControlsStateProvider Access to the state of the browser controls.
182      */
initializeWithNative(Runnable layoutUpdater, OnClickListener tabSwitcherClickHandler, OnLongClickListener tabSwitcherLongClickHandler, OnClickListener newTabClickHandler, OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler, BrowserControlsStateProvider browserControlsStateProvider)183     public void initializeWithNative(Runnable layoutUpdater,
184             OnClickListener tabSwitcherClickHandler,
185             OnLongClickListener tabSwitcherLongClickHandler, OnClickListener newTabClickHandler,
186             OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler,
187             BrowserControlsStateProvider browserControlsStateProvider) {
188         assert mTabModelSelectorSupplier.get() != null;
189         if (mTabSwitcherModeCoordinatorPhone != null) {
190             mTabSwitcherModeCoordinatorPhone.setOnTabSwitcherClickHandler(tabSwitcherClickHandler);
191             mTabSwitcherModeCoordinatorPhone.setOnNewTabClickHandler(newTabClickHandler);
192             mTabSwitcherModeCoordinatorPhone.setTabModelSelector(mTabModelSelectorSupplier.get());
193         } else if (mStartSurfaceToolbarCoordinator != null) {
194             mStartSurfaceToolbarCoordinator.setOnNewTabClickHandler(newTabClickHandler);
195             mStartSurfaceToolbarCoordinator.setTabModelSelector(mTabModelSelectorSupplier.get());
196             mStartSurfaceToolbarCoordinator.setTabSwitcherListener(tabSwitcherClickHandler);
197             mStartSurfaceToolbarCoordinator.setOnTabSwitcherLongClickHandler(
198                     tabSwitcherLongClickHandler);
199             mStartSurfaceToolbarCoordinator.onNativeLibraryReady();
200         }
201 
202         mToolbarLayout.setTabModelSelector(mTabModelSelectorSupplier.get());
203         getLocationBar().updateVisualsForState();
204         mToolbarLayout.setOnTabSwitcherClickHandler(tabSwitcherClickHandler);
205         mToolbarLayout.setOnTabSwitcherLongClickHandler(tabSwitcherLongClickHandler);
206         mToolbarLayout.setBookmarkClickHandler(bookmarkClickHandler);
207         mToolbarLayout.setCustomTabCloseClickHandler(customTabsBackClickHandler);
208         mToolbarLayout.setLayoutUpdater(layoutUpdater);
209 
210         mToolbarLayout.onNativeLibraryReady();
211     }
212 
213     /**
214      * @param urlExpansionObserver The observer that observes URL expansion progress change.
215      */
addUrlExpansionObserver(UrlExpansionObserver urlExpansionObserver)216     public void addUrlExpansionObserver(UrlExpansionObserver urlExpansionObserver) {
217         mToolbarLayout.addUrlExpansionObserver(urlExpansionObserver);
218     }
219 
220     /**
221      * @param urlExpansionObserver The observer that observes URL expansion progress change.
222      */
removeUrlExpansionObserver(UrlExpansionObserver urlExpansionObserver)223     public void removeUrlExpansionObserver(UrlExpansionObserver urlExpansionObserver) {
224         mToolbarLayout.removeUrlExpansionObserver(urlExpansionObserver);
225     }
226 
227     /**
228      * @see View#addOnAttachStateChangeListener(View.OnAttachStateChangeListener)
229      */
addOnAttachStateChangeListener(View.OnAttachStateChangeListener listener)230     public void addOnAttachStateChangeListener(View.OnAttachStateChangeListener listener) {
231         mToolbarLayout.addOnAttachStateChangeListener(listener);
232     }
233 
234     /**
235      * Cleans up any code as necessary.
236      */
destroy()237     public void destroy() {
238         mToolbarLayout.destroy();
239         if (mTabSwitcherModeCoordinatorPhone != null) {
240             mTabSwitcherModeCoordinatorPhone.destroy();
241         } else if (mStartSurfaceToolbarCoordinator != null) {
242             mStartSurfaceToolbarCoordinator.destroy();
243         }
244 
245         if (mOptionalButtonController != null) {
246             mOptionalButtonController.destroy();
247             mOptionalButtonController = null;
248         }
249 
250         if (mAppMenuButtonHelperSupplier != null) {
251             mAppMenuButtonHelperSupplier = null;
252         }
253         if (mTabModelSelectorSupplier != null) {
254             mTabModelSelectorSupplier = null;
255         }
256         if (mControlContainer != null) {
257             mControlContainer = null;
258         }
259     }
260 
261     @Override
disableMenuButton()262     public void disableMenuButton() {
263         mMenuButtonCoordinator.disableMenuButton();
264         mToolbarLayout.onMenuButtonDisabled();
265     }
266 
267     /**
268      * @return The wrapper for the browsing mode toolbar's menu button.
269      */
getMenuButtonWrapper()270     public MenuButton getMenuButtonWrapper() {
271         return mMenuButtonCoordinator.getMenuButton();
272     }
273 
274     @Nullable
275     @Override
getProgressBar()276     public ToolbarProgressBar getProgressBar() {
277         return mToolbarLayout.getProgressBar();
278     }
279 
280     @Override
getPrimaryColor()281     public int getPrimaryColor() {
282         return mToolbarLayout.getToolbarDataProvider().getPrimaryColor();
283     }
284 
285     @Override
getPositionRelativeToContainer(View containerView, int[] position)286     public void getPositionRelativeToContainer(View containerView, int[] position) {
287         mToolbarLayout.getPositionRelativeToContainer(containerView, position);
288     }
289 
290     /**
291      * Sets the {@link Invalidator} that will be called when the toolbar attempts to invalidate the
292      * drawing surface.  This will give the object that registers as the host for the
293      * {@link Invalidator} a chance to defer the actual invalidate to sync drawing.
294      * @param invalidator An {@link Invalidator} instance.
295      */
setInvalidatorCallback(Callback<Runnable> callback)296     public void setInvalidatorCallback(Callback<Runnable> callback) {
297         mToolbarLayout.setInvalidatorCallback(callback);
298     }
299 
300     /**
301      * Gives inheriting classes the chance to respond to
302      * {@link FindToolbar} state changes.
303      * @param showing Whether or not the {@code FindToolbar} will be showing.
304      */
handleFindLocationBarStateChange(boolean showing)305     public void handleFindLocationBarStateChange(boolean showing) {
306         mToolbarLayout.handleFindLocationBarStateChange(showing);
307     }
308 
309     /**
310      * Sets whether the urlbar should be hidden on first page load.
311      */
setUrlBarHidden(boolean hidden)312     public void setUrlBarHidden(boolean hidden) {
313         mToolbarLayout.setUrlBarHidden(hidden);
314     }
315 
316     /**
317      * @return The name of the publisher of the content if it can be reliably extracted, or null
318      *         otherwise.
319      */
getContentPublisher()320     public String getContentPublisher() {
321         return mToolbarLayout.getContentPublisher();
322     }
323 
324     /**
325      * Tells the Toolbar to update what buttons it is currently displaying.
326      */
updateButtonVisibility()327     public void updateButtonVisibility() {
328         mToolbarLayout.updateButtonVisibility();
329         mOptionalButtonController.updateButtonVisibility();
330     }
331 
332     /**
333      * Gives inheriting classes the chance to update the visibility of the
334      * back button.
335      * @param canGoBack Whether or not the current tab has any history to go back to.
336      */
updateBackButtonVisibility(boolean canGoBack)337     public void updateBackButtonVisibility(boolean canGoBack) {
338         mToolbarLayout.updateBackButtonVisibility(canGoBack);
339     }
340 
341     /**
342      * Gives inheriting classes the chance to update the visibility of the
343      * forward button.
344      * @param canGoForward Whether or not the current tab has any history to go forward to.
345      */
updateForwardButtonVisibility(boolean canGoForward)346     public void updateForwardButtonVisibility(boolean canGoForward) {
347         mToolbarLayout.updateForwardButtonVisibility(canGoForward);
348     }
349 
350     /**
351      * Gives inheriting classes the chance to update the visibility of the
352      * reload button.
353      * @param isReloading Whether or not the current tab is loading.
354      */
updateReloadButtonVisibility(boolean isReloading)355     public void updateReloadButtonVisibility(boolean isReloading) {
356         mToolbarLayout.updateReloadButtonVisibility(isReloading);
357     }
358 
359     /**
360      * Gives inheriting classes the chance to update the visual status of the
361      * bookmark button.
362      * @param isBookmarked Whether or not the current tab is already bookmarked.
363      * @param editingAllowed Whether or not bookmarks can be modified (added, edited, or removed).
364      */
updateBookmarkButton(boolean isBookmarked, boolean editingAllowed)365     public void updateBookmarkButton(boolean isBookmarked, boolean editingAllowed) {
366         mToolbarLayout.updateBookmarkButton(isBookmarked, editingAllowed);
367     }
368 
369     /**
370      * Gives inheriting classes the chance to respond to accessibility state changes.
371      * @param enabled Whether or not accessibility is enabled.
372      */
onAccessibilityStatusChanged(boolean enabled)373     public void onAccessibilityStatusChanged(boolean enabled) {
374         mToolbarLayout.onAccessibilityStatusChanged(enabled);
375         if (mTabSwitcherModeCoordinatorPhone != null) {
376             mTabSwitcherModeCoordinatorPhone.onAccessibilityStatusChanged(enabled);
377         } else if (mStartSurfaceToolbarCoordinator != null) {
378             mStartSurfaceToolbarCoordinator.onAccessibilityStatusChanged(enabled);
379         }
380     }
381 
382     /**
383      * Gives inheriting classes the chance to do the necessary UI operations after Chrome is
384      * restored to a previously saved state.
385      */
onStateRestored()386     public void onStateRestored() {
387         mToolbarLayout.onStateRestored();
388     }
389 
390     /**
391      * Triggered when the current tab or model has changed.
392      * <p>
393      * As there are cases where you can select a model with no tabs (i.e. having incognito
394      * tabs but no normal tabs will still allow you to select the normal model), this should
395      * not guarantee that the model's current tab is non-null.
396      */
onTabOrModelChanged()397     public void onTabOrModelChanged() {
398         mToolbarLayout.onTabOrModelChanged();
399     }
400 
401     /**
402      * For extending classes to override and carry out the changes related with the primary color
403      * for the current tab changing.
404      */
onPrimaryColorChanged(boolean shouldAnimate)405     public void onPrimaryColorChanged(boolean shouldAnimate) {
406         mToolbarLayout.onPrimaryColorChanged(shouldAnimate);
407     }
408 
409     /**
410      * Sets whether a title should be shown within the Toolbar.
411      * @param showTitle Whether a title should be shown.
412      */
setShowTitle(boolean showTitle)413     public void setShowTitle(boolean showTitle) {
414         getLocationBar().setShowTitle(showTitle);
415     }
416 
417     /**
418      * Sets the icon drawable that the close button in the toolbar (if any) should show, or hides
419      * it if {@code drawable} is {@code null}.
420      */
setCloseButtonImageResource(@ullable Drawable drawable)421     public void setCloseButtonImageResource(@Nullable Drawable drawable) {
422         mToolbarLayout.setCloseButtonImageResource(drawable);
423     }
424 
425     /**
426      * Adds a custom action button to the toolbar layout, if it is supported.
427      * @param drawable The icon for the button.
428      * @param description The content description for the button.
429      * @param listener The {@link View.OnClickListener} to use for clicks to the button.
430      */
addCustomActionButton( Drawable drawable, String description, View.OnClickListener listener)431     public void addCustomActionButton(
432             Drawable drawable, String description, View.OnClickListener listener) {
433         mToolbarLayout.addCustomActionButton(drawable, description, listener);
434     }
435 
436     /**
437      * Updates the visual appearance of a custom action button in the toolbar layout,
438      * if it is supported.
439      * @param index The index of the button.
440      * @param drawable The icon for the button.
441      * @param description The content description for the button.
442      */
updateCustomActionButton(int index, Drawable drawable, String description)443     public void updateCustomActionButton(int index, Drawable drawable, String description) {
444         mToolbarLayout.updateCustomActionButton(index, drawable, description);
445     }
446 
447     @Override
getTabStripHeight()448     public int getTabStripHeight() {
449         return mToolbarLayout.getTabStripHeight();
450     }
451 
452     /**
453      * Triggered when the content view for the specified tab has changed.
454      */
onTabContentViewChanged()455     public void onTabContentViewChanged() {
456         mToolbarLayout.onTabContentViewChanged();
457     }
458 
459     @Override
isReadyForTextureCapture()460     public boolean isReadyForTextureCapture() {
461         return mToolbarLayout.isReadyForTextureCapture();
462     }
463 
464     @Override
setForceTextureCapture(boolean forceTextureCapture)465     public boolean setForceTextureCapture(boolean forceTextureCapture) {
466         return mToolbarLayout.setForceTextureCapture(forceTextureCapture);
467     }
468 
469     /**
470      * @param attached Whether or not the web content is attached to the view heirarchy.
471      */
setContentAttached(boolean attached)472     public void setContentAttached(boolean attached) {
473         mToolbarLayout.setContentAttached(attached);
474     }
475 
476     /**
477      * Gives inheriting classes the chance to show or hide the TabSwitcher mode of this toolbar.
478      * @param inTabSwitcherMode Whether or not TabSwitcher mode should be shown or hidden.
479      * @param showToolbar    Whether or not to show the normal toolbar while animating.
480      * @param delayAnimation Whether or not to delay the animation until after the transition has
481      *                       finished (which can be detected by a call to
482      *                       {@link #onTabSwitcherTransitionFinished()}).
483      */
setTabSwitcherMode( boolean inTabSwitcherMode, boolean showToolbar, boolean delayAnimation)484     public void setTabSwitcherMode(
485             boolean inTabSwitcherMode, boolean showToolbar, boolean delayAnimation) {
486         mToolbarLayout.setTabSwitcherMode(
487                 inTabSwitcherMode, showToolbar, delayAnimation, mMenuButtonCoordinator);
488         if (mTabSwitcherModeCoordinatorPhone != null) {
489             mTabSwitcherModeCoordinatorPhone.setTabSwitcherMode(inTabSwitcherMode);
490         } else if (mStartSurfaceToolbarCoordinator != null) {
491             mStartSurfaceToolbarCoordinator.setStartSurfaceMode(inTabSwitcherMode);
492         }
493     }
494 
495     /**
496      * Gives inheriting classes the chance to update their state when the TabSwitcher transition has
497      * finished.
498      */
onTabSwitcherTransitionFinished()499     public void onTabSwitcherTransitionFinished() {
500         mToolbarLayout.onTabSwitcherTransitionFinished();
501     }
502 
503     /**
504      * Gives inheriting classes the chance to observe tab count changes.
505      * @param tabCountProvider The {@link TabCountProvider} subclasses can observe.
506      */
setTabCountProvider(TabCountProvider tabCountProvider)507     public void setTabCountProvider(TabCountProvider tabCountProvider) {
508         mToolbarLayout.setTabCountProvider(tabCountProvider);
509         if (mTabSwitcherModeCoordinatorPhone != null) {
510             mTabSwitcherModeCoordinatorPhone.setTabCountProvider(tabCountProvider);
511         }
512         if (mStartSurfaceToolbarCoordinator != null) {
513             mStartSurfaceToolbarCoordinator.setTabCountProvider(tabCountProvider);
514         }
515     }
516 
517     /**
518      * @param provider The provider used to determine incognito state.
519      */
setIncognitoStateProvider(IncognitoStateProvider provider)520     public void setIncognitoStateProvider(IncognitoStateProvider provider) {
521         if (mTabSwitcherModeCoordinatorPhone != null) {
522             mTabSwitcherModeCoordinatorPhone.setIncognitoStateProvider(provider);
523         } else if (mStartSurfaceToolbarCoordinator != null) {
524             mStartSurfaceToolbarCoordinator.setIncognitoStateProvider(provider);
525         }
526     }
527 
528     /**
529      * Gives inheriting classes the chance to update themselves based on default search engine
530      * changes.
531      */
onDefaultSearchEngineChanged()532     public void onDefaultSearchEngineChanged() {
533         mToolbarLayout.onDefaultSearchEngineChanged();
534     }
535 
536     @Override
getLocationBarContentRect(Rect outRect)537     public void getLocationBarContentRect(Rect outRect) {
538         mToolbarLayout.getLocationBarContentRect(outRect);
539     }
540 
541     @Override
setTextureCaptureMode(boolean textureMode)542     public void setTextureCaptureMode(boolean textureMode) {
543         mToolbarLayout.setTextureCaptureMode(textureMode);
544     }
545 
546     @Override
shouldIgnoreSwipeGesture()547     public boolean shouldIgnoreSwipeGesture() {
548         return mToolbarLayout.shouldIgnoreSwipeGesture();
549     }
550 
551     /**
552      * Triggered when the URL input field has gained or lost focus.
553      * @param hasFocus Whether the URL field has gained focus.
554      */
onUrlFocusChange(boolean hasFocus)555     public void onUrlFocusChange(boolean hasFocus) {
556         mToolbarLayout.onUrlFocusChange(hasFocus);
557     }
558 
559     /**
560      * Returns the elapsed realtime in ms of the time at which first draw for the toolbar occurred.
561      */
getFirstDrawTime()562     public long getFirstDrawTime() {
563         return mToolbarLayout.getFirstDrawTime();
564     }
565 
566     /**
567      * Notified when a navigation to a different page has occurred.
568      */
onNavigatedToDifferentPage()569     public void onNavigatedToDifferentPage() {
570         mToolbarLayout.onNavigatedToDifferentPage();
571     }
572 
573     /**
574      * @param enabled Whether the progress bar is enabled.
575      */
setProgressBarEnabled(boolean enabled)576     public void setProgressBarEnabled(boolean enabled) {
577         getProgressBar().setVisibility(enabled ? View.VISIBLE : View.GONE);
578     }
579 
580     /**
581      * Finish any toolbar animations.
582      */
finishAnimations()583     public void finishAnimations() {
584         mToolbarLayout.finishAnimations();
585     }
586 
587     /**
588      * @return {@link LocationBar} object this {@link ToolbarLayout} contains.
589      */
getLocationBar()590     public LocationBar getLocationBar() {
591         return mToolbarLayout.getLocationBar();
592     }
593 
594     /**
595      * Update the start surface toolbar state.
596      * @param newState New Start Surface State.
597      * @param requestToShow Whether or not request showing the start surface toolbar.
598      */
updateStartSurfaceToolbarState( @tartSurfaceState int newState, boolean requestToShow)599     public void updateStartSurfaceToolbarState(
600             @StartSurfaceState int newState, boolean requestToShow) {
601         if (mStartSurfaceToolbarCoordinator == null
602                 || mToolbarLayout.getToolbarDataProvider() == null) {
603             return;
604         }
605         mStartSurfaceToolbarCoordinator.onStartSurfaceStateChanged(newState, requestToShow);
606         updateToolbarContainerVisibility();
607     }
608 
609     /**
610      * Triggered when the offset of start surface header view is changed.
611      * @param verticalOffset The start surface header view's offset.
612      */
onStartSurfaceHeaderOffsetChanged(int verticalOffset)613     public void onStartSurfaceHeaderOffsetChanged(int verticalOffset) {
614         if (mStartSurfaceToolbarCoordinator != null) {
615             mStartSurfaceToolbarCoordinator.onStartSurfaceHeaderOffsetChanged(verticalOffset);
616             updateToolbarContainerVisibility();
617         }
618     }
619 
updateToolbarContainerVisibility()620     private void updateToolbarContainerVisibility() {
621         if (mStartSurfaceToolbarCoordinator != null) {
622             boolean shouldHideToolbarContainer =
623                     mStartSurfaceToolbarCoordinator.shouldHideToolbarContainer(getHeight());
624             mControlContainer.setToolbarContainerVisibility(
625                     shouldHideToolbarContainer ? View.INVISIBLE : View.VISIBLE);
626         }
627     }
628 
629     @Override
getHeight()630     public int getHeight() {
631         return mToolbarLayout.getHeight();
632     }
633 
634     /**
635      * Sets the highlight on the new tab button shown during overview mode.
636      * @param highlight If the new tab button should be highlighted.
637      */
setNewTabButtonHighlight(boolean highlight)638     public void setNewTabButtonHighlight(boolean highlight) {
639         if (mTabSwitcherModeCoordinatorPhone != null) {
640             mTabSwitcherModeCoordinatorPhone.setNewTabButtonHighlight(highlight);
641         } else if (mStartSurfaceToolbarCoordinator != null) {
642             mStartSurfaceToolbarCoordinator.setNewTabButtonHighlight(highlight);
643         }
644     }
645 
646     /**
647      * @return The {@link ToolbarLayout} that constitutes the toolbar.
648      */
649     @VisibleForTesting
getToolbarLayoutForTesting()650     public ToolbarLayout getToolbarLayoutForTesting() {
651         return mToolbarLayout;
652     }
653 
654     @VisibleForTesting
getStartSurfaceToolbarForTesting()655     public StartSurfaceToolbarCoordinator getStartSurfaceToolbarForTesting() {
656         return mStartSurfaceToolbarCoordinator;
657     }
658 }
659