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