OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 #include <vector> | 5 #include <vector> |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/memory/memory_pressure_listener.h" | 9 #include "base/memory/memory_pressure_listener.h" |
10 #include "base/process/launch.h" | 10 #include "base/process/launch.h" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 } | 205 } |
206 } | 206 } |
207 | 207 |
208 GURL url1_; | 208 GURL url1_; |
209 GURL url2_; | 209 GURL url2_; |
210 GURL url3_; | 210 GURL url3_; |
211 | 211 |
212 const BrowserList* active_browser_list_; | 212 const BrowserList* active_browser_list_; |
213 }; | 213 }; |
214 | 214 |
215 // Activates the smart restore behaviour and can track the loading of tabs. | 215 // Activates the smart restore behaviour in "simple" mode and tracks the loading |
216 class SmartSessionRestoreTest : public SessionRestoreTest, | 216 // of tabs. |
217 public content::NotificationObserver { | 217 class SmartSessionRestoreSimpleTest : public SessionRestoreTest, |
| 218 public content::NotificationObserver { |
218 public: | 219 public: |
219 SmartSessionRestoreTest() {} | 220 SmartSessionRestoreSimpleTest() {} |
220 void StartObserving(int num_tabs) { | 221 void StartObserving(int num_tabs) { |
| 222 // Start by clearing everything so it can be reused in the same test. |
| 223 web_contents_.clear(); |
| 224 registrar_.RemoveAll(); |
221 num_tabs_ = num_tabs; | 225 num_tabs_ = num_tabs; |
222 registrar_.Add(this, content::NOTIFICATION_LOAD_START, | 226 registrar_.Add(this, content::NOTIFICATION_LOAD_START, |
223 content::NotificationService::AllSources()); | 227 content::NotificationService::AllSources()); |
224 } | 228 } |
225 void Observe(int type, | 229 void Observe(int type, |
226 const content::NotificationSource& source, | 230 const content::NotificationSource& source, |
227 const content::NotificationDetails& details) override { | 231 const content::NotificationDetails& details) override { |
228 switch (type) { | 232 switch (type) { |
229 case content::NOTIFICATION_LOAD_START: { | 233 case content::NOTIFICATION_LOAD_START: { |
230 content::NavigationController* controller = | 234 content::NavigationController* controller = |
(...skipping 23 matching lines...) Expand all Loading... |
254 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/simple"); | 258 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/simple"); |
255 } | 259 } |
256 | 260 |
257 private: | 261 private: |
258 content::NotificationRegistrar registrar_; | 262 content::NotificationRegistrar registrar_; |
259 // Ordered by load start order. | 263 // Ordered by load start order. |
260 std::vector<content::WebContents*> web_contents_; | 264 std::vector<content::WebContents*> web_contents_; |
261 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | 265 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; |
262 int num_tabs_; | 266 int num_tabs_; |
263 | 267 |
264 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreTest); | 268 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreSimpleTest); |
| 269 }; |
| 270 |
| 271 class SmartSessionRestoreMRUTest : public SmartSessionRestoreSimpleTest { |
| 272 public: |
| 273 SmartSessionRestoreMRUTest() {} |
| 274 |
| 275 protected: |
| 276 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 277 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| 278 switches::kForceFieldTrials, "IntelligentSessionRestore/TestGroup/"); |
| 279 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( |
| 280 switches::kForceFieldTrialParams, |
| 281 "IntelligentSessionRestore.TestGroup:PrioritizeTabs/mru"); |
| 282 } |
| 283 |
| 284 private: |
| 285 DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreMRUTest); |
265 }; | 286 }; |
266 | 287 |
267 // Verifies that restored tabs have a root window. This is important | 288 // Verifies that restored tabs have a root window. This is important |
268 // otherwise the wrong information is communicated to the renderer. | 289 // otherwise the wrong information is communicated to the renderer. |
269 // (http://crbug.com/342672). | 290 // (http://crbug.com/342672). |
270 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoredTabsShouldHaveWindow) { | 291 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoredTabsShouldHaveWindow) { |
271 // Create tabs. | 292 // Create tabs. |
272 ui_test_utils::NavigateToURLWithDisposition( | 293 ui_test_utils::NavigateToURLWithDisposition( |
273 browser(), | 294 browser(), |
274 GURL(url::kAboutBlankURL), | 295 GURL(url::kAboutBlankURL), |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); | 1347 &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); |
1327 EXPECT_TRUE( | 1348 EXPECT_TRUE( |
1328 controller->GetDefaultSessionStorageNamespace()->should_persist()); | 1349 controller->GetDefaultSessionStorageNamespace()->should_persist()); |
1329 | 1350 |
1330 // Quit and restore. Check that no extra tabs were created. | 1351 // Quit and restore. Check that no extra tabs were created. |
1331 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); | 1352 Browser* new_browser = QuitBrowserAndRestore(browser(), 1); |
1332 ASSERT_EQ(1u, active_browser_list_->size()); | 1353 ASSERT_EQ(1u, active_browser_list_->size()); |
1333 EXPECT_EQ(1, new_browser->tab_strip_model()->count()); | 1354 EXPECT_EQ(1, new_browser->tab_strip_model()->count()); |
1334 } | 1355 } |
1335 | 1356 |
1336 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreTest, CorrectLoadingOrder) { | 1357 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreSimpleTest, CorrectLoadingOrder) { |
1337 ASSERT_EQ(SessionRestore::SMART_RESTORE_MODE_SIMPLE, | 1358 ASSERT_EQ(SessionRestore::SMART_RESTORE_MODE_SIMPLE, |
1338 SessionRestore::GetSmartRestoreMode()); | 1359 SessionRestore::GetSmartRestoreMode()); |
1339 | 1360 |
1340 const int NumTabs = 6; | 1361 const int num_tabs = 6; |
1341 | 1362 |
1342 // Start observing the loading of tabs, to make sure the order is correct. | 1363 // Start observing the loading of tabs, to make sure the order is correct. |
1343 StartObserving(NumTabs); | 1364 StartObserving(num_tabs); |
1344 | 1365 |
1345 struct TabInfo { | 1366 struct TabInfo { |
1346 GURL url; | 1367 GURL url; |
1347 bool pinned; | 1368 bool pinned; |
1348 int expected_load_order; | 1369 int expected_load_order; |
1349 }; | 1370 }; |
1350 | 1371 |
1351 TabInfo tab_info[NumTabs] = { | 1372 TabInfo tab_info[num_tabs] = { |
1352 // This will be the foreground tab and will always load first. | 1373 // This will be the foreground tab and will always load first. |
1353 {GURL("http://google.com/1"), false, 1}, | 1374 {GURL("http://google.com/1"), false, 1}, |
1354 {GURL("http://google.com/2"), false, 3}, | 1375 {GURL("http://google.com/2"), false, 3}, |
1355 // Internal page, should load last. | 1376 // Internal page, should load last. |
1356 {GURL(chrome::kChromeUINewTabURL), false, 6}, | 1377 {GURL(chrome::kChromeUINewTabURL), false, 6}, |
1357 {GURL("http://google.com/4"), false, 4}, | 1378 {GURL("http://google.com/4"), false, 4}, |
1358 {GURL("http://google.com/5"), true, 2}, // Pinned, should load second. | 1379 {GURL("http://google.com/5"), true, 2}, // Pinned, should load second. |
1359 {GURL("http://google.com/6"), false, 5}, | 1380 {GURL("http://google.com/6"), false, 5}, |
1360 }; | 1381 }; |
1361 | 1382 |
1362 // Set up the restore data. | 1383 // Set up the restore data. |
1363 std::vector<const sessions::SessionWindow*> session; | 1384 std::vector<const sessions::SessionWindow*> session; |
1364 sessions::SessionWindow window; | 1385 sessions::SessionWindow window; |
1365 sessions::SessionTab tab[NumTabs]; | 1386 sessions::SessionTab tab[num_tabs]; |
1366 | 1387 |
1367 for (int i = 0; i < NumTabs; i++) { | 1388 for (int i = 0; i < num_tabs; i++) { |
1368 SerializedNavigationEntry nav = | 1389 SerializedNavigationEntry nav = |
1369 SerializedNavigationEntryTestHelper::CreateNavigation( | 1390 SerializedNavigationEntryTestHelper::CreateNavigation( |
1370 tab_info[i].url.spec(), tab_info[i].url.spec().c_str()); | 1391 tab_info[i].url.spec(), tab_info[i].url.spec().c_str()); |
1371 sync_pb::SessionTab sync_data; | 1392 sync_pb::SessionTab sync_data; |
1372 sync_data.set_tab_visual_index(0); | 1393 sync_data.set_tab_visual_index(0); |
1373 sync_data.set_current_navigation_index(0); | 1394 sync_data.set_current_navigation_index(0); |
1374 sync_data.add_navigation()->CopyFrom(nav.ToSyncData()); | 1395 sync_data.add_navigation()->CopyFrom(nav.ToSyncData()); |
1375 sync_data.set_pinned(tab_info[i].pinned); | 1396 sync_data.set_pinned(tab_info[i].pinned); |
1376 tab[i].SetFromSyncData(sync_data, base::Time::Now()); | 1397 tab[i].SetFromSyncData(sync_data, base::Time::Now()); |
1377 window.tabs.push_back(tab + i); | 1398 window.tabs.push_back(tab + i); |
1378 } | 1399 } |
1379 | 1400 |
1380 session.push_back(&window); | 1401 session.push_back(&window); |
1381 Profile* profile = browser()->profile(); | 1402 Profile* profile = browser()->profile(); |
1382 ui_test_utils::BrowserAddedObserver window_observer; | |
1383 std::vector<Browser*> browsers = SessionRestore::RestoreForeignSessionWindows( | 1403 std::vector<Browser*> browsers = SessionRestore::RestoreForeignSessionWindows( |
1384 profile, browser()->host_desktop_type(), session.begin(), session.end()); | 1404 profile, browser()->host_desktop_type(), session.begin(), session.end()); |
1385 | 1405 |
1386 ASSERT_EQ(1u, browsers.size()); | 1406 ASSERT_EQ(1u, browsers.size()); |
1387 ASSERT_TRUE(browsers[0]); | 1407 ASSERT_TRUE(browsers[0]); |
1388 ASSERT_EQ(NumTabs, browsers[0]->tab_strip_model()->count()); | 1408 ASSERT_EQ(num_tabs, browsers[0]->tab_strip_model()->count()); |
1389 | 1409 |
1390 WaitForAllTabsToStartLoading(); | 1410 WaitForAllTabsToStartLoading(); |
1391 | 1411 |
1392 ASSERT_EQ(static_cast<size_t>(NumTabs), web_contents().size()); | 1412 ASSERT_EQ(static_cast<size_t>(num_tabs), web_contents().size()); |
1393 | 1413 |
1394 // Make sure that contents are loaded in the correct order, ie. each tab rank | 1414 // Make sure that contents are loaded in the correct order, ie. each tab rank |
1395 // is higher that its preceding one. | 1415 // is higher that its preceding one. |
1396 std::map<GURL, int> ranks; | 1416 std::map<GURL, int> ranks; |
1397 for (auto t : tab_info) | 1417 for (auto t : tab_info) |
1398 ranks[t.url] = t.expected_load_order; | 1418 ranks[t.url] = t.expected_load_order; |
1399 for (size_t i = 1; i < web_contents().size(); i++) { | 1419 for (size_t i = 1; i < web_contents().size(); i++) { |
1400 int current_rank = ranks[web_contents()[i]->GetLastCommittedURL()]; | 1420 int current_rank = ranks[web_contents()[i]->GetLastCommittedURL()]; |
1401 int previous_rank = ranks[web_contents()[i - 1]->GetLastCommittedURL()]; | 1421 int previous_rank = ranks[web_contents()[i - 1]->GetLastCommittedURL()]; |
1402 ASSERT_LT(previous_rank, current_rank); | 1422 ASSERT_LT(previous_rank, current_rank); |
1403 } | 1423 } |
1404 | 1424 |
1405 // The SessionWindow destructor deletes the tabs, so we have to clear them | 1425 // The SessionWindow destructor deletes the tabs, so we have to clear them |
1406 // here to avoid a crash. | 1426 // here to avoid a crash. |
1407 window.tabs.clear(); | 1427 window.tabs.clear(); |
1408 } | 1428 } |
| 1429 |
| 1430 IN_PROC_BROWSER_TEST_F(SmartSessionRestoreMRUTest, CorrectLoadingOrder) { |
| 1431 const int num_tabs = 6; |
| 1432 |
| 1433 Profile* profile = browser()->profile(); |
| 1434 |
| 1435 GURL urls[] = {GURL("http://google.com/1"), |
| 1436 GURL("http://google.com/2"), |
| 1437 GURL("http://google.com/3"), |
| 1438 GURL("http://google.com/4"), |
| 1439 GURL("http://google.com/5"), |
| 1440 GURL("http://google.com/6")}; |
| 1441 |
| 1442 int activation_order[] = {4, 2, 1, 5, 0, 3}; |
| 1443 int activation_order2[] = {4, 2, 5, 0, 3, 1}; |
| 1444 |
| 1445 // Replace the first tab and add the other tabs. |
| 1446 ui_test_utils::NavigateToURL(browser(), urls[0]); |
| 1447 for (int i = 1; i < num_tabs; i++) { |
| 1448 ui_test_utils::NavigateToURLWithDisposition( |
| 1449 browser(), urls[i], NEW_FOREGROUND_TAB, |
| 1450 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 1451 } |
| 1452 |
| 1453 ASSERT_EQ(num_tabs, browser()->tab_strip_model()->count()); |
| 1454 |
| 1455 // Activate the tabs one by one following the random activation order. |
| 1456 for (auto i : activation_order) |
| 1457 browser()->tab_strip_model()->ActivateTabAt(i, true); |
| 1458 |
| 1459 // Close the browser. |
| 1460 g_browser_process->AddRefModule(); |
| 1461 CloseBrowserSynchronously(browser()); |
| 1462 |
| 1463 StartObserving(num_tabs); |
| 1464 |
| 1465 // Create a new window, which should trigger session restore. |
| 1466 ui_test_utils::BrowserAddedObserver window_observer; |
| 1467 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE); |
| 1468 Browser* new_browser = window_observer.WaitForSingleNewBrowser(); |
| 1469 ASSERT_TRUE(new_browser != NULL); |
| 1470 WaitForAllTabsToStartLoading(); |
| 1471 g_browser_process->ReleaseModule(); |
| 1472 |
| 1473 ASSERT_EQ(static_cast<size_t>(num_tabs), web_contents().size()); |
| 1474 // Test that we have observed the tabs being loaded in the inverse order of |
| 1475 // their activation (MRU). Also validate that their last active time is in the |
| 1476 // correct order. |
| 1477 for (size_t i = 0; i < web_contents().size(); i++) { |
| 1478 GURL expected_url = urls[activation_order[num_tabs - i - 1]]; |
| 1479 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL()); |
| 1480 if (i > 0) { |
| 1481 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(), |
| 1482 web_contents()[i]->GetLastActiveTime()); |
| 1483 } |
| 1484 } |
| 1485 |
| 1486 // Activate the 2nd tab then close the browser and open it again, to trigger |
| 1487 // another session restore. The goal is to ensure that activation time is |
| 1488 // persisted between session restores. |
| 1489 |
| 1490 new_browser->tab_strip_model()->ActivateTabAt(1, true); |
| 1491 |
| 1492 // Close the browser. |
| 1493 g_browser_process->AddRefModule(); |
| 1494 CloseBrowserSynchronously(new_browser); |
| 1495 |
| 1496 StartObserving(num_tabs); |
| 1497 |
| 1498 // Create a new window, which should trigger session restore. |
| 1499 ui_test_utils::BrowserAddedObserver window_observer2; |
| 1500 chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE); |
| 1501 Browser* new_browser2 = window_observer2.WaitForSingleNewBrowser(); |
| 1502 ASSERT_TRUE(new_browser2 != NULL); |
| 1503 WaitForAllTabsToStartLoading(); |
| 1504 g_browser_process->ReleaseModule(); |
| 1505 |
| 1506 ASSERT_EQ(static_cast<size_t>(num_tabs), web_contents().size()); |
| 1507 |
| 1508 // Test that we have observed the tabs being loaded in the inverse order of |
| 1509 // their activation (MRU). Also validate that their last active time is in the |
| 1510 // correct order. |
| 1511 for (size_t i = 0; i < web_contents().size(); i++) { |
| 1512 GURL expected_url = urls[activation_order2[num_tabs - i - 1]]; |
| 1513 ASSERT_EQ(expected_url, web_contents()[i]->GetLastCommittedURL()); |
| 1514 if (i > 0) { |
| 1515 ASSERT_GT(web_contents()[i - 1]->GetLastActiveTime(), |
| 1516 web_contents()[i]->GetLastActiveTime()); |
| 1517 } |
| 1518 } |
| 1519 } |
OLD | NEW |