Refactor views app list services to allow more code sharing
[chromium-blink-merge.git] / chrome / browser / ui / browser_tabrestore.cc
blob38a9a932c8572c9222ec344d388ca486ac67d844
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;
27 namespace chrome {
29 namespace {
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(
41 Browser* browser,
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
54 // into the map.
55 content::SessionStorageNamespaceMap session_storage_namespace_map;
56 session_storage_namespace_map[std::string()] = session_storage_namespace;
57 WebContents::CreateParams create_params(
58 browser->profile(),
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(
68 create_params,
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),
79 &entries);
80 DCHECK_EQ(0u, entries.size());
82 return web_contents;
85 } // namespace
87 content::WebContents* AddRestoredTab(
88 Browser* browser,
89 const std::vector<SerializedNavigationEntry>& navigations,
90 int tab_index,
91 int selected_navigation,
92 const std::string& extension_app_id,
93 bool select,
94 bool pin,
95 bool from_last_session,
96 content::SessionStorageNamespace* session_storage_namespace,
97 const std::string& user_agent_override) {
98 WebContents* web_contents = CreateRestoredTab(browser,
99 navigations,
100 selected_navigation,
101 extension_app_id,
102 from_last_session,
103 session_storage_namespace,
104 user_agent_override,
105 !select);
107 int add_types = select ? TabStripModel::ADD_ACTIVE
108 : TabStripModel::ADD_NONE;
109 if (pin) {
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,
116 add_types);
117 if (select) {
118 browser->window()->Activate();
119 } else {
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
125 // logic.
126 apps::ResizeWebContents(web_contents,
127 browser->window()->GetRestoredBounds().size());
128 web_contents->WasHidden();
130 SessionService* session_service =
131 SessionServiceFactory::GetForProfileIfExisting(browser->profile());
132 if (session_service)
133 session_service->TabRestored(web_contents, pin);
134 return web_contents;
137 content::WebContents* ReplaceRestoredTab(
138 Browser* browser,
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,
146 navigations,
147 selected_navigation,
148 extension_app_id,
149 from_last_session,
150 session_storage_namespace,
151 user_agent_override,
152 false);
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,
159 web_contents,
160 TabStripModel::ADD_ACTIVE |
161 TabStripModel::ADD_INHERIT_GROUP);
162 tab_strip->CloseWebContentsAt(insertion_index, TabStripModel::CLOSE_NONE);
163 return web_contents;
166 } // namespace chrome