/** * Handle all necessary tasks that can be delayed until initialization completes. * * @param activityCreationTimeMs The time of creation for the activity this toolbar belongs to. * @param activityName Simple class name for the activity this toolbar belongs to. */ public void onDeferredStartup(final long activityCreationTimeMs, final String activityName) { // Record startup performance statistics long elapsedTime = SystemClock.elapsedRealtime() - activityCreationTimeMs; if (elapsedTime < RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS) { ThreadUtils.postOnUiThreadDelayed( new Runnable() { @Override public void run() { onDeferredStartup(activityCreationTimeMs, activityName); } }, RECORD_UMA_PERFORMANCE_METRICS_DELAY_MS - elapsedTime); } RecordHistogram.recordTimesHistogram( "MobileStartup.ToolbarFirstDrawTime." + activityName, mToolbar.getFirstDrawTime() - activityCreationTimeMs, TimeUnit.MILLISECONDS); long firstFocusTime = mToolbar.getLocationBar().getFirstUrlBarFocusTime(); if (firstFocusTime != 0) { RecordHistogram.recordCustomTimesHistogram( "MobileStartup.ToolbarFirstFocusTime." + activityName, firstFocusTime - activityCreationTimeMs, MIN_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS, MAX_FOCUS_TIME_FOR_UMA_HISTOGRAM_MS, TimeUnit.MILLISECONDS, 50); } }
/** * Focuses or unfocuses the URL bar. * * @param focused Whether URL bar should be focused. */ public void setUrlBarFocus(boolean focused) { if (!isInitialized()) return; mToolbar.getLocationBar().setUrlBarFocus(focused); }
/** * Initialize the manager with the components that had native initialization dependencies. * * <p>Calling this must occur after the native library have completely loaded. * * @param tabModelSelector The selector that handles tab management. * @param fullscreenManager The manager in charge of interacting with the fullscreen feature. * @param findToolbarManager The manager for find in page. * @param overviewModeBehavior The overview mode manager. * @param layoutDriver A {@link LayoutManager} instance used to watch for scene changes. */ public void initializeWithNative( TabModelSelector tabModelSelector, ChromeFullscreenManager fullscreenManager, final FindToolbarManager findToolbarManager, final OverviewModeBehavior overviewModeBehavior, final LayoutManager layoutDriver, OnClickListener tabSwitcherClickHandler, OnClickListener newTabClickHandler, OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler) { assert !mInitializedWithNative; mTabModelSelector = tabModelSelector; mToolbar.getLocationBar().updateVisualsForState(); mToolbar.getLocationBar().setUrlToPageUrl(); mToolbar.setOnTabSwitcherClickHandler(tabSwitcherClickHandler); mToolbar.setOnNewTabClickHandler(newTabClickHandler); mToolbar.setBookmarkClickHandler(bookmarkClickHandler); mToolbar.setCustomTabCloseClickHandler(customTabsBackClickHandler); mToolbarModel.initializeWithNative(); mToolbar.addOnAttachStateChangeListener( new OnAttachStateChangeListener() { @Override public void onViewDetachedFromWindow(View v) { Context context = mToolbar.getContext(); HomepageManager.getInstance(context).removeListener(mHomepageStateListener); mTabModelSelector.removeObserver(mTabModelSelectorObserver); for (TabModel model : mTabModelSelector.getModels()) { model.removeObserver(mTabModelObserver); } if (mBookmarksBridge != null) { mBookmarksBridge.destroy(); mBookmarksBridge = null; } if (mTemplateUrlObserver != null) { TemplateUrlService.getInstance().removeObserver(mTemplateUrlObserver); mTemplateUrlObserver = null; } findToolbarManager.removeObserver(mFindToolbarObserver); if (overviewModeBehavior != null) { overviewModeBehavior.removeOverviewModeObserver(mOverviewModeObserver); } if (layoutDriver != null) { layoutDriver.removeSceneChangeObserver(mSceneChangeObserver); } } @Override public void onViewAttachedToWindow(View v) { // As we have only just registered for notifications, any that were sent prior to // this may have been missed. // Calling refreshSelectedTab in case we missed the initial selection notification. refreshSelectedTab(); } }); mFindToolbarManager = findToolbarManager; assert fullscreenManager != null; mFullscreenManager = fullscreenManager; mNativeLibraryReady = false; findToolbarManager.addObserver(mFindToolbarObserver); if (overviewModeBehavior != null) { overviewModeBehavior.addOverviewModeObserver(mOverviewModeObserver); } if (layoutDriver != null) layoutDriver.addSceneChangeObserver(mSceneChangeObserver); onNativeLibraryReady(); mInitializedWithNative = true; }
/** @return The view that the pop up menu should be anchored to on the UI. */ public View getMenuAnchor() { return mToolbar.getLocationBar().getMenuAnchor(); }
/** * Creates a ToolbarManager object. * * @param controlContainer The container of the toolbar. * @param menuHandler The handler for interacting with the menu. */ public ToolbarManager( final ChromeActivity activity, ToolbarControlContainer controlContainer, final AppMenuHandler menuHandler, final ChromeAppMenuPropertiesDelegate appMenuPropertiesDelegate, Invalidator invalidator) { mActionBarDelegate = new ContextualMenuBar.ActionBarDelegate() { @Override public void setControlTopMargin(int margin) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mControlContainer.getLayoutParams(); lp.topMargin = margin; mControlContainer.setLayoutParams(lp); } @Override public int getControlTopMargin() { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mControlContainer.getLayoutParams(); return lp.topMargin; } @Override public ActionBar getSupportActionBar() { return activity.getSupportActionBar(); } @Override public void setActionBarBackgroundVisibility(boolean visible) { int visibility = visible ? View.VISIBLE : View.GONE; activity.findViewById(R.id.action_bar_black_background).setVisibility(visibility); // TODO(tedchoc): Add support for changing the color based on the brand color. } }; mToolbarModel = new ToolbarModelImpl(); mControlContainer = controlContainer; assert mControlContainer != null; mToolbar = (ToolbarLayout) controlContainer.findViewById(R.id.toolbar); mToolbar.setPaintInvalidator(invalidator); mContextualMenuBar = new ContextualMenuBar(activity, mActionBarDelegate); mContextualMenuBar.setCustomSelectionActionModeCallback( new CustomSelectionActionModeCallback()); mContextualMenuBar.setTabStripHeight(mToolbar.getTabStripHeight()); MenuDelegatePhone menuDelegate = new MenuDelegatePhone() { @Override public void updateReloadButtonState(boolean isLoading) { if (appMenuPropertiesDelegate != null) { appMenuPropertiesDelegate.loadingStateChanged(isLoading); menuHandler.menuItemContentChanged(R.id.icon_row_menu_id); } } }; setMenuDelegatePhone(menuDelegate); mLocationBar = mToolbar.getLocationBar(); mLocationBar.setToolbarDataProvider(mToolbarModel); mLocationBar.setUrlFocusChangeListener(this); mLocationBar.setDefaultTextEditActionModeCallback( mContextualMenuBar.getCustomSelectionActionModeCallback()); mLocationBar.initializeControls( new WindowDelegate(activity.getWindow()), mContextualMenuBar.getActionBarDelegate(), activity.getWindowAndroid()); mLocationBar.setIgnoreURLBarModification(false); setMenuHandler(menuHandler); mToolbar.initialize(mToolbarModel, this, mAppMenuButtonHelper); mHomepageStateListener = new HomepageStateListener() { @Override public void onHomepageStateUpdated() { mToolbar.onHomeButtonUpdate(HomepageManager.isHomepageEnabled(mToolbar.getContext())); } }; HomepageManager.getInstance(mToolbar.getContext()).addListener(mHomepageStateListener); mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() { @Override public void onTabModelSelected(TabModel newModel, TabModel oldModel) { refreshSelectedTab(); updateTabCount(); mControlContainer.invalidateBitmap(); } @Override public void onTabStateInitialized() { mTabRestoreCompleted = true; handleTabRestoreCompleted(); } }; mTabModelObserver = new EmptyTabModelObserver() { @Override public void didAddTab(Tab tab, TabLaunchType type) { updateTabCount(); } @Override public void didSelectTab(Tab tab, TabSelectionType type, int lastId) { mPreselectedTabId = Tab.INVALID_TAB_ID; refreshSelectedTab(); } @Override public void tabClosureUndone(Tab tab) { updateTabCount(); refreshSelectedTab(); } @Override public void didCloseTab(Tab tab) { updateTabCount(); refreshSelectedTab(); } @Override public void tabPendingClosure(Tab tab) { updateTabCount(); refreshSelectedTab(); } @Override public void allTabsPendingClosure(List<Integer> tabIds) { updateTabCount(); refreshSelectedTab(); } }; mTabObserver = new EmptyTabObserver() { @Override public void onSSLStateUpdated(Tab tab) { super.onSSLStateUpdated(tab); assert tab == mToolbarModel.getTab(); mLocationBar.updateSecurityIcon(tab.getSecurityLevel()); } @Override public void onWebContentsInstantSupportDisabled() { mLocationBar.setUrlToPageUrl(); } @Override public void onDidNavigateMainFrame( Tab tab, String url, String baseUrl, boolean isNavigationToDifferentPage, boolean isFragmentNavigation, int statusCode) { if (isNavigationToDifferentPage) { mToolbar.onNavigatedToDifferentPage(); } } @Override public void onPageLoadStarted(Tab tab, String url) { updateButtonStatus(); updateTabLoadingState(true, true); } @Override public void onPageLoadFinished(Tab tab) { ToolbarManager.this.onPageLoadFinished(); } @Override public void onPageLoadFailed(Tab tab, int errorCode) { ToolbarManager.this.onPageLoadFailed(); } @Override public void onTitleUpdated(Tab tab) { mLocationBar.setTitleToPageTitle(); } @Override public void onUrlUpdated(Tab tab) { // Update the SSL security state as a result of this notification as it will // sometimes be the only update we receive. updateTabLoadingState(false, true); // A URL update is a decent enough indicator that the toolbar widget is in // a stable state to capture its bitmap for use in fullscreen. mControlContainer.setReadyForBitmapCapture(true); } @Override public void onCrash(Tab tab, boolean sadTabShown) { onTabCrash(); } @Override public void onLoadProgressChanged(Tab tab, int progress) { updateLoadProgress(progress); } @Override public void onContentChanged(Tab tab) { mToolbar.onTabContentViewChanged(); } @Override public void onWebContentsSwapped(Tab tab, boolean didStartLoad, boolean didFinishLoad) { if (!didStartLoad) return; ChromeTab chromeTab = ChromeTab.fromTab(tab); if (!chromeTab.getBackgroundContentViewHelper().isPageSwappingInProgress() && didFinishLoad) { mLoadProgressSimulator.start(); } } @Override public void onDidStartNavigationToPendingEntry(Tab tab, String url) { // Update URL as soon as it becomes available when it's a new tab. // But we want to update only when it's a new tab. So we check whether the current // navigation entry is initial, meaning whether it has the same target URL as the // initial URL of the tab. WebContents webContents = tab.getWebContents(); if (webContents == null) return; NavigationController navigationController = webContents.getNavigationController(); if (navigationController == null) return; if (navigationController.isInitialNavigation()) { mLocationBar.setUrlToPageUrl(); } } @Override public void onLoadUrl(Tab tab, LoadUrlParams params, int loadType) { NewTabPage ntp = mToolbarModel.getNewTabPageForCurrentTab(); if (ntp == null) return; if (!NewTabPage.isNTPUrl(params.getUrl()) && loadType != TabLoadStatus.PAGE_LOAD_FAILED) { ntp.setUrlFocusAnimationsDisabled(true); mToolbar.onTabOrModelChanged(); } } @Override public void onDidFailLoad( Tab tab, boolean isProvisionalLoad, boolean isMainFrame, int errorCode, String description, String failingUrl) { NewTabPage ntp = mToolbarModel.getNewTabPageForCurrentTab(); if (ntp == null) return; if (isProvisionalLoad && isMainFrame) { ntp.setUrlFocusAnimationsDisabled(false); mToolbar.onTabOrModelChanged(); } } @Override public void onContextualActionBarVisibilityChanged(Tab tab, boolean visible) { if (visible) RecordUserAction.record("MobileActionBarShown"); ActionBar actionBar = mActionBarDelegate.getSupportActionBar(); if (!visible && actionBar != null) actionBar.hide(); if (DeviceFormFactor.isTablet(activity)) { if (visible) { mContextualMenuBar.showControls(); } else { mContextualMenuBar.hideControls(); } } } }; mBookmarksObserver = new BookmarksBridge.BookmarkModelObserver() { @Override public void bookmarkModelChanged() { updateBookmarkButtonStatus(); } }; mFindToolbarObserver = new FindToolbarObserver() { @Override public void onFindToolbarShown() { mToolbar.handleFindToolbarStateChange(true); if (mFullscreenManager != null) { mFullscreenFindInPageToken = mFullscreenManager.showControlsPersistentAndClearOldToken( mFullscreenFindInPageToken); } } @Override public void onFindToolbarHidden() { mToolbar.handleFindToolbarStateChange(false); if (mFullscreenManager != null) { mFullscreenManager.hideControlsPersistent(mFullscreenFindInPageToken); mFullscreenFindInPageToken = FullscreenManager.INVALID_TOKEN; } } }; mOverviewModeObserver = new EmptyOverviewModeObserver() { @Override public void onOverviewModeStartedShowing(boolean showToolbar) { mToolbar.setTabSwitcherMode(true, showToolbar, false); updateButtonStatus(); } @Override public void onOverviewModeStartedHiding(boolean showToolbar, boolean delayAnimation) { mToolbar.setTabSwitcherMode(false, showToolbar, delayAnimation); updateButtonStatus(); } @Override public void onOverviewModeFinishedHiding() { mToolbar.onTabSwitcherTransitionFinished(); } }; mSceneChangeObserver = new SceneChangeObserver() { @Override public void onTabSelectionHinted(int tabId) { mPreselectedTabId = tabId; refreshSelectedTab(); } @Override public void onSceneChange(Layout layout) { mToolbar.setContentAttached(layout.shouldDisplayContentOverlay()); } }; mLoadProgressSimulator = new LoadProgressSimulator(this); }