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

Unified Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
new file mode 100644
index 0000000000000000000000000000000000000000..6874e55a869bd686a4eb2c55f33db1858c5a6fa6
--- /dev/null
+++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChrome.java
@@ -0,0 +1,747 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.compositor.layouts;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.text.TextUtils;
+import android.view.ViewGroup;
+
+import com.google.android.apps.chrome.R;
+
+import org.chromium.base.ObserverList;
+import org.chromium.base.VisibleForTesting;
+import org.chromium.chrome.browser.Tab;
+import org.chromium.chrome.browser.compositor.TitleCache;
+import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
+import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
+import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
+import org.chromium.chrome.browser.compositor.layouts.content.TitleBitmapFactory;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.BlackHoleEventFilter;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeEventFilter.ScrollDirection;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EdgeSwipeHandler;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilter;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.GestureEventFilter;
+import org.chromium.chrome.browser.compositor.overlays.SceneOverlay;
+import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelperManager;
+import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate;
+import org.chromium.chrome.browser.device.DeviceClassManager;
+import org.chromium.chrome.browser.fullscreen.FullscreenManager;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
+import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
+import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
+import org.chromium.chrome.browser.tabmodel.TabModelObserver;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector.CloseAllTabsDelegate;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
+import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver;
+import org.chromium.chrome.browser.tabmodel.TabModelUtils;
+import org.chromium.chrome.browser.util.FeatureUtilities;
+import org.chromium.chrome.browser.widget.OverviewListLayout;
+import org.chromium.ui.base.LocalizationUtils;
+import org.chromium.ui.resources.dynamics.DynamicResourceLoader;
+
+import java.util.List;
+
+/**
+ * A {@link Layout} controller for the more complicated Chrome browser. This is currently a
+ * superset of {@link LayoutManagerDocument}.
+ */
+public class LayoutManagerChrome
+ extends LayoutManagerDocument implements OverviewModeBehavior, CloseAllTabsDelegate {
+ // Layouts
+ /** An {@link Layout} that should be used as the accessibility tab switcher. */
+ protected OverviewListLayout mOverviewListLayout;
+ /** A {@link Layout} that should be used when the user is swiping sideways on the toolbar. */
+ protected ToolbarSwipeLayout mToolbarSwipeLayout;
+ /** A {@link Layout} that should be used when the user is in the tab switcher. */
+ protected Layout mOverviewLayout;
+
+ // Event Filters
+ /** A {@link EventFilter} that consumes all touch events. */
+ protected EventFilter mBlackHoleEventFilter;
+ private final GestureEventFilter mGestureEventFilter;
+
+ // Event Filter Handlers
+ private final EdgeSwipeHandler mToolbarSwipeHandler;
+
+ // Internal State
+ /** A {@link TitleCache} instance that stores all title/favicon bitmaps as CC resources. */
+ protected TitleCache mTitleCache;
+ /** Responsible for building non-incognito titles. */
+ protected TitleBitmapFactory mStandardTitleBitmapFactory;
+ /** Responsible for building all incognito titles. */
+ protected TitleBitmapFactory mIncognitoTitleBitmapFactory;
+ /** Whether or not animations are enabled. This can disable certain layouts or effects. */
+ protected boolean mEnableAnimations = true;
+ private boolean mCreatingNtp;
+ private final ObserverList<OverviewModeObserver> mOverviewModeObservers;
+ private TabModelSelectorObserver mTabModelSelectorObserver;
+ private TabModelObserver mTabModelObserver;
+ private TabModelSelectorTabObserver mTabSelectorTabObserver;
+
+ /**
+ * Protected class to handle {@link TabModelObserver} related tasks. Extending classes will
+ * need to override any related calls to add new functionality */
+ protected class LayoutManagerTabModelObserver extends EmptyTabModelObserver {
+ @Override
+ public void didSelectTab(Tab tab, TabSelectionType type, int lastId) {
+ if (tab.getId() != lastId) tabSelected(tab.getId(), lastId, tab.isIncognito());
+ }
+
+ @Override
+ public void willAddTab(Tab tab, TabLaunchType type) {
+ // Open the new tab
+ if (type == TabLaunchType.FROM_INSTANT || type == TabLaunchType.FROM_RESTORE) return;
+
+ tabCreating(getTabModelSelector().getCurrentTabId(), tab.getUrl(), tab.isIncognito());
+ }
+
+ @Override
+ public void didAddTab(Tab tab, TabLaunchType launchType) {
+ int tabId = tab.getId();
+ if (launchType != TabLaunchType.FROM_INSTANT
+ && launchType != TabLaunchType.FROM_RESTORE) {
+ boolean incognito = tab.isIncognito();
+ boolean willBeSelected = launchType != TabLaunchType.FROM_LONGPRESS_BACKGROUND
+ || (!getTabModelSelector().isIncognitoSelected() && incognito);
+ float lastTapX = LocalizationUtils.isLayoutRtl() ? mLastContentWidthDp : 0.f;
+ float lastTapY = 0.f;
+ if (launchType != TabLaunchType.FROM_MENU_OR_OVERVIEW) {
+ float heightDelta =
+ mLastFullscreenViewportDp.height() - mLastVisibleViewportDp.height();
+ lastTapX = mPxToDp * mLastTapX;
+ lastTapY = mPxToDp * mLastTapY - heightDelta;
+ }
+
+ tabCreated(tabId, getTabModelSelector().getCurrentTabId(), launchType, incognito,
+ willBeSelected, lastTapX, lastTapY);
+ }
+ }
+
+ @Override
+ public void didCloseTab(Tab tab) {
+ tabClosed(tab);
+ }
+
+ @Override
+ public void tabPendingClosure(Tab tab) {
+ tabClosed(tab);
+ }
+
+ @Override
+ public void tabClosureUndone(Tab tab) {
+ tabClosureCancelled(tab.getId(), tab.isIncognito());
+ }
+
+ @Override
+ public void tabClosureCommitted(Tab tab) {
+ LayoutManagerChrome.this.tabClosureCommitted(tab.getId(), tab.isIncognito());
+ }
+
+ @Override
+ public void didMoveTab(Tab tab, int newIndex, int curIndex) {
+ tabMoved(tab.getId(), curIndex, newIndex, tab.isIncognito());
+ }
+ }
+
+ /**
+ * Delegate of a factory to create an overview layout.
+ */
+ public interface OverviewLayoutFactoryDelegate {
+ /**
+ * @param context The current Android's context.
+ * @param updateHost The {@link LayoutUpdateHost} view for this layout.
+ * @param renderHost The {@link LayoutRenderHost} view for this layout.
+ * @param eventFilter The {@link EventFilter} that is needed for this view.
+ */
+ Layout createOverviewLayout(Context context, LayoutUpdateHost updateHost,
+ LayoutRenderHost renderHost, EventFilter eventFilter);
+ }
+
+ /**
+ * Creates the {@link LayoutManagerChrome} instance.
+ * @param host A {@link LayoutManagerHost} instance.
+ * @param overviewLayoutFactoryDelegate A {@link OverviewLayoutFactoryDelegate} instance.
+ */
+ public LayoutManagerChrome(
+ LayoutManagerHost host, OverviewLayoutFactoryDelegate overviewLayoutFactoryDelegate) {
+ super(host);
+ Context context = host.getContext();
+ LayoutRenderHost renderHost = host.getLayoutRenderHost();
+
+ // Set up state
+ mStandardTitleBitmapFactory =
+ new TitleBitmapFactory(context, false, R.drawable.default_favicon);
+ mIncognitoTitleBitmapFactory =
+ new TitleBitmapFactory(context, true, R.drawable.default_favicon_white);
+ mOverviewModeObservers = new ObserverList<OverviewModeObserver>();
+
+ // Build Event Filter Handlers
+ mToolbarSwipeHandler = new ToolbarSwipeHandler(this);
+
+ // Build Event Filters
+ mBlackHoleEventFilter = new BlackHoleEventFilter(context, this);
+ mGestureEventFilter = new GestureEventFilter(context, this, mGestureHandler);
+
+ // Build Layouts
+ mOverviewListLayout =
+ new OverviewListLayout(context, this, renderHost, mBlackHoleEventFilter);
+ mToolbarSwipeLayout =
+ new ToolbarSwipeLayout(context, this, renderHost, mBlackHoleEventFilter);
+ if (overviewLayoutFactoryDelegate != null) {
+ mOverviewLayout = overviewLayoutFactoryDelegate.createOverviewLayout(
+ context, this, renderHost, mGestureEventFilter);
+ }
+ }
+
+ /**
+ * @return The {@link TabModelObserver} instance this class should be using.
+ */
+ protected LayoutManagerTabModelObserver createTabModelObserver() {
+ return new LayoutManagerTabModelObserver();
+ }
+
+ /**
+ * @return A list of virtual views representing compositor rendered views.
+ */
+ @Override
+ public void getVirtualViews(List<VirtualView> views) {
+ if (getActiveLayout() != null) {
+ getActiveLayout().getVirtualViews(views);
+ }
+ }
+
+ /**
+ * @return The {@link EdgeSwipeHandler} responsible for processing swipe events for the toolbar.
+ */
+ @Override
+ public EdgeSwipeHandler getTopSwipeHandler() {
+ return mToolbarSwipeHandler;
+ }
+
+ @Override
+ public void init(TabModelSelector selector, TabCreatorManager creator,
+ TabContentManager content, ViewGroup androidContentContainer,
+ ContextualSearchManagementDelegate contextualSearchDelegate,
+ DynamicResourceLoader dynamicResourceLoader) {
+ // TODO: TitleCache should be a part of the ResourceManager.
+ mTitleCache = mHost.getTitleCache();
+
+ // Initialize Layouts
+ mToolbarSwipeLayout.setTabModelSelector(selector, content);
+ mOverviewListLayout.setTabModelSelector(selector, content);
+ if (mOverviewLayout != null) mOverviewLayout.setTabModelSelector(selector, content);
+
+ super.init(selector, creator, content, androidContentContainer, contextualSearchDelegate,
+ dynamicResourceLoader);
+
+ mTabModelSelectorObserver = new EmptyTabModelSelectorObserver() {
+ @Override
+ public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
+ tabModelSwitched(newModel.isIncognito());
+ }
+ };
+ selector.addObserver(mTabModelSelectorObserver);
+ selector.setCloseAllTabsDelegate(this);
+
+ mTabModelObserver = createTabModelObserver();
+ for (TabModel model : selector.getModels()) model.addObserver(mTabModelObserver);
+
+ mTabSelectorTabObserver = new TabModelSelectorTabObserver(selector) {
+ @Override
+ public void onLoadStarted(Tab tab) {
+ tabLoadStarted(tab.getId(), tab.isIncognito());
+ }
+
+ @Override
+ public void onLoadStopped(Tab tab) {
+ tabLoadFinished(tab.getId(), tab.isIncognito());
+ }
+
+ @Override
+ public void onPageLoadStarted(Tab tab) {
+ tabPageLoadStarted(tab.getId(), tab.isIncognito());
+ }
+
+ @Override
+ public void onPageLoadFinished(Tab tab) {
+ tabPageLoadFinished(tab.getId(), tab.isIncognito());
+ }
+
+ @Override
+ public void onPageLoadFailed(Tab tab, int errorCode) {
+ tabPageLoadFinished(tab.getId(), tab.isIncognito());
+ }
+
+ @Override
+ public void onCrash(Tab tab, boolean sadTabShown) {
+ tabPageLoadFinished(tab.getId(), tab.isIncognito());
+ }
+ };
+ }
+
+ @Override
+ public void destroy() {
+ super.destroy();
+ if (mTabModelSelectorObserver != null) {
+ getTabModelSelector().removeObserver(mTabModelSelectorObserver);
+ }
+ if (mTabModelObserver != null) {
+ for (TabModel model : getTabModelSelector().getModels()) {
+ model.removeObserver(mTabModelObserver);
+ }
+ }
+ if (mTabSelectorTabObserver != null) mTabSelectorTabObserver.destroy();
+ mOverviewModeObservers.clear();
+
+ if (mOverviewLayout != null) {
+ mOverviewLayout.destroy();
+ mOverviewLayout = null;
+ }
+ mOverviewListLayout.destroy();
+ mToolbarSwipeLayout.destroy();
+ }
+
+ @Override
+ protected void addGlobalSceneOverlay(SceneOverlay helper) {
+ super.addGlobalSceneOverlay(helper);
+ mOverviewListLayout.addSceneOverlay(helper);
+ mToolbarSwipeLayout.addSceneOverlay(helper);
+ if (mOverviewLayout != null) mOverviewLayout.addSceneOverlay(helper);
+ }
+
+ /**
+ * Meant to be overridden by child classes for when they need to extend the toolbar side swipe
+ * functionality.
+ * @param provider A {@link LayoutProvider} instance.
+ * @return A {@link ToolbarSwipeHandler} instance that will be used by internal layouts.
+ */
+ protected ToolbarSwipeHandler createToolbarSwipeHandler(LayoutProvider provider) {
+ return new ToolbarSwipeHandler(provider);
+ }
+
+ /**
+ * Simulates a click on the view at the specified pixel offset
+ * from the top left of the view.
+ * This is used by UI tests.
+ * @param x Coordinate of the click in dp.
+ * @param y Coordinate of the click in dp.
+ */
+ @VisibleForTesting
+ public void simulateClick(float x, float y) {
+ if (getActiveLayout() != null) getActiveLayout().click(time(), x, y);
+ }
+
+ /**
+ * Simulates a drag and issues Up-event to commit the drag.
+ * @param x Coordinate to start the Drag from in dp.
+ * @param y Coordinate to start the Drag from in dp.
+ * @param dX Amount of drag in X direction in dp.
+ * @param dY Amount of drag in Y direction in dp.
+ */
+ @VisibleForTesting
+ public void simulateDrag(float x, float y, float dX, float dY) {
+ if (getActiveLayout() != null) {
+ getActiveLayout().onDown(0, x, y);
+ getActiveLayout().drag(0, x, y, dX, dY);
+ getActiveLayout().onUpOrCancel(time());
+ }
+ }
+
+ private boolean isOverviewLayout(Layout layout) {
+ return layout != null && (layout == mOverviewLayout || layout == mOverviewListLayout);
+ }
+
+ @Override
+ protected void startShowing(Layout layout, boolean animate) {
+ mCreatingNtp = false;
+ super.startShowing(layout, animate);
+
+ Layout layoutBeingShown = getActiveLayout();
+
+ // Check if a layout is showing that should hide the contextual search bar.
+ if (mContextualSearchDelegate != null
+ && (isOverviewLayout(layoutBeingShown)
+ || layoutBeingShown == mToolbarSwipeLayout)) {
+ mContextualSearchDelegate.dismissContextualSearchBar();
+ }
+
+ // Check if we should notify OverviewModeObservers.
+ if (isOverviewLayout(layoutBeingShown)) {
+ boolean showToolbar =
+ !mEnableAnimations || getTabModelSelector().getCurrentModel().getCount() <= 0;
+ for (OverviewModeObserver observer : mOverviewModeObservers) {
+ observer.onOverviewModeStartedShowing(showToolbar);
+ }
+ }
+ }
+
+ @Override
+ public void startHiding(int nextTabId, boolean hintAtTabSelection) {
+ super.startHiding(nextTabId, hintAtTabSelection);
+
+ Layout layoutBeingHidden = getActiveLayout();
+ if (isOverviewLayout(layoutBeingHidden)) {
+ boolean showToolbar = true;
+ if (mEnableAnimations && layoutBeingHidden == mOverviewLayout) {
+ final LayoutTab tab = layoutBeingHidden.getLayoutTab(nextTabId);
+ showToolbar = tab != null ? !tab.showToolbar() : true;
+ }
+
+ boolean creatingNtp = layoutBeingHidden == mOverviewLayout && mCreatingNtp;
+
+ for (OverviewModeObserver observer : mOverviewModeObservers) {
+ observer.onOverviewModeStartedHiding(showToolbar, creatingNtp);
+ }
+ }
+ }
+
+ @Override
+ public void doneShowing() {
+ super.doneShowing();
+
+ if (isOverviewLayout(getActiveLayout())) {
+ for (OverviewModeObserver observer : mOverviewModeObservers) {
+ observer.onOverviewModeFinishedShowing();
+ }
+ }
+ }
+
+ @Override
+ public void doneHiding() {
+ Layout layoutBeingHidden = getActiveLayout();
+
+ if (getNextLayout() == getDefaultLayout()) {
+ Tab tab = getTabModelSelector() != null ? getTabModelSelector().getCurrentTab() : null;
+ emptyCachesExcept(tab != null ? tab.getId() : Tab.INVALID_TAB_ID);
+ }
+
+ super.doneHiding();
+
+ if (isOverviewLayout(layoutBeingHidden)) {
+ for (OverviewModeObserver observer : mOverviewModeObservers) {
+ observer.onOverviewModeFinishedHiding();
+ }
+ }
+ }
+
+ @VisibleForTesting
+ public void tabSelected(int tabId, int prevId, boolean incognito) {
+ // Update the model here so we properly set the right selected TabModel.
+ if (getActiveLayout() != null) {
+ getActiveLayout().onTabSelected(time(), tabId, prevId, incognito);
+ }
+ }
+
+ /**
+ * Should be called when a tab created event is triggered.
+ * @param id The id of the tab that was created.
+ * @param sourceId The id of the creating tab if any.
+ * @param launchType How the tab was launched.
+ * @param incognito Whether or not the created tab is incognito.
+ * @param willBeSelected Whether or not the created tab will be selected.
+ * @param originX The x coordinate of the action that created this tab in dp.
+ * @param originY The y coordinate of the action that created this tab in dp.
+ */
+ protected void tabCreated(int id, int sourceId, TabLaunchType launchType, boolean incognito,
+ boolean willBeSelected, float originX, float originY) {
+ Tab newTab = TabModelUtils.getTabById(getTabModelSelector().getModel(incognito), id);
+ mCreatingNtp = newTab != null && newTab.isNativePage();
+
+ int newIndex = TabModelUtils.getTabIndexById(getTabModelSelector().getModel(incognito), id);
+ getActiveLayout().onTabCreated(
+ time(), id, newIndex, sourceId, incognito, !willBeSelected, originX, originY);
+ }
+
+ /**
+ * Should be called when a tab creating event is triggered (called before the tab is done being
+ * created).
+ * @param sourceId The id of the creating tab if any.
+ * @param url The url of the created tab.
+ * @param isIncognito Whether or not created tab will be incognito.
+ */
+ protected void tabCreating(int sourceId, String url, boolean isIncognito) {
+ if (getActiveLayout() != null) getActiveLayout().onTabCreating(sourceId);
+ }
+
+ /**
+ * Should be called when a tab closed event is triggered.
+ * @param id The id of the closed tab.
+ * @param nextId The id of the next tab that will be visible, if any.
+ * @param incognito Whether or not the closed tab is incognito.
+ */
+ protected void tabClosed(int id, int nextId, boolean incognito) {
+ if (getActiveLayout() != null) getActiveLayout().onTabClosed(time(), id, nextId, incognito);
+ }
+
+ private void tabClosed(Tab tab) {
+ Tab currentTab =
+ getTabModelSelector() != null ? getTabModelSelector().getCurrentTab() : null;
+ int nextTabId = currentTab != null ? currentTab.getId() : Tab.INVALID_TAB_ID;
+ tabClosed(tab.getId(), nextTabId, tab.isIncognito());
+ }
+
+ /**
+ * Called when a tab closure has been committed and all tab cleanup should happen.
+ * @param id The id of the closed tab.
+ * @param incognito Whether or not the closed tab is incognito.
+ */
+ protected void tabClosureCommitted(int id, boolean incognito) {
+ if (getActiveLayout() != null) {
+ getActiveLayout().onTabClosureCommitted(time(), id, incognito);
+ }
+ }
+
+ @Override
+ public boolean closeAllTabsRequest(boolean incognito) {
+ if (!isOverviewLayout(getActiveLayout()) || !getActiveLayout().handlesCloseAll()) {
+ return false;
+ }
+ getActiveLayout().onTabsAllClosing(time(), incognito);
+ return true;
+ }
+
+ /**
+ * Called when the selected tab model has switched.
+ * @param incognito Whether or not the new current tab model is incognito.
+ */
+ protected void tabModelSwitched(boolean incognito) {
+ if (getActiveLayout() != null) getActiveLayout().onTabModelSwitched(incognito);
+ }
+
+ private void tabMoved(int id, int oldIndex, int newIndex, boolean incognito) {
+ if (getActiveLayout() != null) {
+ getActiveLayout().onTabMoved(time(), id, oldIndex, newIndex, incognito);
+ }
+ }
+
+ private void tabPageLoadStarted(int id, boolean incognito) {
+ if (getActiveLayout() != null) getActiveLayout().onTabPageLoadStarted(id, incognito);
+ }
+
+ private void tabPageLoadFinished(int id, boolean incognito) {
+ if (getActiveLayout() != null) getActiveLayout().onTabPageLoadFinished(id, incognito);
+ }
+
+ private void tabLoadStarted(int id, boolean incognito) {
+ if (getActiveLayout() != null) getActiveLayout().onTabLoadStarted(id, incognito);
+ }
+
+ private void tabLoadFinished(int id, boolean incognito) {
+ if (getActiveLayout() != null) getActiveLayout().onTabLoadFinished(id, incognito);
+ }
+
+ private void tabClosureCancelled(int id, boolean incognito) {
+ if (getActiveLayout() != null) {
+ getActiveLayout().onTabClosureCancelled(time(), id, incognito);
+ }
+ }
+
+ @Override
+ public void initLayoutTabFromHost(int tabId) {
+ super.initLayoutTabFromHost(tabId);
+
+ if (getTabModelSelector() == null || getActiveLayout() == null) return;
+
+ TabModelSelector selector = getTabModelSelector();
+ Tab tab = selector.getTabById(tabId);
+ if (tab == null) return;
+
+ LayoutTab layoutTab = getExistingLayoutTab(tabId);
+ if (layoutTab == null) return;
+
+ if (mTitleCache != null && layoutTab.isTitleNeeded()) {
+ mTitleCache.put(tabId, getTitleBitmap(tab), getFaviconBitmap(tab), tab.isIncognito(),
+ tab.isTitleDirectionRtl());
+ }
+ }
+
+ /**
+ * Builds a title bitmap for a {@link Tab}. This function does not do anything in the
+ * general case because only the phone need to bake special resource.
+ *
+ * @param tab The tab to build the title bitmap for.
+ * @return The Title bitmap
+ */
+ protected Bitmap getTitleBitmap(Tab tab) {
+ TitleBitmapFactory titleBitmapFactory =
+ tab.isIncognito() ? mIncognitoTitleBitmapFactory : mStandardTitleBitmapFactory;
+
+ return titleBitmapFactory.getTitleBitmap(mHost.getContext(), getTitleForTab(tab));
+ }
+
+ /**
+ * Comes up with a valid title to return for a tab.
+ * @param tab The {@link Tab} to build a title for.
+ * @return The title to use.
+ */
+ protected String getTitleForTab(Tab tab) {
+ String title = tab.getTitle();
+ if (TextUtils.isEmpty(title)) title = tab.getUrl();
+ return title;
+ }
+
+ /**
+ * Builds a favicon bitmap for a {@link Tab}. This function does not do anything in the
+ * general case because only the phone need to bake special texture.
+ *
+ * @param tab The tab to build the title bitmap for.
+ * @return The Favicon bitmap
+ */
+ protected Bitmap getFaviconBitmap(Tab tab) {
+ TitleBitmapFactory titleBitmapFactory =
+ tab.isIncognito() ? mIncognitoTitleBitmapFactory : mStandardTitleBitmapFactory;
+ return titleBitmapFactory.getFaviconBitmap(mHost.getContext(), tab.getFavicon());
+ }
+
+ /**
+ * @return The {@link OverviewListLayout} managed by this class.
+ */
+ @VisibleForTesting
+ public Layout getOverviewListLayout() {
+ return mOverviewListLayout;
+ }
+
+ /**
+ * @return The overview layout {@link Layout} managed by this class.
+ */
+ @VisibleForTesting
+ public Layout getOverviewLayout() {
+ return mOverviewLayout;
+ }
+
+ /**
+ * @return The {@link StripLayoutHelperManager} managed by this class.
+ */
+ @VisibleForTesting
+ public StripLayoutHelperManager getStripLayoutHelperManager() {
+ return null;
+ }
+
+ /**
+ * @return Whether or not to use the accessibility layout.
+ */
+ protected boolean useAccessibilityLayout() {
+ return DeviceClassManager.isAccessibilityModeEnabled(mHost.getContext())
+ || DeviceClassManager.enableAccessibilityLayout();
+ }
+
+ /**
+ * Show the overview {@link Layout}. This is generally a {@link Layout} that visibly represents
+ * all of the {@link Tab}s opened by the user.
+ * @param animate Whether or not to animate the transition to overview mode.
+ */
+ public void showOverview(boolean animate) {
+ boolean useAccessibility = useAccessibilityLayout();
+
+ boolean accessibilityIsVisible =
+ useAccessibility && getActiveLayout() == mOverviewListLayout;
+ boolean normalIsVisible = getActiveLayout() == mOverviewLayout && mOverviewLayout != null;
+
+ // We only want to use the AccessibilityOverviewLayout if the following are all valid:
+ // 1. We're already showing the AccessibilityOverviewLayout OR we're using accessibility.
+ // 2. We're not already showing the normal OverviewLayout (or we are on a tablet, in which
+ // case the normal layout is always visible).
+ if ((accessibilityIsVisible || useAccessibility) && !normalIsVisible) {
+ startShowing(mOverviewListLayout, animate);
+ } else if (mOverviewLayout != null) {
+ startShowing(mOverviewLayout, animate);
+ }
+ }
+
+ /**
+ * Hides the current {@link Layout}, returning to the default {@link Layout}.
+ * @param animate Whether or not to animate the transition to the default {@link Layout}.
+ */
+ public void hideOverview(boolean animate) {
+ Layout activeLayout = getActiveLayout();
+ if (activeLayout != null && !activeLayout.isHiding()) {
+ if (animate) {
+ activeLayout.onTabSelecting(time(), Tab.INVALID_TAB_ID);
+ } else {
+ startHiding(Tab.INVALID_TAB_ID, false);
+ doneHiding();
+ }
+ }
+ }
+
+ /**
+ * @param enabled Whether or not to allow model-reactive animations (tab creation, closing,
+ * etc.).
+ */
+ public void setEnableAnimations(boolean enabled) {
+ mEnableAnimations = enabled;
+ }
+
+ @Override
+ public boolean overviewVisible() {
+ Layout activeLayout = getActiveLayout();
+ return isOverviewLayout(activeLayout) && !activeLayout.isHiding();
+ }
+
+ @Override
+ public void addOverviewModeObserver(OverviewModeObserver listener) {
+ mOverviewModeObservers.addObserver(listener);
+ }
+
+ @Override
+ public void removeOverviewModeObserver(OverviewModeObserver listener) {
+ mOverviewModeObservers.removeObserver(listener);
+ }
+
+ /**
+ * A {@link EdgeSwipeHandler} meant to respond to edge events for the toolbar.
+ */
+ protected class ToolbarSwipeHandler extends EdgeSwipeHandlerLayoutDelegate {
+ /**
+ * Creates an instance of the {@link ToolbarSwipeHandler}.
+ * @param provider A {@link LayoutProvider} instance.
+ */
+ public ToolbarSwipeHandler(LayoutProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public void swipeStarted(ScrollDirection direction, float x, float y) {
+ if (direction == ScrollDirection.DOWN) {
+ startShowing(mOverviewLayout, true);
+ super.swipeStarted(direction, x, y);
+ } else if (direction == ScrollDirection.LEFT || direction == ScrollDirection.RIGHT) {
+ startShowing(mToolbarSwipeLayout, true);
+ super.swipeStarted(direction, x, y);
+ }
+ }
+
+ @Override
+ public boolean isSwipeEnabled(ScrollDirection direction) {
+ FullscreenManager manager = mHost.getFullscreenManager();
+ if (getActiveLayout() != mStaticLayout
+ || !DeviceClassManager.enableToolbarSwipe(
+ FeatureUtilities.isDocumentMode(mHost.getContext()))
+ || (manager != null && manager.getPersistentFullscreenMode())) {
+ return false;
+ }
+
+ boolean isAccessibility =
+ DeviceClassManager.isAccessibilityModeEnabled(mHost.getContext());
+ return direction == ScrollDirection.LEFT || direction == ScrollDirection.RIGHT
+ || (direction == ScrollDirection.DOWN && mOverviewLayout != null
+ && !isAccessibility);
+ }
+ }
+
+ /**
+ * @param id The id of the {@link Tab} to search for.
+ * @return A {@link Tab} instance or {@code null} if it could be found.
+ */
+ protected Tab getTabById(int id) {
+ TabModelSelector selector = getTabModelSelector();
+ return selector == null ? null : selector.getTabById(id);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698