Home | History | Annotate | Download | only in sessions
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <vector>
      6 
      7 #include "base/command_line.h"
      8 #include "base/files/file_path.h"
      9 #include "base/process/launch.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "base/time/time.h"
     12 #include "chrome/browser/browser_process.h"
     13 #include "chrome/browser/chrome_notification_types.h"
     14 #include "chrome/browser/defaults.h"
     15 #include "chrome/browser/first_run/first_run.h"
     16 #include "chrome/browser/profiles/profile.h"
     17 #include "chrome/browser/profiles/profile_manager.h"
     18 #include "chrome/browser/sessions/session_restore.h"
     19 #include "chrome/browser/sessions/session_service.h"
     20 #include "chrome/browser/sessions/session_service_factory.h"
     21 #include "chrome/browser/sessions/session_service_test_helper.h"
     22 #include "chrome/browser/sessions/session_types.h"
     23 #include "chrome/browser/sessions/tab_restore_service.h"
     24 #include "chrome/browser/sessions/tab_restore_service_factory.h"
     25 #include "chrome/browser/ui/browser.h"
     26 #include "chrome/browser/ui/browser_commands.h"
     27 #include "chrome/browser/ui/browser_list.h"
     28 #include "chrome/browser/ui/browser_tabstrip.h"
     29 #include "chrome/browser/ui/browser_window.h"
     30 #include "chrome/browser/ui/host_desktop.h"
     31 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     32 #include "chrome/common/chrome_switches.h"
     33 #include "chrome/common/url_constants.h"
     34 #include "chrome/test/base/in_process_browser_test.h"
     35 #include "chrome/test/base/test_switches.h"
     36 #include "chrome/test/base/ui_test_utils.h"
     37 #include "components/sessions/serialized_navigation_entry_test_helper.h"
     38 #include "content/public/browser/navigation_controller.h"
     39 #include "content/public/browser/navigation_entry.h"
     40 #include "content/public/browser/notification_service.h"
     41 #include "content/public/browser/notification_types.h"
     42 #include "content/public/browser/render_process_host.h"
     43 #include "content/public/browser/render_view_host.h"
     44 #include "content/public/browser/web_contents.h"
     45 #include "content/public/common/bindings_policy.h"
     46 #include "content/public/common/page_transition_types.h"
     47 #include "content/public/test/browser_test_utils.h"
     48 #include "content/public/test/test_navigation_observer.h"
     49 #include "sync/protocol/session_specifics.pb.h"
     50 
     51 using sessions::SerializedNavigationEntry;
     52 using sessions::SerializedNavigationEntryTestHelper;
     53 
     54 #if defined(OS_MACOSX)
     55 #include "base/mac/scoped_nsautorelease_pool.h"
     56 #endif
     57 
     58 #if defined(USE_AURA)
     59 #include "ui/aura/window.h"
     60 #endif
     61 
     62 class SessionRestoreTest : public InProcessBrowserTest {
     63  public:
     64   SessionRestoreTest() : active_browser_list_(NULL) {}
     65 
     66  protected:
     67 #if defined(OS_CHROMEOS)
     68   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
     69     // TODO(nkostylev): Investigate if we can remove this switch.
     70     command_line->AppendSwitch(switches::kCreateBrowserOnStartupForTests);
     71     InProcessBrowserTest::SetUpCommandLine(command_line);
     72   }
     73 #endif
     74 
     75   virtual void SetUpOnMainThread() OVERRIDE {
     76     active_browser_list_ = BrowserList::GetInstance(chrome::GetActiveDesktop());
     77 
     78     SessionStartupPref pref(SessionStartupPref::LAST);
     79     SessionStartupPref::SetStartupPref(browser()->profile(), pref);
     80 #if defined(OS_CHROMEOS)
     81     const testing::TestInfo* const test_info =
     82         testing::UnitTest::GetInstance()->current_test_info();
     83     if (strcmp(test_info->name(), "NoSessionRestoreNewWindowChromeOS") != 0) {
     84       // Undo the effect of kBrowserAliveWithNoWindows in defaults.cc so that we
     85       // can get these test to work without quitting.
     86       SessionServiceTestHelper helper(
     87           SessionServiceFactory::GetForProfile(browser()->profile()));
     88       helper.SetForceBrowserNotAliveWithNoWindows(true);
     89       helper.ReleaseService();
     90     }
     91 #endif
     92 
     93     InProcessBrowserTest::SetUpOnMainThread();
     94   }
     95 
     96   virtual bool SetUpUserDataDirectory() OVERRIDE {
     97     url1_ = ui_test_utils::GetTestUrl(
     98         base::FilePath().AppendASCII("session_history"),
     99         base::FilePath().AppendASCII("bot1.html"));
    100     url2_ = ui_test_utils::GetTestUrl(
    101         base::FilePath().AppendASCII("session_history"),
    102         base::FilePath().AppendASCII("bot2.html"));
    103     url3_ = ui_test_utils::GetTestUrl(
    104         base::FilePath().AppendASCII("session_history"),
    105         base::FilePath().AppendASCII("bot3.html"));
    106 
    107     return InProcessBrowserTest::SetUpUserDataDirectory();
    108   }
    109 
    110   void CloseBrowserSynchronously(Browser* browser) {
    111     content::WindowedNotificationObserver observer(
    112         chrome::NOTIFICATION_BROWSER_CLOSED,
    113         content::NotificationService::AllSources());
    114     browser->window()->Close();
    115 #if defined(OS_MACOSX)
    116     // BrowserWindowController depends on the auto release pool being recycled
    117     // in the message loop to delete itself, which frees the Browser object
    118     // which fires this event.
    119     AutoreleasePool()->Recycle();
    120 #endif
    121     observer.Wait();
    122   }
    123 
    124   Browser* QuitBrowserAndRestore(Browser* browser, int expected_tab_count) {
    125     return QuitBrowserAndRestoreWithURL(browser, expected_tab_count, GURL());
    126   }
    127 
    128   Browser* QuitBrowserAndRestoreWithURL(Browser* browser,
    129                                         int expected_tab_count,
    130                                         const GURL& url) {
    131     Profile* profile = browser->profile();
    132 
    133     // Close the browser.
    134     g_browser_process->AddRefModule();
    135     CloseBrowserSynchronously(browser);
    136 
    137     // Create a new window, which should trigger session restore.
    138     ui_test_utils::BrowserAddedObserver window_observer;
    139     content::WindowedNotificationObserver restore_observer(
    140         chrome::NOTIFICATION_SESSION_RESTORE_DONE,
    141         content::NotificationService::AllSources());
    142     if (url.is_empty()) {
    143       chrome::NewEmptyWindow(profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
    144     } else {
    145       chrome::NavigateParams params(profile,
    146                                     url,
    147                                     content::PAGE_TRANSITION_LINK);
    148       chrome::Navigate(&params);
    149     }
    150     Browser* new_browser = window_observer.WaitForSingleNewBrowser();
    151     restore_observer.Wait();
    152     g_browser_process->ReleaseModule();
    153 
    154     return new_browser;
    155   }
    156 
    157   void GoBack(Browser* browser) {
    158     content::TestNavigationObserver observer(
    159         browser->tab_strip_model()->GetActiveWebContents());
    160     chrome::GoBack(browser, CURRENT_TAB);
    161     observer.Wait();
    162   }
    163 
    164   void GoForward(Browser* browser) {
    165     content::TestNavigationObserver observer(
    166         browser->tab_strip_model()->GetActiveWebContents());
    167     chrome::GoForward(browser, CURRENT_TAB);
    168     observer.Wait();
    169   }
    170 
    171   void AssertOneWindowWithOneTab(Browser* browser) {
    172     ASSERT_EQ(1u, active_browser_list_->size());
    173     ASSERT_EQ(1, browser->tab_strip_model()->count());
    174   }
    175 
    176   int RenderProcessHostCount() {
    177     content::RenderProcessHost::iterator hosts =
    178         content::RenderProcessHost::AllHostsIterator();
    179     int count = 0;
    180     while (!hosts.IsAtEnd()) {
    181       if (hosts.GetCurrentValue()->HasConnection())
    182         count++;
    183       hosts.Advance();
    184     }
    185     return count;
    186   }
    187 
    188   GURL url1_;
    189   GURL url2_;
    190   GURL url3_;
    191 
    192   const BrowserList* active_browser_list_;
    193 };
    194 
    195 #if defined(USE_AURA)
    196 // Verifies that restored tabs have a root window. This is important
    197 // otherwise the wrong information is communicated to the renderer.
    198 // (http://crbug.com/342672).
    199 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoredTabsShouldHaveRootWindow) {
    200   // Create tabs.
    201   ui_test_utils::NavigateToURLWithDisposition(
    202       browser(),
    203       GURL(url::kAboutBlankURL),
    204       NEW_FOREGROUND_TAB,
    205       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    206   ui_test_utils::NavigateToURLWithDisposition(
    207       browser(),
    208       GURL(url::kAboutBlankURL),
    209       NEW_BACKGROUND_TAB,
    210       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    211 
    212   // Restart and session restore the tabs.
    213   Browser* restored = QuitBrowserAndRestore(browser(), 3);
    214   TabStripModel* tab_strip_model = restored->tab_strip_model();
    215   const int tabs = tab_strip_model->count();
    216   ASSERT_EQ(3, tabs);
    217 
    218   // Check the restored tabs have a root window.
    219   for (int i = 0; i < tabs; ++i) {
    220     content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
    221     gfx::NativeView window = contents->GetNativeView();
    222     bool tab_has_root_window = !!window->GetRootWindow();
    223     EXPECT_TRUE(tab_has_root_window);
    224   }
    225 }
    226 #endif  // USE_AURA
    227 
    228 // Verify that restored tabs have correct disposition. Only one tab should
    229 // have "visible" visibility state, the rest should not.
    230 // (http://crbug.com/155365 http://crbug.com/118269)
    231 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
    232     RestoredTabsHaveCorrectVisibilityState) {
    233   // Create tabs.
    234   GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(),
    235       base::FilePath(FILE_PATH_LITERAL("tab-restore-visibilty.html"))));
    236   ui_test_utils::NavigateToURLWithDisposition(
    237       browser(), test_page, NEW_FOREGROUND_TAB,
    238       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    239   ui_test_utils::NavigateToURLWithDisposition(
    240       browser(), test_page, NEW_BACKGROUND_TAB,
    241       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    242 
    243   // Restart and session restore the tabs.
    244   content::DOMMessageQueue message_queue;
    245   Browser* restored = QuitBrowserAndRestore(browser(), 3);
    246   for (int i = 0; i < 2; ++i) {
    247     std::string message;
    248     EXPECT_TRUE(message_queue.WaitForMessage(&message));
    249     EXPECT_EQ("\"READY\"", message);
    250   }
    251 
    252   // There should be 3 restored tabs in the new browser.
    253   TabStripModel* tab_strip_model = restored->tab_strip_model();
    254   const int tabs = tab_strip_model->count();
    255   ASSERT_EQ(3, tabs);
    256 
    257   // The middle tab only should have visible disposition.
    258   for (int i = 0; i < tabs; ++i) {
    259     content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
    260     std::string document_visibility_state;
    261     const char kGetStateJS[] = "window.domAutomationController.send("
    262         "window.document.visibilityState);";
    263     EXPECT_TRUE(content::ExecuteScriptAndExtractString(
    264         contents, kGetStateJS, &document_visibility_state));
    265     if (i == 1) {
    266       EXPECT_EQ("visible", document_visibility_state);
    267     } else {
    268       EXPECT_EQ("hidden", document_visibility_state);
    269     }
    270   }
    271 }
    272 
    273 #if defined(OS_CHROMEOS)
    274 // Verify that session restore does not occur when a user opens a browser window
    275 // when no other browser windows are open on ChromeOS.
    276 // TODO(pkotwicz): Add test which doesn't open incognito browser once
    277 // disable-zero-browsers-open-for-tests is removed.
    278 // (http://crbug.com/119175)
    279 // TODO(pkotwicz): Mac should have the behavior outlined by this test. It should
    280 // not do session restore if an incognito window is already open.
    281 // (http://crbug.com/120927)
    282 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, NoSessionRestoreNewWindowChromeOS) {
    283   GURL url(ui_test_utils::GetTestUrl(
    284       base::FilePath(base::FilePath::kCurrentDirectory),
    285       base::FilePath(FILE_PATH_LITERAL("title1.html"))));
    286 
    287   // Add a single tab.
    288   ui_test_utils::NavigateToURL(browser(), url);
    289 
    290   Browser* incognito_browser = CreateIncognitoBrowser();
    291   chrome::AddTabAt(incognito_browser, GURL(), -1, true);
    292   incognito_browser->window()->Show();
    293 
    294   // Close the normal browser. After this we only have the incognito window
    295   // open.
    296   CloseBrowserSynchronously(browser());
    297 
    298   // Create a new window, which should open NTP.
    299   ui_test_utils::BrowserAddedObserver browser_added_observer;
    300   chrome::NewWindow(incognito_browser);
    301   Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
    302 
    303   ASSERT_TRUE(new_browser);
    304   EXPECT_EQ(1, new_browser->tab_strip_model()->count());
    305   EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
    306             new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
    307 }
    308 
    309 // Test that maximized applications get restored maximized.
    310 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, MaximizedApps) {
    311   const char* app_name = "TestApp";
    312   Browser* app_browser = CreateBrowserForApp(app_name, browser()->profile());
    313   app_browser->window()->Maximize();
    314   app_browser->window()->Show();
    315   EXPECT_TRUE(app_browser->window()->IsMaximized());
    316   EXPECT_TRUE(app_browser->is_app());
    317   EXPECT_TRUE(app_browser->is_type_popup());
    318 
    319   // Close the normal browser. After this we only have the app_browser window.
    320   CloseBrowserSynchronously(browser());
    321 
    322   // Create a new window, which should open NTP.
    323   ui_test_utils::BrowserAddedObserver browser_added_observer;
    324   chrome::NewWindow(app_browser);
    325   Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
    326 
    327   ASSERT_TRUE(new_browser);
    328   EXPECT_TRUE(app_browser->window()->IsMaximized());
    329   EXPECT_TRUE(app_browser->is_app());
    330   EXPECT_TRUE(app_browser->is_type_popup());
    331 }
    332 #endif  // OS_CHROMEOS
    333 
    334 #if !defined(OS_CHROMEOS)
    335 // This test does not apply to ChromeOS as it does not do session restore when
    336 // a new window is opened.
    337 
    338 #if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
    339 // Crashes on Linux Views: http://crbug.com/39476
    340 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
    341         DISABLED_RestoreOnNewWindowWithNoTabbedBrowsers
    342 #else
    343 #define MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers \
    344         RestoreOnNewWindowWithNoTabbedBrowsers
    345 #endif
    346 
    347 // Makes sure when session restore is triggered in the same process we don't end
    348 // up with an extra tab.
    349 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
    350                        MAYBE_RestoreOnNewWindowWithNoTabbedBrowsers) {
    351   const base::FilePath::CharType* kTitle1File =
    352       FILE_PATH_LITERAL("title1.html");
    353   GURL url(ui_test_utils::GetTestUrl(base::FilePath(
    354       base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File)));
    355   ui_test_utils::NavigateToURL(browser(), url);
    356 
    357   // Turn on session restore.
    358   SessionStartupPref::SetStartupPref(
    359       browser()->profile(),
    360       SessionStartupPref(SessionStartupPref::LAST));
    361 
    362   // Create a new popup.
    363   Profile* profile = browser()->profile();
    364   Browser* popup =
    365       new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile,
    366                                         browser()->host_desktop_type()));
    367   popup->window()->Show();
    368 
    369   // Close the browser.
    370   CloseBrowserSynchronously(browser());
    371 
    372   // Create a new window, which should trigger session restore.
    373   ui_test_utils::BrowserAddedObserver observer;
    374   chrome::NewWindow(popup);
    375   Browser* new_browser = observer.WaitForSingleNewBrowser();
    376 
    377   ASSERT_TRUE(new_browser != NULL);
    378 
    379   // The browser should only have one tab.
    380   ASSERT_EQ(1, new_browser->tab_strip_model()->count());
    381 
    382   // And the first url should be url.
    383   EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
    384 }
    385 #endif  // !OS_CHROMEOS
    386 
    387 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreIndividualTabFromWindow) {
    388   GURL url1(ui_test_utils::GetTestUrl(
    389       base::FilePath(base::FilePath::kCurrentDirectory),
    390       base::FilePath(FILE_PATH_LITERAL("title1.html"))));
    391   // Any page that will yield a 200 status code will work here.
    392   GURL url2("about:version");
    393   GURL url3(ui_test_utils::GetTestUrl(
    394       base::FilePath(base::FilePath::kCurrentDirectory),
    395       base::FilePath(FILE_PATH_LITERAL("title3.html"))));
    396 
    397   // Add and navigate three tabs.
    398   ui_test_utils::NavigateToURL(browser(), url1);
    399   {
    400     content::WindowedNotificationObserver observer(
    401         content::NOTIFICATION_LOAD_STOP,
    402         content::NotificationService::AllSources());
    403     chrome::AddSelectedTabWithURL(browser(), url2,
    404                                   content::PAGE_TRANSITION_LINK);
    405     observer.Wait();
    406   }
    407   {
    408     content::WindowedNotificationObserver observer(
    409         content::NOTIFICATION_LOAD_STOP,
    410         content::NotificationService::AllSources());
    411     chrome::AddSelectedTabWithURL(browser(), url3,
    412                                   content::PAGE_TRANSITION_LINK);
    413     observer.Wait();
    414   }
    415 
    416   TabRestoreService* service =
    417       TabRestoreServiceFactory::GetForProfile(browser()->profile());
    418   service->ClearEntries();
    419 
    420   chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
    421 
    422   browser()->window()->Close();
    423 
    424   // Expect a window with three tabs.
    425   ASSERT_EQ(1U, service->entries().size());
    426   ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
    427   const TabRestoreService::Window* window =
    428       static_cast<TabRestoreService::Window*>(service->entries().front());
    429   EXPECT_EQ(3U, window->tabs.size());
    430 
    431   // Find the SessionID for entry2. Since the session service was destroyed,
    432   // there is no guarantee that the SessionID for the tab has remained the same.
    433   base::Time timestamp;
    434   int http_status_code = 0;
    435   for (std::vector<TabRestoreService::Tab>::const_iterator it =
    436            window->tabs.begin(); it != window->tabs.end(); ++it) {
    437     const TabRestoreService::Tab& tab = *it;
    438     // If this tab held url2, then restore this single tab.
    439     if (tab.navigations[0].virtual_url() == url2) {
    440       timestamp = tab.navigations[0].timestamp();
    441       http_status_code = tab.navigations[0].http_status_code();
    442       std::vector<content::WebContents*> content =
    443           service->RestoreEntryById(NULL, tab.id, host_desktop_type, UNKNOWN);
    444       ASSERT_EQ(1U, content.size());
    445       ASSERT_TRUE(content[0]);
    446       EXPECT_EQ(url2, content[0]->GetURL());
    447       break;
    448     }
    449   }
    450   EXPECT_FALSE(timestamp.is_null());
    451   EXPECT_EQ(200, http_status_code);
    452 
    453   // Make sure that the restored tab is removed from the service.
    454   ASSERT_EQ(1U, service->entries().size());
    455   ASSERT_EQ(TabRestoreService::WINDOW, service->entries().front()->type);
    456   window = static_cast<TabRestoreService::Window*>(service->entries().front());
    457   EXPECT_EQ(2U, window->tabs.size());
    458 
    459   // Make sure that the restored tab was restored with the correct
    460   // timestamp and status code.
    461   const content::WebContents* contents =
    462       browser()->tab_strip_model()->GetActiveWebContents();
    463   ASSERT_TRUE(contents);
    464   const content::NavigationEntry* entry =
    465       contents->GetController().GetActiveEntry();
    466   ASSERT_TRUE(entry);
    467   EXPECT_EQ(timestamp, entry->GetTimestamp());
    468   EXPECT_EQ(http_status_code, entry->GetHttpStatusCode());
    469 }
    470 
    471 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, WindowWithOneTab) {
    472   GURL url(ui_test_utils::GetTestUrl(
    473       base::FilePath(base::FilePath::kCurrentDirectory),
    474       base::FilePath(FILE_PATH_LITERAL("title1.html"))));
    475 
    476   // Add a single tab.
    477   ui_test_utils::NavigateToURL(browser(), url);
    478 
    479   TabRestoreService* service =
    480       TabRestoreServiceFactory::GetForProfile(browser()->profile());
    481   service->ClearEntries();
    482   EXPECT_EQ(0U, service->entries().size());
    483 
    484   chrome::HostDesktopType host_desktop_type = browser()->host_desktop_type();
    485 
    486   // Close the window.
    487   browser()->window()->Close();
    488 
    489   // Expect the window to be converted to a tab by the TRS.
    490   EXPECT_EQ(1U, service->entries().size());
    491   ASSERT_EQ(TabRestoreService::TAB, service->entries().front()->type);
    492   const TabRestoreService::Tab* tab =
    493       static_cast<TabRestoreService::Tab*>(service->entries().front());
    494 
    495   // Restore the tab.
    496   std::vector<content::WebContents*> content =
    497       service->RestoreEntryById(NULL, tab->id, host_desktop_type, UNKNOWN);
    498   ASSERT_EQ(1U, content.size());
    499   ASSERT_TRUE(content[0]);
    500   EXPECT_EQ(url, content[0]->GetURL());
    501 
    502   // Make sure the restore was successful.
    503   EXPECT_EQ(0U, service->entries().size());
    504 }
    505 
    506 #if !defined(OS_CHROMEOS)
    507 // This test does not apply to ChromeOS as ChromeOS does not do session
    508 // restore when a new window is open.
    509 
    510 // Verifies we remember the last browser window when closing the last
    511 // non-incognito window while an incognito window is open.
    512 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, IncognitotoNonIncognito) {
    513   GURL url(ui_test_utils::GetTestUrl(
    514       base::FilePath(base::FilePath::kCurrentDirectory),
    515       base::FilePath(FILE_PATH_LITERAL("title1.html"))));
    516 
    517   // Add a single tab.
    518   ui_test_utils::NavigateToURL(browser(), url);
    519 
    520   // Create a new incognito window.
    521   Browser* incognito_browser = CreateIncognitoBrowser();
    522   chrome::AddTabAt(incognito_browser, GURL(), -1, true);
    523   incognito_browser->window()->Show();
    524 
    525   // Close the normal browser. After this we only have the incognito window
    526   // open.
    527   CloseBrowserSynchronously(browser());
    528 
    529   // Create a new window, which should trigger session restore.
    530   ui_test_utils::BrowserAddedObserver browser_added_observer;
    531   chrome::NewWindow(incognito_browser);
    532   Browser* new_browser = browser_added_observer.WaitForSingleNewBrowser();
    533 
    534   // The first tab should have 'url' as its url.
    535   ASSERT_TRUE(new_browser);
    536   EXPECT_EQ(url, new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
    537 }
    538 #endif  // !OS_CHROMEOS
    539 
    540 namespace {
    541 
    542 // Verifies that the given NavigationController has exactly two
    543 // entries that correspond to the given URLs and that all but the last
    544 // entry have null timestamps.
    545 void VerifyNavigationEntries(
    546     const content::NavigationController& controller,
    547     GURL url1, GURL url2) {
    548   ASSERT_EQ(2, controller.GetEntryCount());
    549   EXPECT_EQ(1, controller.GetCurrentEntryIndex());
    550   EXPECT_EQ(url1, controller.GetEntryAtIndex(0)->GetURL());
    551   EXPECT_EQ(url2, controller.GetEntryAtIndex(1)->GetURL());
    552   EXPECT_TRUE(controller.GetEntryAtIndex(0)->GetTimestamp().is_null());
    553   EXPECT_FALSE(controller.GetEntryAtIndex(1)->GetTimestamp().is_null());
    554 }
    555 
    556 }  // namespace
    557 
    558 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignTab) {
    559   GURL url1("http://google.com");
    560   GURL url2("http://google2.com");
    561   SerializedNavigationEntry nav1 =
    562       SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
    563   SerializedNavigationEntry nav2 =
    564       SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
    565 
    566   // Set up the restore data.
    567   sync_pb::SessionTab sync_data;
    568   sync_data.set_tab_visual_index(0);
    569   sync_data.set_current_navigation_index(1);
    570   sync_data.set_pinned(false);
    571   sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
    572   sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
    573 
    574   SessionTab tab;
    575   tab.SetFromSyncData(sync_data, base::Time::Now());
    576   EXPECT_EQ(2U, tab.navigations.size());
    577   for (size_t i = 0; i < tab.navigations.size(); ++i)
    578     EXPECT_TRUE(tab.navigations[i].timestamp().is_null());
    579 
    580   ASSERT_EQ(1, browser()->tab_strip_model()->count());
    581 
    582   // Restore in the current tab.
    583   content::WebContents* tab_content = NULL;
    584   {
    585     content::WindowedNotificationObserver observer(
    586         content::NOTIFICATION_LOAD_STOP,
    587         content::NotificationService::AllSources());
    588     tab_content = SessionRestore::RestoreForeignSessionTab(
    589         browser()->tab_strip_model()->GetActiveWebContents(), tab, CURRENT_TAB);
    590     observer.Wait();
    591   }
    592   ASSERT_EQ(1, browser()->tab_strip_model()->count());
    593   content::WebContents* web_contents =
    594       browser()->tab_strip_model()->GetWebContentsAt(0);
    595   VerifyNavigationEntries(web_contents->GetController(), url1, url2);
    596   ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
    597   ASSERT_TRUE(tab_content);
    598   ASSERT_EQ(url2, tab_content->GetURL());
    599 
    600   // Restore in a new tab.
    601   tab_content = NULL;
    602   {
    603     content::WindowedNotificationObserver observer(
    604         content::NOTIFICATION_LOAD_STOP,
    605         content::NotificationService::AllSources());
    606     tab_content = SessionRestore::RestoreForeignSessionTab(
    607         browser()->tab_strip_model()->GetActiveWebContents(),
    608         tab, NEW_BACKGROUND_TAB);
    609     observer.Wait();
    610   }
    611   ASSERT_EQ(2, browser()->tab_strip_model()->count());
    612   ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
    613   web_contents = browser()->tab_strip_model()->GetWebContentsAt(1);
    614   VerifyNavigationEntries(web_contents->GetController(), url1, url2);
    615   ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
    616   ASSERT_TRUE(tab_content);
    617   ASSERT_EQ(url2, tab_content->GetURL());
    618 
    619   // Restore in a new window.
    620   Browser* new_browser = NULL;
    621   tab_content = NULL;
    622   {
    623     ui_test_utils::BrowserAddedObserver browser_observer;
    624     content::WindowedNotificationObserver observer(
    625         content::NOTIFICATION_LOAD_STOP,
    626         content::NotificationService::AllSources());
    627     tab_content = SessionRestore::RestoreForeignSessionTab(
    628         browser()->tab_strip_model()->GetActiveWebContents(), tab, NEW_WINDOW);
    629     new_browser = browser_observer.WaitForSingleNewBrowser();
    630     observer.Wait();
    631   }
    632 
    633   ASSERT_EQ(1, new_browser->tab_strip_model()->count());
    634   web_contents = new_browser->tab_strip_model()->GetWebContentsAt(0);
    635   VerifyNavigationEntries(web_contents->GetController(), url1, url2);
    636   ASSERT_TRUE(web_contents->GetUserAgentOverride().empty());
    637   ASSERT_TRUE(tab_content);
    638   ASSERT_EQ(url2, tab_content->GetURL());
    639 }
    640 
    641 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreForeignSession) {
    642   Profile* profile = browser()->profile();
    643 
    644   GURL url1("http://google.com");
    645   GURL url2("http://google2.com");
    646   SerializedNavigationEntry nav1 =
    647       SerializedNavigationEntryTestHelper::CreateNavigation(url1.spec(), "one");
    648   SerializedNavigationEntry nav2 =
    649       SerializedNavigationEntryTestHelper::CreateNavigation(url2.spec(), "two");
    650   SerializedNavigationEntryTestHelper::SetIsOverridingUserAgent(true, &nav2);
    651 
    652   // Set up the restore data -- one window with two tabs.
    653   std::vector<const SessionWindow*> session;
    654   SessionWindow window;
    655   SessionTab tab1;
    656   {
    657     sync_pb::SessionTab sync_data;
    658     sync_data.set_tab_visual_index(0);
    659     sync_data.set_current_navigation_index(0);
    660     sync_data.set_pinned(true);
    661     sync_data.add_navigation()->CopyFrom(nav1.ToSyncData());
    662     tab1.SetFromSyncData(sync_data, base::Time::Now());
    663   }
    664   window.tabs.push_back(&tab1);
    665 
    666   SessionTab tab2;
    667   {
    668     sync_pb::SessionTab sync_data;
    669     sync_data.set_tab_visual_index(1);
    670     sync_data.set_current_navigation_index(0);
    671     sync_data.set_pinned(false);
    672     sync_data.add_navigation()->CopyFrom(nav2.ToSyncData());
    673     tab2.SetFromSyncData(sync_data, base::Time::Now());
    674   }
    675   window.tabs.push_back(&tab2);
    676 
    677   // Leave tab3 empty. Should have no effect on restored session, but simulates
    678   // partially complete foreign session data.
    679   SessionTab tab3;
    680   window.tabs.push_back(&tab3);
    681 
    682   session.push_back(static_cast<const SessionWindow*>(&window));
    683   ui_test_utils::BrowserAddedObserver window_observer;
    684   std::vector<Browser*> browsers =
    685       SessionRestore::RestoreForeignSessionWindows(
    686           profile, browser()->host_desktop_type(), session.begin(),
    687           session.end());
    688   Browser* new_browser = window_observer.WaitForSingleNewBrowser();
    689   ASSERT_TRUE(new_browser);
    690   ASSERT_EQ(2u, active_browser_list_->size());
    691   ASSERT_EQ(2, new_browser->tab_strip_model()->count());
    692 
    693   ASSERT_EQ(1u, browsers.size());
    694   ASSERT_TRUE(browsers[0]);
    695   ASSERT_EQ(2, browsers[0]->tab_strip_model()->count());
    696 
    697   content::WebContents* web_contents_1 =
    698       new_browser->tab_strip_model()->GetWebContentsAt(0);
    699   content::WebContents* web_contents_2 =
    700       new_browser->tab_strip_model()->GetWebContentsAt(1);
    701   ASSERT_EQ(url1, web_contents_1->GetURL());
    702   ASSERT_EQ(url2, web_contents_2->GetURL());
    703 
    704   // Check user agent override state.
    705   ASSERT_TRUE(web_contents_1->GetUserAgentOverride().empty());
    706   ASSERT_TRUE(web_contents_2->GetUserAgentOverride().empty());
    707 
    708   content::NavigationEntry* entry =
    709       web_contents_1->GetController().GetActiveEntry();
    710   ASSERT_TRUE(entry);
    711   ASSERT_FALSE(entry->GetIsOverridingUserAgent());
    712 
    713   entry = web_contents_2->GetController().GetActiveEntry();
    714   ASSERT_TRUE(entry);
    715   ASSERT_FALSE(entry->GetIsOverridingUserAgent());
    716 
    717   // The SessionWindow destructor deletes the tabs, so we have to clear them
    718   // here to avoid a crash.
    719   window.tabs.clear();
    720 }
    721 
    722 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, Basic) {
    723   ui_test_utils::NavigateToURL(browser(), url1_);
    724   ui_test_utils::NavigateToURL(browser(), url2_);
    725 
    726   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
    727   ASSERT_EQ(1u, active_browser_list_->size());
    728   ASSERT_EQ(url2_,
    729             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    730   GoBack(new_browser);
    731   ASSERT_EQ(url1_,
    732             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    733 }
    734 
    735 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUI) {
    736   const GURL webui_url("chrome://omnibox");
    737   ui_test_utils::NavigateToURL(browser(), webui_url);
    738   const content::WebContents* old_tab =
    739       browser()->tab_strip_model()->GetActiveWebContents();
    740   EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
    741             old_tab->GetRenderViewHost()->GetEnabledBindings());
    742 
    743   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
    744   ASSERT_EQ(1u, active_browser_list_->size());
    745   const content::WebContents* new_tab =
    746       new_browser->tab_strip_model()->GetActiveWebContents();
    747   EXPECT_EQ(webui_url, new_tab->GetURL());
    748   EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
    749             new_tab->GetRenderViewHost()->GetEnabledBindings());
    750 }
    751 
    752 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWebUISettings) {
    753   const GURL webui_url("chrome://settings");
    754   ui_test_utils::NavigateToURL(browser(), webui_url);
    755   const content::WebContents* old_tab =
    756       browser()->tab_strip_model()->GetActiveWebContents();
    757   EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
    758             old_tab->GetRenderViewHost()->GetEnabledBindings());
    759 
    760   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
    761   ASSERT_EQ(1u, active_browser_list_->size());
    762   const content::WebContents* new_tab =
    763       new_browser->tab_strip_model()->GetActiveWebContents();
    764   EXPECT_EQ(webui_url, new_tab->GetURL());
    765   EXPECT_EQ(content::BINDINGS_POLICY_WEB_UI,
    766             new_tab->GetRenderViewHost()->GetEnabledBindings());
    767 }
    768 
    769 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoresForwardAndBackwardNavs) {
    770   ui_test_utils::NavigateToURL(browser(), url1_);
    771   ui_test_utils::NavigateToURL(browser(), url2_);
    772   ui_test_utils::NavigateToURL(browser(), url3_);
    773 
    774   GoBack(browser());
    775   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
    776   ASSERT_EQ(1u, active_browser_list_->size());
    777   ASSERT_EQ(url2_,
    778             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    779   GoForward(new_browser);
    780   ASSERT_EQ(url3_,
    781             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    782   GoBack(new_browser);
    783   ASSERT_EQ(url2_,
    784             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    785 
    786   // Test renderer-initiated back/forward as well.
    787   GURL go_back_url("javascript:history.back();");
    788   ui_test_utils::NavigateToURL(new_browser, go_back_url);
    789   ASSERT_EQ(url1_,
    790             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    791 }
    792 
    793 // Tests that the SiteInstances used for entries in a restored tab's history
    794 // are given appropriate max page IDs, so that going back to a restored
    795 // cross-site page and then forward again works.  (Bug 1204135)
    796 // This test fails. See http://crbug.com/237497.
    797 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
    798                        DISABLED_RestoresCrossSiteForwardAndBackwardNavs) {
    799   ASSERT_TRUE(test_server()->Start());
    800 
    801   GURL cross_site_url(test_server()->GetURL("files/title2.html"));
    802 
    803   // Visit URLs on different sites.
    804   ui_test_utils::NavigateToURL(browser(), url1_);
    805   ui_test_utils::NavigateToURL(browser(), cross_site_url);
    806   ui_test_utils::NavigateToURL(browser(), url2_);
    807 
    808   GoBack(browser());
    809   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
    810   ASSERT_EQ(1u, active_browser_list_->size());
    811   ASSERT_EQ(1, new_browser->tab_strip_model()->count());
    812 
    813   // Check that back and forward work as expected.
    814   ASSERT_EQ(cross_site_url,
    815             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    816 
    817   GoBack(new_browser);
    818   ASSERT_EQ(url1_,
    819             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    820 
    821   GoForward(new_browser);
    822   ASSERT_EQ(cross_site_url,
    823             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    824 
    825   // Test renderer-initiated back/forward as well.
    826   GURL go_forward_url("javascript:history.forward();");
    827   ui_test_utils::NavigateToURL(new_browser, go_forward_url);
    828   ASSERT_EQ(url2_,
    829             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    830 }
    831 
    832 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoTabsSecondSelected) {
    833   ui_test_utils::NavigateToURL(browser(), url1_);
    834 
    835   ui_test_utils::NavigateToURLWithDisposition(
    836       browser(), url2_, NEW_FOREGROUND_TAB,
    837       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    838 
    839   Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
    840 
    841   ASSERT_EQ(1u, active_browser_list_->size());
    842   ASSERT_EQ(2, new_browser->tab_strip_model()->count());
    843   ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
    844   ASSERT_EQ(url2_,
    845             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    846 
    847   ASSERT_EQ(url1_,
    848             new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
    849 }
    850 
    851 // Creates two tabs, closes one, quits and makes sure only one tab is restored.
    852 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClosedTabStaysClosed) {
    853   ui_test_utils::NavigateToURL(browser(), url1_);
    854 
    855   ui_test_utils::NavigateToURLWithDisposition(
    856       browser(), url2_, NEW_FOREGROUND_TAB,
    857       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    858   chrome::CloseTab(browser());
    859 
    860   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
    861 
    862   AssertOneWindowWithOneTab(new_browser);
    863   ASSERT_EQ(url1_,
    864             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    865 }
    866 
    867 // Ensures active tab properly restored when tabs before it closed.
    868 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtClose) {
    869   ui_test_utils::NavigateToURL(browser(), url1_);
    870   ui_test_utils::NavigateToURLWithDisposition(
    871       browser(), url2_, NEW_FOREGROUND_TAB,
    872       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    873   ui_test_utils::NavigateToURLWithDisposition(
    874       browser(), url3_, NEW_BACKGROUND_TAB,
    875       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    876 
    877   browser()->tab_strip_model()->CloseWebContentsAt(
    878       0,
    879       TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
    880 
    881   Browser* new_browser = QuitBrowserAndRestore(browser(), 2);
    882 
    883   ASSERT_EQ(url2_,
    884             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    885   ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 0);
    886 }
    887 
    888 // Ensures active tab properly restored when tabs are inserted before it .
    889 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ActiveIndexUpdatedAtInsert) {
    890   ui_test_utils::NavigateToURL(browser(), url1_);
    891   ui_test_utils::NavigateToURLWithDisposition(
    892       browser(), url2_, NEW_BACKGROUND_TAB,
    893       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    894 
    895   chrome::NavigateParams navigate_params(browser(), url3_,
    896                                          content::PAGE_TRANSITION_TYPED);
    897   navigate_params.tabstrip_index = 0;
    898   navigate_params.disposition = NEW_BACKGROUND_TAB;
    899   ui_test_utils::NavigateToURL(&navigate_params);
    900 
    901   Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
    902 
    903   ASSERT_EQ(url1_,
    904             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    905   ASSERT_EQ(new_browser->tab_strip_model()->active_index(), 1);
    906 }
    907 
    908 #if !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
    909 // This test doesn't apply to the Mac version; see GetCommandLineForRelaunch
    910 // for details. It was disabled for a long time so might never have worked on
    911 // ChromeOS.
    912 
    913 // Launches an app window, closes tabbed browser, launches and makes sure
    914 // we restore the tabbed browser url.
    915 // If this test flakes, use http://crbug.com/29110
    916 IN_PROC_BROWSER_TEST_F(SessionRestoreTest,
    917                        RestoreAfterClosingTabbedBrowserWithAppAndLaunching) {
    918 #if defined(OS_WIN) && defined(USE_ASH)
    919   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    920   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    921     return;
    922 #endif
    923 
    924   ui_test_utils::NavigateToURL(browser(), url1_);
    925 
    926   // Launch an app.
    927   CommandLine app_launch_arguments = GetCommandLineForRelaunch();
    928   app_launch_arguments.AppendSwitchASCII(switches::kApp, url2_.spec());
    929 
    930   ui_test_utils::BrowserAddedObserver window_observer;
    931 
    932   base::LaunchProcess(app_launch_arguments, base::LaunchOptionsForTest(), NULL);
    933 
    934   Browser* app_window = window_observer.WaitForSingleNewBrowser();
    935   ASSERT_EQ(2u, active_browser_list_->size());
    936 
    937   // Close the first window. The only window left is the App window.
    938   CloseBrowserSynchronously(browser());
    939 
    940   // Restore the session, which should bring back the first window with url1_.
    941   Browser* new_browser = QuitBrowserAndRestore(app_window, 1);
    942 
    943   AssertOneWindowWithOneTab(new_browser);
    944 
    945   ASSERT_EQ(url1_,
    946             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    947 }
    948 
    949 #endif  // !defined(OS_CHROMEOS) && !defined(OS_MACOSX)
    950 
    951 // Creates two windows, closes one, restores, make sure only one window open.
    952 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, TwoWindowsCloseOneRestoreOnlyOne) {
    953   ui_test_utils::NavigateToURL(browser(), url1_);
    954 
    955   // Open a second window.
    956   ui_test_utils::NavigateToURLWithDisposition(
    957       browser(),
    958       GURL(url::kAboutBlankURL),
    959       NEW_WINDOW,
    960       ui_test_utils::BROWSER_TEST_WAIT_FOR_BROWSER);
    961 
    962   ASSERT_EQ(2u, active_browser_list_->size());
    963 
    964   // Close it.
    965   Browser* new_window = active_browser_list_->get(1);
    966   CloseBrowserSynchronously(new_window);
    967 
    968   // Restart and make sure we have only one window with one tab and the url
    969   // is url1_.
    970   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
    971 
    972   AssertOneWindowWithOneTab(new_browser);
    973 
    974   ASSERT_EQ(url1_,
    975             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
    976 }
    977 
    978 // Make sure after a restore the number of processes matches that of the number
    979 // of processes running before the restore. This creates a new tab so that
    980 // we should have two new tabs running.  (This test will pass in both
    981 // process-per-site and process-per-site-instance, because we treat the new tab
    982 // as a special case in process-per-site-instance so that it only ever uses one
    983 // process.)
    984 //
    985 // Flaky: http://code.google.com/p/chromium/issues/detail?id=52022
    986 // Unfortunately, the fix at http://codereview.chromium.org/6546078
    987 // breaks NTP background image refreshing, so ThemeSource had to revert to
    988 // replacing the existing data source.
    989 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ShareProcessesOnRestore) {
    990   // Create two new tabs.
    991   ui_test_utils::NavigateToURLWithDisposition(
    992       browser(),
    993       GURL(url::kAboutBlankURL),
    994       NEW_FOREGROUND_TAB,
    995       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    996   ui_test_utils::NavigateToURLWithDisposition(
    997       browser(),
    998       GURL(url::kAboutBlankURL),
    999       NEW_FOREGROUND_TAB,
   1000       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1001 
   1002   int expected_process_count = RenderProcessHostCount();
   1003 
   1004   // Restart.
   1005   Browser* new_browser = QuitBrowserAndRestore(browser(), 3);
   1006 
   1007   ASSERT_EQ(3, new_browser->tab_strip_model()->count());
   1008 
   1009   ASSERT_EQ(expected_process_count, RenderProcessHostCount());
   1010 }
   1011 
   1012 // Test that changing the user agent override will persist it to disk.
   1013 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, PersistAndRestoreUserAgentOverride) {
   1014   // Create a tab with an overridden user agent.
   1015   ui_test_utils::NavigateToURL(browser(), url1_);
   1016   ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
   1017   browser()->tab_strip_model()->GetWebContentsAt(0)->
   1018       SetUserAgentOverride("override");
   1019 
   1020   // Create a tab without an overridden user agent.
   1021   ui_test_utils::NavigateToURLWithDisposition(
   1022       browser(), url2_, NEW_FOREGROUND_TAB,
   1023       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1024   ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
   1025 
   1026   // Kill the original browser then open a new one to trigger a restore.
   1027   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
   1028   ASSERT_EQ(1u, active_browser_list_->size());
   1029   ASSERT_EQ(2, new_browser->tab_strip_model()->count());
   1030   ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
   1031 
   1032   // Confirm that the user agent overrides are properly set.
   1033   EXPECT_EQ("override",
   1034             new_browser->tab_strip_model()->GetWebContentsAt(0)->
   1035                 GetUserAgentOverride());
   1036   EXPECT_EQ("",
   1037             new_browser->tab_strip_model()->GetWebContentsAt(1)->
   1038                 GetUserAgentOverride());
   1039 }
   1040 
   1041 // Regression test for crbug.com/125958. When restoring a pinned selected tab in
   1042 // a setting where there are existing tabs, the selected index computation was
   1043 // wrong, leading to the wrong tab getting selected, DCHECKs firing, and the
   1044 // pinned tab not getting loaded.
   1045 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestorePinnedSelectedTab) {
   1046   // Create a pinned tab.
   1047   ui_test_utils::NavigateToURL(browser(), url1_);
   1048   browser()->tab_strip_model()->SetTabPinned(0, true);
   1049   ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
   1050   // Create a nonpinned tab.
   1051   ui_test_utils::NavigateToURLWithDisposition(
   1052       browser(), url2_, NEW_FOREGROUND_TAB,
   1053       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1054   ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
   1055   // Select the pinned tab.
   1056   browser()->tab_strip_model()->ActivateTabAt(0, true);
   1057   ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
   1058   Profile* profile = browser()->profile();
   1059 
   1060   // This will also initiate a session restore, but we're not interested in it.
   1061   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
   1062   ASSERT_EQ(1u, active_browser_list_->size());
   1063   ASSERT_EQ(2, new_browser->tab_strip_model()->count());
   1064   ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
   1065   // Close the pinned tab.
   1066   chrome::CloseTab(new_browser);
   1067   ASSERT_EQ(1, new_browser->tab_strip_model()->count());
   1068   ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
   1069   // Use the existing tab to navigate away, so that we can verify it was really
   1070   // clobbered.
   1071   ui_test_utils::NavigateToURL(new_browser, url3_);
   1072 
   1073   // Restore the session again, clobbering the existing tab.
   1074   SessionRestore::RestoreSession(
   1075       profile, new_browser,
   1076       new_browser->host_desktop_type(),
   1077       SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
   1078       std::vector<GURL>());
   1079 
   1080   // The pinned tab is the selected tab.
   1081   ASSERT_EQ(2, new_browser->tab_strip_model()->count());
   1082   EXPECT_EQ(0, new_browser->tab_strip_model()->active_index());
   1083   EXPECT_EQ(url1_,
   1084             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
   1085   EXPECT_EQ(url2_,
   1086             new_browser->tab_strip_model()->GetWebContentsAt(1)->GetURL());
   1087 }
   1088 
   1089 // Regression test for crbug.com/240156. When restoring tabs with a navigation,
   1090 // the navigation should take active tab focus.
   1091 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, RestoreWithNavigateSelectedTab) {
   1092   // Create 2 tabs.
   1093   ui_test_utils::NavigateToURL(browser(), url1_);
   1094   ui_test_utils::NavigateToURLWithDisposition(
   1095       browser(), url2_, NEW_FOREGROUND_TAB,
   1096       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1097 
   1098   // Restore the session by calling chrome::Navigate().
   1099   Browser* new_browser = QuitBrowserAndRestoreWithURL(browser(), 3, url3_);
   1100   ASSERT_EQ(1u, active_browser_list_->size());
   1101   ASSERT_EQ(3, new_browser->tab_strip_model()->count());
   1102   // Navigated url should be the active tab.
   1103   ASSERT_EQ(url3_,
   1104             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
   1105 }
   1106 
   1107 // Do a clobber restore from the new tab page. This test follows the code path
   1108 // of a crash followed by the user clicking restore from the new tab page.
   1109 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, ClobberRestoreTest) {
   1110   // Create 2 tabs.
   1111   ui_test_utils::NavigateToURL(browser(), url1_);
   1112   ASSERT_EQ(0, browser()->tab_strip_model()->active_index());
   1113   ui_test_utils::NavigateToURLWithDisposition(
   1114       browser(), url2_, NEW_FOREGROUND_TAB,
   1115       ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
   1116   ASSERT_EQ(1, browser()->tab_strip_model()->active_index());
   1117   Profile* profile = browser()->profile();
   1118 
   1119   // This will also initiate a session restore, but we're not interested in it.
   1120   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
   1121   ASSERT_EQ(1u, active_browser_list_->size());
   1122   ASSERT_EQ(2, new_browser->tab_strip_model()->count());
   1123   ASSERT_EQ(1, new_browser->tab_strip_model()->active_index());
   1124   // Close the first tab.
   1125   chrome::CloseTab(new_browser);
   1126   ASSERT_EQ(1, new_browser->tab_strip_model()->count());
   1127   ASSERT_EQ(0, new_browser->tab_strip_model()->active_index());
   1128   // Use the existing tab to navigate to the NTP.
   1129   ui_test_utils::NavigateToURL(new_browser, GURL(chrome::kChromeUINewTabURL));
   1130 
   1131   // Restore the session again, clobbering the existing tab.
   1132   SessionRestore::RestoreSession(
   1133       profile, new_browser,
   1134       new_browser->host_desktop_type(),
   1135       SessionRestore::CLOBBER_CURRENT_TAB | SessionRestore::SYNCHRONOUS,
   1136       std::vector<GURL>());
   1137 
   1138   // 2 tabs should have been restored, with the existing tab clobbered, giving
   1139   // us a total of 2 tabs.
   1140   ASSERT_EQ(2, new_browser->tab_strip_model()->count());
   1141   EXPECT_EQ(1, new_browser->tab_strip_model()->active_index());
   1142   EXPECT_EQ(url1_,
   1143             new_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL());
   1144   EXPECT_EQ(url2_,
   1145             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
   1146 }
   1147 
   1148 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorage) {
   1149   ui_test_utils::NavigateToURL(browser(), url1_);
   1150   content::NavigationController* controller =
   1151       &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
   1152   ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
   1153   std::string session_storage_persistent_id =
   1154       controller->GetDefaultSessionStorageNamespace()->persistent_id();
   1155   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
   1156   ASSERT_EQ(1u, active_browser_list_->size());
   1157   ASSERT_EQ(url1_,
   1158             new_browser->tab_strip_model()->GetActiveWebContents()->GetURL());
   1159   content::NavigationController* new_controller =
   1160       &new_browser->tab_strip_model()->GetActiveWebContents()->GetController();
   1161   ASSERT_TRUE(new_controller->GetDefaultSessionStorageNamespace());
   1162   std::string restored_session_storage_persistent_id =
   1163       new_controller->GetDefaultSessionStorageNamespace()->persistent_id();
   1164   EXPECT_EQ(session_storage_persistent_id,
   1165             restored_session_storage_persistent_id);
   1166 }
   1167 
   1168 IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) {
   1169   // Simulate what prerendering does: create a new WebContents with the same
   1170   // SessionStorageNamespace as an existing tab, then replace the tab with it.
   1171   {
   1172     content::NavigationController* controller =
   1173         &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
   1174     ASSERT_TRUE(controller->GetDefaultSessionStorageNamespace());
   1175 
   1176     content::SessionStorageNamespaceMap session_storage_namespace_map;
   1177     session_storage_namespace_map[std::string()] =
   1178         controller->GetDefaultSessionStorageNamespace();
   1179     scoped_ptr<content::WebContents> web_contents(
   1180         content::WebContents::CreateWithSessionStorage(
   1181             content::WebContents::CreateParams(browser()->profile()),
   1182             session_storage_namespace_map));
   1183 
   1184     TabStripModel* tab_strip_model = browser()->tab_strip_model();
   1185     scoped_ptr<content::WebContents> old_web_contents(
   1186         tab_strip_model->ReplaceWebContentsAt(
   1187             tab_strip_model->active_index(), web_contents.release()));
   1188     // Navigate with the new tab.
   1189     ui_test_utils::NavigateToURL(browser(), url2_);
   1190     // old_web_contents goes out of scope.
   1191   }
   1192 
   1193   // Check that the sessionStorage data is going to be persisted.
   1194   content::NavigationController* controller =
   1195       &browser()->tab_strip_model()->GetActiveWebContents()->GetController();
   1196   EXPECT_TRUE(
   1197       controller->GetDefaultSessionStorageNamespace()->should_persist());
   1198 
   1199   // Quit and restore. Check that no extra tabs were created.
   1200   Browser* new_browser = QuitBrowserAndRestore(browser(), 1);
   1201   ASSERT_EQ(1u, active_browser_list_->size());
   1202   EXPECT_EQ(1, new_browser->tab_strip_model()->count());
   1203 }
   1204