Home | History | Annotate | Download | only in ui
      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 "chrome/browser/ui/browser_tabrestore.h"
      6 
      7 #include "chrome/browser/extensions/tab_helper.h"
      8 #include "chrome/browser/profiles/profile.h"
      9 #include "chrome/browser/sessions/session_service.h"
     10 #include "chrome/browser/sessions/session_service_factory.h"
     11 #include "chrome/browser/tab_contents/tab_util.h"
     12 #include "chrome/browser/ui/browser.h"
     13 #include "chrome/browser/ui/browser_window.h"
     14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     15 #include "content/public/browser/navigation_controller.h"
     16 #include "content/public/browser/navigation_entry.h"
     17 #include "content/public/browser/session_storage_namespace.h"
     18 #include "content/public/browser/web_contents.h"
     19 #include "content/public/browser/web_contents_view.h"
     20 
     21 using content::WebContents;
     22 using content::NavigationController;
     23 using content::NavigationEntry;
     24 using sessions::SerializedNavigationEntry;
     25 
     26 namespace chrome {
     27 
     28 namespace {
     29 
     30 NavigationController::RestoreType GetRestoreType(Browser* browser,
     31                                                  bool from_last_session) {
     32   if (!from_last_session)
     33     return NavigationController::RESTORE_CURRENT_SESSION;
     34   return browser->profile()->GetLastSessionExitType() == Profile::EXIT_CRASHED ?
     35       NavigationController::RESTORE_LAST_SESSION_CRASHED :
     36       NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY;
     37 }
     38 
     39 WebContents* CreateRestoredTab(
     40     Browser* browser,
     41     const std::vector<SerializedNavigationEntry>& navigations,
     42     int selected_navigation,
     43     const std::string& extension_app_id,
     44     bool from_last_session,
     45     content::SessionStorageNamespace* session_storage_namespace,
     46     const std::string& user_agent_override) {
     47   GURL restore_url = navigations.at(selected_navigation).virtual_url();
     48   // TODO(ajwong): Remove the temporary session_storage_namespace_map when
     49   // we teach session restore to understand that one tab can have multiple
     50   // SessionStorageNamespace objects. Also remove the
     51   // session_storage_namespace.h include since we only need that to assign
     52   // into the map.
     53   content::SessionStorageNamespaceMap session_storage_namespace_map;
     54   session_storage_namespace_map[std::string()] = session_storage_namespace;
     55   WebContents::CreateParams create_params(
     56       browser->profile(),
     57       tab_util::GetSiteInstanceForNewTab(browser->profile(), restore_url));
     58   WebContents* base_web_contents =
     59       browser->tab_strip_model()->GetActiveWebContents();
     60   if (base_web_contents) {
     61     create_params.initial_size =
     62         base_web_contents->GetView()->GetContainerSize();
     63   }
     64   WebContents* web_contents = content::WebContents::CreateWithSessionStorage(
     65       create_params,
     66       session_storage_namespace_map);
     67   extensions::TabHelper::CreateForWebContents(web_contents);
     68   extensions::TabHelper::FromWebContents(web_contents)->
     69       SetExtensionAppById(extension_app_id);
     70   std::vector<NavigationEntry*> entries =
     71       SerializedNavigationEntry::ToNavigationEntries(
     72           navigations, browser->profile());
     73   web_contents->SetUserAgentOverride(user_agent_override);
     74   web_contents->GetController().Restore(
     75       selected_navigation, GetRestoreType(browser, from_last_session),
     76       &entries);
     77   DCHECK_EQ(0u, entries.size());
     78 
     79   return web_contents;
     80 }
     81 
     82 }  // namespace
     83 
     84 content::WebContents* AddRestoredTab(
     85     Browser* browser,
     86     const std::vector<SerializedNavigationEntry>& navigations,
     87     int tab_index,
     88     int selected_navigation,
     89     const std::string& extension_app_id,
     90     bool select,
     91     bool pin,
     92     bool from_last_session,
     93     content::SessionStorageNamespace* session_storage_namespace,
     94     const std::string& user_agent_override) {
     95   WebContents* web_contents = CreateRestoredTab(browser,
     96                                                 navigations,
     97                                                 selected_navigation,
     98                                                 extension_app_id,
     99                                                 from_last_session,
    100                                                 session_storage_namespace,
    101                                                 user_agent_override);
    102 
    103   int add_types = select ? TabStripModel::ADD_ACTIVE
    104                          : TabStripModel::ADD_NONE;
    105   if (pin) {
    106     int first_mini_tab_idx =
    107         browser->tab_strip_model()->IndexOfFirstNonMiniTab();
    108     tab_index = std::min(tab_index, first_mini_tab_idx);
    109     add_types |= TabStripModel::ADD_PINNED;
    110   }
    111   browser->tab_strip_model()->InsertWebContentsAt(tab_index, web_contents,
    112                                                   add_types);
    113   if (select) {
    114     browser->window()->Activate();
    115   } else {
    116     // We set the size of the view here, before WebKit does its initial
    117     // layout.  If we don't, the initial layout of background tabs will be
    118     // performed with a view width of 0, which may cause script outputs and
    119     // anchor link location calculations to be incorrect even after a new
    120     // layout with proper view dimensions. TabStripModel::AddWebContents()
    121     // contains similar logic.
    122     web_contents->GetView()->SizeContents(
    123         browser->window()->GetRestoredBounds().size());
    124     web_contents->WasHidden();
    125   }
    126   SessionService* session_service =
    127       SessionServiceFactory::GetForProfileIfExisting(browser->profile());
    128   if (session_service)
    129     session_service->TabRestored(web_contents, pin);
    130   return web_contents;
    131 }
    132 
    133 content::WebContents* ReplaceRestoredTab(
    134     Browser* browser,
    135     const std::vector<SerializedNavigationEntry>& navigations,
    136     int selected_navigation,
    137     bool from_last_session,
    138     const std::string& extension_app_id,
    139     content::SessionStorageNamespace* session_storage_namespace,
    140     const std::string& user_agent_override) {
    141   WebContents* web_contents = CreateRestoredTab(browser,
    142                                                 navigations,
    143                                                 selected_navigation,
    144                                                 extension_app_id,
    145                                                 from_last_session,
    146                                                 session_storage_namespace,
    147                                                 user_agent_override);
    148 
    149   // ReplaceWebContentsAt won't animate in the restoration, so manually do the
    150   // equivalent of ReplaceWebContentsAt.
    151   TabStripModel* tab_strip = browser->tab_strip_model();
    152   int insertion_index = tab_strip->active_index();
    153   tab_strip->InsertWebContentsAt(insertion_index + 1,
    154                                  web_contents,
    155                                  TabStripModel::ADD_ACTIVE |
    156                                  TabStripModel::ADD_INHERIT_GROUP);
    157   tab_strip->CloseWebContentsAt(insertion_index, TabStripModel::CLOSE_NONE);
    158   return web_contents;
    159 }
    160 
    161 }  // namespace chrome
    162