Commit 7293c74a authored by Michael Thiessen's avatar Michael Thiessen Committed by Commit Bot

Fix crash when starting in incognito mode.

https://chromium-review.googlesource.com/c/chromium/src/+/1749845
inadvertently removed the ability to change the current tab model
before tab models have been initialized. This CL fixes that by
refactoring how initial incognito state is set when the
tabmodelselector is initialized.

Bug: 995680
Change-Id: I1136d1365078db50decd5868f12445bdbfad65a6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1761485
Commit-Queue: Michael Thiessen <mthiesse@chromium.org>
Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#688699}
parent 7d3083d0
...@@ -58,8 +58,8 @@ public class CustomTabActivityTabFactory { ...@@ -58,8 +58,8 @@ public class CustomTabActivityTabFactory {
/** Creates a {@link TabModelSelector} for the custom tab. */ /** Creates a {@link TabModelSelector} for the custom tab. */
public TabModelSelectorImpl createTabModelSelector() { public TabModelSelectorImpl createTabModelSelector() {
mTabModelSelector = mTabModelSelector = new TabModelSelectorImpl(
new TabModelSelectorImpl(mActivity, mActivity, mPersistencePolicy, false, false); mActivity, mActivity, mPersistencePolicy, false, false, false);
return mTabModelSelector; return mTabModelSelector;
} }
......
...@@ -14,8 +14,8 @@ import org.chromium.chrome.browser.tab.Tab; ...@@ -14,8 +14,8 @@ import org.chromium.chrome.browser.tab.Tab;
public class SingleTabModelSelector extends TabModelSelectorBase { public class SingleTabModelSelector extends TabModelSelectorBase {
public SingleTabModelSelector( public SingleTabModelSelector(
Activity activity, TabCreatorManager tabCreatorManager, boolean incognito) { Activity activity, TabCreatorManager tabCreatorManager, boolean incognito) {
super(tabCreatorManager); super(tabCreatorManager, incognito);
initialize(incognito, new SingleTabModel(activity, incognito)); initialize(new SingleTabModel(activity, incognito));
TabModelObserver tabModelObserver = new EmptyTabModelObserver() { TabModelObserver tabModelObserver = new EmptyTabModelObserver() {
@Override @Override
......
...@@ -30,23 +30,24 @@ public abstract class TabModelSelectorBase implements TabModelSelector { ...@@ -30,23 +30,24 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
private TabModelFilterProvider mTabModelFilterProvider = new TabModelFilterProvider(); private TabModelFilterProvider mTabModelFilterProvider = new TabModelFilterProvider();
private int mActiveModelIndex; private int mActiveModelIndex;
private final ObserverList<TabModelSelectorObserver> mObservers = private final ObserverList<TabModelSelectorObserver> mObservers = new ObserverList<>();
new ObserverList<TabModelSelectorObserver>();
private boolean mTabStateInitialized; private boolean mTabStateInitialized;
private boolean mStartIncognito;
private final TabCreatorManager mTabCreatorManager; private final TabCreatorManager mTabCreatorManager;
protected TabModelSelectorBase(TabCreatorManager tabCreatorManager) { protected TabModelSelectorBase(TabCreatorManager tabCreatorManager, boolean startIncognito) {
mTabCreatorManager = tabCreatorManager; mTabCreatorManager = tabCreatorManager;
mStartIncognito = startIncognito;
} }
protected final void initialize(boolean startIncognito, TabModel... models) { protected final void initialize(TabModel... models) {
// Only normal and incognito supported for now. // Only normal and incognito supported for now.
assert mTabModels.isEmpty(); assert mTabModels.isEmpty();
assert models.length > 0; assert models.length > 0;
Collections.addAll(mTabModels, models); Collections.addAll(mTabModels, models);
mActiveModelIndex = getModelIndex(startIncognito); mActiveModelIndex = getModelIndex(mStartIncognito);
assert mActiveModelIndex != MODEL_NOT_FOUND; assert mActiveModelIndex != MODEL_NOT_FOUND;
mTabModelFilterProvider = new TabModelFilterProvider(mTabModels); mTabModelFilterProvider = new TabModelFilterProvider(mTabModels);
...@@ -84,6 +85,10 @@ public abstract class TabModelSelectorBase implements TabModelSelector { ...@@ -84,6 +85,10 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
@Override @Override
public void selectModel(boolean incognito) { public void selectModel(boolean incognito) {
if (mTabModels.size() == 0) {
mStartIncognito = incognito;
return;
}
int newIndex = getModelIndex(incognito); int newIndex = getModelIndex(incognito);
assert newIndex != MODEL_NOT_FOUND; assert newIndex != MODEL_NOT_FOUND;
if (newIndex == mActiveModelIndex) return; if (newIndex == mActiveModelIndex) return;
...@@ -150,6 +155,7 @@ public abstract class TabModelSelectorBase implements TabModelSelector { ...@@ -150,6 +155,7 @@ public abstract class TabModelSelectorBase implements TabModelSelector {
@Override @Override
public boolean isIncognitoSelected() { public boolean isIncognitoSelected() {
if (mTabModels.size() == 0) return mStartIncognito;
return getCurrentModel().isIncognito(); return getCurrentModel().isIncognito();
} }
......
...@@ -57,8 +57,9 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod ...@@ -57,8 +57,9 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod
* @param supportUndo Whether a tab closure can be undone. * @param supportUndo Whether a tab closure can be undone.
*/ */
public TabModelSelectorImpl(Activity activity, TabCreatorManager tabCreatorManager, public TabModelSelectorImpl(Activity activity, TabCreatorManager tabCreatorManager,
TabPersistencePolicy persistencePolicy, boolean supportUndo, boolean isTabbedActivity) { TabPersistencePolicy persistencePolicy, boolean supportUndo, boolean isTabbedActivity,
super(tabCreatorManager); boolean startIncognito) {
super(tabCreatorManager, startIncognito);
mUma = new TabModelSelectorUma(activity); mUma = new TabModelSelectorUma(activity);
final TabPersistentStoreObserver persistentStoreObserver = final TabPersistentStoreObserver persistentStoreObserver =
new TabPersistentStoreObserver() { new TabPersistentStoreObserver() {
...@@ -126,7 +127,7 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod ...@@ -126,7 +127,7 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod
TabModel incognitoModel = new IncognitoTabModel(new IncognitoTabModelImplCreator( TabModel incognitoModel = new IncognitoTabModel(new IncognitoTabModelImplCreator(
regularTabCreator, incognitoTabCreator, mUma, mOrderController, regularTabCreator, incognitoTabCreator, mUma, mOrderController,
mTabContentManager, mTabSaver, this)); mTabContentManager, mTabSaver, this));
initialize(isIncognitoSelected(), normalModel, incognitoModel); initialize(normalModel, incognitoModel);
regularTabCreator.setTabModel(normalModel, mOrderController); regularTabCreator.setTabModel(normalModel, mOrderController);
incognitoTabCreator.setTabModel(incognitoModel, mOrderController); incognitoTabCreator.setTabModel(incognitoModel, mOrderController);
mTabSaver.setTabContentManager(mTabContentManager); mTabSaver.setTabContentManager(mTabContentManager);
...@@ -208,7 +209,7 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod ...@@ -208,7 +209,7 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod
*/ */
@VisibleForTesting @VisibleForTesting
public void initializeForTesting(TabModel normalModel, TabModel incognitoModel) { public void initializeForTesting(TabModel normalModel, TabModel incognitoModel) {
initialize(isIncognitoSelected(), normalModel, incognitoModel); initialize(normalModel, incognitoModel);
} }
@Override @Override
......
...@@ -218,7 +218,7 @@ public class TabWindowManager implements ActivityStateListener { ...@@ -218,7 +218,7 @@ public class TabWindowManager implements ActivityStateListener {
TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePolicy( TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePolicy(
selectorIndex, mergeTabs); selectorIndex, mergeTabs);
return new TabModelSelectorImpl( return new TabModelSelectorImpl(
activity, tabCreatorManager, persistencePolicy, true, true); activity, tabCreatorManager, persistencePolicy, true, true, false);
} }
} }
} }
...@@ -463,7 +463,7 @@ public class CustomTabTabPersistencePolicyTest { ...@@ -463,7 +463,7 @@ public class CustomTabTabPersistencePolicyTest {
CustomTabActivity activity = new CustomTabActivity(); CustomTabActivity activity = new CustomTabActivity();
ApplicationStatus.onStateChangeForTesting(activity, ActivityState.CREATED); ApplicationStatus.onStateChangeForTesting(activity, ActivityState.CREATED);
TabModelSelectorImpl selector = new TabModelSelectorImpl( TabModelSelectorImpl selector = new TabModelSelectorImpl(
activity, activity, buildTestPersistencePolicy(), false, false); activity, activity, buildTestPersistencePolicy(), 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;
......
...@@ -81,7 +81,7 @@ public class ContextMenuLoadUrlParamsTest { ...@@ -81,7 +81,7 @@ public class ContextMenuLoadUrlParamsTest {
public RecordingTabModelSelector( public RecordingTabModelSelector(
Activity activity, TabCreatorManager tabCreatorManager, int selectorIndex) { Activity activity, TabCreatorManager tabCreatorManager, int selectorIndex) {
super(activity, tabCreatorManager, super(activity, tabCreatorManager,
new TabbedModeTabPersistencePolicy(selectorIndex, false), false, false); new TabbedModeTabPersistencePolicy(selectorIndex, false), false, false, false);
} }
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.tabmodel; package org.chromium.chrome.browser.tabmodel;
import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import org.junit.Assert; import org.junit.Assert;
...@@ -16,10 +17,14 @@ import org.chromium.base.test.util.CommandLineFlags; ...@@ -16,10 +17,14 @@ import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.RetryOnFailure; import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ChromeTabbedActivity;
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.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.ApplicationTestUtils;
import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils;
/** /**
...@@ -70,4 +75,19 @@ public class IncognitoTabModelTest { ...@@ -70,4 +75,19 @@ public class IncognitoTabModelTest {
createTabOnUiThread(); createTabOnUiThread();
Assert.assertEquals(1, mTabModel.getCount()); Assert.assertEquals(1, mTabModel.getCount());
} }
@Test
@MediumTest
@Feature({"OffTheRecord"})
public void testRecreateInIncognito() {
createTabOnUiThread();
// Need to wait for contentsState to be initialized for the tab to restore correctly.
CriteriaHelper.pollUiThread(() -> {
return TabState.from(mActivityTestRule.getActivity().getActivityTab()).contentsState
!= null;
});
ChromeTabbedActivity newActivity =
ApplicationTestUtils.recreateActivity(mActivityTestRule.getActivity());
CriteriaHelper.pollUiThread(() -> newActivity.getTabModelSelector().isIncognitoSelected());
}
} }
...@@ -67,7 +67,7 @@ public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule { ...@@ -67,7 +67,7 @@ public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule {
.getTargetContext() .getTargetContext()
.getApplicationContext()); .getApplicationContext());
mSelector = new TabModelSelectorBase(null) { mSelector = new TabModelSelectorBase(null, false) {
@Override @Override
public Tab openNewTab(LoadUrlParams loadUrlParams, @TabLaunchType int type, Tab parent, public Tab openNewTab(LoadUrlParams loadUrlParams, @TabLaunchType int type, Tab parent,
boolean incognito) { boolean incognito) {
...@@ -127,7 +127,7 @@ public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule { ...@@ -127,7 +127,7 @@ public class TabModelSelectorObserverTestRule extends ChromeBrowserTestRule {
mIncognitoTabModel = new TabModelSelectorTestTabModel( mIncognitoTabModel = new TabModelSelectorTestTabModel(
true, orderController, tabContentManager, tabPersistentStore, delegate); true, orderController, tabContentManager, tabPersistentStore, delegate);
mSelector.initialize(false, mNormalTabModel, mIncognitoTabModel); mSelector.initialize(mNormalTabModel, mIncognitoTabModel);
} }
/** /**
......
...@@ -64,7 +64,7 @@ public class TabModelSelectorTabModelObserverTest { ...@@ -64,7 +64,7 @@ public class TabModelSelectorTabModelObserverTest {
@UiThreadTest @UiThreadTest
@SmallTest @SmallTest
public void testUninitializedSelector() throws InterruptedException, TimeoutException { public void testUninitializedSelector() throws InterruptedException, TimeoutException {
mSelector = new TabModelSelectorBase(null) { mSelector = new TabModelSelectorBase(null, false) {
@Override @Override
public Tab openNewTab(LoadUrlParams loadUrlParams, @TabLaunchType int type, Tab parent, public Tab openNewTab(LoadUrlParams loadUrlParams, @TabLaunchType int type, Tab parent,
boolean incognito) { boolean incognito) {
...@@ -79,8 +79,7 @@ public class TabModelSelectorTabModelObserverTest { ...@@ -79,8 +79,7 @@ public class TabModelSelectorTabModelObserverTest {
registrationCompleteCallback.notifyCalled(); registrationCompleteCallback.notifyCalled();
} }
}; };
mSelector.initialize( mSelector.initialize(mTestRule.getNormalTabModel(), mTestRule.getIncognitoTabModel());
false, mTestRule.getNormalTabModel(), mTestRule.getIncognitoTabModel());
registrationCompleteCallback.waitForCallback(0); registrationCompleteCallback.waitForCallback(0);
assertAllModelsHaveObserver(mSelector, observer); assertAllModelsHaveObserver(mSelector, observer);
} }
......
...@@ -110,7 +110,7 @@ public class TabModelSelectorTabObserverTest { ...@@ -110,7 +110,7 @@ public class TabModelSelectorTabObserverTest {
@Test @Test
@SmallTest @SmallTest
public void testObserverAddedBeforeInitialize() { public void testObserverAddedBeforeInitialize() {
TabModelSelectorBase selector = new TabModelSelectorBase(null) { TabModelSelectorBase selector = new TabModelSelectorBase(null, false) {
@Override @Override
public Tab openNewTab(LoadUrlParams loadUrlParams, @TabLaunchType int type, Tab parent, public Tab openNewTab(LoadUrlParams loadUrlParams, @TabLaunchType int type, Tab parent,
boolean incognito) { boolean incognito) {
...@@ -118,7 +118,7 @@ public class TabModelSelectorTabObserverTest { ...@@ -118,7 +118,7 @@ public class TabModelSelectorTabObserverTest {
} }
}; };
TestTabModelSelectorTabObserver observer = createTabModelSelectorTabObserver(); TestTabModelSelectorTabObserver observer = createTabModelSelectorTabObserver();
selector.initialize(false, mTestRule.getNormalTabModel(), mTestRule.getIncognitoTabModel()); selector.initialize(mTestRule.getNormalTabModel(), mTestRule.getIncognitoTabModel());
Tab normalTab1 = createTestTab(false); Tab normalTab1 = createTestTab(false);
addTab(mTestRule.getNormalTabModel(), normalTab1); addTab(mTestRule.getNormalTabModel(), normalTab1);
......
...@@ -171,7 +171,7 @@ public class TabPersistentStoreTest { ...@@ -171,7 +171,7 @@ public class TabPersistentStoreTest {
private final TabModelOrderController mTabModelOrderController; private final TabModelOrderController mTabModelOrderController;
public TestTabModelSelector() throws Exception { public TestTabModelSelector() throws Exception {
super(new MockTabCreatorManager()); super(new MockTabCreatorManager(), false);
((MockTabCreatorManager) getTabCreatorManager()).initialize(this); ((MockTabCreatorManager) getTabCreatorManager()).initialize(this);
mTabPersistentStoreObserver = new MockTabPersistentStoreObserver(); mTabPersistentStoreObserver = new MockTabPersistentStoreObserver();
mTabPersistentStore = mTabPersistentStore =
...@@ -202,7 +202,7 @@ public class TabPersistentStoreTest { ...@@ -202,7 +202,7 @@ public class TabPersistentStoreTest {
new IncognitoTabModelImplCreator(getTabCreatorManager().getTabCreator(false), new IncognitoTabModelImplCreator(getTabCreatorManager().getTabCreator(false),
getTabCreatorManager().getTabCreator(true), null, getTabCreatorManager().getTabCreator(true), null,
mTabModelOrderController, null, mTabPersistentStore, this)); mTabModelOrderController, null, mTabPersistentStore, this));
initialize(false, regularTabModel, incognitoTabModel); initialize(regularTabModel, incognitoTabModel);
} }
@Override @Override
......
...@@ -23,8 +23,8 @@ public class MockTabModelSelector extends TabModelSelectorBase { ...@@ -23,8 +23,8 @@ public class MockTabModelSelector extends TabModelSelectorBase {
public MockTabModelSelector( public MockTabModelSelector(
int tabCount, int incognitoTabCount, MockTabModel.MockTabModelDelegate delegate) { int tabCount, int incognitoTabCount, MockTabModel.MockTabModelDelegate delegate) {
super(null); super(null, false);
initialize(false, new MockTabModel(false, delegate), new MockTabModel(true, delegate)); initialize(new MockTabModel(false, delegate), new MockTabModel(true, delegate));
for (int i = 0; i < tabCount; i++) { for (int i = 0; i < tabCount; i++) {
addMockTab(); addMockTab();
} }
......
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