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 "chrome/browser/ui/web_contents_sizer.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"
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 bool initially_hidden
) {
48 GURL restore_url
= navigations
.at(selected_navigation
).virtual_url();
49 // TODO(ajwong): Remove the temporary session_storage_namespace_map when
50 // we teach session restore to understand that one tab can have multiple
51 // SessionStorageNamespace objects. Also remove the
52 // session_storage_namespace.h include since we only need that to assign
54 content::SessionStorageNamespaceMap session_storage_namespace_map
;
55 session_storage_namespace_map
[std::string()] = session_storage_namespace
;
56 WebContents::CreateParams
create_params(
58 tab_util::GetSiteInstanceForNewTab(browser
->profile(), restore_url
));
59 create_params
.initially_hidden
= initially_hidden
;
60 WebContents
* base_web_contents
=
61 browser
->tab_strip_model()->GetActiveWebContents();
62 if (base_web_contents
) {
63 create_params
.initial_size
=
64 base_web_contents
->GetContainerBounds().size();
66 WebContents
* web_contents
= content::WebContents::CreateWithSessionStorage(
68 session_storage_namespace_map
);
69 extensions::TabHelper::CreateForWebContents(web_contents
);
70 extensions::TabHelper::FromWebContents(web_contents
)->
71 SetExtensionAppById(extension_app_id
);
72 std::vector
<NavigationEntry
*> entries
=
73 SerializedNavigationEntry::ToNavigationEntries(
74 navigations
, browser
->profile());
75 web_contents
->SetUserAgentOverride(user_agent_override
);
76 web_contents
->GetController().Restore(
77 selected_navigation
, GetRestoreType(browser
, from_last_session
),
79 DCHECK_EQ(0u, entries
.size());
86 content::WebContents
* AddRestoredTab(
88 const std::vector
<SerializedNavigationEntry
>& navigations
,
90 int selected_navigation
,
91 const std::string
& extension_app_id
,
94 bool from_last_session
,
95 content::SessionStorageNamespace
* session_storage_namespace
,
96 const std::string
& user_agent_override
) {
97 WebContents
* web_contents
= CreateRestoredTab(browser
,
102 session_storage_namespace
,
106 int add_types
= select
? TabStripModel::ADD_ACTIVE
107 : TabStripModel::ADD_NONE
;
109 int first_mini_tab_idx
=
110 browser
->tab_strip_model()->IndexOfFirstNonMiniTab();
111 tab_index
= std::min(tab_index
, first_mini_tab_idx
);
112 add_types
|= TabStripModel::ADD_PINNED
;
114 browser
->tab_strip_model()->InsertWebContentsAt(tab_index
, web_contents
,
117 browser
->window()->Activate();
119 // We set the size of the view here, before Blink does its initial layout.
120 // If we don't, the initial layout of background tabs will be performed
121 // with a view width of 0, which may cause script outputs and anchor link
122 // location calculations to be incorrect even after a new layout with
123 // proper view dimensions. TabStripModel::AddWebContents() contains similar
125 gfx::Size size
= browser
->window()->GetBounds().size();
126 // Fallback to the restore bounds if it's empty as the window is not shown
127 // yet and the bounds may not be available on all platforms.
129 size
= browser
->window()->GetRestoredBounds().size();
130 ResizeWebContents(web_contents
, size
);
131 web_contents
->WasHidden();
133 SessionService
* session_service
=
134 SessionServiceFactory::GetForProfileIfExisting(browser
->profile());
136 session_service
->TabRestored(web_contents
, pin
);
140 content::WebContents
* ReplaceRestoredTab(
142 const std::vector
<SerializedNavigationEntry
>& navigations
,
143 int selected_navigation
,
144 bool from_last_session
,
145 const std::string
& extension_app_id
,
146 content::SessionStorageNamespace
* session_storage_namespace
,
147 const std::string
& user_agent_override
) {
148 WebContents
* web_contents
= CreateRestoredTab(browser
,
153 session_storage_namespace
,
157 // ReplaceWebContentsAt won't animate in the restoration, so manually do the
158 // equivalent of ReplaceWebContentsAt.
159 TabStripModel
* tab_strip
= browser
->tab_strip_model();
160 int insertion_index
= tab_strip
->active_index();
161 tab_strip
->InsertWebContentsAt(insertion_index
+ 1,
163 TabStripModel::ADD_ACTIVE
|
164 TabStripModel::ADD_INHERIT_GROUP
);
165 tab_strip
->CloseWebContentsAt(insertion_index
, TabStripModel::CLOSE_NONE
);
169 } // namespace chrome