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.
5 #include "chrome/browser/ui/browser_tabrestore.h"
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"
21 using content::WebContents
;
22 using content::NavigationController
;
23 using content::NavigationEntry
;
24 using sessions::SerializedNavigationEntry
;
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
;
39 WebContents
* CreateRestoredTab(
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
53 content::SessionStorageNamespaceMap session_storage_namespace_map
;
54 session_storage_namespace_map
[std::string()] = session_storage_namespace
;
55 WebContents::CreateParams
create_params(
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();
64 WebContents
* web_contents
= content::WebContents::CreateWithSessionStorage(
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
),
77 DCHECK_EQ(0u, entries
.size());
84 content::WebContents
* AddRestoredTab(
86 const std::vector
<SerializedNavigationEntry
>& navigations
,
88 int selected_navigation
,
89 const std::string
& extension_app_id
,
92 bool from_last_session
,
93 content::SessionStorageNamespace
* session_storage_namespace
,
94 const std::string
& user_agent_override
) {
95 WebContents
* web_contents
= CreateRestoredTab(browser
,
100 session_storage_namespace
,
101 user_agent_override
);
103 int add_types
= select
? TabStripModel::ADD_ACTIVE
104 : TabStripModel::ADD_NONE
;
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
;
111 browser
->tab_strip_model()->InsertWebContentsAt(tab_index
, web_contents
,
114 browser
->window()->Activate();
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();
126 SessionService
* session_service
=
127 SessionServiceFactory::GetForProfileIfExisting(browser
->profile());
129 session_service
->TabRestored(web_contents
, pin
);
133 content::WebContents
* ReplaceRestoredTab(
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
,
146 session_storage_namespace
,
147 user_agent_override
);
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,
155 TabStripModel::ADD_ACTIVE
|
156 TabStripModel::ADD_INHERIT_GROUP
);
157 tab_strip
->CloseWebContentsAt(insertion_index
, TabStripModel::CLOSE_NONE
);
161 } // namespace chrome