| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.tabmodel; | 5 package org.chromium.chrome.browser.tabmodel; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.content.SharedPreferences; | 8 import android.content.SharedPreferences; |
| 9 import android.os.AsyncTask; | 9 import android.os.AsyncTask; |
| 10 import android.support.test.InstrumentationRegistry; |
| 10 import android.support.test.filters.SmallTest; | 11 import android.support.test.filters.SmallTest; |
| 11 import android.util.Pair; | 12 import android.util.Pair; |
| 12 import android.util.SparseArray; | 13 import android.util.SparseArray; |
| 13 | 14 |
| 15 import org.junit.After; |
| 16 import org.junit.Assert; |
| 17 import org.junit.Before; |
| 18 import org.junit.Rule; |
| 19 import org.junit.Test; |
| 20 import org.junit.runner.RunWith; |
| 21 |
| 14 import org.chromium.base.ActivityState; | 22 import org.chromium.base.ActivityState; |
| 15 import org.chromium.base.ContextUtils; | 23 import org.chromium.base.ContextUtils; |
| 16 import org.chromium.base.ThreadUtils; | 24 import org.chromium.base.ThreadUtils; |
| 25 import org.chromium.base.test.BaseJUnit4ClassRunner; |
| 17 import org.chromium.base.test.util.AdvancedMockContext; | 26 import org.chromium.base.test.util.AdvancedMockContext; |
| 18 import org.chromium.base.test.util.CallbackHelper; | 27 import org.chromium.base.test.util.CallbackHelper; |
| 19 import org.chromium.base.test.util.Feature; | 28 import org.chromium.base.test.util.Feature; |
| 20 import org.chromium.base.test.util.MinAndroidSdkLevel; | 29 import org.chromium.base.test.util.MinAndroidSdkLevel; |
| 21 import org.chromium.base.test.util.RetryOnFailure; | 30 import org.chromium.base.test.util.RetryOnFailure; |
| 22 import org.chromium.chrome.browser.ChromeActivity; | 31 import org.chromium.chrome.browser.ChromeActivity; |
| 23 import org.chromium.chrome.browser.TabState; | 32 import org.chromium.chrome.browser.TabState; |
| 24 import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelper; | 33 import org.chromium.chrome.browser.compositor.overlays.strip.StripLayoutHelper; |
| 25 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; | 34 import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; |
| 26 import org.chromium.chrome.browser.snackbar.undo.UndoBarController; | 35 import org.chromium.chrome.browser.snackbar.undo.UndoBarController; |
| 27 import org.chromium.chrome.browser.tab.Tab; | 36 import org.chromium.chrome.browser.tab.Tab; |
| 28 import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator; | 37 import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator; |
| 29 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; | 38 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
| 30 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; | 39 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; |
| 31 import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabPersistentStor
eObserver; | 40 import org.chromium.chrome.browser.tabmodel.TabPersistentStore.TabPersistentStor
eObserver; |
| 32 import org.chromium.chrome.browser.tabmodel.TestTabModelDirectory.TabModelMetaDa
taInfo; | 41 import org.chromium.chrome.browser.tabmodel.TestTabModelDirectory.TabModelMetaDa
taInfo; |
| 42 import org.chromium.chrome.browser.test.ChromeBrowserTestRule; |
| 33 import org.chromium.chrome.browser.widget.OverviewListLayout; | 43 import org.chromium.chrome.browser.widget.OverviewListLayout; |
| 34 import org.chromium.chrome.test.util.browser.tabmodel.MockTabModelSelector; | 44 import org.chromium.chrome.test.util.browser.tabmodel.MockTabModelSelector; |
| 35 import org.chromium.content.browser.test.NativeLibraryTestBase; | |
| 36 import org.chromium.content_public.browser.LoadUrlParams; | 45 import org.chromium.content_public.browser.LoadUrlParams; |
| 37 import org.chromium.content_public.browser.WebContents; | 46 import org.chromium.content_public.browser.WebContents; |
| 38 | 47 |
| 39 import java.util.ArrayList; | 48 import java.util.ArrayList; |
| 40 import java.util.List; | 49 import java.util.List; |
| 41 import java.util.concurrent.Callable; | 50 import java.util.concurrent.Callable; |
| 42 | 51 |
| 43 /** Tests for the TabPersistentStore. */ | 52 /** Tests for the TabPersistentStore. */ |
| 44 public class TabPersistentStoreTest extends NativeLibraryTestBase { | 53 @RunWith(BaseJUnit4ClassRunner.class) |
| 54 public class TabPersistentStoreTest { |
| 55 @Rule |
| 56 public final ChromeBrowserTestRule mBrowserTestRule = |
| 57 new ChromeBrowserTestRule(true /* initBrowserProcess */); |
| 58 |
| 59 private ChromeActivity mChromeActivity; |
| 60 |
| 45 private static final int SELECTOR_INDEX = 0; | 61 private static final int SELECTOR_INDEX = 0; |
| 46 | 62 |
| 47 private static class TabRestoredDetails { | 63 private static class TabRestoredDetails { |
| 48 public int index; | 64 public int index; |
| 49 public int id; | 65 public int id; |
| 50 public String url; | 66 public String url; |
| 51 public boolean isStandardActiveIndex; | 67 public boolean isStandardActiveIndex; |
| 52 public boolean isIncognitoActiveIndex; | 68 public boolean isIncognitoActiveIndex; |
| 53 | 69 |
| 54 /** Store information about a Tab that's been restored. */ | 70 /** Store information about a Tab that's been restored. */ |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 public void onStateMerged() { | 258 public void onStateMerged() { |
| 243 stateMergedCallback.notifyCalled(); | 259 stateMergedCallback.notifyCalled(); |
| 244 } | 260 } |
| 245 | 261 |
| 246 @Override | 262 @Override |
| 247 public void onMetadataSavedAsynchronously() { | 263 public void onMetadataSavedAsynchronously() { |
| 248 listWrittenCallback.notifyCalled(); | 264 listWrittenCallback.notifyCalled(); |
| 249 } | 265 } |
| 250 } | 266 } |
| 251 | 267 |
| 252 private final ChromeActivity mFakeChromeActivity = new ChromeActivity() { | |
| 253 @Override | |
| 254 protected boolean handleBackPressed() { | |
| 255 return false; | |
| 256 } | |
| 257 | |
| 258 @Override | |
| 259 protected Pair<? extends TabCreator, ? extends TabCreator> createTabCrea
tors() { | |
| 260 return null; | |
| 261 } | |
| 262 | |
| 263 @Override | |
| 264 protected TabModelSelector createTabModelSelector() { | |
| 265 return null; | |
| 266 } | |
| 267 | |
| 268 @Override | |
| 269 protected ChromeFullscreenManager createFullscreenManager() { | |
| 270 return null; | |
| 271 } | |
| 272 }; | |
| 273 | |
| 274 private final TabWindowManager.TabModelSelectorFactory mMockTabModelSelector
Factory = | 268 private final TabWindowManager.TabModelSelectorFactory mMockTabModelSelector
Factory = |
| 275 new TabWindowManager.TabModelSelectorFactory() { | 269 new TabWindowManager.TabModelSelectorFactory() { |
| 276 @Override | 270 @Override |
| 277 public TabModelSelector buildSelector(Activity activity, | 271 public TabModelSelector buildSelector(Activity activity, |
| 278 TabCreatorManager tabCreatorManager, int selectorIndex)
{ | 272 TabCreatorManager tabCreatorManager, int selectorIndex)
{ |
| 279 try { | 273 try { |
| 280 return new TestTabModelSelector(); | 274 return new TestTabModelSelector(); |
| 281 } catch (Exception e) { | 275 } catch (Exception e) { |
| 282 throw new RuntimeException(e); | 276 throw new RuntimeException(e); |
| 283 } | 277 } |
| 284 } | 278 } |
| 285 }; | 279 }; |
| 286 | 280 |
| 287 /** Class for mocking out the directory containing all of the TabState files
. */ | 281 /** Class for mocking out the directory containing all of the TabState files
. */ |
| 288 private TestTabModelDirectory mMockDirectory; | 282 private TestTabModelDirectory mMockDirectory; |
| 289 private AdvancedMockContext mAppContext; | 283 private AdvancedMockContext mAppContext; |
| 290 private SharedPreferences mPreferences; | 284 private SharedPreferences mPreferences; |
| 291 | 285 |
| 292 @Override | 286 @Before |
| 293 public void setUp() throws Exception { | 287 public void setUp() throws Exception { |
| 294 super.setUp(); | 288 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 295 loadNativeLibraryAndInitBrowserProcess(); | 289 @Override |
| 290 public void run() { |
| 291 mChromeActivity = new ChromeActivity() { |
| 292 @Override |
| 293 protected boolean handleBackPressed() { |
| 294 return false; |
| 295 } |
| 296 |
| 297 @Override |
| 298 protected Pair<? extends TabCreator, ? extends TabCreator> c
reateTabCreators() { |
| 299 return null; |
| 300 } |
| 301 |
| 302 @Override |
| 303 protected TabModelSelector createTabModelSelector() { |
| 304 return null; |
| 305 } |
| 306 |
| 307 @Override |
| 308 protected ChromeFullscreenManager createFullscreenManager()
{ |
| 309 return null; |
| 310 } |
| 311 }; |
| 312 } |
| 313 }); |
| 314 |
| 296 // Using an AdvancedMockContext allows us to use a fresh in-memory Share
dPreference. | 315 // Using an AdvancedMockContext allows us to use a fresh in-memory Share
dPreference. |
| 297 mAppContext = new AdvancedMockContext( | 316 mAppContext = new AdvancedMockContext(InstrumentationRegistry.getInstrum
entation() |
| 298 getInstrumentation().getTargetContext().getApplicationContext())
; | 317 .getTargetContext() |
| 318 .getApplicationContext()); |
| 299 ContextUtils.initApplicationContextForTests(mAppContext); | 319 ContextUtils.initApplicationContextForTests(mAppContext); |
| 300 mPreferences = ContextUtils.getAppSharedPreferences(); | 320 mPreferences = ContextUtils.getAppSharedPreferences(); |
| 301 mMockDirectory = new TestTabModelDirectory( | 321 mMockDirectory = new TestTabModelDirectory( |
| 302 mAppContext, "TabPersistentStoreTest", Integer.toString(SELECTOR
_INDEX)); | 322 mAppContext, "TabPersistentStoreTest", Integer.toString(SELECTOR
_INDEX)); |
| 303 TabPersistentStore.setBaseStateDirectoryForTests(mMockDirectory.getBaseD
irectory()); | 323 TabPersistentStore.setBaseStateDirectoryForTests(mMockDirectory.getBaseD
irectory()); |
| 304 } | 324 } |
| 305 | 325 |
| 306 @Override | 326 @After |
| 307 public void tearDown() throws Exception { | 327 public void tearDown() throws Exception { |
| 308 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | 328 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 309 @Override | 329 @Override |
| 310 public void run() { | 330 public void run() { |
| 311 TabWindowManager.getInstance().onActivityStateChange( | 331 TabWindowManager.getInstance().onActivityStateChange( |
| 312 mFakeChromeActivity, ActivityState.DESTROYED); | 332 mChromeActivity, ActivityState.DESTROYED); |
| 313 } | 333 } |
| 314 }); | 334 }); |
| 315 mMockDirectory.tearDown(); | 335 mMockDirectory.tearDown(); |
| 316 super.tearDown(); | |
| 317 } | 336 } |
| 318 | 337 |
| 319 private TabPersistentStore buildTabPersistentStore(final TabPersistencePolic
y persistencePolicy, | 338 private TabPersistentStore buildTabPersistentStore(final TabPersistencePolic
y persistencePolicy, |
| 320 final TabModelSelector modelSelector, final TabCreatorManager creato
rManager, | 339 final TabModelSelector modelSelector, final TabCreatorManager creato
rManager, |
| 321 final TabPersistentStoreObserver observer) { | 340 final TabPersistentStoreObserver observer) { |
| 322 return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<TabPers
istentStore>() { | 341 return ThreadUtils.runOnUiThreadBlockingNoException(new Callable<TabPers
istentStore>() { |
| 323 @Override | 342 @Override |
| 324 public TabPersistentStore call() throws Exception { | 343 public TabPersistentStore call() throws Exception { |
| 325 return new TabPersistentStore(persistencePolicy, modelSelector,
creatorManager, | 344 return new TabPersistentStore(persistencePolicy, modelSelector,
creatorManager, |
| 326 observer); | 345 observer); |
| 327 } | 346 } |
| 328 }); | 347 }); |
| 329 } | 348 } |
| 330 | 349 |
| 350 @Test |
| 331 @SmallTest | 351 @SmallTest |
| 332 @Feature({"TabPersistentStore"}) | 352 @Feature("TabPersistentStore") |
| 333 public void testBasic() throws Exception { | 353 public void testBasic() throws Exception { |
| 334 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V4; | 354 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V4; |
| 335 int numExpectedTabs = info.contents.length; | 355 int numExpectedTabs = info.contents.length; |
| 336 | 356 |
| 337 mMockDirectory.writeTabModelFiles(info, true); | 357 mMockDirectory.writeTabModelFiles(info, true); |
| 338 | 358 |
| 339 // Set up the TabPersistentStore. | 359 // Set up the TabPersistentStore. |
| 340 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; | 360 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; |
| 341 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); | 361 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); |
| 342 MockTabCreator regularCreator = mockManager.getTabCreator(false); | 362 MockTabCreator regularCreator = mockManager.getTabCreator(false); |
| 343 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); | 363 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); |
| 344 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); | 364 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); |
| 345 TabPersistentStore store = buildTabPersistentStore( | 365 final TabPersistentStore store = |
| 346 persistencePolicy, mockSelector, mockManager, mockObserver); | 366 buildTabPersistentStore(persistencePolicy, mockSelector, mockMan
ager, mockObserver); |
| 347 | 367 |
| 348 // Should not prefetch with no prior active tab preference stored. | 368 // Should not prefetch with no prior active tab preference stored. |
| 349 assertNull(store.mPrefetchActiveTabTask); | 369 Assert.assertNull(store.mPrefetchActiveTabTask); |
| 350 | 370 |
| 351 // Make sure the metadata file loads properly and in order. | 371 // Make sure the metadata file loads properly and in order. |
| 352 store.loadState(false /* ignoreIncognitoFiles */); | 372 store.loadState(false /* ignoreIncognitoFiles */); |
| 353 mockObserver.initializedCallback.waitForCallback(0, 1); | 373 mockObserver.initializedCallback.waitForCallback(0, 1); |
| 354 assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); | 374 Assert.assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); |
| 355 | 375 |
| 356 mockObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); | 376 mockObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); |
| 357 assertEquals(numExpectedTabs, mockObserver.details.size()); | 377 Assert.assertEquals(numExpectedTabs, mockObserver.details.size()); |
| 358 for (int i = 0; i < numExpectedTabs; i++) { | 378 for (int i = 0; i < numExpectedTabs; i++) { |
| 359 TabRestoredDetails details = mockObserver.details.get(i); | 379 TabRestoredDetails details = mockObserver.details.get(i); |
| 360 assertEquals(i, details.index); | 380 Assert.assertEquals(i, details.index); |
| 361 assertEquals(info.contents[i].tabId, details.id); | 381 Assert.assertEquals(info.contents[i].tabId, details.id); |
| 362 assertEquals(info.contents[i].url, details.url); | 382 Assert.assertEquals(info.contents[i].url, details.url); |
| 363 assertEquals(details.id == info.selectedTabId, details.isStandardAct
iveIndex); | 383 Assert.assertEquals(details.id == info.selectedTabId, details.isStan
dardActiveIndex); |
| 364 assertEquals(false, details.isIncognitoActiveIndex); | 384 Assert.assertEquals(false, details.isIncognitoActiveIndex); |
| 365 } | 385 } |
| 366 | 386 |
| 367 // Restore the TabStates. The first Tab added should be the most recent
ly selected tab. | 387 // Restore the TabStates. The first Tab added should be the most recent
ly selected tab. |
| 368 store.restoreTabs(true); | 388 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 389 @Override |
| 390 public void run() { |
| 391 store.restoreTabs(true); |
| 392 } |
| 393 }); |
| 369 regularCreator.callback.waitForCallback(0, 1); | 394 regularCreator.callback.waitForCallback(0, 1); |
| 370 assertEquals(info.selectedTabId, regularCreator.idOfFirstCreatedTab); | 395 Assert.assertEquals(info.selectedTabId, regularCreator.idOfFirstCreatedT
ab); |
| 371 | 396 |
| 372 // Confirm that all the TabStates were read from storage (i.e. non-null)
. | 397 // Confirm that all the TabStates were read from storage (i.e. non-null)
. |
| 373 mockObserver.stateLoadedCallback.waitForCallback(0, 1); | 398 mockObserver.stateLoadedCallback.waitForCallback(0, 1); |
| 374 for (int i = 0; i < info.contents.length; i++) { | 399 for (int i = 0; i < info.contents.length; i++) { |
| 375 int tabId = info.contents[i].tabId; | 400 int tabId = info.contents[i].tabId; |
| 376 assertNotNull(regularCreator.created.get(tabId)); | 401 Assert.assertNotNull(regularCreator.created.get(tabId)); |
| 377 } | 402 } |
| 378 } | 403 } |
| 379 | 404 |
| 405 @Test |
| 380 @SmallTest | 406 @SmallTest |
| 381 @Feature({"TabPersistentStore"}) | 407 @Feature({"TabPersistentStore"}) |
| 382 public void testInterruptedButStillRestoresAllTabs() throws Exception { | 408 public void testInterruptedButStillRestoresAllTabs() throws Exception { |
| 383 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V4; | 409 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V4; |
| 384 int numExpectedTabs = info.contents.length; | 410 int numExpectedTabs = info.contents.length; |
| 385 | 411 |
| 386 mMockDirectory.writeTabModelFiles(info, true); | 412 mMockDirectory.writeTabModelFiles(info, true); |
| 387 | 413 |
| 388 // Load up one TabPersistentStore, but don't load up the TabState files.
This prevents the | 414 // Load up one TabPersistentStore, but don't load up the TabState files.
This prevents the |
| 389 // Tabs from being added to the TabModel. | 415 // Tabs from being added to the TabModel. |
| 390 MockTabModelSelector firstSelector = new MockTabModelSelector(0, 0, null
); | 416 MockTabModelSelector firstSelector = new MockTabModelSelector(0, 0, null
); |
| 391 MockTabCreatorManager firstManager = new MockTabCreatorManager(firstSele
ctor); | 417 MockTabCreatorManager firstManager = new MockTabCreatorManager(firstSele
ctor); |
| 392 MockTabPersistentStoreObserver firstObserver = new MockTabPersistentStor
eObserver(); | 418 MockTabPersistentStoreObserver firstObserver = new MockTabPersistentStor
eObserver(); |
| 393 TabPersistencePolicy firstPersistencePolicy = new TabbedModeTabPersisten
cePolicy(0, false); | 419 TabPersistencePolicy firstPersistencePolicy = new TabbedModeTabPersisten
cePolicy(0, false); |
| 394 final TabPersistentStore firstStore = buildTabPersistentStore( | 420 final TabPersistentStore firstStore = buildTabPersistentStore( |
| 395 firstPersistencePolicy, firstSelector, firstManager, firstObserv
er); | 421 firstPersistencePolicy, firstSelector, firstManager, firstObserv
er); |
| 396 firstStore.loadState(false /* ignoreIncognitoFiles */); | 422 firstStore.loadState(false /* ignoreIncognitoFiles */); |
| 397 firstObserver.initializedCallback.waitForCallback(0, 1); | 423 firstObserver.initializedCallback.waitForCallback(0, 1); |
| 398 assertEquals(numExpectedTabs, firstObserver.mTabCountAtStartup); | 424 Assert.assertEquals(numExpectedTabs, firstObserver.mTabCountAtStartup); |
| 399 firstObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); | 425 firstObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); |
| 400 | 426 |
| 401 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | 427 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 402 @Override | 428 @Override |
| 403 public void run() { | 429 public void run() { |
| 404 firstStore.saveState(); | 430 firstStore.saveState(); |
| 405 } | 431 } |
| 406 }); | 432 }); |
| 407 | 433 |
| 408 // Prepare a second TabPersistentStore. | 434 // Prepare a second TabPersistentStore. |
| 409 MockTabModelSelector secondSelector = new MockTabModelSelector(0, 0, nul
l); | 435 MockTabModelSelector secondSelector = new MockTabModelSelector(0, 0, nul
l); |
| 410 MockTabCreatorManager secondManager = new MockTabCreatorManager(secondSe
lector); | 436 MockTabCreatorManager secondManager = new MockTabCreatorManager(secondSe
lector); |
| 411 MockTabCreator secondCreator = secondManager.getTabCreator(false); | 437 MockTabCreator secondCreator = secondManager.getTabCreator(false); |
| 412 MockTabPersistentStoreObserver secondObserver = new MockTabPersistentSto
reObserver(); | 438 MockTabPersistentStoreObserver secondObserver = new MockTabPersistentSto
reObserver(); |
| 413 TabPersistencePolicy secondPersistencePolicy = new TabbedModeTabPersiste
ncePolicy(0, false); | 439 TabPersistencePolicy secondPersistencePolicy = new TabbedModeTabPersiste
ncePolicy(0, false); |
| 414 | 440 |
| 415 TabPersistentStore secondStore = buildTabPersistentStore( | 441 final TabPersistentStore secondStore = buildTabPersistentStore( |
| 416 secondPersistencePolicy, secondSelector, secondManager, secondOb
server); | 442 secondPersistencePolicy, secondSelector, secondManager, secondOb
server); |
| 417 | 443 |
| 418 // The second TabPersistentStore reads the file written by the first Tab
PersistentStore. | 444 // The second TabPersistentStore reads the file written by the first Tab
PersistentStore. |
| 419 // Make sure that all of the Tabs appear in the new one -- even though t
he new file was | 445 // Make sure that all of the Tabs appear in the new one -- even though t
he new file was |
| 420 // written before the first TabPersistentStore loaded any TabState files
and added them to | 446 // written before the first TabPersistentStore loaded any TabState files
and added them to |
| 421 // the TabModels. | 447 // the TabModels. |
| 422 secondStore.loadState(false /* ignoreIncognitoFiles */); | 448 secondStore.loadState(false /* ignoreIncognitoFiles */); |
| 423 secondObserver.initializedCallback.waitForCallback(0, 1); | 449 secondObserver.initializedCallback.waitForCallback(0, 1); |
| 424 assertEquals(numExpectedTabs, secondObserver.mTabCountAtStartup); | 450 Assert.assertEquals(numExpectedTabs, secondObserver.mTabCountAtStartup); |
| 425 | 451 |
| 426 secondObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); | 452 secondObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); |
| 427 assertEquals(numExpectedTabs, secondObserver.details.size()); | 453 Assert.assertEquals(numExpectedTabs, secondObserver.details.size()); |
| 428 for (int i = 0; i < numExpectedTabs; i++) { | 454 for (int i = 0; i < numExpectedTabs; i++) { |
| 429 TabRestoredDetails details = secondObserver.details.get(i); | 455 TabRestoredDetails details = secondObserver.details.get(i); |
| 430 | 456 |
| 431 // Find the details for the current Tab ID. | 457 // Find the details for the current Tab ID. |
| 432 // TODO(dfalcantara): Revisit this bit when tab ordering is correctl
y preserved. | 458 // TODO(dfalcantara): Revisit this bit when tab ordering is correctl
y preserved. |
| 433 TestTabModelDirectory.TabStateInfo currentInfo = null; | 459 TestTabModelDirectory.TabStateInfo currentInfo = null; |
| 434 for (int j = 0; j < numExpectedTabs && currentInfo == null; j++) { | 460 for (int j = 0; j < numExpectedTabs && currentInfo == null; j++) { |
| 435 if (TestTabModelDirectory.TAB_MODEL_METADATA_V4.contents[j].tabI
d == details.id) { | 461 if (TestTabModelDirectory.TAB_MODEL_METADATA_V4.contents[j].tabI
d == details.id) { |
| 436 currentInfo = TestTabModelDirectory.TAB_MODEL_METADATA_V4.co
ntents[j]; | 462 currentInfo = TestTabModelDirectory.TAB_MODEL_METADATA_V4.co
ntents[j]; |
| 437 } | 463 } |
| 438 } | 464 } |
| 439 | 465 |
| 440 // TODO(dfalcantara): This won't be properly set until we have tab o
rdering preserved. | 466 // TODO(dfalcantara): This won't be properly set until we have tab o
rdering preserved. |
| 441 // assertEquals(details.id == TestTabModelDirectory.TAB_MODEL_METADA
TA_V4_SELECTED_ID, | 467 // Assert.assertEquals(details.id == |
| 468 // TestTabModelDirectory.TAB_MODEL_METADATA_V4_SELECTED_ID, |
| 442 // details.isStandardActiveIndex); | 469 // details.isStandardActiveIndex); |
| 443 | 470 |
| 444 assertEquals(currentInfo.url, details.url); | 471 Assert.assertEquals(currentInfo.url, details.url); |
| 445 assertEquals(false, details.isIncognitoActiveIndex); | 472 Assert.assertEquals(false, details.isIncognitoActiveIndex); |
| 446 } | 473 } |
| 447 | 474 |
| 448 // Restore all of the TabStates. Confirm that all the TabStates were re
ad (i.e. non-null). | 475 // Restore all of the TabStates. Confirm that all the TabStates were re
ad (i.e. non-null). |
| 449 secondStore.restoreTabs(true); | 476 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 477 @Override |
| 478 public void run() { |
| 479 secondStore.restoreTabs(true); |
| 480 } |
| 481 }); |
| 482 |
| 450 secondObserver.stateLoadedCallback.waitForCallback(0, 1); | 483 secondObserver.stateLoadedCallback.waitForCallback(0, 1); |
| 451 for (int i = 0; i < numExpectedTabs; i++) { | 484 for (int i = 0; i < numExpectedTabs; i++) { |
| 452 int tabId = TestTabModelDirectory.TAB_MODEL_METADATA_V4.contents[i].
tabId; | 485 int tabId = TestTabModelDirectory.TAB_MODEL_METADATA_V4.contents[i].
tabId; |
| 453 assertNotNull(secondCreator.created.get(tabId)); | 486 Assert.assertNotNull(secondCreator.created.get(tabId)); |
| 454 } | 487 } |
| 455 } | 488 } |
| 456 | 489 |
| 490 @Test |
| 457 @SmallTest | 491 @SmallTest |
| 458 @Feature({"TabPersistentStore"}) | 492 @Feature({"TabPersistentStore"}) |
| 459 public void testMissingTabStateButStillRestoresTab() throws Exception { | 493 public void testMissingTabStateButStillRestoresTab() throws Exception { |
| 460 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5; | 494 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5; |
| 461 int numExpectedTabs = info.contents.length; | 495 int numExpectedTabs = info.contents.length; |
| 462 | 496 |
| 463 // Write out info for all but the third tab (arbitrarily chosen). | 497 // Write out info for all but the third tab (arbitrarily chosen). |
| 464 mMockDirectory.writeTabModelFiles(info, false); | 498 mMockDirectory.writeTabModelFiles(info, false); |
| 465 for (int i = 0; i < info.contents.length; i++) { | 499 for (int i = 0; i < info.contents.length; i++) { |
| 466 if (i != 2) mMockDirectory.writeTabStateFile(info.contents[i]); | 500 if (i != 2) mMockDirectory.writeTabStateFile(info.contents[i]); |
| 467 } | 501 } |
| 468 | 502 |
| 469 // Initialize the classes. | 503 // Initialize the classes. |
| 470 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; | 504 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; |
| 471 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); | 505 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); |
| 472 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); | 506 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); |
| 473 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); | 507 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); |
| 474 TabPersistentStore store = buildTabPersistentStore( | 508 final TabPersistentStore store = |
| 475 persistencePolicy, mockSelector, mockManager, mockObserver); | 509 buildTabPersistentStore(persistencePolicy, mockSelector, mockMan
ager, mockObserver); |
| 476 | 510 |
| 477 // Make sure the metadata file loads properly and in order. | 511 // Make sure the metadata file loads properly and in order. |
| 478 store.loadState(false /* ignoreIncognitoFiles */); | 512 store.loadState(false /* ignoreIncognitoFiles */); |
| 479 mockObserver.initializedCallback.waitForCallback(0, 1); | 513 mockObserver.initializedCallback.waitForCallback(0, 1); |
| 480 assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); | 514 Assert.assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); |
| 481 | 515 |
| 482 mockObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); | 516 mockObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); |
| 483 assertEquals(numExpectedTabs, mockObserver.details.size()); | 517 Assert.assertEquals(numExpectedTabs, mockObserver.details.size()); |
| 484 for (int i = 0; i < numExpectedTabs; i++) { | 518 for (int i = 0; i < numExpectedTabs; i++) { |
| 485 TabRestoredDetails details = mockObserver.details.get(i); | 519 TabRestoredDetails details = mockObserver.details.get(i); |
| 486 assertEquals(i, details.index); | 520 Assert.assertEquals(i, details.index); |
| 487 assertEquals(info.contents[i].tabId, details.id); | 521 Assert.assertEquals(info.contents[i].tabId, details.id); |
| 488 assertEquals(info.contents[i].url, details.url); | 522 Assert.assertEquals(info.contents[i].url, details.url); |
| 489 assertEquals(details.id == info.selectedTabId, details.isStandardAct
iveIndex); | 523 Assert.assertEquals(details.id == info.selectedTabId, details.isStan
dardActiveIndex); |
| 490 assertEquals(false, details.isIncognitoActiveIndex); | 524 Assert.assertEquals(false, details.isIncognitoActiveIndex); |
| 491 } | 525 } |
| 492 | 526 |
| 493 // Restore the TabStates, and confirm that the correct number of tabs is
created even with | 527 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 494 // one missing. | 528 @Override |
| 495 store.restoreTabs(true); | 529 public void run() { |
| 530 // Restore the TabStates, and confirm that the correct number of
tabs is created |
| 531 // even with one missing. |
| 532 store.restoreTabs(true); |
| 533 } |
| 534 }); |
| 496 mockObserver.stateLoadedCallback.waitForCallback(0, 1); | 535 mockObserver.stateLoadedCallback.waitForCallback(0, 1); |
| 497 assertEquals(numExpectedTabs, mockSelector.getModel(false).getCount()); | 536 Assert.assertEquals(numExpectedTabs, mockSelector.getModel(false).getCou
nt()); |
| 498 assertEquals(0, mockSelector.getModel(true).getCount()); | 537 Assert.assertEquals(0, mockSelector.getModel(true).getCount()); |
| 499 } | 538 } |
| 500 | 539 |
| 540 @Test |
| 501 @SmallTest | 541 @SmallTest |
| 502 @Feature({"TabPersistentStore"}) | 542 @Feature({"TabPersistentStore"}) |
| 503 public void testRestoresTabWithMissingTabStateWhileIgnoringIncognitoTab() th
rows Exception { | 543 public void testRestoresTabWithMissingTabStateWhileIgnoringIncognitoTab() th
rows Exception { |
| 504 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_
WITH_INCOGNITO; | 544 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_
WITH_INCOGNITO; |
| 505 int numExpectedTabs = info.contents.length; | 545 int numExpectedTabs = info.contents.length; |
| 506 | 546 |
| 507 // Write out info for all but the third tab (arbitrarily chosen). | 547 // Write out info for all but the third tab (arbitrarily chosen). |
| 508 mMockDirectory.writeTabModelFiles(info, false); | 548 mMockDirectory.writeTabModelFiles(info, false); |
| 509 for (int i = 0; i < info.contents.length; i++) { | 549 for (int i = 0; i < info.contents.length; i++) { |
| 510 if (i != 2) mMockDirectory.writeTabStateFile(info.contents[i]); | 550 if (i != 2) mMockDirectory.writeTabStateFile(info.contents[i]); |
| 511 } | 551 } |
| 512 | 552 |
| 513 // Initialize the classes. | 553 // Initialize the classes. |
| 514 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; | 554 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; |
| 515 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); | 555 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); |
| 516 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); | 556 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); |
| 517 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); | 557 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); |
| 518 TabPersistentStore store = buildTabPersistentStore( | 558 final TabPersistentStore store = |
| 519 persistencePolicy, mockSelector, mockManager, mockObserver); | 559 buildTabPersistentStore(persistencePolicy, mockSelector, mockMan
ager, mockObserver); |
| 520 | 560 |
| 521 // Load the TabModel metadata. | 561 // Load the TabModel metadata. |
| 522 store.loadState(false /* ignoreIncognitoFiles */); | 562 store.loadState(false /* ignoreIncognitoFiles */); |
| 523 mockObserver.initializedCallback.waitForCallback(0, 1); | 563 mockObserver.initializedCallback.waitForCallback(0, 1); |
| 524 assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); | 564 Assert.assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); |
| 525 mockObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); | 565 mockObserver.detailsReadCallback.waitForCallback(0, numExpectedTabs); |
| 526 assertEquals(numExpectedTabs, mockObserver.details.size()); | 566 Assert.assertEquals(numExpectedTabs, mockObserver.details.size()); |
| 527 | 567 |
| 528 // TODO(dfalcantara): Expand MockTabModel* to support Incognito Tab decr
yption. | 568 // TODO(dfalcantara): Expand MockTabModel* to support Incognito Tab decr
yption. |
| 529 | 569 |
| 530 // Restore the TabStates, and confirm that the correct number of tabs is
created even with | 570 // Restore the TabStates, and confirm that the correct number of tabs is
created even with |
| 531 // one missing. No Incognito tabs should be created because the TabStat
e is missing. | 571 // one missing. No Incognito tabs should be created because the TabStat
e is missing. |
| 532 store.restoreTabs(true); | 572 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 573 @Override |
| 574 public void run() { |
| 575 store.restoreTabs(true); |
| 576 } |
| 577 }); |
| 533 mockObserver.stateLoadedCallback.waitForCallback(0, 1); | 578 mockObserver.stateLoadedCallback.waitForCallback(0, 1); |
| 534 assertEquals(info.numRegularTabs, mockSelector.getModel(false).getCount(
)); | 579 Assert.assertEquals(info.numRegularTabs, mockSelector.getModel(false).ge
tCount()); |
| 535 assertEquals(0, mockSelector.getModel(true).getCount()); | 580 Assert.assertEquals(0, mockSelector.getModel(true).getCount()); |
| 536 } | 581 } |
| 537 | 582 |
| 583 @Test |
| 538 @SmallTest | 584 @SmallTest |
| 539 @Feature({"TabPersistentStore"}) | 585 @Feature({"TabPersistentStore"}) |
| 540 public void testPrefetchActiveTab() throws Exception { | 586 public void testPrefetchActiveTab() throws Exception { |
| 541 final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADA
TA_V5_NO_M18; | 587 final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADA
TA_V5_NO_M18; |
| 542 mMockDirectory.writeTabModelFiles(info, true); | 588 mMockDirectory.writeTabModelFiles(info, true); |
| 543 | 589 |
| 544 // Set to pre-fetch | 590 // Set to pre-fetch |
| 545 mPreferences.edit().putInt( | 591 mPreferences.edit().putInt( |
| 546 TabPersistentStore.PREF_ACTIVE_TAB_ID, info.selectedTabId).apply
(); | 592 TabPersistentStore.PREF_ACTIVE_TAB_ID, info.selectedTabId).apply
(); |
| 547 | 593 |
| 548 // Initialize the classes. | 594 // Initialize the classes. |
| 549 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; | 595 MockTabModelSelector mockSelector = new MockTabModelSelector(0, 0, null)
; |
| 550 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); | 596 MockTabCreatorManager mockManager = new MockTabCreatorManager(mockSelect
or); |
| 551 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); | 597 MockTabPersistentStoreObserver mockObserver = new MockTabPersistentStore
Observer(); |
| 552 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); | 598 TabPersistencePolicy persistencePolicy = new TabbedModeTabPersistencePol
icy(0, false); |
| 553 final TabPersistentStore store = buildTabPersistentStore( | 599 final TabPersistentStore store = buildTabPersistentStore( |
| 554 persistencePolicy, mockSelector, mockManager, mockObserver); | 600 persistencePolicy, mockSelector, mockManager, mockObserver); |
| 555 store.waitForMigrationToFinish(); | 601 store.waitForMigrationToFinish(); |
| 556 | 602 |
| 557 assertNotNull(store.mPrefetchActiveTabTask); | 603 Assert.assertNotNull(store.mPrefetchActiveTabTask); |
| 558 | 604 |
| 559 store.loadState(false /* ignoreIncognitoFiles */); | 605 store.loadState(false /* ignoreIncognitoFiles */); |
| 560 store.restoreTabs(true); | 606 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 607 @Override |
| 608 public void run() { |
| 609 store.restoreTabs(true); |
| 610 } |
| 611 }); |
| 561 | 612 |
| 562 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | 613 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 563 @Override | 614 @Override |
| 564 public void run() { | 615 public void run() { |
| 565 // Confirm that the pre-fetched active tab state was used, must
be done here on the | 616 // Confirm that the pre-fetched active tab state was used, must
be done here on the |
| 566 // UI thread as the message to finish the task is posted here. | 617 // UI thread as the message to finish the task is posted here. |
| 567 assertEquals(AsyncTask.Status.FINISHED, store.mPrefetchActiveTab
Task.getStatus()); | 618 Assert.assertEquals( |
| 619 AsyncTask.Status.FINISHED, store.mPrefetchActiveTabTask.
getStatus()); |
| 568 | 620 |
| 569 // Confirm that the correct active tab ID is updated when saving
state. | 621 // Confirm that the correct active tab ID is updated when saving
state. |
| 570 mPreferences.edit().putInt(TabPersistentStore.PREF_ACTIVE_TAB_ID
, -1).apply(); | 622 mPreferences.edit().putInt(TabPersistentStore.PREF_ACTIVE_TAB_ID
, -1).apply(); |
| 623 |
| 571 store.saveState(); | 624 store.saveState(); |
| 572 assertEquals(info.selectedTabId, | |
| 573 mPreferences.getInt(TabPersistentStore.PREF_ACTIVE_TAB_I
D, -1)); | |
| 574 } | 625 } |
| 575 }); | 626 }); |
| 627 |
| 628 Assert.assertEquals( |
| 629 info.selectedTabId, mPreferences.getInt(TabPersistentStore.PREF_
ACTIVE_TAB_ID, -1)); |
| 576 } | 630 } |
| 577 | 631 |
| 578 /** | 632 /** |
| 579 * Tests that a real {@link TabModelImpl} will use the {@link TabPersistentS
tore} to write out | 633 * Tests that a real {@link TabModelImpl} will use the {@link TabPersistentS
tore} to write out |
| 580 * an updated metadata file when a closure is undone. | 634 * an updated metadata file when a closure is undone. |
| 581 */ | 635 */ |
| 636 @Test |
| 582 @SmallTest | 637 @SmallTest |
| 583 @Feature({"TabPersistentStore"}) | 638 @Feature({"TabPersistentStore"}) |
| 584 public void testUndoSingleTabClosureWritesTabListFile() throws Exception { | 639 public void testUndoSingleTabClosureWritesTabListFile() throws Exception { |
| 585 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_
NO_M18; | 640 TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADATA_V5_
NO_M18; |
| 586 mMockDirectory.writeTabModelFiles(info, true); | 641 mMockDirectory.writeTabModelFiles(info, true); |
| 587 | 642 |
| 588 // Start closing one tab, then undo it. Make sure the tab list metadata
is saved out. | 643 // Start closing one tab, then undo it. Make sure the tab list metadata
is saved out. |
| 589 TestTabModelSelector selector = createAndRestoreRealTabModelImpls(info); | 644 TestTabModelSelector selector = createAndRestoreRealTabModelImpls(info); |
| 590 MockTabPersistentStoreObserver mockObserver = selector.mTabPersistentSto
reObserver; | 645 MockTabPersistentStoreObserver mockObserver = selector.mTabPersistentSto
reObserver; |
| 591 final TabModel regularModel = selector.getModel(false); | 646 final TabModel regularModel = selector.getModel(false); |
| 592 int currentWrittenCallbackCount = mockObserver.listWrittenCallback.getCa
llCount(); | 647 int currentWrittenCallbackCount = mockObserver.listWrittenCallback.getCa
llCount(); |
| 593 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | 648 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 594 @Override | 649 @Override |
| 595 public void run() { | 650 public void run() { |
| 596 Tab tabToClose = regularModel.getTabAt(2); | 651 Tab tabToClose = regularModel.getTabAt(2); |
| 597 regularModel.closeTab(tabToClose, false, false, true); | 652 regularModel.closeTab(tabToClose, false, false, true); |
| 598 regularModel.cancelTabClosure(tabToClose.getId()); | 653 regularModel.cancelTabClosure(tabToClose.getId()); |
| 599 } | 654 } |
| 600 }); | 655 }); |
| 601 mockObserver.listWrittenCallback.waitForCallback(currentWrittenCallbackC
ount, 1); | 656 mockObserver.listWrittenCallback.waitForCallback(currentWrittenCallbackC
ount, 1); |
| 602 } | 657 } |
| 603 | 658 |
| 604 /** | 659 /** |
| 605 * Tests that a real {@link TabModelImpl} will use the {@link TabPersistentS
tore} to write out | 660 * Tests that a real {@link TabModelImpl} will use the {@link TabPersistentS
tore} to write out |
| 606 * valid a valid metadata file and the TabModel's associated TabStates after
closing and | 661 * valid a valid metadata file and the TabModel's associated TabStates after
closing and |
| 607 * canceling the closure of all the tabs simultaneously. | 662 * canceling the closure of all the tabs simultaneously. |
| 608 */ | 663 */ |
| 664 @Test |
| 609 @SmallTest | 665 @SmallTest |
| 610 @Feature({"TabPersistentStore"}) | 666 @Feature({"TabPersistentStore"}) |
| 611 @RetryOnFailure | 667 @RetryOnFailure |
| 612 public void testUndoCloseAllTabsWritesTabListFile() throws Exception { | 668 public void testUndoCloseAllTabsWritesTabListFile() throws Exception { |
| 613 final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADA
TA_V5_NO_M18; | 669 final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADA
TA_V5_NO_M18; |
| 614 mMockDirectory.writeTabModelFiles(info, true); | 670 mMockDirectory.writeTabModelFiles(info, true); |
| 615 | 671 |
| 616 for (int i = 0; i < 2; i++) { | 672 for (int i = 0; i < 2; i++) { |
| 617 final TestTabModelSelector selector = createAndRestoreRealTabModelIm
pls(info); | 673 final TestTabModelSelector selector = createAndRestoreRealTabModelIm
pls(info); |
| 618 | 674 |
| 619 // Undoing tab closures one-by-one results in the first tab always b
eing selected after | 675 // Undoing tab closures one-by-one results in the first tab always b
eing selected after |
| 620 // the initial restoration. | 676 // the initial restoration. |
| 621 if (i == 0) { | 677 if (i == 0) { |
| 622 assertEquals(info.selectedTabId, selector.getCurrentTab().getId(
)); | 678 Assert.assertEquals(info.selectedTabId, selector.getCurrentTab()
.getId()); |
| 623 } else { | 679 } else { |
| 624 assertEquals(info.contents[0].tabId, selector.getCurrentTab().ge
tId()); | 680 Assert.assertEquals(info.contents[0].tabId, selector.getCurrentT
ab().getId()); |
| 625 } | 681 } |
| 626 | 682 |
| 627 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | 683 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 628 @Override | 684 @Override |
| 629 public void run() { | 685 public void run() { |
| 630 closeAllTabsThenUndo(selector, info); | 686 closeAllTabsThenUndo(selector, info); |
| 631 | 687 |
| 632 // Synchronously save the data out to simulate minimizing Ch
rome. | 688 // Synchronously save the data out to simulate minimizing Ch
rome. |
| 633 selector.mTabPersistentStore.saveState(); | 689 selector.mTabPersistentStore.saveState(); |
| 634 } | 690 } |
| 635 }); | 691 }); |
| 636 | 692 |
| 637 // Load up each TabState and confirm that values are still correct. | 693 // Load up each TabState and confirm that values are still correct. |
| 638 for (int j = 0; j < info.numRegularTabs; j++) { | 694 for (int j = 0; j < info.numRegularTabs; j++) { |
| 639 TabState currentState = TabState.restoreTabState( | 695 TabState currentState = TabState.restoreTabState( |
| 640 mMockDirectory.getDataDirectory(), info.contents[j].tabI
d); | 696 mMockDirectory.getDataDirectory(), info.contents[j].tabI
d); |
| 641 assertEquals(info.contents[j].title, currentState.getDisplayTitl
eFromState()); | 697 Assert.assertEquals( |
| 642 assertEquals(info.contents[j].url, currentState.getVirtualUrlFro
mState()); | 698 info.contents[j].title, currentState.getDisplayTitleFrom
State()); |
| 699 Assert.assertEquals(info.contents[j].url, currentState.getVirtua
lUrlFromState()); |
| 643 } | 700 } |
| 644 } | 701 } |
| 645 } | 702 } |
| 646 | 703 |
| 704 @Test |
| 647 @SmallTest | 705 @SmallTest |
| 648 @Feature({"TabPersistentStore", "MultiWindow"}) | 706 @Feature({"TabPersistentStore", "MultiWindow"}) |
| 649 @MinAndroidSdkLevel(24) | 707 @MinAndroidSdkLevel(24) |
| 650 public void testDuplicateTabIdsOnColdStart() throws Exception { | 708 public void testDuplicateTabIdsOnColdStart() throws Exception { |
| 651 final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADA
TA_V5_NO_M18; | 709 final TabModelMetaDataInfo info = TestTabModelDirectory.TAB_MODEL_METADA
TA_V5_NO_M18; |
| 652 | 710 |
| 653 // Write the same data to tab_state0 and tab_state1. | 711 // Write the same data to tab_state0 and tab_state1. |
| 654 mMockDirectory.writeTabModelFiles(info, true, 0); | 712 mMockDirectory.writeTabModelFiles(info, true, 0); |
| 655 mMockDirectory.writeTabModelFiles(info, true, 1); | 713 mMockDirectory.writeTabModelFiles(info, true, 1); |
| 656 | 714 |
| 657 // This method will check that the correct number of tabs are created. | 715 // This method will check that the correct number of tabs are created. |
| 658 createAndRestoreRealTabModelImpls(info); | 716 createAndRestoreRealTabModelImpls(info); |
| 659 } | 717 } |
| 660 | 718 |
| 661 private TestTabModelSelector createAndRestoreRealTabModelImpls(TabModelMetaD
ataInfo info) | 719 private TestTabModelSelector createAndRestoreRealTabModelImpls(TabModelMetaD
ataInfo info) |
| 662 throws Exception { | 720 throws Exception { |
| 663 TestTabModelSelector selector = | 721 TestTabModelSelector selector = |
| 664 ThreadUtils.runOnUiThreadBlocking(new Callable<TestTabModelSelec
tor>() { | 722 ThreadUtils.runOnUiThreadBlocking(new Callable<TestTabModelSelec
tor>() { |
| 665 @Override | 723 @Override |
| 666 public TestTabModelSelector call() { | 724 public TestTabModelSelector call() { |
| 667 TabWindowManager tabWindowManager = TabWindowManager.get
Instance(); | 725 TabWindowManager tabWindowManager = TabWindowManager.get
Instance(); |
| 668 tabWindowManager.setTabModelSelectorFactory(mMockTabMode
lSelectorFactory); | 726 tabWindowManager.setTabModelSelectorFactory(mMockTabMode
lSelectorFactory); |
| 669 // Clear any existing TestTabModelSelector (required whe
n | 727 // Clear any existing TestTabModelSelector (required whe
n |
| 670 // createAndRestoreRealTabModelImpls is called multiple
times in one test). | 728 // createAndRestoreRealTabModelImpls is called multiple
times in one test). |
| 671 tabWindowManager.onActivityStateChange( | 729 tabWindowManager.onActivityStateChange( |
| 672 mFakeChromeActivity, ActivityState.DESTROYED); | 730 mChromeActivity, ActivityState.DESTROYED); |
| 673 return (TestTabModelSelector) tabWindowManager.requestSe
lector( | 731 return (TestTabModelSelector) tabWindowManager.requestSe
lector( |
| 674 mFakeChromeActivity, mFakeChromeActivity, 0); | 732 mChromeActivity, mChromeActivity, 0); |
| 675 } | 733 } |
| 676 }); | 734 }); |
| 677 | 735 |
| 678 TabPersistentStore store = selector.mTabPersistentStore; | 736 final TabPersistentStore store = selector.mTabPersistentStore; |
| 679 MockTabPersistentStoreObserver mockObserver = selector.mTabPersistentSto
reObserver; | 737 MockTabPersistentStoreObserver mockObserver = selector.mTabPersistentSto
reObserver; |
| 680 | 738 |
| 681 // Load up the TabModel metadata. | 739 // Load up the TabModel metadata. |
| 682 int numExpectedTabs = info.numRegularTabs + info.numIncognitoTabs; | 740 int numExpectedTabs = info.numRegularTabs + info.numIncognitoTabs; |
| 683 store.loadState(false /* ignoreIncognitoFiles */); | 741 store.loadState(false /* ignoreIncognitoFiles */); |
| 684 mockObserver.initializedCallback.waitForCallback(0, 1); | 742 mockObserver.initializedCallback.waitForCallback(0, 1); |
| 685 assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); | 743 Assert.assertEquals(numExpectedTabs, mockObserver.mTabCountAtStartup); |
| 686 mockObserver.detailsReadCallback.waitForCallback(0, info.contents.length
); | 744 mockObserver.detailsReadCallback.waitForCallback(0, info.contents.length
); |
| 687 assertEquals(numExpectedTabs, mockObserver.details.size()); | 745 Assert.assertEquals(numExpectedTabs, mockObserver.details.size()); |
| 688 | 746 |
| 689 // Restore the TabStates, check that things were restored correctly, in
the right tab order. | 747 // Restore the TabStates, check that things were restored correctly, in
the right tab order. |
| 690 store.restoreTabs(true); | 748 ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
| 749 @Override |
| 750 public void run() { |
| 751 store.restoreTabs(true); |
| 752 } |
| 753 }); |
| 691 mockObserver.stateLoadedCallback.waitForCallback(0, 1); | 754 mockObserver.stateLoadedCallback.waitForCallback(0, 1); |
| 692 assertEquals(info.numRegularTabs, selector.getModel(false).getCount()); | 755 Assert.assertEquals(info.numRegularTabs, selector.getModel(false).getCou
nt()); |
| 693 assertEquals(info.numIncognitoTabs, selector.getModel(true).getCount()); | 756 Assert.assertEquals(info.numIncognitoTabs, selector.getModel(true).getCo
unt()); |
| 694 for (int i = 0; i < numExpectedTabs; i++) { | 757 for (int i = 0; i < numExpectedTabs; i++) { |
| 695 assertEquals(info.contents[i].tabId, selector.getModel(false).getTab
At(i).getId()); | 758 Assert.assertEquals( |
| 759 info.contents[i].tabId, selector.getModel(false).getTabAt(i)
.getId()); |
| 696 } | 760 } |
| 697 | 761 |
| 698 return selector; | 762 return selector; |
| 699 } | 763 } |
| 700 | 764 |
| 701 /** | 765 /** |
| 702 * Close all Tabs in the regular TabModel, then undo the operation to restor
e the Tabs. | 766 * Close all Tabs in the regular TabModel, then undo the operation to restor
e the Tabs. |
| 703 * This simulates how {@link StripLayoutHelper} and {@link UndoBarController
} would close | 767 * This simulates how {@link StripLayoutHelper} and {@link UndoBarController
} would close |
| 704 * all of a {@link TabModel}'s tabs on tablets, which is different from how
the | 768 * all of a {@link TabModel}'s tabs on tablets, which is different from how
the |
| 705 * {@link OverviewListLayout} would do it on phones. | 769 * {@link OverviewListLayout} would do it on phones. |
| 706 */ | 770 */ |
| 707 private void closeAllTabsThenUndo(TabModelSelector selector, TabModelMetaDat
aInfo info) { | 771 private void closeAllTabsThenUndo(TabModelSelector selector, TabModelMetaDat
aInfo info) { |
| 708 // Close all the tabs, using an Observer to determine what is actually b
eing closed. | 772 // Close all the tabs, using an Observer to determine what is actually b
eing closed. |
| 709 TabModel regularModel = selector.getModel(false); | 773 TabModel regularModel = selector.getModel(false); |
| 710 final List<Integer> closedTabIds = new ArrayList<>(); | 774 final List<Integer> closedTabIds = new ArrayList<>(); |
| 711 TabModelObserver closeObserver = new EmptyTabModelObserver() { | 775 TabModelObserver closeObserver = new EmptyTabModelObserver() { |
| 712 @Override | 776 @Override |
| 713 public void allTabsPendingClosure(List<Tab> tabs) { | 777 public void allTabsPendingClosure(List<Tab> tabs) { |
| 714 for (Tab tab : tabs) closedTabIds.add(tab.getId()); | 778 for (Tab tab : tabs) closedTabIds.add(tab.getId()); |
| 715 } | 779 } |
| 716 }; | 780 }; |
| 717 regularModel.addObserver(closeObserver); | 781 regularModel.addObserver(closeObserver); |
| 718 regularModel.closeAllTabs(false, false); | 782 regularModel.closeAllTabs(false, false); |
| 719 assertEquals(info.numRegularTabs, closedTabIds.size()); | 783 Assert.assertEquals(info.numRegularTabs, closedTabIds.size()); |
| 720 | 784 |
| 721 // Cancel closing each tab. | 785 // Cancel closing each tab. |
| 722 for (Integer id : closedTabIds) regularModel.cancelTabClosure(id); | 786 for (Integer id : closedTabIds) regularModel.cancelTabClosure(id); |
| 723 assertEquals(info.numRegularTabs, regularModel.getCount()); | 787 Assert.assertEquals(info.numRegularTabs, regularModel.getCount()); |
| 724 } | 788 } |
| 725 } | 789 } |
| OLD | NEW |