// 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.view.ViewGroup; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.phone.SimpleAnimationLayout; import org.chromium.chrome.browser.compositor.overlays.SceneOverlay; import org.chromium.chrome.browser.contextualsearch.ContextualSearchManagementDelegate; import org.chromium.chrome.browser.dom_distiller.ReaderModeManagerDelegate; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.ui.resources.dynamics.DynamicResourceLoader; /** * {@link LayoutManagerChromePhone} is the specialization of {@link LayoutManagerChrome} for the * phone. */ public class LayoutManagerChromePhone extends LayoutManagerChrome { // Layouts private final Layout mSimpleAnimationLayout; /** * Creates an instance of a {@link LayoutManagerChromePhone}. * @param host A {@link LayoutManagerHost} instance. * @param overviewLayoutFactoryDelegate A {@link OverviewLayoutFactoryDelegate} instance. */ public LayoutManagerChromePhone( LayoutManagerHost host, OverviewLayoutFactoryDelegate overviewLayoutFactoryDelegate) { super(host, overviewLayoutFactoryDelegate); Context context = host.getContext(); LayoutRenderHost renderHost = host.getLayoutRenderHost(); // Build Layouts mSimpleAnimationLayout = new SimpleAnimationLayout(context, this, renderHost, mBlackHoleEventFilter); // Set up layout parameters mStaticLayout.setLayoutHandlesTabLifecycles(false); mToolbarSwipeLayout.setMovesToolbar(true); } @Override public void init(TabModelSelector selector, TabCreatorManager creator, TabContentManager content, ViewGroup androidContentContainer, ContextualSearchManagementDelegate contextualSearchDelegate, ReaderModeManagerDelegate readerModeDelegate, DynamicResourceLoader dynamicResourceLoader) { // Initialize Layouts mSimpleAnimationLayout.setTabModelSelector(selector, content); super.init(selector, creator, content, androidContentContainer, contextualSearchDelegate, readerModeDelegate, dynamicResourceLoader); } @Override protected LayoutManagerTabModelObserver createTabModelObserver() { return new LayoutManagerTabModelObserver() { @Override public void willCloseTab(Tab tab, boolean animate) { super.willCloseTab(tab, animate); if (animate) tabClosing(tab.getId()); } }; } @Override protected void addGlobalSceneOverlay(SceneOverlay helper) { super.addGlobalSceneOverlay(helper); mSimpleAnimationLayout.addSceneOverlay(helper); } @Override protected void emptyCachesExcept(int tabId) { super.emptyCachesExcept(tabId); if (mTitleCache != null) mTitleCache.clearExcept(tabId); } private void tabClosing(int id) { Tab closedTab = getTabById(id); if (closedTab == null) return; if (getActiveLayout().handlesTabClosing()) { // The user is currently interacting with the {@code LayoutHost}. // Allow the foreground layout to animate the tab closing. getActiveLayout().onTabClosing(time(), id); } else if (animationsEnabled()) { startShowing(mSimpleAnimationLayout, false); getActiveLayout().onTabClosing(time(), id); } } @Override protected void tabClosed(int id, int nextId, boolean incognito, boolean tabRemoved) { boolean showOverview = nextId == Tab.INVALID_TAB_ID; Layout overviewLayout = useAccessibilityLayout() ? mOverviewListLayout : mOverviewLayout; if (getActiveLayout() != overviewLayout && showOverview) { // Since there will be no 'next' tab to display, switch to // overview mode when the animation is finished. setNextLayout(overviewLayout); } getActiveLayout().onTabClosed(time(), id, nextId, incognito); Tab nextTab = getTabById(nextId); if (nextTab != null) nextTab.requestFocus(); boolean animate = !tabRemoved && animationsEnabled(); if (getActiveLayout() != overviewLayout && showOverview && !animate) { startShowing(overviewLayout, false); } } @Override protected void tabCreating(int sourceId, String url, boolean isIncognito) { if (!getActiveLayout().isHiding() && getActiveLayout().handlesTabCreating()) { // If the current layout in the foreground, let it handle the tab creation animation. // This check allows us to switch from the StackLayout to the SimpleAnimationLayout // smoothly. getActiveLayout().onTabCreating(sourceId); } else if (animationsEnabled()) { if (getActiveLayout() != null && getActiveLayout().isHiding()) { setNextLayout(mSimpleAnimationLayout); // The method Layout#doneHiding() will automatically show the next layout. getActiveLayout().doneHiding(); } else { startShowing(mSimpleAnimationLayout, false); } getActiveLayout().onTabCreating(sourceId); } } @Override protected void tabCreated(int id, int sourceId, TabLaunchType launchType, boolean isIncognito, boolean willBeSelected, float originX, float originY) { super.tabCreated(id, sourceId, launchType, isIncognito, willBeSelected, originX, originY); if (willBeSelected) { Tab newTab = TabModelUtils.getTabById(getTabModelSelector().getModel(isIncognito), id); if (newTab != null) newTab.requestFocus(); } } @Override public void releaseTabLayout(int id) { mTitleCache.remove(id); super.releaseTabLayout(id); } }