f939a74327c13c3394d662f3a9e7d44766a7017e
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / browser_tabrestore.cc
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