Commit ddad167d authored by Henrique Nakashima's avatar Henrique Nakashima Committed by Chromium LUCI CQ

Reland "Create glue-layer TabModelOrchestrators"

This is a reland of 314cbf4c

Patchset 1 is the original change.

The main difference is that now the TabPersistentStore is created
with the actual index that TabWindowManagerImpl assigned to the
TabModelSelector, rather than the index that was "requested".

Other changes are to adapt tests.

Original change's description:
> Create glue-layer TabModelOrchestrators
>
> TabModelSelectorImpl does not create or destroy TabPersistentStore
> anymore. Instead, TabModelOrchestrators manage the lifetime of TabModelSelectorImpl and
> TabPersistentStore.
>
> Give TabModelSelectorImpl a Supplier<TabPersistentStore> instead of
> passing TabPersistentStore directly.
>
> This is a step to break the two-way dependency between
> TabModelSelectorImpl and TabPersistentStore.
>
> Bug: 1138561
> Change-Id: Ie2fa4a2735e509ff816b3e2cf5f8f6fffda7999c
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2572639
> Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
> Reviewed-by: David Trainor <dtrainor@chromium.org>
> Reviewed-by: Ella Ge <eirage@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#835819}

Bug: 1138561,1158259
Change-Id: Iac6eaaed149e853536813cd627d28236638657de
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2590427
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: default avatarElla Ge <eirage@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843752}
parent 79de88f2
...@@ -84,8 +84,11 @@ chrome_java_sources = [ ...@@ -84,8 +84,11 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/app/tabmodel/AsyncTabParamsManagerSingleton.java", "java/src/org/chromium/chrome/browser/app/tabmodel/AsyncTabParamsManagerSingleton.java",
"java/src/org/chromium/chrome/browser/app/tabmodel/ChromeNextTabPolicySupplier.java", "java/src/org/chromium/chrome/browser/app/tabmodel/ChromeNextTabPolicySupplier.java",
"java/src/org/chromium/chrome/browser/app/tabmodel/ChromeTabModelFilterFactory.java", "java/src/org/chromium/chrome/browser/app/tabmodel/ChromeTabModelFilterFactory.java",
"java/src/org/chromium/chrome/browser/app/tabmodel/CustomTabsTabModelOrchestrator.java",
"java/src/org/chromium/chrome/browser/app/tabmodel/DefaultTabModelSelectorFactory.java", "java/src/org/chromium/chrome/browser/app/tabmodel/DefaultTabModelSelectorFactory.java",
"java/src/org/chromium/chrome/browser/app/tabmodel/TabModelOrchestrator.java",
"java/src/org/chromium/chrome/browser/app/tabmodel/TabWindowManagerSingleton.java", "java/src/org/chromium/chrome/browser/app/tabmodel/TabWindowManagerSingleton.java",
"java/src/org/chromium/chrome/browser/app/tabmodel/TabbedModeTabModelOrchestrator.java",
"java/src/org/chromium/chrome/browser/app/video_tutorials/ChromeLanguageInfoProvider.java", "java/src/org/chromium/chrome/browser/app/video_tutorials/ChromeLanguageInfoProvider.java",
"java/src/org/chromium/chrome/browser/app/video_tutorials/NewTabPageVideoIPHManager.java", "java/src/org/chromium/chrome/browser/app/video_tutorials/NewTabPageVideoIPHManager.java",
"java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java", "java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java",
......
...@@ -60,7 +60,9 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout ...@@ -60,7 +60,9 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
import org.chromium.chrome.browser.app.tabmodel.ChromeNextTabPolicySupplier; import org.chromium.chrome.browser.app.tabmodel.ChromeNextTabPolicySupplier;
import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator;
import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton;
import org.chromium.chrome.browser.app.tabmodel.TabbedModeTabModelOrchestrator;
import org.chromium.chrome.browser.bookmarks.BookmarkUtils; import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
import org.chromium.chrome.browser.compositor.CompositorViewHolder; import org.chromium.chrome.browser.compositor.CompositorViewHolder;
import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator; import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator;
...@@ -247,6 +249,7 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent ...@@ -247,6 +249,7 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
private ToolbarControlContainer mControlContainer; private ToolbarControlContainer mControlContainer;
private TabbedModeTabModelOrchestrator mTabModelOrchestrator;
private TabModelSelectorImpl mTabModelSelectorImpl; private TabModelSelectorImpl mTabModelSelectorImpl;
private TabModelSelectorTabObserver mTabModelSelectorTabObserver; private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
private TabModelSelectorTabModelObserver mTabModelObserver; private TabModelSelectorTabModelObserver mTabModelObserver;
...@@ -1628,7 +1631,13 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent ...@@ -1628,7 +1631,13 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
} }
@Override @Override
protected TabModelSelector createTabModelSelector() { protected TabModelOrchestrator createTabModelOrchestrator() {
mTabModelOrchestrator = new TabbedModeTabModelOrchestrator();
return mTabModelOrchestrator;
}
@Override
protected void createTabModels() {
assert mTabModelSelectorImpl == null; assert mTabModelSelectorImpl == null;
Bundle savedInstanceState = getSavedInstanceState(); Bundle savedInstanceState = getSavedInstanceState();
...@@ -1639,17 +1648,15 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent ...@@ -1639,17 +1648,15 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
int index = savedInstanceState != null ? savedInstanceState.getInt(WINDOW_INDEX, 0) : 0; int index = savedInstanceState != null ? savedInstanceState.getInt(WINDOW_INDEX, 0) : 0;
mNextTabPolicySupplier = new ChromeNextTabPolicySupplier(mOverviewModeBehaviorSupplier); mNextTabPolicySupplier = new ChromeNextTabPolicySupplier(mOverviewModeBehaviorSupplier);
mTabModelSelectorImpl =
(TabModelSelectorImpl) TabWindowManagerSingleton.getInstance().requestSelector( boolean tabModelWasCreated =
this, this, mNextTabPolicySupplier, index); mTabModelOrchestrator.createTabModels(this, this, mNextTabPolicySupplier, index);
if (mTabModelSelectorImpl == null) { if (!tabModelWasCreated) {
Toast.makeText(
this, getString(R.string.unsupported_number_of_windows), Toast.LENGTH_LONG)
.show();
finish(); finish();
return null; return;
} }
mTabModelSelectorImpl = mTabModelOrchestrator.getTabModelSelector();
mTabModelSelectorImpl.addObserver(new EmptyTabModelSelectorObserver() { mTabModelSelectorImpl.addObserver(new EmptyTabModelSelectorObserver() {
@Override @Override
public void onTabStateInitialized() { public void onTabStateInitialized() {
...@@ -1673,8 +1680,6 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent ...@@ -1673,8 +1680,6 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
mAppIndexingUtil = new AppIndexingUtil(mTabModelSelectorImpl); mAppIndexingUtil = new AppIndexingUtil(mTabModelSelectorImpl);
if (startIncognito) mTabModelSelectorImpl.selectModel(true); if (startIncognito) mTabModelSelectorImpl.selectModel(true);
return mTabModelSelectorImpl;
} }
@Override @Override
...@@ -2223,6 +2228,13 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent ...@@ -2223,6 +2228,13 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
super.onDestroyInternal(); super.onDestroyInternal();
} }
@Override
protected void destroyTabModels() {
if (mTabModelOrchestrator != null) {
mTabModelOrchestrator.destroy();
}
}
@Override @Override
public void onTrimMemory(int level) { public void onTrimMemory(int level) {
super.onTrimMemory(level); super.onTrimMemory(level);
......
...@@ -71,6 +71,7 @@ import org.chromium.chrome.browser.app.flags.ChromeCachedFlags; ...@@ -71,6 +71,7 @@ import org.chromium.chrome.browser.app.flags.ChromeCachedFlags;
import org.chromium.chrome.browser.app.tab_activity_glue.ReparentingDelegateFactory; import org.chromium.chrome.browser.app.tab_activity_glue.ReparentingDelegateFactory;
import org.chromium.chrome.browser.app.tab_activity_glue.TabReparentingController; import org.chromium.chrome.browser.app.tab_activity_glue.TabReparentingController;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge; import org.chromium.chrome.browser.bookmarks.BookmarkBridge;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem; import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
import org.chromium.chrome.browser.bookmarks.BookmarkModel; import org.chromium.chrome.browser.bookmarks.BookmarkModel;
...@@ -241,7 +242,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -241,7 +242,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
new TabModelSelectorProfileSupplier(mTabModelSelectorSupplier); new TabModelSelectorProfileSupplier(mTabModelSelectorSupplier);
protected ObservableSupplierImpl<BookmarkBridge> mBookmarkBridgeSupplier = protected ObservableSupplierImpl<BookmarkBridge> mBookmarkBridgeSupplier =
new ObservableSupplierImpl<>(); new ObservableSupplierImpl<>();
private TabModelSelector mTabModelSelector; private TabModelOrchestrator mTabModelOrchestrator;
private TabModelSelectorTabObserver mTabModelSelectorTabObserver; private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
private TabCreator mRegularTabCreator; private TabCreator mRegularTabCreator;
private TabCreator mIncognitoTabCreator; private TabCreator mIncognitoTabCreator;
...@@ -263,7 +264,6 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -263,7 +264,6 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
/** Whether or not {@link #postDeferredStartupIfNeeded()} has already successfully run. */ /** Whether or not {@link #postDeferredStartupIfNeeded()} has already successfully run. */
private boolean mDeferredStartupPosted; private boolean mDeferredStartupPosted;
private boolean mTabModelsInitialized;
private boolean mNativeInitialized; private boolean mNativeInitialized;
private boolean mRemoveWindowBackgroundDone; private boolean mRemoveWindowBackgroundDone;
protected AccessibilityVisibilityHandler mAccessibilityVisibilityHandler; protected AccessibilityVisibilityHandler mAccessibilityVisibilityHandler;
...@@ -358,6 +358,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -358,6 +358,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
// onPreInflationStartup event. // onPreInflationStartup event.
mComponent = createComponent(); mComponent = createComponent();
// Create the orchestrator that manages Tab models and persistence
mTabModelOrchestrator = createTabModelOrchestrator();
// There's no corresponding call to removeObserver() for this addObserver() because // There's no corresponding call to removeObserver() for this addObserver() because
// mTabModelProfileSupplier has the same lifecycle as this activity. // mTabModelProfileSupplier has the same lifecycle as this activity.
mTabModelProfileSupplier.addObserver((profile) -> { mTabModelProfileSupplier.addObserver((profile) -> {
...@@ -483,9 +486,10 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -483,9 +486,10 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
mCompositorViewHolder.getCompositorView()); mCompositorViewHolder.getCompositorView());
initializeTabModels(); initializeTabModels();
TabModelSelector tabModelSelector = mTabModelOrchestrator.getTabModelSelector();
setTabContentManager(new TabContentManager(this, getContentOffsetProvider(), setTabContentManager(new TabContentManager(this, getContentOffsetProvider(),
!SysUtils.isLowEndDevice(), !SysUtils.isLowEndDevice(),
mTabModelSelector != null ? mTabModelSelector::getTabById : null)); tabModelSelector != null ? tabModelSelector::getTabById : null));
if (!isFinishing()) { if (!isFinishing()) {
getBrowserControlsManager().initialize( getBrowserControlsManager().initialize(
...@@ -647,28 +651,28 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -647,28 +651,28 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* this activity. * this activity.
*/ */
public final void initializeTabModels() { public final void initializeTabModels() {
if (mTabModelsInitialized) return; if (mTabModelOrchestrator.areTabModelsInitialized()) return;
mTabModelSelector = createTabModelSelector(); createTabModels();
TabModelSelector tabModelSelector = mTabModelOrchestrator.getTabModelSelector();
if (mTabModelSelector == null) { if (tabModelSelector == null) {
assert isFinishing(); assert isFinishing();
mTabModelsInitialized = true;
return; return;
} }
mTabModelSelectorSupplier.set(mTabModelSelector); mTabModelSelectorSupplier.set(tabModelSelector);
mActivityTabProvider.setTabModelSelector(mTabModelSelector); mActivityTabProvider.setTabModelSelector(tabModelSelector);
getStatusBarColorController().setTabModelSelector(mTabModelSelector); getStatusBarColorController().setTabModelSelector(tabModelSelector);
Pair<? extends TabCreator, ? extends TabCreator> tabCreators = createTabCreators(); Pair<? extends TabCreator, ? extends TabCreator> tabCreators = createTabCreators();
mRegularTabCreator = tabCreators.first; mRegularTabCreator = tabCreators.first;
mIncognitoTabCreator = tabCreators.second; mIncognitoTabCreator = tabCreators.second;
OfflinePageUtils.observeTabModelSelector(this, mTabModelSelector); OfflinePageUtils.observeTabModelSelector(this, tabModelSelector);
if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy(); if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy();
mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(mTabModelSelector) { mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(tabModelSelector) {
@Override @Override
public void onLoadStopped(Tab tab, boolean toDifferentDocument) { public void onLoadStopped(Tab tab, boolean toDifferentDocument) {
postDeferredStartupIfNeeded(); postDeferredStartupIfNeeded();
...@@ -685,8 +689,6 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -685,8 +689,6 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
postDeferredStartupIfNeeded(); postDeferredStartupIfNeeded();
} }
}; };
mTabModelsInitialized = true;
} }
/** /**
...@@ -702,9 +704,19 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -702,9 +704,19 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
} }
/** /**
* @return The {@link TabModelSelector} owned by this {@link ChromeActivity}. * @return The {@link TabModelOrchestrator} owned by this {@link ChromeActivity}.
*/
protected abstract TabModelOrchestrator createTabModelOrchestrator();
/**
* Call the {@link TabModelOrchestrator} to initialize its members.
*/ */
protected abstract TabModelSelector createTabModelSelector(); protected abstract void createTabModels();
/**
* Call the {@link TabModelOrchestrator} to destroy its members.
*/
protected abstract void destroyTabModels();
/** /**
* @return The {@link TabCreator}s owned * @return The {@link TabCreator}s owned
...@@ -843,7 +855,8 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -843,7 +855,8 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
VrModuleProvider.getDelegate().onActivityHidden(this); VrModuleProvider.getDelegate().onActivityHidden(this);
Tab tab = getActivityTab(); Tab tab = getActivityTab();
if (mTabModelSelector != null && !mTabModelSelector.isReparentingInProgress() TabModelSelector tabModelSelector = mTabModelOrchestrator.getTabModelSelector();
if (tabModelSelector != null && !tabModelSelector.isReparentingInProgress()
&& tab != null) { && tab != null) {
tab.hide(TabHidingType.ACTIVITY_HIDDEN); tab.hide(TabHidingType.ACTIVITY_HIDDEN);
} }
...@@ -1304,10 +1317,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1304,10 +1317,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
mActivityTabStartupMetricsTracker = null; mActivityTabStartupMetricsTracker = null;
} }
if (mTabModelsInitialized) { destroyTabModels();
TabModelSelector selector = getTabModelSelector();
if (selector != null) selector.destroy();
}
if (mBookmarkBridgeSupplier != null) { if (mBookmarkBridgeSupplier != null) {
BookmarkBridge bookmarkBridge = mBookmarkBridgeSupplier.get(); BookmarkBridge bookmarkBridge = mBookmarkBridgeSupplier.get();
...@@ -1583,7 +1593,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1583,7 +1593,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* @return Whether the tab models have been fully initialized. * @return Whether the tab models have been fully initialized.
*/ */
public boolean areTabModelsInitialized() { public boolean areTabModelsInitialized() {
return mTabModelsInitialized; return mTabModelOrchestrator.areTabModelsInitialized();
} }
/** /**
...@@ -1592,11 +1602,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1592,11 +1602,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* @return The {@link TabModelSelector}, possibly null. * @return The {@link TabModelSelector}, possibly null.
*/ */
public TabModelSelector getTabModelSelector() { public TabModelSelector getTabModelSelector() {
if (!mTabModelsInitialized) { if (!mTabModelOrchestrator.areTabModelsInitialized()) {
throw new IllegalStateException( throw new IllegalStateException(
"Attempting to access TabModelSelector before initialization"); "Attempting to access TabModelSelector before initialization");
} }
return mTabModelSelector; return mTabModelOrchestrator.getTabModelSelector();
} }
/** /**
...@@ -1617,7 +1627,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1617,7 +1627,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
@Override @Override
public TabCreator getTabCreator(boolean incognito) { public TabCreator getTabCreator(boolean incognito) {
if (!mTabModelsInitialized) { if (!mTabModelOrchestrator.areTabModelsInitialized()) {
throw new IllegalStateException( throw new IllegalStateException(
"Attempting to access TabCreator before initialization"); "Attempting to access TabCreator before initialization");
} }
...@@ -1684,7 +1694,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1684,7 +1694,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* null if the Tab does not exist or the system is not initialized. * null if the Tab does not exist or the system is not initialized.
*/ */
public Tab getActivityTab() { public Tab getActivityTab() {
if (!mTabModelsInitialized) { if (!mTabModelOrchestrator.areTabModelsInitialized()) {
return null; return null;
} }
return TabModelUtils.getCurrentTab(getCurrentTabModel()); return TabModelUtils.getCurrentTab(getCurrentTabModel());
...@@ -1695,7 +1705,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -1695,7 +1705,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* WebContents. * WebContents.
*/ */
public WebContents getCurrentWebContents() { public WebContents getCurrentWebContents() {
if (!mTabModelsInitialized) { if (!mTabModelOrchestrator.areTabModelsInitialized()) {
return null; return null;
} }
return TabModelUtils.getCurrentWebContents(getCurrentTabModel()); return TabModelUtils.getCurrentWebContents(getCurrentTabModel());
...@@ -2019,7 +2029,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent> ...@@ -2019,7 +2029,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
if (id == R.id.help_id) { if (id == R.id.help_id) {
String url = currentTab != null ? currentTab.getUrlString() : ""; String url = currentTab != null ? currentTab.getUrlString() : "";
Profile profile = mTabModelSelector.isIncognitoSelected() Profile profile = getTabModelSelector().isIncognitoSelected()
? Profile.getLastUsedRegularProfile().getPrimaryOTRProfile() ? Profile.getLastUsedRegularProfile().getPrimaryOTRProfile()
: Profile.getLastUsedRegularProfile(); : Profile.getLastUsedRegularProfile();
startHelpAndFeedback(url, "MobileMenuFeedback", profile); startHelpAndFeedback(url, "MobileMenuFeedback", profile);
......
// Copyright 2020 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.app.tabmodel;
import androidx.annotation.Nullable;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.dependency_injection.ActivityScope;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.browser.tabmodel.TabModelFilterFactory;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tabmodel.TabPersistencePolicy;
import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
import org.chromium.ui.base.WindowAndroid;
import javax.inject.Inject;
/**
* Glue-level class that manages lifetime of root .tabmodel objects: {@link TabPersistentStore} and
* {@link TabModelSelectorImpl} for custom tabs.
*/
@ActivityScope
public class CustomTabsTabModelOrchestrator extends TabModelOrchestrator {
@Inject
public CustomTabsTabModelOrchestrator() {}
/**
* Creates the TabModelSelector and the TabPersistentStore.
*/
public void createTabModels(@Nullable Supplier<WindowAndroid> windowAndroidSupplier,
TabCreatorManager tabCreatorManager, TabModelFilterFactory tabModelFilterFactory,
TabPersistencePolicy persistencePolicy, AsyncTabParamsManager asyncTabParamsManager) {
// Instantiate TabModelSelectorImpl
NextTabPolicySupplier nextTabPolicySupplier = () -> NextTabPolicy.LOCATIONAL;
mTabModelSelector = new TabModelSelectorImpl(windowAndroidSupplier, tabCreatorManager,
tabModelFilterFactory, nextTabPolicySupplier, asyncTabParamsManager, false, false,
false);
// Instantiate TabPersistentStore
mTabPersistentStore =
new TabPersistentStore(persistencePolicy, mTabModelSelector, tabCreatorManager);
wireSelectorAndStore();
markTabModelsInitialized();
}
}
...@@ -5,19 +5,15 @@ ...@@ -5,19 +5,15 @@
package org.chromium.chrome.browser.app.tabmodel; package org.chromium.chrome.browser.app.tabmodel;
import android.app.Activity; import android.app.Activity;
import android.os.Build;
import org.chromium.base.annotations.VerifiesOnN; import org.chromium.base.annotations.VerifiesOnN;
import org.chromium.chrome.browser.multiwindow.MultiInstanceManager; import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier; import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager; import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.browser.tabmodel.TabModelFilterFactory; import org.chromium.chrome.browser.tabmodel.TabModelFilterFactory;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorFactory; import org.chromium.chrome.browser.tabmodel.TabModelSelectorFactory;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tabmodel.TabPersistencePolicy;
import org.chromium.chrome.browser.tabmodel.TabbedModeTabPersistencePolicy;
/** /**
* Default {@link TabModelSelectorFactory} for Chrome. * Default {@link TabModelSelectorFactory} for Chrome.
...@@ -29,32 +25,11 @@ public class DefaultTabModelSelectorFactory implements TabModelSelectorFactory { ...@@ -29,32 +25,11 @@ public class DefaultTabModelSelectorFactory implements TabModelSelectorFactory {
@Override @Override
public TabModelSelector buildSelector(Activity activity, TabCreatorManager tabCreatorManager, public TabModelSelector buildSelector(Activity activity, TabCreatorManager tabCreatorManager,
NextTabPolicySupplier nextTabPolicySupplier, int selectorIndex) { NextTabPolicySupplier nextTabPolicySupplier, int selectorIndex) {
// Merge tabs if this TabModelSelector is for a ChromeTabbedActivity created in
// fullscreen mode and there are no TabModelSelector's currently alive. This indicates
// that it is a cold start or process restart in fullscreen mode.
boolean mergeTabs = Build.VERSION.SDK_INT > Build.VERSION_CODES.M
&& MultiInstanceManager.isTabModelMergingEnabled()
&& !activity.isInMultiWindowMode();
if (MultiInstanceManager.shouldMergeOnStartup(activity)) {
mergeTabs = mergeTabs
&& (!MultiWindowUtils.getInstance().isInMultiDisplayMode(activity)
|| TabWindowManagerSingleton.getInstance()
.getNumberOfAssignedTabModelSelectors()
== 0);
} else {
mergeTabs = mergeTabs
&& TabWindowManagerSingleton.getInstance()
.getNumberOfAssignedTabModelSelectors()
== 0;
}
if (mergeTabs) {
MultiInstanceManager.mergedOnStartup();
}
TabPersistencePolicy persistencePolicy =
new TabbedModeTabPersistencePolicy(selectorIndex, mergeTabs);
TabModelFilterFactory tabModelFilterFactory = new ChromeTabModelFilterFactory(); TabModelFilterFactory tabModelFilterFactory = new ChromeTabModelFilterFactory();
return new TabModelSelectorImpl(activity, /*windowAndroidSupplier=*/null, tabCreatorManager, AsyncTabParamsManager asyncTabParamsManager = AsyncTabParamsManagerSingleton.getInstance();
persistencePolicy, tabModelFilterFactory, nextTabPolicySupplier,
AsyncTabParamsManagerSingleton.getInstance(), true, true, false); return new TabModelSelectorImpl(/*windowAndroidSupplier=*/null, tabCreatorManager,
tabModelFilterFactory, nextTabPolicySupplier, asyncTabParamsManager, true, true,
false);
} }
} }
// Copyright 2020 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.app.tabmodel;
import org.chromium.base.supplier.ObservableSupplierImpl;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabPersistentStoreObserver;
/**
* Implementers are glue-level objects that manage lifetime of root .tabmodel objects: {@link
* TabPersistentStore} and {@link TabModelSelectorImpl}.
*/
public abstract class TabModelOrchestrator {
protected TabPersistentStore mTabPersistentStore;
protected TabModelSelectorImpl mTabModelSelector;
private boolean mTabModelsInitialized;
/**
* @return Whether the tab models have been fully initialized.
*/
public boolean areTabModelsInitialized() {
return mTabModelsInitialized;
}
/**
* @return The {@link TabModelSelectorImpl} managed by this orchestrator.
*/
public TabModelSelectorImpl getTabModelSelector() {
return mTabModelSelector;
}
/**
* Destroy the {@link TabPersistentStore} and {@link TabModelSelectorImpl} members.
*/
public void destroy() {
if (!mTabModelsInitialized) {
return;
}
if (mTabPersistentStore != null) {
mTabPersistentStore.destroy();
mTabPersistentStore = null;
}
if (mTabModelSelector != null) {
mTabModelSelector.destroy();
mTabModelSelector = null;
}
mTabModelsInitialized = false;
}
protected void wireSelectorAndStore() {
// Supply TabModelSelectorImpl with TabPersistentStore.
//
// TODO(crbug.com/1138561): Remove this dependency by making TabModelSelectorImpl emit
// events and TabPersistentStore react to them as an observer.
ObservableSupplierImpl<TabPersistentStore> tabPersistentStoreSupplier =
new ObservableSupplierImpl<>();
tabPersistentStoreSupplier.set(mTabPersistentStore);
mTabModelSelector.setTabPersistentStoreSupplier(tabPersistentStoreSupplier);
// Notify TabModelSelectorImpl when TabPersistentStore initializes tab state
final TabPersistentStoreObserver persistentStoreObserver =
new TabPersistentStoreObserver() {
@Override
public void onStateLoaded() {
mTabModelSelector.markTabStateInitialized();
}
};
mTabPersistentStore.addObserver(persistentStoreObserver);
}
protected void markTabModelsInitialized() {
mTabModelsInitialized = true;
}
}
// Copyright 2020 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.app.tabmodel;
import android.app.Activity;
import android.os.Build;
import android.util.Pair;
import org.chromium.chrome.browser.multiwindow.MultiInstanceManager;
import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tabmodel.TabPersistencePolicy;
import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
import org.chromium.chrome.browser.tabmodel.TabbedModeTabPersistencePolicy;
import org.chromium.ui.widget.Toast;
/**
* Glue-level class that manages lifetime of root .tabmodel objects: {@link TabPersistentStore} and
* {@link TabModelSelectorImpl} for tabbed mode.
*/
public class TabbedModeTabModelOrchestrator extends TabModelOrchestrator {
public TabbedModeTabModelOrchestrator() {}
/**
* Creates the TabModelSelector and the TabPersistentStore.
*
* @return Whether the creation was successful. It may fail is we reached the limit of number of
* windows.
*/
public boolean createTabModels(Activity activity, TabCreatorManager tabCreatorManager,
NextTabPolicySupplier nextTabPolicySupplier, int selectorIndex) {
boolean mergeTabs = shouldMergeTabs(activity);
if (mergeTabs) {
MultiInstanceManager.mergedOnStartup();
}
// Instantiate TabModelSelectorImpl
Pair<Integer, TabModelSelector> selectorAssignment =
TabWindowManagerSingleton.getInstance().requestSelector(
activity, tabCreatorManager, nextTabPolicySupplier, selectorIndex);
int assignedIndex = selectorAssignment.first;
mTabModelSelector = (TabModelSelectorImpl) selectorAssignment.second;
if (mTabModelSelector == null) {
markTabModelsInitialized();
Toast.makeText(activity,
activity.getString(
org.chromium.chrome.R.string.unsupported_number_of_windows),
Toast.LENGTH_LONG)
.show();
return false;
}
// Instantiate TabPersistentStore
TabPersistencePolicy tabPersistencePolicy =
new TabbedModeTabPersistencePolicy(assignedIndex, mergeTabs);
mTabPersistentStore =
new TabPersistentStore(tabPersistencePolicy, mTabModelSelector, tabCreatorManager);
wireSelectorAndStore();
markTabModelsInitialized();
return true;
}
private boolean shouldMergeTabs(Activity activity) {
// Merge tabs if this TabModelSelector is for a ChromeTabbedActivity created in
// fullscreen mode and there are no TabModelSelector's currently alive. This indicates
// that it is a cold start or process restart in fullscreen mode.
boolean mergeTabs = Build.VERSION.SDK_INT > Build.VERSION_CODES.M
&& MultiInstanceManager.isTabModelMergingEnabled()
&& !activity.isInMultiWindowMode();
if (MultiInstanceManager.shouldMergeOnStartup(activity)) {
mergeTabs = mergeTabs
&& (!MultiWindowUtils.getInstance().isInMultiDisplayMode(activity)
|| TabWindowManagerSingleton.getInstance()
.getNumberOfAssignedTabModelSelectors()
== 0);
} else {
mergeTabs = mergeTabs
&& TabWindowManagerSingleton.getInstance()
.getNumberOfAssignedTabModelSelectors()
== 0;
}
return mergeTabs;
}
}
...@@ -24,6 +24,7 @@ import org.chromium.chrome.R; ...@@ -24,6 +24,7 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.KeyboardShortcuts; import org.chromium.chrome.browser.KeyboardShortcuts;
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.browserservices.ui.controller.Verifier; import org.chromium.chrome.browser.browserservices.ui.controller.Verifier;
import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityCoordinator; import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityCoordinator;
...@@ -45,7 +46,6 @@ import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor; ...@@ -45,7 +46,6 @@ import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabState; import org.chromium.chrome.browser.tab.TabState;
import org.chromium.chrome.browser.tabmodel.ChromeTabCreator; import org.chromium.chrome.browser.tabmodel.ChromeTabCreator;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.theme.TopUiThemeColorProvider; import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
import org.chromium.chrome.browser.ui.RootUiCoordinator; import org.chromium.chrome.browser.ui.RootUiCoordinator;
...@@ -293,8 +293,20 @@ public abstract class BaseCustomTabActivity extends ChromeActivity<BaseCustomTab ...@@ -293,8 +293,20 @@ public abstract class BaseCustomTabActivity extends ChromeActivity<BaseCustomTab
} }
@Override @Override
protected TabModelSelector createTabModelSelector() { protected TabModelOrchestrator createTabModelOrchestrator() {
return mTabFactory.createTabModelSelector(); return mTabFactory.createTabModelOrchestrator();
}
@Override
protected void destroyTabModels() {
if (mTabFactory != null) {
mTabFactory.destroyTabModelOrchestrator();
}
}
@Override
protected void createTabModels() {
mTabFactory.createTabModels();
} }
@Override @Override
......
...@@ -15,6 +15,8 @@ import org.chromium.chrome.browser.IntentHandler; ...@@ -15,6 +15,8 @@ import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
import org.chromium.chrome.browser.app.tabmodel.ChromeTabModelFilterFactory; import org.chromium.chrome.browser.app.tabmodel.ChromeTabModelFilterFactory;
import org.chromium.chrome.browser.app.tabmodel.CustomTabsTabModelOrchestrator;
import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory; import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory;
import org.chromium.chrome.browser.customtabs.CustomTabTabPersistencePolicy; import org.chromium.chrome.browser.customtabs.CustomTabTabPersistencePolicy;
...@@ -26,7 +28,6 @@ import org.chromium.chrome.browser.tab.TabDelegateFactory; ...@@ -26,7 +28,6 @@ import org.chromium.chrome.browser.tab.TabDelegateFactory;
import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager; import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
import org.chromium.chrome.browser.tabmodel.ChromeTabCreator; import org.chromium.chrome.browser.tabmodel.ChromeTabCreator;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy;
import org.chromium.chrome.browser.tabmodel.TabModelFilterFactory; import org.chromium.chrome.browser.tabmodel.TabModelFilterFactory;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
...@@ -56,7 +57,7 @@ public class CustomTabActivityTabFactory { ...@@ -56,7 +57,7 @@ public class CustomTabActivityTabFactory {
private final Lazy<AsyncTabParamsManager> mAsyncTabParamsManager; private final Lazy<AsyncTabParamsManager> mAsyncTabParamsManager;
@Nullable @Nullable
private TabModelSelectorImpl mTabModelSelector; private CustomTabsTabModelOrchestrator mTabModelOrchestrator;
@Inject @Inject
public CustomTabActivityTabFactory(ChromeActivity<?> activity, public CustomTabActivityTabFactory(ChromeActivity<?> activity,
...@@ -77,21 +78,35 @@ public class CustomTabActivityTabFactory { ...@@ -77,21 +78,35 @@ public class CustomTabActivityTabFactory {
mAsyncTabParamsManager = asyncTabParamsManager; mAsyncTabParamsManager = asyncTabParamsManager;
} }
/** Creates a {@link TabModelSelector} for the custom tab. */ /** Creates a {@link TabModelOrchestrator} for the custom tab. */
public TabModelSelectorImpl createTabModelSelector() { public TabModelOrchestrator createTabModelOrchestrator() {
mTabModelSelector = new TabModelSelectorImpl(mActivity, mActivityWindowAndroid::get, mTabModelOrchestrator = new CustomTabsTabModelOrchestrator();
mActivity, mPersistencePolicy, mTabModelFilterFactory, return mTabModelOrchestrator;
() -> NextTabPolicy.LOCATIONAL, mAsyncTabParamsManager.get(), false, false, false); }
return mTabModelSelector;
public void destroyTabModelOrchestrator() {
if (mTabModelOrchestrator != null) {
mTabModelOrchestrator.destroy();
}
}
/** Calls the {@link TabModelOrchestrator} to create TabModels and TabPersistentStore. */
public void createTabModels() {
mTabModelOrchestrator.createTabModels(mActivityWindowAndroid::get, mActivity,
mTabModelFilterFactory, mPersistencePolicy, mAsyncTabParamsManager.get());
} }
/** Returns the previously created {@link TabModelSelector}. */ /** Returns the previously created {@link TabModelSelector}. */
public TabModelSelectorImpl getTabModelSelector() { public TabModelSelectorImpl getTabModelSelector() {
if (mTabModelSelector == null) { if (mTabModelOrchestrator == null) {
assert false;
createTabModelOrchestrator();
}
if (mTabModelOrchestrator.getTabModelSelector() == null) {
assert false; assert false;
return createTabModelSelector(); createTabModels();
} }
return mTabModelSelector; return mTabModelOrchestrator.getTabModelSelector();
} }
/** Creates a {@link ChromeTabCreator}s for the custom tab. */ /** Creates a {@link ChromeTabCreator}s for the custom tab. */
......
...@@ -34,12 +34,11 @@ import org.chromium.base.test.util.Feature; ...@@ -34,12 +34,11 @@ import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
import org.chromium.chrome.browser.app.tabmodel.ChromeTabModelFilterFactory; import org.chromium.chrome.browser.app.tabmodel.ChromeTabModelFilterFactory;
import org.chromium.chrome.browser.app.tabmodel.CustomTabsTabModelOrchestrator;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.tab.MockTab; import org.chromium.chrome.browser.tab.MockTab;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabStateFileManager; import org.chromium.chrome.browser.tab.TabStateFileManager;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier;
import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl; import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
import org.chromium.chrome.browser.tabmodel.TabPersistencePolicy; import org.chromium.chrome.browser.tabmodel.TabPersistencePolicy;
...@@ -456,12 +455,11 @@ public class CustomTabTabPersistencePolicyTest { ...@@ -456,12 +455,11 @@ public class CustomTabTabPersistencePolicyTest {
CustomTabActivity activity = new CustomTabActivity(); CustomTabActivity activity = new CustomTabActivity();
ApplicationStatus.onStateChangeForTesting(activity, ActivityState.CREATED); ApplicationStatus.onStateChangeForTesting(activity, ActivityState.CREATED);
NextTabPolicySupplier nextTabPolicySupplier = () -> NextTabPolicy.LOCATIONAL; CustomTabsTabModelOrchestrator orchestrator = new CustomTabsTabModelOrchestrator();
orchestrator.createTabModels(activity::getWindowAndroid, activity,
TabModelSelectorImpl selector = new TabModelSelectorImpl(activity, new ChromeTabModelFilterFactory(), buildTestPersistencePolicy(),
activity::getWindowAndroid, activity, buildTestPersistencePolicy(), AsyncTabParamsManagerSingleton.getInstance());
new ChromeTabModelFilterFactory(), nextTabPolicySupplier, TabModelSelectorImpl selector = orchestrator.getTabModelSelector();
AsyncTabParamsManagerSingleton.getInstance(), false, false, false);
selector.initializeForTesting(normalTabModel, incognitoTabModel); selector.initializeForTesting(normalTabModel, incognitoTabModel);
ApplicationStatus.onStateChangeForTesting(activity, ActivityState.DESTROYED); ApplicationStatus.onStateChangeForTesting(activity, ActivityState.DESTROYED);
return selector; return selector;
......
...@@ -74,8 +74,7 @@ public class ContextMenuLoadUrlParamsTest { ...@@ -74,8 +74,7 @@ public class ContextMenuLoadUrlParamsTest {
public RecordingTabModelSelector(Activity activity, TabCreatorManager tabCreatorManager, public RecordingTabModelSelector(Activity activity, TabCreatorManager tabCreatorManager,
TabModelFilterFactory tabModelFilterFactory, int selectorIndex) { TabModelFilterFactory tabModelFilterFactory, int selectorIndex) {
super(activity, null, tabCreatorManager, super(null, tabCreatorManager, tabModelFilterFactory,
new TabbedModeTabPersistencePolicy(selectorIndex, false), tabModelFilterFactory,
() ()
-> NextTabPolicy.HIERARCHICAL, -> NextTabPolicy.HIERARCHICAL,
AsyncTabParamsManagerSingleton.getInstance(), false, false, false); AsyncTabParamsManagerSingleton.getInstance(), false, false, false);
......
...@@ -361,7 +361,9 @@ public class TabModelMergingTest { ...@@ -361,7 +361,9 @@ public class TabModelMergingTest {
MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStoreObserver(); MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStoreObserver();
TabModelSelectorImpl tabModelSelector = TabModelSelectorImpl tabModelSelector =
(TabModelSelectorImpl) mActivity2.getTabModelSelector(); (TabModelSelectorImpl) mActivity2.getTabModelSelector();
tabModelSelector.getTabPersistentStoreForTesting().addObserver(mockObserver); TestThreadUtils.runOnUiThreadBlocking(() -> {
tabModelSelector.getTabPersistentStoreForTesting().addObserver(mockObserver);
});
// Merge tabs into ChromeTabbedActivity2. Wait for the merge to finish, ensuring the // Merge tabs into ChromeTabbedActivity2. Wait for the merge to finish, ensuring the
// tab metadata file for ChromeTabbedActivity gets deleted before attempting to merge // tab metadata file for ChromeTabbedActivity gets deleted before attempting to merge
......
...@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout ...@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
import org.chromium.chrome.browser.app.tabmodel.ChromeTabModelFilterFactory; import org.chromium.chrome.browser.app.tabmodel.ChromeTabModelFilterFactory;
import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator;
import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton;
import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelper; import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelper;
import org.chromium.chrome.browser.flags.ActivityType; import org.chromium.chrome.browser.flags.ActivityType;
...@@ -246,10 +247,16 @@ public class TabPersistentStoreTest { ...@@ -246,10 +247,16 @@ public class TabPersistentStoreTest {
} }
@Override @Override
protected TabModelSelector createTabModelSelector() { protected TabModelOrchestrator createTabModelOrchestrator() {
return null; return null;
} }
@Override
protected void createTabModels() {}
@Override
protected void destroyTabModels() {}
@Override @Override
protected BrowserControlsManager createBrowserControlsManager() { protected BrowserControlsManager createBrowserControlsManager() {
return null; return null;
...@@ -721,8 +728,9 @@ public class TabPersistentStoreTest { ...@@ -721,8 +728,9 @@ public class TabPersistentStoreTest {
// createAndRestoreRealTabModelImpls is called multiple times in one test). // createAndRestoreRealTabModelImpls is called multiple times in one test).
sTabWindowManager.onActivityStateChange( sTabWindowManager.onActivityStateChange(
mChromeActivity, ActivityState.DESTROYED); mChromeActivity, ActivityState.DESTROYED);
return (TestTabModelSelector) sTabWindowManager.requestSelector( return (TestTabModelSelector) sTabWindowManager
mChromeActivity, mChromeActivity, null, 0); .requestSelector(mChromeActivity, mChromeActivity, null, 0)
.second;
} }
}); });
......
...@@ -8,8 +8,6 @@ import static org.mockito.ArgumentMatchers.any; ...@@ -8,8 +8,6 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import android.app.Activity;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
...@@ -17,7 +15,6 @@ import org.junit.runner.RunWith; ...@@ -17,7 +15,6 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.BaseRobolectricTestRunner;
...@@ -37,8 +34,6 @@ import org.chromium.ui.base.WindowAndroid; ...@@ -37,8 +34,6 @@ import org.chromium.ui.base.WindowAndroid;
@RunWith(BaseRobolectricTestRunner.class) @RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE) @Config(manifest = Config.NONE)
public class TabModelSelectorImplTest { public class TabModelSelectorImplTest {
@Mock
TabPersistencePolicy mMockTabPersistencePolicy;
@Mock @Mock
TabModelFilterFactory mMockTabModelFilterFactory; TabModelFilterFactory mMockTabModelFilterFactory;
@Mock @Mock
...@@ -50,27 +45,22 @@ public class TabModelSelectorImplTest { ...@@ -50,27 +45,22 @@ public class TabModelSelectorImplTest {
private TabModelSelectorImpl mTabModelSelector; private TabModelSelectorImpl mTabModelSelector;
private MockTabCreatorManager mTabCreatorManager; private MockTabCreatorManager mTabCreatorManager;
private Activity mActivity;
@Before @Before
public void setUp() { public void setUp() {
mActivity = Robolectric.buildActivity(Activity.class).setup().get();
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
doReturn(TabPersistentStore.SAVED_STATE_FILE_PREFIX)
.when(mMockTabPersistencePolicy)
.getStateFileName();
doReturn(mock(TabModelFilter.class)) doReturn(mock(TabModelFilter.class))
.when(mMockTabModelFilterFactory) .when(mMockTabModelFilterFactory)
.createTabModelFilter(any()); .createTabModelFilter(any());
mTabCreatorManager = new MockTabCreatorManager(); mTabCreatorManager = new MockTabCreatorManager();
AsyncTabParamsManager realAsyncTabParamsManager = AsyncTabParamsManager realAsyncTabParamsManager =
AsyncTabParamsManagerFactory.createAsyncTabParamsManager(); AsyncTabParamsManagerFactory.createAsyncTabParamsManager();
mTabModelSelector = new TabModelSelectorImpl(mActivity, null, mTabCreatorManager, mTabModelSelector = new TabModelSelectorImpl(null, mTabCreatorManager,
mMockTabPersistencePolicy, mMockTabModelFilterFactory, mNextTabPolicySupplier, mMockTabModelFilterFactory, mNextTabPolicySupplier, realAsyncTabParamsManager,
realAsyncTabParamsManager, /*supportUndo=*/false, /*supportUndo=*/false,
/*isTabbedActivity=*/false, /*startIncognito=*/false); /*isTabbedActivity=*/false, /*startIncognito=*/false);
mTabModelSelector.setTabPersistentStoreSupplier(() -> null);
mTabCreatorManager.initialize(mTabModelSelector); mTabCreatorManager.initialize(mTabModelSelector);
mTabModelSelector.onNativeLibraryReadyInternal(mMockTabContentManager, mTabModelSelector.onNativeLibraryReadyInternal(mMockTabContentManager,
new MockTabModel(false, null), new MockTabModel(true, null)); new MockTabModel(false, null), new MockTabModel(true, null));
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.tabmodel; package org.chromium.chrome.browser.tabmodel;
import android.app.Activity; import android.app.Activity;
import android.util.Pair;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier; import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier;
...@@ -34,11 +35,13 @@ public interface TabWindowManager { ...@@ -34,11 +35,13 @@ public interface TabWindowManager {
* @param nextTabPolicySupplier An instance of {@link NextTabPolicySupplier}. * @param nextTabPolicySupplier An instance of {@link NextTabPolicySupplier}.
* @param index The index of the requested {@link TabModelSelector}. Not guaranteed to be the * @param index The index of the requested {@link TabModelSelector}. Not guaranteed to be the
* index of the {@link TabModelSelector} returned. * index of the {@link TabModelSelector} returned.
* @return A {@link TabModelSelector} index, or {@code null} if there are too many * @return {@link Pair} of the index and the {@link TabModelSelector} assigned to that index, or
* {@code null} if there are too many
* {@link TabModelSelector}s already built. * {@link TabModelSelector}s already built.
*/ */
TabModelSelector requestSelector(Activity activity, TabCreatorManager tabCreatorManager, Pair<Integer, TabModelSelector> requestSelector(Activity activity,
NextTabPolicySupplier nextTabPolicySupplier, int index); TabCreatorManager tabCreatorManager, NextTabPolicySupplier nextTabPolicySupplier,
int index);
/** /**
* An index that represents the invalid state (i.e. when the window wasn't found in the list). * An index that represents the invalid state (i.e. when the window wasn't found in the list).
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.tabmodel; package org.chromium.chrome.browser.tabmodel;
import android.app.Activity; import android.app.Activity;
import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import org.chromium.base.ActivityState; import org.chromium.base.ActivityState;
...@@ -43,10 +44,18 @@ public class TabWindowManagerImpl implements ActivityStateListener, TabWindowMan ...@@ -43,10 +44,18 @@ public class TabWindowManagerImpl implements ActivityStateListener, TabWindowMan
} }
@Override @Override
public TabModelSelector requestSelector(Activity activity, TabCreatorManager tabCreatorManager, public Pair<Integer, TabModelSelector> requestSelector(Activity activity,
NextTabPolicySupplier nextTabPolicySupplier, int index) { TabCreatorManager tabCreatorManager, NextTabPolicySupplier nextTabPolicySupplier,
int index) {
if (mAssignments.get(activity) != null) { if (mAssignments.get(activity) != null) {
return mAssignments.get(activity); TabModelSelector assignedSelector = mAssignments.get(activity);
for (int i = 0; i < mSelectors.size(); i++) {
if (mSelectors.get(i) == assignedSelector) {
return Pair.create(i, assignedSelector);
}
}
throw new IllegalStateException(
"TabModelSelector is assigned to an Activity but has no index.");
} }
if (index < 0 || index >= mSelectors.size()) index = 0; if (index < 0 || index >= mSelectors.size()) index = 0;
...@@ -68,7 +77,7 @@ public class TabWindowManagerImpl implements ActivityStateListener, TabWindowMan ...@@ -68,7 +77,7 @@ public class TabWindowManagerImpl implements ActivityStateListener, TabWindowMan
mSelectors.set(index, selector); mSelectors.set(index, selector);
mAssignments.put(activity, selector); mAssignments.put(activity, selector);
return selector; return Pair.create(index, selector);
} }
@Override @Override
......
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