OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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; |
| 6 |
| 7 import android.graphics.Bitmap; |
| 8 import android.os.SystemClock; |
| 9 import android.support.v7.app.ActionBar; |
| 10 import android.view.View; |
| 11 import android.view.View.OnClickListener; |
| 12 import android.widget.FrameLayout; |
| 13 |
| 14 import com.google.android.apps.chrome.R; |
| 15 |
| 16 import org.chromium.base.ThreadUtils; |
| 17 import org.chromium.base.metrics.RecordHistogram; |
| 18 import org.chromium.base.metrics.RecordUserAction; |
| 19 import org.chromium.chrome.browser.CompositorChromeActivity; |
| 20 import org.chromium.chrome.browser.ContextualMenuBar; |
| 21 import org.chromium.chrome.browser.CustomSelectionActionModeCallback; |
| 22 import org.chromium.chrome.browser.Tab; |
| 23 import org.chromium.chrome.browser.TabObserver; |
| 24 import org.chromium.chrome.browser.WindowDelegate; |
| 25 import org.chromium.chrome.browser.appmenu.AppMenuHandler; |
| 26 import org.chromium.chrome.browser.appmenu.ChromeAppMenuPropertiesDelegate; |
| 27 import org.chromium.chrome.browser.compositor.Invalidator; |
| 28 import org.chromium.chrome.browser.compositor.layouts.LayoutManager; |
| 29 import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; |
| 30 import org.chromium.chrome.browser.tabmodel.TabModelSelector; |
| 31 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; |
| 32 import org.chromium.chrome.browser.toolbar.ToolbarManager.MenuDelegatePhone; |
| 33 import org.chromium.chrome.browser.widget.ControlContainer; |
| 34 import org.chromium.chrome.browser.widget.findinpage.FindToolbarManager; |
| 35 import org.chromium.ui.base.DeviceFormFactor; |
| 36 |
| 37 import java.util.concurrent.TimeUnit; |
| 38 |
| 39 /** |
| 40 * Helper class to handle inflating the right view hierarchy and initialize it. |
| 41 */ |
| 42 public class ToolbarHelper { |
| 43 /** |
| 44 * The number of ms to wait before reporting to UMA omnibox interaction metr
ics. |
| 45 */ |
| 46 private static final int RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS = 30000; |
| 47 |
| 48 private static final int MIN_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS = 1000; |
| 49 private static final int MAX_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS = 30000; |
| 50 |
| 51 protected final CompositorChromeActivity mActivity; |
| 52 private final ToolbarControlContainer mControlContainer; |
| 53 private TabObserver mTabObserver; |
| 54 |
| 55 private final Toolbar mToolbar; |
| 56 private final ToolbarManager mToolbarManager; |
| 57 |
| 58 private final ContextualMenuBar mContextualMenuBar; |
| 59 private final ContextualMenuBar.ActionBarDelegate mActionBarDelegate; |
| 60 |
| 61 private boolean mInitialized; |
| 62 |
| 63 /** |
| 64 * Constructor for {@link ToolbarHelper}. |
| 65 * @param activity The current activity. |
| 66 * @param controlContainer {@link ControlContainer} that the Toolbar View Hi
erarchy will be |
| 67 * attached to. |
| 68 * @param appMenuHandler Controller for showing/hiding app menu. |
| 69 * @param appMenuPropertiesDelegate Controller for app menu item visibility. |
| 70 * @param invalidator Notifier to toolbar to force view invalidations. |
| 71 */ |
| 72 public ToolbarHelper(CompositorChromeActivity activity, |
| 73 ToolbarControlContainer controlContainer, |
| 74 final AppMenuHandler appMenuHandler, |
| 75 final ChromeAppMenuPropertiesDelegate appMenuPropertiesDelegate, |
| 76 Invalidator invalidator) { |
| 77 mActivity = activity; |
| 78 mControlContainer = controlContainer; |
| 79 assert mControlContainer != null; |
| 80 |
| 81 mToolbarManager = new ToolbarManager(mControlContainer, appMenuHandler); |
| 82 mToolbar = mToolbarManager.getToolbar(); |
| 83 |
| 84 mActionBarDelegate = new ContextualMenuBar.ActionBarDelegate() { |
| 85 @Override |
| 86 public void setControlTopMargin(int margin) { |
| 87 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 88 mControlContainer.getLayoutParams(); |
| 89 lp.topMargin = margin; |
| 90 mControlContainer.setLayoutParams(lp); |
| 91 } |
| 92 |
| 93 @Override |
| 94 public int getControlTopMargin() { |
| 95 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) |
| 96 mControlContainer.getLayoutParams(); |
| 97 return lp.topMargin; |
| 98 } |
| 99 |
| 100 @Override |
| 101 public ActionBar getSupportActionBar() { |
| 102 return mActivity.getSupportActionBar(); |
| 103 } |
| 104 |
| 105 @Override |
| 106 public void setActionBarBackgroundVisibility(boolean visible) { |
| 107 int visibility = visible ? View.VISIBLE : View.GONE; |
| 108 mActivity.findViewById(R.id.action_bar_black_background).setVisi
bility(visibility); |
| 109 // TODO(tedchoc): Add support for changing the color based on th
e brand color. |
| 110 } |
| 111 }; |
| 112 mContextualMenuBar = new ContextualMenuBar(activity, mActionBarDelegate)
; |
| 113 mContextualMenuBar.setCustomSelectionActionModeCallback( |
| 114 new CustomSelectionActionModeCallback()); |
| 115 |
| 116 mToolbar.setPaintInvalidator(invalidator); |
| 117 mToolbarManager.setDefaultActionModeCallbackForTextEdit( |
| 118 mContextualMenuBar.getCustomSelectionActionModeCallback()); |
| 119 mToolbar.getLocationBar().initializeControls( |
| 120 new WindowDelegate(mActivity.getWindow()), |
| 121 mContextualMenuBar.getActionBarDelegate(), |
| 122 mActivity.getWindowAndroid()); |
| 123 mToolbar.getLocationBar().setIgnoreURLBarModification(false); |
| 124 |
| 125 MenuDelegatePhone menuDelegate = new MenuDelegatePhone() { |
| 126 @Override |
| 127 public void updateReloadButtonState(boolean isLoading) { |
| 128 if (appMenuPropertiesDelegate != null) { |
| 129 appMenuPropertiesDelegate.loadingStateChanged(isLoading); |
| 130 appMenuHandler.menuItemContentChanged(R.id.icon_row_menu_id)
; |
| 131 } |
| 132 } |
| 133 }; |
| 134 mToolbarManager.setMenuDelegatePhone(menuDelegate); |
| 135 } |
| 136 |
| 137 /** |
| 138 * Initializes the controls for the current toolbar mode. |
| 139 * @param findToolbarManager Manager for find in page. |
| 140 * @param overviewModeBehavior Interface to query and listen to the overview
state. |
| 141 * @param layoutManager A {@link LayoutManager} instance to use to watch for
scene changes. |
| 142 * @param tabSwitcherClickHandler Click listener for the tab switcher button
. |
| 143 * @param newTabClickHandler Click listener for the new tab button. |
| 144 * @param bookmarkClickHandler Click listener for the bookmark button. |
| 145 */ |
| 146 public void initializeControls(FindToolbarManager findToolbarManager, |
| 147 OverviewModeBehavior overviewModeBehavior, |
| 148 LayoutManager layoutManager, |
| 149 OnClickListener tabSwitcherClickHandler, |
| 150 OnClickListener newTabClickHandler, |
| 151 OnClickListener bookmarkClickHandler, |
| 152 OnClickListener hostedBackClickHandler) { |
| 153 |
| 154 |
| 155 TabModelSelector selector = mActivity.getTabModelSelector(); |
| 156 mTabObserver = new TabModelSelectorTabObserver(selector) { |
| 157 @Override |
| 158 public void onContextualActionBarVisibilityChanged(Tab tab, boolean
visible) { |
| 159 if (visible) RecordUserAction.record("MobileActionBarShown"); |
| 160 ActionBar actionBar = mActionBarDelegate.getSupportActionBar(); |
| 161 if (!visible && actionBar != null) actionBar.hide(); |
| 162 if (DeviceFormFactor.isTablet(mActivity)) { |
| 163 if (visible) { |
| 164 mContextualMenuBar.showControls(); |
| 165 } else { |
| 166 mContextualMenuBar.hideControls(); |
| 167 } |
| 168 } |
| 169 } |
| 170 }; |
| 171 mToolbarManager.initializeWithNative( |
| 172 selector, mActivity.getFullscreenManager(), |
| 173 findToolbarManager, overviewModeBehavior, layoutManager); |
| 174 mToolbar.getLocationBar().updateVisualsForState(); |
| 175 mToolbar.getLocationBar().setUrlToPageUrl(); |
| 176 mToolbar.setOnTabSwitcherClickHandler(tabSwitcherClickHandler); |
| 177 mToolbar.setOnNewTabClickHandler(newTabClickHandler); |
| 178 mToolbar.setBookmarkClickHandler(bookmarkClickHandler); |
| 179 mToolbar.setHostedBackClickHandler(hostedBackClickHandler); |
| 180 mInitialized = true; |
| 181 } |
| 182 |
| 183 /** |
| 184 * @return The menu bar for handling contextual text selection. |
| 185 */ |
| 186 public ContextualMenuBar getContextualMenuBar() { |
| 187 return mContextualMenuBar; |
| 188 } |
| 189 |
| 190 /** |
| 191 * @return Whether the UI has been initialized. |
| 192 */ |
| 193 public boolean isInitialized() { |
| 194 return mInitialized; |
| 195 } |
| 196 |
| 197 /** |
| 198 * @return The view that the pop up menu should be anchored to on the UI. |
| 199 */ |
| 200 public View getMenuAnchor() { |
| 201 return mToolbar.getLocationBar().getMenuAnchor(); |
| 202 } |
| 203 |
| 204 /** |
| 205 * Should be called when the accessibility state changes. |
| 206 * @param enabled Whether or not accessibility and touch exploration are ena
bled. |
| 207 */ |
| 208 public void onAccessibilityStatusChanged(boolean enabled) { |
| 209 mToolbarManager.onAccessibilityStatusChanged(enabled); |
| 210 } |
| 211 |
| 212 /** |
| 213 * Update the brand color for the titlebar. |
| 214 * @param color The current theme color used. |
| 215 */ |
| 216 public void setThemeColor(int color) { |
| 217 mToolbarManager.updatePrimaryColor(color); |
| 218 } |
| 219 |
| 220 /** |
| 221 * Adds a custom action button to the {@link Toolbar} if it is supported. |
| 222 * @param buttonSource The {@link Bitmap} resource to use as the source for
the button. |
| 223 * @param listener The {@link OnClickListener} to use for clicks to the butt
on. |
| 224 */ |
| 225 public void addCustomActionButton(Bitmap buttonSource, OnClickListener liste
ner) { |
| 226 mToolbar.addCustomActionButton(buttonSource, listener); |
| 227 } |
| 228 |
| 229 /** |
| 230 * Call to tear down all of the toolbar dependencies. |
| 231 */ |
| 232 public void destroy() { |
| 233 Tab activityTab = mActivity.getActivityTab(); |
| 234 if (activityTab != null) activityTab.removeObserver(mTabObserver); |
| 235 } |
| 236 |
| 237 /** |
| 238 * Called when the orientation of the activity has changed. |
| 239 */ |
| 240 public void onOrientationChange() { |
| 241 mContextualMenuBar.showControlsOnOrientationChange(); |
| 242 } |
| 243 |
| 244 /** |
| 245 * Navigates the current Tab back. |
| 246 * @return Whether or not the current Tab did go back. |
| 247 */ |
| 248 public boolean back() { |
| 249 return mToolbarManager.back(); |
| 250 } |
| 251 |
| 252 /** |
| 253 * Focuses or unfocuses the URL bar. |
| 254 * @param focused Whether URL bar should be focused. |
| 255 */ |
| 256 public void setUrlBarFocus(boolean focused) { |
| 257 if (!isInitialized()) return; |
| 258 mToolbar.getLocationBar().setUrlBarFocus(focused); |
| 259 } |
| 260 |
| 261 /** |
| 262 * @return Whether {@link Toolbar} has drawn at least once. |
| 263 */ |
| 264 public boolean hasDoneFirstDraw() { |
| 265 return mToolbar.getFirstDrawTime() != 0; |
| 266 } |
| 267 |
| 268 /** |
| 269 * Handle all necessary tasks that can be delayed until initialization compl
etes. |
| 270 */ |
| 271 public void onDeferredStartup() { |
| 272 // Record startup performance statistics |
| 273 long elapsedTime = SystemClock.elapsedRealtime() - mActivity.getOnCreate
TimestampMs(); |
| 274 if (elapsedTime < RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS) { |
| 275 ThreadUtils.postOnUiThreadDelayed(new Runnable() { |
| 276 @Override |
| 277 public void run() { |
| 278 onDeferredStartup(); |
| 279 } |
| 280 }, RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS - elapsedTime); |
| 281 } |
| 282 |
| 283 long creationTime = mActivity.getOnCreateTimestampMs(); |
| 284 String className = mActivity.getClass().getSimpleName(); |
| 285 RecordHistogram.recordTimesHistogram("MobileStartup.ToolbarFirstDrawTime
." + className, |
| 286 mToolbar.getFirstDrawTime() - creationTime, TimeUnit.MILLISECOND
S); |
| 287 |
| 288 long firstFocusTime = mToolbar.getLocationBar().getFirstUrlBarFocusTime(
); |
| 289 if (firstFocusTime != 0) { |
| 290 RecordHistogram.recordCustomTimesHistogram( |
| 291 "MobileStartup.ToolbarFirstFocusTime." + className, |
| 292 firstFocusTime - creationTime, MIN_FOCUS_TIME_FOR_UMA_HISTOG
RAM_MS, |
| 293 MAX_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS, TimeUnit.MILLISECONDS,
50); |
| 294 } |
| 295 } |
| 296 |
| 297 /** |
| 298 * Finish any toolbar animations. |
| 299 */ |
| 300 public void finishAnimations() { |
| 301 if (isInitialized()) mToolbar.finishAnimations(); |
| 302 } |
| 303 } |
OLD | NEW |