Commit 3ddb9b70 authored by Henrique Nakashima's avatar Henrique Nakashima Committed by Commit Bot

Use IncognitoTabModelObserver to break IncognitoTabModel->.incognito

Two new classes IncognitoNotificationPresenceController and
IncognitoProfileDestroyer now bind the TabModelSelector to the
.incognito package, controlling respectively the incognito notification
and the incognito Profile destruction.

Since TabModelSelectorBase creates the TabModels only after native load,
it acts as a relay for the events. It is changed to recognize that there
are two TabModels, one normal and one incognito, so it can observe the
incognito one.

Splitting IncognitoTabModel into interface and impl keeps tests from
having to depend on IncognitoTabModelImpl.

Bug: 1109013
Change-Id: I697f8422777ec42b44ddf19af8abb82702e136a2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2343790
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarMei Liang <meiliang@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798298}
parent 2d66c06a
......@@ -809,7 +809,9 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGenerator.java",
"java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java",
"java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationManager.java",
"java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationPresenceController.java",
"java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java",
"java/src/org/chromium/chrome/browser/incognito/IncognitoProfileDestroyer.java",
"java/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncher.java",
"java/src/org/chromium/chrome/browser/incognito/IncognitoTabSnapshotController.java",
"java/src/org/chromium/chrome/browser/incognito/IncognitoUtils.java",
......@@ -1537,7 +1539,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java",
"java/src/org/chromium/chrome/browser/tabmodel/AsyncTabParamsManager.java",
"java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java",
"java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java",
"java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImpl.java",
"java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelImplCreator.java",
"java/src/org/chromium/chrome/browser/tabmodel/TabModelDelegate.java",
"java/src/org/chromium/chrome/browser/tabmodel/TabModelImpl.java",
......
......@@ -91,6 +91,8 @@ import org.chromium.chrome.browser.gsa.GSAAccountChangeListener;
import org.chromium.chrome.browser.gsa.GSAState;
import org.chromium.chrome.browser.help.HelpAndFeedback;
import org.chromium.chrome.browser.history.HistoryManagerUtils;
import org.chromium.chrome.browser.incognito.IncognitoNotificationPresenceController;
import org.chromium.chrome.browser.incognito.IncognitoProfileDestroyer;
import org.chromium.chrome.browser.init.AsyncInitializationActivity;
import org.chromium.chrome.browser.init.ProcessInitializationHandler;
import org.chromium.chrome.browser.init.StartupTabPreloader;
......@@ -620,6 +622,8 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
mIncognitoTabCreator = tabCreators.second;
OfflinePageUtils.observeTabModelSelector(this, mTabModelSelector);
IncognitoProfileDestroyer.observeTabModelSelector(mTabModelSelector);
IncognitoNotificationPresenceController.observeTabModelSelector(mTabModelSelector);
if (mTabModelSelectorTabObserver != null) mTabModelSelectorTabObserver.destroy();
......
// 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.incognito;
import org.chromium.chrome.browser.tabmodel.IncognitoTabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
/**
* Controls the presence incognito notification through {@link IncognitoNotificationManager}.
*
* Reacts to the presence or absence of incognito tabs.
*/
public class IncognitoNotificationPresenceController implements IncognitoTabModelObserver {
/**
* Creates an {@link IncognitoNotificationPresenceController} that reacts to incognito tabs in a
* given |tabModelSelector|.
* @param tabModelSelector The {@link TabModelSelector} to observe
*/
public static void observeTabModelSelector(TabModelSelector tabModelSelector) {
tabModelSelector.addIncognitoTabModelObserver(
new IncognitoNotificationPresenceController());
}
IncognitoNotificationPresenceController() {}
@Override
public void wasFirstTabCreated() {
IncognitoNotificationManager.showIncognitoNotification();
}
@Override
public void didBecomeEmpty() {
if (!IncognitoUtils.doIncognitoTabsExist()) {
IncognitoNotificationManager.dismissIncognitoNotification();
}
}
}
// 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.incognito;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tabmodel.IncognitoTabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
/**
* Destroys incognito {@link Profile}s when the last incognito tab is destroyed.
*
* Reacts to the presence or absence of incognito tabs.
*/
public class IncognitoProfileDestroyer implements IncognitoTabModelObserver {
private final TabModelSelector mTabModelSelector;
/**
* Creates an {@link IncognitoProfileDestroyer} that reacts to incognito tabs in a
* given |tabModelSelector|.
* @param tabModelSelector The {@link TabModelSelector} to observe
*/
public static void observeTabModelSelector(TabModelSelector tabModelSelector) {
tabModelSelector.addIncognitoTabModelObserver(
new IncognitoProfileDestroyer(tabModelSelector));
}
IncognitoProfileDestroyer(TabModelSelector tabModelSelector) {
mTabModelSelector = tabModelSelector;
}
@Override
public void didBecomeEmpty() {
if (!IncognitoUtils.doIncognitoTabsExist()) {
// Only delete the incognito profile if there are no incognito tabs open in any tab
// model selector as the profile is shared between them.
Profile profile = mTabModelSelector.getModel(true).getProfile();
if (profile != null) {
profile.destroyWhenAppropriate();
}
}
}
}
......@@ -6,7 +6,6 @@ package org.chromium.chrome.browser.tabmodel;
import org.chromium.base.ObserverList;
import org.chromium.base.ThreadUtils;
import org.chromium.chrome.browser.incognito.IncognitoNotificationManager;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab.TabCreationState;
......@@ -27,15 +26,12 @@ import java.util.List;
* no Tabs remain, the native model will be destroyed and only rebuilt when a new incognito Tab
* is created.
*/
public class IncognitoTabModel implements TabModel {
public class IncognitoTabModelImpl implements IncognitoTabModel {
/** Creates TabModels for use in IncognitoModel. */
public interface IncognitoTabModelDelegate {
/** Creates a fully working TabModel to delegate calls to. */
TabModel createTabModel();
/** @return Whether Incognito Tabs exist. */
boolean doIncognitoTabsExist();
/**
* @param model {@link TabModel} to act on.
* @return Whether the provided {@link TabModel} is currently selected in the corresponding
......@@ -45,14 +41,16 @@ public class IncognitoTabModel implements TabModel {
}
private final IncognitoTabModelDelegate mDelegate;
private final ObserverList<TabModelObserver> mObservers = new ObserverList<TabModelObserver>();
private final ObserverList<TabModelObserver> mObservers = new ObserverList<>();
private final ObserverList<IncognitoTabModelObserver> mIncognitoObservers =
new ObserverList<>();
private TabModel mDelegateModel;
private boolean mIsAddingTab;
/**
* Constructor for IncognitoTabModel.
*/
public IncognitoTabModel(IncognitoTabModelDelegate tabModelCreator) {
public IncognitoTabModelImpl(IncognitoTabModelDelegate tabModelCreator) {
mDelegate = tabModelCreator;
mDelegateModel = EmptyTabModel.getInstance();
}
......@@ -64,23 +62,18 @@ public class IncognitoTabModel implements TabModel {
ThreadUtils.assertOnUiThread();
if (!(mDelegateModel instanceof EmptyTabModel)) return;
IncognitoNotificationManager.showIncognitoNotification();
mDelegateModel = mDelegate.createTabModel();
for (TabModelObserver observer : mObservers) {
mDelegateModel.addObserver(observer);
}
for (IncognitoTabModelObserver observer : mIncognitoObservers) {
observer.wasFirstTabCreated();
}
}
/**
* @return The TabModel that this {@link IncognitoTabModel} is delegating calls to.
*/
protected TabModel getDelegateModel() {
return mDelegateModel;
}
/**
* Destroys the Incognito profile when all Incognito tabs have been closed. Also resets the
* delegate TabModel to be a stub EmptyTabModel.
* Resets the delegate TabModel to be a stub EmptyTabModel and notifies
* {@link IncognitoTabModelObserver}s.
*/
protected void destroyIncognitoIfNecessary() {
ThreadUtils.assertOnUiThread();
......@@ -88,15 +81,10 @@ public class IncognitoTabModel implements TabModel {
return;
}
Profile profile = getProfile();
mDelegateModel.destroy();
// Only delete the incognito profile if there are no incognito tabs open in any tab
// model selector as the profile is shared between them.
if (profile != null && !mDelegate.doIncognitoTabsExist()) {
IncognitoNotificationManager.dismissIncognitoNotification();
profile.destroyWhenAppropriate();
for (IncognitoTabModelObserver observer : mIncognitoObservers) {
observer.didBecomeEmpty();
}
mDelegateModel = EmptyTabModel.getInstance();
......@@ -262,6 +250,16 @@ public class IncognitoTabModel implements TabModel {
mDelegateModel.removeObserver(observer);
}
@Override
public void addIncognitoObserver(IncognitoTabModelObserver observer) {
mIncognitoObservers.addObserver(observer);
}
@Override
public void removeIncognitoObserver(IncognitoTabModelObserver observer) {
mIncognitoObservers.removeObserver(observer);
}
@Override
public void removeTab(Tab tab) {
mDelegateModel.removeTab(tab);
......@@ -271,6 +269,5 @@ public class IncognitoTabModel implements TabModel {
}
@Override
public void openMostRecentlyClosedTab() {
}
public void openMostRecentlyClosedTab() {}
}
......@@ -5,8 +5,7 @@
package org.chromium.chrome.browser.tabmodel;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.incognito.IncognitoUtils;
import org.chromium.chrome.browser.tabmodel.IncognitoTabModel.IncognitoTabModelDelegate;
import org.chromium.chrome.browser.tabmodel.IncognitoTabModelImpl.IncognitoTabModelDelegate;
import org.chromium.chrome.browser.tabmodel.NextTabPolicy.NextTabPolicySupplier;
/**
......@@ -24,10 +23,10 @@ class IncognitoTabModelImplCreator implements IncognitoTabModelDelegate {
private final TabModelDelegate mModelDelegate;
/**
* Constructor for an IncognitoTabModelImplCreator, used by {@link IncognitoTabModel}.
* Constructor for an IncognitoTabModelImplCreator, used by {@link IncognitoTabModelImpl}.
*
* Creating an instance of this class does not create the Incognito TabModelImpl immediately.
* The {@link IncognitoTabModel} will use this class to create the real TabModelImpl when it
* The {@link IncognitoTabModelImpl} will use this class to create the real TabModelImpl when it
* will actually be used.
* @param regularTabCreator Creates regular tabs.
* @param incognitoTabCreator Creates incognito tabs.
......@@ -62,11 +61,6 @@ class IncognitoTabModelImplCreator implements IncognitoTabModelDelegate {
mAsyncTabParamsManager, mModelDelegate, false);
}
@Override
public boolean doIncognitoTabsExist() {
return IncognitoUtils.doIncognitoTabsExist();
}
@Override
public boolean isCurrentModel(TabModel model) {
return mModelDelegate.isCurrentModel(model);
......
......@@ -12,18 +12,18 @@ import org.chromium.chrome.browser.tab.TabSelectionType;
import org.chromium.content_public.browser.LoadUrlParams;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Implement methods shared across the different model implementations.
*/
public abstract class TabModelSelectorBase implements TabModelSelector {
public abstract class TabModelSelectorBase implements TabModelSelector, IncognitoTabModelObserver {
private static final int MODEL_NOT_FOUND = -1;
private static TabModelSelectorObserver sObserver;
private List<TabModel> mTabModels = new ArrayList<>();
private IncognitoTabModel mIncognitoTabModel;
/**
* This is a dummy implementation intended to stub out TabModelFilterProvider before native is
......@@ -34,6 +34,8 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
private final TabModelFilterFactory mTabModelFilterFactory;
private int mActiveModelIndex;
private final ObserverList<TabModelSelectorObserver> mObservers = new ObserverList<>();
private final ObserverList<IncognitoTabModelObserver> mIncognitoObservers =
new ObserverList<>();
private boolean mTabStateInitialized;
private boolean mStartIncognito;
private boolean mReparentingInProgress;
......@@ -47,12 +49,13 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
mStartIncognito = startIncognito;
}
protected final void initialize(TabModel... models) {
protected final void initialize(TabModel normalModel, IncognitoTabModel incognitoModel) {
// Only normal and incognito supported for now.
assert mTabModels.isEmpty();
assert models.length > 0;
Collections.addAll(mTabModels, models);
mTabModels.add(normalModel);
mTabModels.add(incognitoModel);
mIncognitoTabModel = incognitoModel;
mActiveModelIndex = getModelIndex(mStartIncognito);
assert mActiveModelIndex != MODEL_NOT_FOUND;
mTabModelFilterProvider = new TabModelFilterProvider(mTabModelFilterFactory, mTabModels);
......@@ -83,6 +86,8 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
addObserver(sObserver);
}
mIncognitoTabModel.addIncognitoObserver(this);
notifyChanged();
}
......@@ -261,6 +266,10 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
public void destroy() {
removeObserver(mTabModelFilterProvider);
mTabModelFilterProvider.destroy();
if (mIncognitoTabModel != null) {
mIncognitoTabModel.removeIncognitoObserver(this);
}
for (int i = 0; i < getModels().size(); i++) mTabModels.get(i).destroy();
mTabModels.clear();
}
......@@ -278,7 +287,7 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
/**
* Notifies all the listeners that a new tab has been created.
* @param tab The tab that has been created.
* @param creationSTate How the tab was created.
* @param creationState How the tab was created.
*/
private void notifyNewTabCreated(Tab tab, @TabCreationState int creationState) {
for (TabModelSelectorObserver listener : mObservers) {
......@@ -299,4 +308,23 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
public boolean isReparentingInProgress() {
return mReparentingInProgress;
}
@Override
public void addIncognitoTabModelObserver(IncognitoTabModelObserver incognitoObserver) {
mIncognitoObservers.addObserver(incognitoObserver);
}
@Override
public void wasFirstTabCreated() {
for (IncognitoTabModelObserver observer : mIncognitoObservers) {
observer.wasFirstTabCreated();
}
}
@Override
public void didBecomeEmpty() {
for (IncognitoTabModelObserver observer : mIncognitoObservers) {
observer.didBecomeEmpty();
}
}
}
......@@ -128,20 +128,21 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod
(ChromeTabCreator) getTabCreatorManager().getTabCreator(false);
ChromeTabCreator incognitoTabCreator =
(ChromeTabCreator) getTabCreatorManager().getTabCreator(true);
TabModelImpl normalModel = new TabModelImpl(false, mIsTabbedActivityForSync,
regularTabCreator, incognitoTabCreator, mUma, mOrderController, mTabContentManager,
mTabSaver, mNextTabPolicySupplier, mAsyncTabParamsManager, this, mIsUndoSupported);
TabModel incognitoModel = new IncognitoTabModel(new IncognitoTabModelImplCreator(
regularTabCreator, incognitoTabCreator, mUma, mOrderController, mTabContentManager,
mTabSaver, mNextTabPolicySupplier, mAsyncTabParamsManager, this));
TabModel normalModel = new TabModelImpl(false, mIsTabbedActivityForSync, regularTabCreator,
incognitoTabCreator, mUma, mOrderController, mTabContentManager, mTabSaver,
mNextTabPolicySupplier, mAsyncTabParamsManager, this, mIsUndoSupported);
IncognitoTabModel incognitoModel =
new IncognitoTabModelImpl(new IncognitoTabModelImplCreator(regularTabCreator,
incognitoTabCreator, mUma, mOrderController, mTabContentManager, mTabSaver,
mNextTabPolicySupplier, mAsyncTabParamsManager, this));
regularTabCreator.setTabModel(normalModel, mOrderController);
incognitoTabCreator.setTabModel(incognitoModel, mOrderController);
onNativeLibraryReadyInternal(tabContentProvider, normalModel, incognitoModel);
}
@VisibleForTesting
void onNativeLibraryReadyInternal(
TabContentManager tabContentProvider, TabModel normalModel, TabModel incognitoModel) {
void onNativeLibraryReadyInternal(TabContentManager tabContentProvider, TabModel normalModel,
IncognitoTabModel incognitoModel) {
mTabContentManager = tabContentProvider;
initialize(normalModel, incognitoModel);
mTabSaver.setTabContentManager(mTabContentManager);
......@@ -226,7 +227,7 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod
* @param incognitoModel The incognito tab model.
*/
@VisibleForTesting
public void initializeForTesting(TabModel normalModel, TabModel incognitoModel) {
public void initializeForTesting(TabModel normalModel, IncognitoTabModel incognitoModel) {
initialize(normalModel, incognitoModel);
}
......
......@@ -28,7 +28,7 @@ import java.util.Set;
public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule {
private TabModelSelectorBase mSelector;
private TabModelSelectorTestTabModel mNormalTabModel;
private TabModelSelectorTestTabModel mIncognitoTabModel;
private TabModelSelectorTestIncognitoTabModel mIncognitoTabModel;
public TabModelSelectorBase getSelector() {
return mSelector;
......@@ -38,7 +38,7 @@ public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule {
return mNormalTabModel;
}
public TabModelSelectorTestTabModel getIncognitoTabModel() {
public TabModelSelectorTestIncognitoTabModel getIncognitoTabModel() {
return mIncognitoTabModel;
}
......@@ -121,7 +121,7 @@ public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule {
tabPersistentStore, nextTabPolicySupplier, asyncTabParamsManager, delegate);
mIncognitoTabModel =
new TabModelSelectorTestTabModel(true, orderController, tabContentManager,
new TabModelSelectorTestIncognitoTabModel(orderController, tabContentManager,
tabPersistentStore, nextTabPolicySupplier, asyncTabParamsManager, delegate);
mSelector.initialize(mNormalTabModel, mIncognitoTabModel);
......@@ -158,4 +158,24 @@ public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule {
return mObserverSet;
}
}
/**
* Test IncognitoTabModel that exposes the needed capabilities for testing.
*/
public static class TabModelSelectorTestIncognitoTabModel
extends TabModelSelectorTestTabModel implements IncognitoTabModel {
public TabModelSelectorTestIncognitoTabModel(TabModelOrderController orderController,
TabContentManager tabContentManager, TabPersistentStore tabPersistentStore,
NextTabPolicySupplier nextTabPolicySupplier,
AsyncTabParamsManager asyncTabParamsManager, TabModelDelegate modelDelegate) {
super(true, orderController, tabContentManager, tabPersistentStore,
nextTabPolicySupplier, asyncTabParamsManager, modelDelegate);
}
@Override
public void addIncognitoObserver(IncognitoTabModelObserver observer) {}
@Override
public void removeIncognitoObserver(IncognitoTabModelObserver observer) {}
}
}
......@@ -119,12 +119,14 @@ public class TabPersistentStoreTest {
AsyncTabParamsManager.getInstance(), TestTabModelSelector.this, true);
}
};
TabModelImpl regularTabModel = TestThreadUtils.runOnUiThreadBlocking(callable);
TabModel incognitoTabModel = new IncognitoTabModel(new IncognitoTabModelImplCreator(
getTabCreatorManager().getTabCreator(false),
getTabCreatorManager().getTabCreator(true), null, mTabModelOrderController,
null, mTabPersistentStore,
() -> NextTabPolicy.HIERARCHICAL, AsyncTabParamsManager.getInstance(), this));
TabModel regularTabModel = TestThreadUtils.runOnUiThreadBlocking(callable);
IncognitoTabModel incognitoTabModel = new IncognitoTabModelImpl(
new IncognitoTabModelImplCreator(getTabCreatorManager().getTabCreator(false),
getTabCreatorManager().getTabCreator(true), null,
mTabModelOrderController, null, mTabPersistentStore,
()
-> NextTabPolicy.HIERARCHICAL,
AsyncTabParamsManager.getInstance(), this));
initialize(regularTabModel, incognitoTabModel);
}
......
......@@ -14,6 +14,8 @@ android_library("java") {
"android/java/src/org/chromium/chrome/browser/tabmodel/EmptyTabModelSelectorObserver.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHost.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabHostRegistry.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModel.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/IncognitoTabModelObserver.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/NextTabPolicy.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/TabCreator.java",
"android/java/src/org/chromium/chrome/browser/tabmodel/TabCreatorManager.java",
......
// 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.tabmodel;
/**
* A {@link TabModel} which also emits events relevant to incognito tabs.
*/
public interface IncognitoTabModel extends TabModel {
/**
* Subscribes an {@link IncognitoTabModelObserver} to be notified about incognito events.
* @param observer The observer to be subscribed.
*/
void addIncognitoObserver(IncognitoTabModelObserver observer);
/**
* Unsubscribes an {@link IncognitoTabModelObserver}.
* @param observer The observer to be unsubscribed.
*/
void removeIncognitoObserver(IncognitoTabModelObserver observer);
}
// 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.tabmodel;
/**
* An observer of {@link IncognitoTabModel} that receives events relevant to incognito tabs.
*/
public interface IncognitoTabModelObserver {
/**
* Called when the first tab of the {@link IncognitoTabModel} is created.
*/
default void wasFirstTabCreated() {}
/**
* Called when the last tab of the {@link IncognitoTabModel} is closed.
*/
default void didBecomeEmpty() {}
}
......@@ -179,6 +179,14 @@ public interface TabModelSelector {
/** Returns whether reparenting is in progress. */
boolean isReparentingInProgress();
/**
* Subscribe an {@link IncognitoTabModelObserver} to events that the {@link IncognitoTabModel}
* in this selector emits. The model could be observed directly, but observing the
* selector allows an observer to subscribe itself before the model is created.
* @param incognitoObserver The observer to subscribe.
*/
void addIncognitoTabModelObserver(IncognitoTabModelObserver incognitoObserver);
/**
* Destroy all owned {@link TabModel}s and {@link Tab}s referenced by this selector.
*/
......
......@@ -11,6 +11,8 @@ import org.chromium.chrome.browser.tab.TabCreationState;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tab.TabSelectionType;
import org.chromium.chrome.browser.tabmodel.EmptyTabModel;
import org.chromium.chrome.browser.tabmodel.IncognitoTabModel;
import org.chromium.chrome.browser.tabmodel.IncognitoTabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelObserver;
......@@ -19,7 +21,7 @@ import java.util.ArrayList;
/**
* Almost empty implementation to mock a TabModel. It only handles tab creation and queries.
*/
public class MockTabModel extends EmptyTabModel {
public class MockTabModel extends EmptyTabModel implements IncognitoTabModel {
/**
* Used to create different kinds of Tabs. If a MockTabModelDelegate is not provided, regular
* Tabs are produced.
......@@ -114,4 +116,10 @@ public class MockTabModel extends EmptyTabModel {
public void removeObserver(TabModelObserver observer) {
mObservers.removeObserver(observer);
}
@Override
public void addIncognitoObserver(IncognitoTabModelObserver observer) {}
@Override
public void removeIncognitoObserver(IncognitoTabModelObserver observer) {}
}
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