Commit 40a4a6b6 authored by Xi Han's avatar Xi Han Committed by Commit Bot

[Instant Start] Supports stack tab switcher.

In this CL, we remove the check of stack tab switcher in
TabUiFeatureUtilities#supportInstantStart(). Thus instant start can be
enabled in MVP++. These changes can be verified by:
- StartSurfaceTest#testShow_SingleAsHomepage_V2__Instant*.

The following changes are made to support stack tab switcher in instant
start:
1) Defer the creation of TabList in StackLayoutBase. It allows the
   StackLayoutBase/StartSurfaceStackLayout to be created pre-native.
2) Add pending observer list in TabModelFilterProvider. Any observer
   which is added before the TabModelFilterProvider is initialized, will
   be cached and notified when the initialization is completed.
3) StartSurfaceLayout and StackLayoutBase will create its SceneLayer if
   hasn't yet before calling updateSceneLayer().

Bug: 1116449, 1076449
Change-Id: I42a730045d4b9799d4bb08dc7d7dc947956f42ac
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2356167Reviewed-by: default avatarHenrique Nakashima <hnakashima@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarMatthew Jones <mdjones@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Commit-Queue: Xi Han <hanxi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810924}
parent dc7c12e1
...@@ -108,7 +108,7 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM ...@@ -108,7 +108,7 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM
mIsInitialized = true; mIsInitialized = true;
mStartSurface.initWithNative(); mStartSurface.initWithNative();
mSceneLayer = new TabListSceneLayer(); ensureSceneLayerCreated();
mSceneLayer.setTabModelSelector(mTabModelSelector); mSceneLayer.setTabModelSelector(mTabModelSelector);
} }
...@@ -214,6 +214,7 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM ...@@ -214,6 +214,7 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM
@Override @Override
protected void updateLayout(long time, long dt) { protected void updateLayout(long time, long dt) {
ensureSceneLayerCreated();
super.updateLayout(time, dt); super.updateLayout(time, dt);
if (mLayoutTabs == null) return; if (mLayoutTabs == null) return;
...@@ -274,6 +275,11 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM ...@@ -274,6 +275,11 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM
return mSceneLayer; return mSceneLayer;
} }
private void ensureSceneLayerCreated() {
if (mSceneLayer != null) return;
mSceneLayer = new TabListSceneLayer();
}
@Override @Override
public boolean handlesTabClosing() { public boolean handlesTabClosing() {
return true; return true;
...@@ -478,6 +484,7 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM ...@@ -478,6 +484,7 @@ public class StartSurfaceLayout extends Layout implements StartSurface.OverviewM
protected void updateSceneLayer(RectF viewport, RectF contentViewport, protected void updateSceneLayer(RectF viewport, RectF contentViewport,
LayerTitleCache layerTitleCache, TabContentManager tabContentManager, LayerTitleCache layerTitleCache, TabContentManager tabContentManager,
ResourceManager resourceManager, BrowserControlsStateProvider browserControls) { ResourceManager resourceManager, BrowserControlsStateProvider browserControls) {
ensureSceneLayerCreated();
super.updateSceneLayer(viewport, contentViewport, layerTitleCache, tabContentManager, super.updateSceneLayer(viewport, contentViewport, layerTitleCache, tabContentManager,
resourceManager, browserControls); resourceManager, browserControls);
assert mSceneLayer != null; assert mSceneLayer != null;
......
...@@ -35,6 +35,7 @@ public class StartSurfaceStackLayout extends StackLayout { ...@@ -35,6 +35,7 @@ public class StartSurfaceStackLayout extends StackLayout {
mIsInitialized = true; mIsInitialized = true;
super.onFinishNativeInitialization(); super.onFinishNativeInitialization();
super.initWithNative();
mCoordinator.initWithNative(); mCoordinator.initWithNative();
} }
...@@ -44,6 +45,9 @@ public class StartSurfaceStackLayout extends StackLayout { ...@@ -44,6 +45,9 @@ public class StartSurfaceStackLayout extends StackLayout {
mCoordinator.initialize(); mCoordinator.initialize();
mController.showOverview(false); mController.showOverview(false);
if (!mIsInitialized) {
return;
}
super.show(time, animate); super.show(time, animate);
} }
......
...@@ -690,7 +690,15 @@ public class StartSurfaceTest { ...@@ -690,7 +690,15 @@ public class StartSurfaceTest {
instanceOf(StackLayout.class)); instanceOf(StackLayout.class));
pressBack(); pressBack();
onViewWaiting(withId(R.id.primary_tasks_surface_view)); onView(withId(R.id.primary_tasks_surface_view));
if (isInstantReturn()
&& (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.O)) {
// TODO(crbug.com/1092642): Fix androidx.test.espresso.PerformException issue when
// performing a single click on position: 0. See code below.
return;
}
OverviewModeBehaviorWatcher hideWatcher = OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity()); TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
......
...@@ -175,11 +175,8 @@ public class TabUiFeatureUtilities { ...@@ -175,11 +175,8 @@ public class TabUiFeatureUtilities {
* @return Whether the instant start is supported. * @return Whether the instant start is supported.
*/ */
public static boolean supportInstantStart(boolean isTablet) { public static boolean supportInstantStart(boolean isTablet) {
// TODO(crbug.com/1076449): Support instant start when the stack tab switcher is
// enabled.
return !DeviceClassManager.enableAccessibilityLayout() return !DeviceClassManager.enableAccessibilityLayout()
&& CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START) && !isTablet && CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START) && !isTablet;
&& !StartSurfaceConfiguration.isStartSurfaceStackTabSwitcherEnabled();
} }
/** /**
......
...@@ -56,6 +56,7 @@ public class ChromeCachedFlags { ...@@ -56,6 +56,7 @@ public class ChromeCachedFlags {
ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID, ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID,
ChromeFeatureList.DOWNLOADS_AUTO_RESUMPTION_NATIVE, ChromeFeatureList.DOWNLOADS_AUTO_RESUMPTION_NATIVE,
ChromeFeatureList.HOMEPAGE_LOCATION_POLICY, ChromeFeatureList.HOMEPAGE_LOCATION_POLICY,
ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID,
ChromeFeatureList.IMMERSIVE_UI_MODE, ChromeFeatureList.IMMERSIVE_UI_MODE,
ChromeFeatureList.INSTANT_START, ChromeFeatureList.INSTANT_START,
ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS,
......
...@@ -453,6 +453,9 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider, ...@@ -453,6 +453,9 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
// Initialize Layouts // Initialize Layouts
mStaticLayout.onFinishNativeInitialization(); mStaticLayout.onFinishNativeInitialization();
if (mTabModelSelector == null) {
setTabModelSelector(selector);
}
// Contextual Search scene overlay. // Contextual Search scene overlay.
mContextualSearchPanel = new ContextualSearchPanel(mContext, this, mOverlayPanelManager); mContextualSearchPanel = new ContextualSearchPanel(mContext, this, mOverlayPanelManager);
...@@ -477,10 +480,6 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider, ...@@ -477,10 +480,6 @@ public class LayoutManager implements LayoutUpdateHost, LayoutProvider,
// Set the dynamic resource loader for all overlay panels. // Set the dynamic resource loader for all overlay panels.
mOverlayPanelManager.setDynamicResourceLoader(dynamicResourceLoader); mOverlayPanelManager.setDynamicResourceLoader(dynamicResourceLoader);
mOverlayPanelManager.setContainerView(mContentContainer); mOverlayPanelManager.setContainerView(mContentContainer);
if (mTabModelSelector != selector) {
setTabModelSelector(selector);
}
} }
// TODO(hanxi): Passes the TabModelSelectorSupplier in the constructor since the // TODO(hanxi): Passes the TabModelSelectorSupplier in the constructor since the
......
...@@ -198,8 +198,8 @@ public class LayoutManagerChrome ...@@ -198,8 +198,8 @@ public class LayoutManagerChrome
mToolbarSwipeLayout.setTabModelSelector(selector, content); mToolbarSwipeLayout.setTabModelSelector(selector, content);
mOverviewListLayout.setTabModelSelector(selector, content); mOverviewListLayout.setTabModelSelector(selector, content);
if (mOverviewLayout != null) { if (mOverviewLayout != null) {
mOverviewLayout.onFinishNativeInitialization();
mOverviewLayout.setTabModelSelector(selector, content); mOverviewLayout.setTabModelSelector(selector, content);
mOverviewLayout.onFinishNativeInitialization();
} }
} }
......
...@@ -56,6 +56,9 @@ public class StackLayout extends StackLayoutBase { ...@@ -56,6 +56,9 @@ public class StackLayout extends StackLayoutBase {
@Override @Override
public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) { public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) {
super.setTabModelSelector(modelSelector, manager); super.setTabModelSelector(modelSelector, manager);
if (modelSelector.getTabModelFilterProvider().getCurrentTabModelFilter() == null) {
return;
}
ArrayList<TabList> tabLists = new ArrayList<TabList>(); ArrayList<TabList> tabLists = new ArrayList<TabList>();
tabLists.add(modelSelector.getTabModelFilterProvider().getTabModelFilter(false)); tabLists.add(modelSelector.getTabModelFilterProvider().getTabModelFilter(false));
tabLists.add(modelSelector.getTabModelFilterProvider().getTabModelFilter(true)); tabLists.add(modelSelector.getTabModelFilterProvider().getTabModelFilter(true));
......
...@@ -43,6 +43,7 @@ import org.chromium.chrome.browser.compositor.layouts.phone.stack.Stack; ...@@ -43,6 +43,7 @@ import org.chromium.chrome.browser.compositor.layouts.phone.stack.Stack;
import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab;
import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer; import org.chromium.chrome.browser.compositor.scene_layer.SceneLayer;
import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer; import org.chromium.chrome.browser.compositor.scene_layer.TabListSceneLayer;
import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.homepage.HomepageManager; import org.chromium.chrome.browser.homepage.HomepageManager;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
...@@ -226,7 +227,6 @@ public abstract class StackLayoutBase extends Layout { ...@@ -226,7 +227,6 @@ public abstract class StackLayoutBase extends Layout {
private final ViewGroup mViewContainer; private final ViewGroup mViewContainer;
private final GestureEventFilter mGestureEventFilter; private final GestureEventFilter mGestureEventFilter;
private final TabListSceneLayer mSceneLayer;
private StackLayoutGestureHandler mGestureHandler; private StackLayoutGestureHandler mGestureHandler;
...@@ -236,6 +236,8 @@ public abstract class StackLayoutBase extends Layout { ...@@ -236,6 +236,8 @@ public abstract class StackLayoutBase extends Layout {
private final ObservableSupplier<BrowserControlsStateProvider> mBrowserControlsSupplier; private final ObservableSupplier<BrowserControlsStateProvider> mBrowserControlsSupplier;
private final BrowserControlsStateProvider.Observer mBrowserControlsObserver; private final BrowserControlsStateProvider.Observer mBrowserControlsObserver;
private Callback<BrowserControlsStateProvider> mBrowserControlsSupplierObserver; private Callback<BrowserControlsStateProvider> mBrowserControlsSupplierObserver;
private TabListSceneLayer mSceneLayer;
private boolean mShowPending;
private class StackLayoutGestureHandler implements GestureHandler { private class StackLayoutGestureHandler implements GestureHandler {
@Override @Override
...@@ -394,7 +396,7 @@ public abstract class StackLayoutBase extends Layout { ...@@ -394,7 +396,7 @@ public abstract class StackLayoutBase extends Layout {
mStacks = new ArrayList<Stack>(); mStacks = new ArrayList<Stack>();
mStackRects = new ArrayList<RectF>(); mStackRects = new ArrayList<RectF>();
mViewContainer = new FrameLayout(getContext()); mViewContainer = new FrameLayout(getContext());
mSceneLayer = new TabListSceneLayer();
mDpToPx = context.getResources().getDisplayMetrics().density; mDpToPx = context.getResources().getDisplayMetrics().density;
mBrowserControlsSupplier = browserControlsStateProviderSupplier; mBrowserControlsSupplier = browserControlsStateProviderSupplier;
mBrowserControlsObserver = new BrowserControlsStateProvider.Observer() { mBrowserControlsObserver = new BrowserControlsStateProvider.Observer() {
...@@ -413,6 +415,14 @@ public abstract class StackLayoutBase extends Layout { ...@@ -413,6 +415,14 @@ public abstract class StackLayoutBase extends Layout {
mBrowserControlsSupplier.addObserver(mBrowserControlsSupplierObserver); mBrowserControlsSupplier.addObserver(mBrowserControlsSupplierObserver);
} }
public void initWithNative() {
ensureSceneLayerCreated();
if (mShowPending) {
mShowPending = false;
show(LayoutManager.time(), false);
}
}
@Override @Override
public void destroy() { public void destroy() {
if (mBrowserControlsSupplier != null) { if (mBrowserControlsSupplier != null) {
...@@ -441,7 +451,7 @@ public abstract class StackLayoutBase extends Layout { ...@@ -441,7 +451,7 @@ public abstract class StackLayoutBase extends Layout {
* switcher in both portrait and landscape mode) is enabled. * switcher in both portrait and landscape mode) is enabled.
*/ */
protected boolean isHorizontalTabSwitcherFlagEnabled() { protected boolean isHorizontalTabSwitcherFlagEnabled() {
return ChromeFeatureList.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID); return CachedFeatureFlags.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID);
} }
/** /**
...@@ -526,7 +536,9 @@ public abstract class StackLayoutBase extends Layout { ...@@ -526,7 +536,9 @@ public abstract class StackLayoutBase extends Layout {
@Override @Override
public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) { public void setTabModelSelector(TabModelSelector modelSelector, TabContentManager manager) {
super.setTabModelSelector(modelSelector, manager); super.setTabModelSelector(modelSelector, manager);
mSceneLayer.setTabModelSelector(modelSelector); if (mSceneLayer != null) {
mSceneLayer.setTabModelSelector(modelSelector);
}
resetScrollData(); resetScrollData();
new TabModelSelectorTabModelObserver(mTabModelSelector) { new TabModelSelectorTabModelObserver(mTabModelSelector) {
...@@ -713,6 +725,10 @@ public abstract class StackLayoutBase extends Layout { ...@@ -713,6 +725,10 @@ public abstract class StackLayoutBase extends Layout {
super.onTabRestored(time, tabId); super.onTabRestored(time, tabId);
// Call show() so that new stack tabs and potentially new stacks get created. // Call show() so that new stack tabs and potentially new stacks get created.
// TODO(twellington): add animation for showing the restored tab. // TODO(twellington): add animation for showing the restored tab.
if (mSceneLayer == null) {
mShowPending = true;
return;
}
show(time, false); show(time, false);
} }
...@@ -1321,6 +1337,8 @@ public abstract class StackLayoutBase extends Layout { ...@@ -1321,6 +1337,8 @@ public abstract class StackLayoutBase extends Layout {
@Override @Override
protected void updateLayout(long time, long dt) { protected void updateLayout(long time, long dt) {
if (mStacks.size() == 0) return;
super.updateLayout(time, dt); super.updateLayout(time, dt);
boolean needUpdate = false; boolean needUpdate = false;
...@@ -1641,10 +1659,16 @@ public abstract class StackLayoutBase extends Layout { ...@@ -1641,10 +1659,16 @@ public abstract class StackLayoutBase extends Layout {
return mSceneLayer; return mSceneLayer;
} }
private void ensureSceneLayerCreated() {
if (mSceneLayer != null) return;
mSceneLayer = new TabListSceneLayer();
}
@Override @Override
protected void updateSceneLayer(RectF viewport, RectF contentViewport, protected void updateSceneLayer(RectF viewport, RectF contentViewport,
LayerTitleCache layerTitleCache, TabContentManager tabContentManager, LayerTitleCache layerTitleCache, TabContentManager tabContentManager,
ResourceManager resourceManager, BrowserControlsStateProvider browserControls) { ResourceManager resourceManager, BrowserControlsStateProvider browserControls) {
ensureSceneLayerCreated();
super.updateSceneLayer(viewport, contentViewport, layerTitleCache, tabContentManager, super.updateSceneLayer(viewport, contentViewport, layerTitleCache, tabContentManager,
resourceManager, browserControls); resourceManager, browserControls);
assert mSceneLayer != null; assert mSceneLayer != null;
......
...@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab; ...@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection; import org.chromium.chrome.browser.compositor.layouts.eventfilter.ScrollDirection;
import org.chromium.chrome.browser.compositor.layouts.phone.StackLayoutBase; import org.chromium.chrome.browser.compositor.layouts.phone.StackLayoutBase;
import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType; import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackAnimation.OverviewAnimationType;
import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabList; import org.chromium.chrome.browser.tabmodel.TabList;
...@@ -450,6 +451,8 @@ public abstract class Stack { ...@@ -450,6 +451,8 @@ public abstract class Stack {
* @return Whether or not the TabList represented by this TabStackState should be displayed. * @return Whether or not the TabList represented by this TabStackState should be displayed.
*/ */
public boolean isDisplayable() { public boolean isDisplayable() {
if (mTabList == null) return false;
return !mTabList.isIncognito() || (!mIsDying && mTabList.getCount() > 0); return !mTabList.isIncognito() || (!mIsDying && mTabList.getCount() > 0);
} }
...@@ -1714,6 +1717,8 @@ public abstract class Stack { ...@@ -1714,6 +1717,8 @@ public abstract class Stack {
* restored if we're calling this while the switcher is already visible. * restored if we're calling this while the switcher is already visible.
*/ */
private void createStackTabs(boolean restoreState) { private void createStackTabs(boolean restoreState) {
if (mTabList == null) return;
final int count = mTabList.getCount(); final int count = mTabList.getCount();
if (count == 0) { if (count == 0) {
cleanupTabs(); cleanupTabs();
...@@ -2027,7 +2032,7 @@ public abstract class Stack { ...@@ -2027,7 +2032,7 @@ public abstract class Stack {
} }
protected void updateCurrentMode(@Orientation int orientation) { protected void updateCurrentMode(@Orientation int orientation) {
if (ChromeFeatureList.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID)) { if (CachedFeatureFlags.isEnabled(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID)) {
mCurrentMode = Orientation.LANDSCAPE; mCurrentMode = Orientation.LANDSCAPE;
} else { } else {
mCurrentMode = orientation; mCurrentMode = orientation;
......
...@@ -58,7 +58,7 @@ public abstract class TabModelSelectorBase implements TabModelSelector, Incognit ...@@ -58,7 +58,7 @@ public abstract class TabModelSelectorBase implements TabModelSelector, Incognit
mIncognitoTabModel = incognitoModel; mIncognitoTabModel = incognitoModel;
mActiveModelIndex = getModelIndex(mStartIncognito); mActiveModelIndex = getModelIndex(mStartIncognito);
assert mActiveModelIndex != MODEL_NOT_FOUND; assert mActiveModelIndex != MODEL_NOT_FOUND;
mTabModelFilterProvider = new TabModelFilterProvider(mTabModelFilterFactory, mTabModels); mTabModelFilterProvider.init(mTabModelFilterFactory, mTabModels);
addObserver(mTabModelFilterProvider); addObserver(mTabModelFilterProvider);
TabModelObserver tabModelObserver = new TabModelObserver() { TabModelObserver tabModelObserver = new TabModelObserver() {
......
...@@ -156,6 +156,9 @@ public class LayoutManagerTest implements MockTabModelDelegate { ...@@ -156,6 +156,9 @@ public class LayoutManagerTest implements MockTabModelDelegate {
TabModelUtils.setIndex(mTabModelSelector.getModel(true), incognitoIndexSelected); TabModelUtils.setIndex(mTabModelSelector.getModel(true), incognitoIndexSelected);
} }
mTabModelSelector.selectModel(incognitoSelected); mTabModelSelector.selectModel(incognitoSelected);
Assert.assertNotNull(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter());
LayoutManagerHost layoutManagerHost = new MockLayoutHost(context); LayoutManagerHost layoutManagerHost = new MockLayoutHost(context);
TabContentManager tabContentManager = new TabContentManager(context, null, false, null); TabContentManager tabContentManager = new TabContentManager(context, null, false, null);
tabContentManager.initWithNative(); tabContentManager.initWithNative();
......
...@@ -51,6 +51,7 @@ public class CachedFeatureFlags { ...@@ -51,6 +51,7 @@ public class CachedFeatureFlags {
put(ChromeFeatureList.ANDROID_PARTNER_CUSTOMIZATION_PHENOTYPE, true); put(ChromeFeatureList.ANDROID_PARTNER_CUSTOMIZATION_PHENOTYPE, true);
put(ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID, false); put(ChromeFeatureList.CONDITIONAL_TAB_STRIP_ANDROID, false);
put(ChromeFeatureList.HOMEPAGE_LOCATION_POLICY, false); put(ChromeFeatureList.HOMEPAGE_LOCATION_POLICY, false);
put(ChromeFeatureList.HORIZONTAL_TAB_SWITCHER_ANDROID, false);
put(ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD, false); put(ChromeFeatureList.SERVICE_MANAGER_FOR_DOWNLOAD, false);
put(ChromeFeatureList.SERVICE_MANAGER_FOR_BACKGROUND_PREFETCH, true); put(ChromeFeatureList.SERVICE_MANAGER_FOR_BACKGROUND_PREFETCH, true);
put(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, true); put(ChromeFeatureList.INTEREST_FEED_CONTENT_SUGGESTIONS, true);
......
...@@ -15,23 +15,40 @@ import java.util.List; ...@@ -15,23 +15,40 @@ import java.util.List;
*/ */
public class TabModelFilterProvider extends EmptyTabModelSelectorObserver { public class TabModelFilterProvider extends EmptyTabModelSelectorObserver {
private List<TabModelFilter> mTabModelFilterList = Collections.emptyList(); private List<TabModelFilter> mTabModelFilterList = Collections.emptyList();
private final List<TabModelObserver> mPendingTabModelObserver = new ArrayList<>();
TabModelFilterProvider() {} TabModelFilterProvider() {}
TabModelFilterProvider(TabModelFilterFactory tabModelFilterFactory, List<TabModel> tabModels) { public void init(TabModelFilterFactory tabModelFilterFactory, List<TabModel> tabModels) {
assert mTabModelFilterList.isEmpty();
assert tabModels.size() > 0;
List<TabModelFilter> filters = new ArrayList<>(); List<TabModelFilter> filters = new ArrayList<>();
for (int i = 0; i < tabModels.size(); i++) { for (int i = 0; i < tabModels.size(); i++) {
filters.add(tabModelFilterFactory.createTabModelFilter(tabModels.get(i))); filters.add(tabModelFilterFactory.createTabModelFilter(tabModels.get(i)));
} }
mTabModelFilterList = Collections.unmodifiableList(filters); mTabModelFilterList = Collections.unmodifiableList(filters);
// Registers the pending observers.
for (TabModelObserver observer : mPendingTabModelObserver) {
for (TabModelFilter tabModelFilter : mTabModelFilterList) {
tabModelFilter.addObserver(observer);
}
}
mPendingTabModelObserver.clear();
} }
/** /**
* This method adds {@link TabModelObserver} to both {@link TabModelFilter}s. * This method adds {@link TabModelObserver} to both {@link TabModelFilter}s. Caches the
* observer until {@link TabModelFilter}s are created.
* @param observer {@link TabModelObserver} to add. * @param observer {@link TabModelObserver} to add.
*/ */
public void addTabModelFilterObserver(TabModelObserver observer) { public void addTabModelFilterObserver(TabModelObserver observer) {
if (mTabModelFilterList.isEmpty()) {
mPendingTabModelObserver.add(observer);
return;
}
for (int i = 0; i < mTabModelFilterList.size(); i++) { for (int i = 0; i < mTabModelFilterList.size(); i++) {
mTabModelFilterList.get(i).addObserver(observer); mTabModelFilterList.get(i).addObserver(observer);
} }
...@@ -42,6 +59,11 @@ public class TabModelFilterProvider extends EmptyTabModelSelectorObserver { ...@@ -42,6 +59,11 @@ public class TabModelFilterProvider extends EmptyTabModelSelectorObserver {
* @param observer {@link TabModelObserver} to remove. * @param observer {@link TabModelObserver} to remove.
*/ */
public void removeTabModelFilterObserver(TabModelObserver observer) { public void removeTabModelFilterObserver(TabModelObserver observer) {
if (mTabModelFilterList.isEmpty() && !mPendingTabModelObserver.isEmpty()) {
mPendingTabModelObserver.remove(observer);
return;
}
for (int i = 0; i < mTabModelFilterList.size(); i++) { for (int i = 0; i < mTabModelFilterList.size(); i++) {
mTabModelFilterList.get(i).removeObserver(observer); mTabModelFilterList.get(i).removeObserver(observer);
} }
...@@ -83,6 +105,7 @@ public class TabModelFilterProvider extends EmptyTabModelSelectorObserver { ...@@ -83,6 +105,7 @@ public class TabModelFilterProvider extends EmptyTabModelSelectorObserver {
for (int i = 0; i < mTabModelFilterList.size(); i++) { for (int i = 0; i < mTabModelFilterList.size(); i++) {
mTabModelFilterList.get(i).destroy(); mTabModelFilterList.get(i).destroy();
} }
mPendingTabModelObserver.clear();
} }
private void markTabStateInitialized() { private void markTabStateInitialized() {
......
...@@ -42,6 +42,7 @@ public class MockTabModel extends EmptyTabModel implements IncognitoTabModel { ...@@ -42,6 +42,7 @@ public class MockTabModel extends EmptyTabModel implements IncognitoTabModel {
private final ArrayList<Tab> mTabs = new ArrayList<Tab>(); private final ArrayList<Tab> mTabs = new ArrayList<Tab>();
private final boolean mIncognito; private final boolean mIncognito;
private final MockTabModelDelegate mDelegate; private final MockTabModelDelegate mDelegate;
private boolean mIsCurrentModel;
public MockTabModel(boolean incognito, MockTabModelDelegate delegate) { public MockTabModel(boolean incognito, MockTabModelDelegate delegate) {
mIncognito = incognito; mIncognito = incognito;
...@@ -122,4 +123,13 @@ public class MockTabModel extends EmptyTabModel implements IncognitoTabModel { ...@@ -122,4 +123,13 @@ public class MockTabModel extends EmptyTabModel implements IncognitoTabModel {
@Override @Override
public void removeIncognitoObserver(IncognitoTabModelObserver observer) {} public void removeIncognitoObserver(IncognitoTabModelObserver observer) {}
@Override
public boolean isCurrentModel() {
return mIsCurrentModel;
}
public void setAsCurrentModelForTesting() {
mIsCurrentModel = true;
}
} }
...@@ -64,4 +64,10 @@ public class MockTabModelSelector extends TabModelSelectorBase { ...@@ -64,4 +64,10 @@ public class MockTabModelSelector extends TabModelSelectorBase {
public int getTotalTabCount() { public int getTotalTabCount() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void selectModel(boolean incognito) {
super.selectModel(incognito);
((MockTabModel) getModel(incognito)).setAsCurrentModelForTesting();
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment