Commit 749006de authored by Sky Malice's avatar Sky Malice Committed by Chromium LUCI CQ

Revert "Reland "Create glue-layer TabModelOrchestrators""

This reverts commit ddad167d.

Reason for revert: Failing many XR/VR tests during activity initialization. See https://ci.chromium.org/ui/p/chromium/builders/ci/Nougat%20Phone%20Tester/16101/overview

Original change's description:
> 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: Ella Ge <eirage@chromium.org>
> Reviewed-by: David Trainor <dtrainor@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#843752}

TBR=dtrainor@chromium.org,eirage@chromium.org,hnakashima@chromium.org,chromium-scoped@luci-project-accounts.iam.gserviceaccount.com

Change-Id: Id6440841c48bffa2dc0f33b89bcddb36ea2f0c3c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1138561
Bug: 1158259
Bug: 1167010
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2632386Reviewed-by: default avatarSky Malice <skym@chromium.org>
Reviewed-by: default avatarNatalie Chouinard <chouinard@chromium.org>
Auto-Submit: Sky Malice <skym@chromium.org>
Commit-Queue: Natalie Chouinard <chouinard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#844070}
parent c7b95818
......@@ -84,11 +84,8 @@ chrome_java_sources = [
"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/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/TabModelOrchestrator.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/NewTabPageVideoIPHManager.java",
"java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java",
......
......@@ -60,9 +60,7 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
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.TabbedModeTabModelOrchestrator;
import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
import org.chromium.chrome.browser.compositor.bottombar.ephemeraltab.EphemeralTabCoordinator;
......@@ -249,7 +247,6 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
private ToolbarControlContainer mControlContainer;
private TabbedModeTabModelOrchestrator mTabModelOrchestrator;
private TabModelSelectorImpl mTabModelSelectorImpl;
private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
private TabModelSelectorTabModelObserver mTabModelObserver;
......@@ -1626,13 +1623,7 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
}
@Override
protected TabModelOrchestrator createTabModelOrchestrator() {
mTabModelOrchestrator = new TabbedModeTabModelOrchestrator();
return mTabModelOrchestrator;
}
@Override
protected void createTabModels() {
protected TabModelSelector createTabModelSelector() {
assert mTabModelSelectorImpl == null;
Bundle savedInstanceState = getSavedInstanceState();
......@@ -1643,15 +1634,17 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
int index = savedInstanceState != null ? savedInstanceState.getInt(WINDOW_INDEX, 0) : 0;
mNextTabPolicySupplier = new ChromeNextTabPolicySupplier(mOverviewModeBehaviorSupplier);
boolean tabModelWasCreated =
mTabModelOrchestrator.createTabModels(this, this, mNextTabPolicySupplier, index);
if (!tabModelWasCreated) {
mTabModelSelectorImpl =
(TabModelSelectorImpl) TabWindowManagerSingleton.getInstance().requestSelector(
this, this, mNextTabPolicySupplier, index);
if (mTabModelSelectorImpl == null) {
Toast.makeText(
this, getString(R.string.unsupported_number_of_windows), Toast.LENGTH_LONG)
.show();
finish();
return;
return null;
}
mTabModelSelectorImpl = mTabModelOrchestrator.getTabModelSelector();
mTabModelSelectorImpl.addObserver(new EmptyTabModelSelectorObserver() {
@Override
public void onTabStateInitialized() {
......@@ -1675,6 +1668,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
mAppIndexingUtil = new AppIndexingUtil(mTabModelSelectorImpl);
if (startIncognito) mTabModelSelectorImpl.selectModel(true);
return mTabModelSelectorImpl;
}
@Override
......@@ -2223,13 +2218,6 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
super.onDestroyInternal();
}
@Override
protected void destroyTabModels() {
if (mTabModelOrchestrator != null) {
mTabModelOrchestrator.destroy();
}
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
......
......@@ -71,7 +71,6 @@ 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.TabReparentingController;
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.BookmarkItem;
import org.chromium.chrome.browser.bookmarks.BookmarkModel;
......@@ -242,7 +241,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
new TabModelSelectorProfileSupplier(mTabModelSelectorSupplier);
protected ObservableSupplierImpl<BookmarkBridge> mBookmarkBridgeSupplier =
new ObservableSupplierImpl<>();
private TabModelOrchestrator mTabModelOrchestrator;
private TabModelSelector mTabModelSelector;
private TabModelSelectorTabObserver mTabModelSelectorTabObserver;
private TabCreator mRegularTabCreator;
private TabCreator mIncognitoTabCreator;
......@@ -264,6 +263,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
/** Whether or not {@link #postDeferredStartupIfNeeded()} has already successfully run. */
private boolean mDeferredStartupPosted;
private boolean mTabModelsInitialized;
private boolean mNativeInitialized;
private boolean mRemoveWindowBackgroundDone;
protected AccessibilityVisibilityHandler mAccessibilityVisibilityHandler;
......@@ -358,9 +358,6 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
// onPreInflationStartup event.
mComponent = createComponent();
// Create the orchestrator that manages Tab models and persistence
mTabModelOrchestrator = createTabModelOrchestrator();
// There's no corresponding call to removeObserver() for this addObserver() because
// mTabModelProfileSupplier has the same lifecycle as this activity.
mTabModelProfileSupplier.addObserver((profile) -> {
......@@ -491,10 +488,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
mCompositorViewHolder.getCompositorView());
initializeTabModels();
TabModelSelector tabModelSelector = mTabModelOrchestrator.getTabModelSelector();
setTabContentManager(new TabContentManager(this, getContentOffsetProvider(),
!SysUtils.isLowEndDevice(),
tabModelSelector != null ? tabModelSelector::getTabById : null));
mTabModelSelector != null ? mTabModelSelector::getTabById : null));
if (!isFinishing()) {
getBrowserControlsManager().initialize(
......@@ -656,28 +652,28 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* this activity.
*/
public final void initializeTabModels() {
if (mTabModelOrchestrator.areTabModelsInitialized()) return;
if (mTabModelsInitialized) return;
createTabModels();
TabModelSelector tabModelSelector = mTabModelOrchestrator.getTabModelSelector();
mTabModelSelector = createTabModelSelector();
if (tabModelSelector == null) {
if (mTabModelSelector == null) {
assert isFinishing();
mTabModelsInitialized = true;
return;
}
mTabModelSelectorSupplier.set(tabModelSelector);
mActivityTabProvider.setTabModelSelector(tabModelSelector);
getStatusBarColorController().setTabModelSelector(tabModelSelector);
mTabModelSelectorSupplier.set(mTabModelSelector);
mActivityTabProvider.setTabModelSelector(mTabModelSelector);
getStatusBarColorController().setTabModelSelector(mTabModelSelector);
Pair<? extends TabCreator, ? extends TabCreator> tabCreators = createTabCreators();
mRegularTabCreator = tabCreators.first;
mIncognitoTabCreator = tabCreators.second;
OfflinePageUtils.observeTabModelSelector(this, tabModelSelector);
OfflinePageUtils.observeTabModelSelector(this, mTabModelSelector);
if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy();
mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(tabModelSelector) {
mTabModelSelectorTabObserver = new TabModelSelectorTabObserver(mTabModelSelector) {
@Override
public void onLoadStopped(Tab tab, boolean toDifferentDocument) {
postDeferredStartupIfNeeded();
......@@ -694,6 +690,8 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
postDeferredStartupIfNeeded();
}
};
mTabModelsInitialized = true;
}
/**
......@@ -709,19 +707,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
}
/**
* @return The {@link TabModelOrchestrator} owned by this {@link ChromeActivity}.
*/
protected abstract TabModelOrchestrator createTabModelOrchestrator();
/**
* Call the {@link TabModelOrchestrator} to initialize its members.
* @return The {@link TabModelSelector} owned by this {@link ChromeActivity}.
*/
protected abstract void createTabModels();
/**
* Call the {@link TabModelOrchestrator} to destroy its members.
*/
protected abstract void destroyTabModels();
protected abstract TabModelSelector createTabModelSelector();
/**
* @return The {@link TabCreator}s owned
......@@ -860,8 +848,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
VrModuleProvider.getDelegate().onActivityHidden(this);
Tab tab = getActivityTab();
TabModelSelector tabModelSelector = mTabModelOrchestrator.getTabModelSelector();
if (tabModelSelector != null && !tabModelSelector.isReparentingInProgress()
if (mTabModelSelector != null && !mTabModelSelector.isReparentingInProgress()
&& tab != null) {
tab.hide(TabHidingType.ACTIVITY_HIDDEN);
}
......@@ -1325,7 +1312,10 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
mActivityTabStartupMetricsTracker = null;
}
destroyTabModels();
if (mTabModelsInitialized) {
TabModelSelector selector = getTabModelSelector();
if (selector != null) selector.destroy();
}
if (mBookmarkBridgeSupplier != null) {
BookmarkBridge bookmarkBridge = mBookmarkBridgeSupplier.get();
......@@ -1601,7 +1591,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* @return Whether the tab models have been fully initialized.
*/
public boolean areTabModelsInitialized() {
return mTabModelOrchestrator.areTabModelsInitialized();
return mTabModelsInitialized;
}
/**
......@@ -1610,11 +1600,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* @return The {@link TabModelSelector}, possibly null.
*/
public TabModelSelector getTabModelSelector() {
if (!mTabModelOrchestrator.areTabModelsInitialized()) {
if (!mTabModelsInitialized) {
throw new IllegalStateException(
"Attempting to access TabModelSelector before initialization");
}
return mTabModelOrchestrator.getTabModelSelector();
return mTabModelSelector;
}
/**
......@@ -1635,7 +1625,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
@Override
public TabCreator getTabCreator(boolean incognito) {
if (!mTabModelOrchestrator.areTabModelsInitialized()) {
if (!mTabModelsInitialized) {
throw new IllegalStateException(
"Attempting to access TabCreator before initialization");
}
......@@ -1702,7 +1692,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* null if the Tab does not exist or the system is not initialized.
*/
public Tab getActivityTab() {
if (!mTabModelOrchestrator.areTabModelsInitialized()) {
if (!mTabModelsInitialized) {
return null;
}
return TabModelUtils.getCurrentTab(getCurrentTabModel());
......@@ -1713,7 +1703,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
* WebContents.
*/
public WebContents getCurrentWebContents() {
if (!mTabModelOrchestrator.areTabModelsInitialized()) {
if (!mTabModelsInitialized) {
return null;
}
return TabModelUtils.getCurrentWebContents(getCurrentTabModel());
......@@ -2037,7 +2027,7 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
if (id == R.id.help_id) {
String url = currentTab != null ? currentTab.getUrlString() : "";
Profile profile = getTabModelSelector().isIncognitoSelected()
Profile profile = mTabModelSelector.isIncognitoSelected()
? Profile.getLastUsedRegularProfile().getPrimaryOTRProfile()
: Profile.getLastUsedRegularProfile();
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,15 +5,19 @@
package org.chromium.chrome.browser.app.tabmodel;
import android.app.Activity;
import android.os.Build;
import org.chromium.base.annotations.VerifiesOnN;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
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.TabModelFilterFactory;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorFactory;
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.
......@@ -25,11 +29,32 @@ public class DefaultTabModelSelectorFactory implements TabModelSelectorFactory {
@Override
public TabModelSelector buildSelector(Activity activity, TabCreatorManager tabCreatorManager,
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();
AsyncTabParamsManager asyncTabParamsManager = AsyncTabParamsManagerSingleton.getInstance();
return new TabModelSelectorImpl(/*windowAndroidSupplier=*/null, tabCreatorManager,
tabModelFilterFactory, nextTabPolicySupplier, asyncTabParamsManager, true, true,
false);
return new TabModelSelectorImpl(activity, /*windowAndroidSupplier=*/null, tabCreatorManager,
persistencePolicy, tabModelFilterFactory, nextTabPolicySupplier,
AsyncTabParamsManagerSingleton.getInstance(), 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,7 +24,6 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.KeyboardShortcuts;
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.ui.controller.Verifier;
import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityCoordinator;
......@@ -46,6 +45,7 @@ import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabState;
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.theme.TopUiThemeColorProvider;
import org.chromium.chrome.browser.ui.RootUiCoordinator;
......@@ -293,20 +293,8 @@ public abstract class BaseCustomTabActivity extends ChromeActivity<BaseCustomTab
}
@Override
protected TabModelOrchestrator createTabModelOrchestrator() {
return mTabFactory.createTabModelOrchestrator();
}
@Override
protected void destroyTabModels() {
if (mTabFactory != null) {
mTabFactory.destroyTabModelOrchestrator();
}
}
@Override
protected void createTabModels() {
mTabFactory.createTabModels();
protected TabModelSelector createTabModelSelector() {
return mTabFactory.createTabModelSelector();
}
@Override
......
......@@ -15,8 +15,6 @@ import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
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.customtabs.CustomTabDelegateFactory;
import org.chromium.chrome.browser.customtabs.CustomTabTabPersistencePolicy;
......@@ -28,6 +26,7 @@ import org.chromium.chrome.browser.tab.TabDelegateFactory;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.AsyncTabParamsManager;
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.TabModelSelector;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorImpl;
......@@ -57,7 +56,7 @@ public class CustomTabActivityTabFactory {
private final Lazy<AsyncTabParamsManager> mAsyncTabParamsManager;
@Nullable
private CustomTabsTabModelOrchestrator mTabModelOrchestrator;
private TabModelSelectorImpl mTabModelSelector;
@Inject
public CustomTabActivityTabFactory(ChromeActivity<?> activity,
......@@ -78,35 +77,21 @@ public class CustomTabActivityTabFactory {
mAsyncTabParamsManager = asyncTabParamsManager;
}
/** Creates a {@link TabModelOrchestrator} for the custom tab. */
public TabModelOrchestrator createTabModelOrchestrator() {
mTabModelOrchestrator = new CustomTabsTabModelOrchestrator();
return mTabModelOrchestrator;
}
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());
/** Creates a {@link TabModelSelector} for the custom tab. */
public TabModelSelectorImpl createTabModelSelector() {
mTabModelSelector = new TabModelSelectorImpl(mActivity, mActivityWindowAndroid::get,
mActivity, mPersistencePolicy, mTabModelFilterFactory,
() -> NextTabPolicy.LOCATIONAL, mAsyncTabParamsManager.get(), false, false, false);
return mTabModelSelector;
}
/** Returns the previously created {@link TabModelSelector}. */
public TabModelSelectorImpl getTabModelSelector() {
if (mTabModelOrchestrator == null) {
assert false;
createTabModelOrchestrator();
}
if (mTabModelOrchestrator.getTabModelSelector() == null) {
if (mTabModelSelector == null) {
assert false;
createTabModels();
return createTabModelSelector();
}
return mTabModelOrchestrator.getTabModelSelector();
return mTabModelSelector;
}
/** Creates a {@link ChromeTabCreator}s for the custom tab. */
......
......@@ -34,11 +34,12 @@ import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
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.tab.MockTab;
import org.chromium.chrome.browser.tab.Tab;
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.TabModelSelectorImpl;
import org.chromium.chrome.browser.tabmodel.TabPersistencePolicy;
......@@ -455,11 +456,12 @@ public class CustomTabTabPersistencePolicyTest {
CustomTabActivity activity = new CustomTabActivity();
ApplicationStatus.onStateChangeForTesting(activity, ActivityState.CREATED);
CustomTabsTabModelOrchestrator orchestrator = new CustomTabsTabModelOrchestrator();
orchestrator.createTabModels(activity::getWindowAndroid, activity,
new ChromeTabModelFilterFactory(), buildTestPersistencePolicy(),
AsyncTabParamsManagerSingleton.getInstance());
TabModelSelectorImpl selector = orchestrator.getTabModelSelector();
NextTabPolicySupplier nextTabPolicySupplier = () -> NextTabPolicy.LOCATIONAL;
TabModelSelectorImpl selector = new TabModelSelectorImpl(activity,
activity::getWindowAndroid, activity, buildTestPersistencePolicy(),
new ChromeTabModelFilterFactory(), nextTabPolicySupplier,
AsyncTabParamsManagerSingleton.getInstance(), false, false, false);
selector.initializeForTesting(normalTabModel, incognitoTabModel);
ApplicationStatus.onStateChangeForTesting(activity, ActivityState.DESTROYED);
return selector;
......
......@@ -74,7 +74,8 @@ public class ContextMenuLoadUrlParamsTest {
public RecordingTabModelSelector(Activity activity, TabCreatorManager tabCreatorManager,
TabModelFilterFactory tabModelFilterFactory, int selectorIndex) {
super(null, tabCreatorManager, tabModelFilterFactory,
super(activity, null, tabCreatorManager,
new TabbedModeTabPersistencePolicy(selectorIndex, false), tabModelFilterFactory,
()
-> NextTabPolicy.HIERARCHICAL,
AsyncTabParamsManagerSingleton.getInstance(), false, false, false);
......
......@@ -361,9 +361,7 @@ public class TabModelMergingTest {
MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStoreObserver();
TabModelSelectorImpl tabModelSelector =
(TabModelSelectorImpl) mActivity2.getTabModelSelector();
TestThreadUtils.runOnUiThreadBlocking(() -> {
tabModelSelector.getTabPersistentStoreForTesting().addObserver(mockObserver);
});
tabModelSelector.getTabPersistentStoreForTesting().addObserver(mockObserver);
// Merge tabs into ChromeTabbedActivity2. Wait for the merge to finish, ensuring the
// tab metadata file for ChromeTabbedActivity gets deleted before attempting to merge
......
......@@ -32,7 +32,6 @@ import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout
import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.app.tabmodel.AsyncTabParamsManagerSingleton;
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.compositor.overlays.strip.StripLayoutHelper;
import org.chromium.chrome.browser.flags.ActivityType;
......@@ -247,16 +246,10 @@ public class TabPersistentStoreTest {
}
@Override
protected TabModelOrchestrator createTabModelOrchestrator() {
protected TabModelSelector createTabModelSelector() {
return null;
}
@Override
protected void createTabModels() {}
@Override
protected void destroyTabModels() {}
@Override
protected BrowserControlsManager createBrowserControlsManager() {
return null;
......@@ -728,9 +721,8 @@ public class TabPersistentStoreTest {
// createAndRestoreRealTabModelImpls is called multiple times in one test).
sTabWindowManager.onActivityStateChange(
mChromeActivity, ActivityState.DESTROYED);
return (TestTabModelSelector) sTabWindowManager
.requestSelector(mChromeActivity, mChromeActivity, null, 0)
.second;
return (TestTabModelSelector) sTabWindowManager.requestSelector(
mChromeActivity, mChromeActivity, null, 0);
}
});
......
......@@ -8,6 +8,8 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import android.app.Activity;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
......@@ -15,6 +17,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.chromium.base.test.BaseRobolectricTestRunner;
......@@ -34,6 +37,8 @@ import org.chromium.ui.base.WindowAndroid;
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class TabModelSelectorImplTest {
@Mock
TabPersistencePolicy mMockTabPersistencePolicy;
@Mock
TabModelFilterFactory mMockTabModelFilterFactory;
@Mock
......@@ -45,22 +50,27 @@ public class TabModelSelectorImplTest {
private TabModelSelectorImpl mTabModelSelector;
private MockTabCreatorManager mTabCreatorManager;
private Activity mActivity;
@Before
public void setUp() {
mActivity = Robolectric.buildActivity(Activity.class).setup().get();
MockitoAnnotations.initMocks(this);
doReturn(TabPersistentStore.SAVED_STATE_FILE_PREFIX)
.when(mMockTabPersistencePolicy)
.getStateFileName();
doReturn(mock(TabModelFilter.class))
.when(mMockTabModelFilterFactory)
.createTabModelFilter(any());
mTabCreatorManager = new MockTabCreatorManager();
AsyncTabParamsManager realAsyncTabParamsManager =
AsyncTabParamsManagerFactory.createAsyncTabParamsManager();
mTabModelSelector = new TabModelSelectorImpl(null, mTabCreatorManager,
mMockTabModelFilterFactory, mNextTabPolicySupplier, realAsyncTabParamsManager,
/*supportUndo=*/false,
mTabModelSelector = new TabModelSelectorImpl(mActivity, null, mTabCreatorManager,
mMockTabPersistencePolicy, mMockTabModelFilterFactory, mNextTabPolicySupplier,
realAsyncTabParamsManager, /*supportUndo=*/false,
/*isTabbedActivity=*/false, /*startIncognito=*/false);
mTabModelSelector.setTabPersistentStoreSupplier(() -> null);
mTabCreatorManager.initialize(mTabModelSelector);
mTabModelSelector.onNativeLibraryReadyInternal(mMockTabContentManager,
new MockTabModel(false, null), new MockTabModel(true, null));
......
......@@ -5,7 +5,6 @@
package org.chromium.chrome.browser.tabmodel;
import android.app.Activity;
import android.util.Pair;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier;
......@@ -35,13 +34,11 @@ public interface TabWindowManager {
* @param nextTabPolicySupplier An instance of {@link NextTabPolicySupplier}.
* @param index The index of the requested {@link TabModelSelector}. Not guaranteed to be the
* index of the {@link TabModelSelector} returned.
* @return {@link Pair} of the index and the {@link TabModelSelector} assigned to that index, or
* {@code null} if there are too many
* @return A {@link TabModelSelector} index, or {@code null} if there are too many
* {@link TabModelSelector}s already built.
*/
Pair<Integer, TabModelSelector> requestSelector(Activity activity,
TabCreatorManager tabCreatorManager, NextTabPolicySupplier nextTabPolicySupplier,
int index);
TabModelSelector requestSelector(Activity activity, TabCreatorManager tabCreatorManager,
NextTabPolicySupplier nextTabPolicySupplier, int index);
/**
* An index that represents the invalid state (i.e. when the window wasn't found in the list).
......
......@@ -5,7 +5,6 @@
package org.chromium.chrome.browser.tabmodel;
import android.app.Activity;
import android.util.Pair;
import android.util.SparseArray;
import org.chromium.base.ActivityState;
......@@ -44,18 +43,10 @@ public class TabWindowManagerImpl implements ActivityStateListener, TabWindowMan
}
@Override
public Pair<Integer, TabModelSelector> requestSelector(Activity activity,
TabCreatorManager tabCreatorManager, NextTabPolicySupplier nextTabPolicySupplier,
int index) {
public TabModelSelector requestSelector(Activity activity, TabCreatorManager tabCreatorManager,
NextTabPolicySupplier nextTabPolicySupplier, int index) {
if (mAssignments.get(activity) != null) {
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.");
return mAssignments.get(activity);
}
if (index < 0 || index >= mSelectors.size()) index = 0;
......@@ -77,7 +68,7 @@ public class TabWindowManagerImpl implements ActivityStateListener, TabWindowMan
mSelectors.set(index, selector);
mAssignments.put(activity, selector);
return Pair.create(index, selector);
return selector;
}
@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