15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_tabrestore.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_service.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_service_factory.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/tab_contents/tab_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 17ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/public/browser/session_storage_namespace.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using sessions::SerializedNavigationEntry; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)NavigationController::RestoreType GetRestoreType(Browser* browser, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool from_last_session) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!from_last_session) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NavigationController::RESTORE_CURRENT_SESSION; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser->profile()->GetLastSessionExitType() == Profile::EXIT_CRASHED ? 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController::RESTORE_LAST_SESSION_CRASHED : 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebContents* CreateRestoredTab( 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser, 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<SerializedNavigationEntry>& navigations, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_navigation, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_app_id, 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool from_last_session, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::SessionStorageNamespace* session_storage_namespace, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_agent_override) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL restore_url = navigations.at(selected_navigation).virtual_url(); 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(ajwong): Remove the temporary session_storage_namespace_map when 49ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // we teach session restore to understand that one tab can have multiple 50ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // SessionStorageNamespace objects. Also remove the 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // session_storage_namespace.h include since we only need that to assign 52ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // into the map. 53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch content::SessionStorageNamespaceMap session_storage_namespace_map; 54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_storage_namespace_map[std::string()] = session_storage_namespace; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents::CreateParams create_params( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->profile(), 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_util::GetSiteInstanceForNewTab(browser->profile(), restore_url)); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* base_web_contents = 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->GetActiveWebContents(); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (base_web_contents) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) create_params.initial_size = 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base_web_contents->GetView()->GetContainerSize(); 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* web_contents = content::WebContents::CreateWithSessionStorage( 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) create_params, 66ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_storage_namespace_map); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::TabHelper::CreateForWebContents(web_contents); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::TabHelper::FromWebContents(web_contents)-> 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetExtensionAppById(extension_app_id); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<NavigationEntry*> entries = 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SerializedNavigationEntry::ToNavigationEntries( 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) navigations, browser->profile()); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents->SetUserAgentOverride(user_agent_override); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents->GetController().Restore( 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) selected_navigation, GetRestoreType(browser, from_last_session), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &entries); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0u, entries.size()); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_contents; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)content::WebContents* AddRestoredTab( 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser, 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<SerializedNavigationEntry>& navigations, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int tab_index, 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int selected_navigation, 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_app_id, 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool select, 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool pin, 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool from_last_session, 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::SessionStorageNamespace* session_storage_namespace, 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& user_agent_override) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* web_contents = CreateRestoredTab(browser, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) navigations, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) selected_navigation, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_app_id, 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) from_last_session, 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_storage_namespace, 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_agent_override); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int add_types = select ? TabStripModel::ADD_ACTIVE 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : TabStripModel::ADD_NONE; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pin) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int first_mini_tab_idx = 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->tab_strip_model()->IndexOfFirstNonMiniTab(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_index = std::min(tab_index, first_mini_tab_idx); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_types |= TabStripModel::ADD_PINNED; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser->tab_strip_model()->InsertWebContentsAt(tab_index, web_contents, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_types); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (select) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->Activate(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We set the size of the view here, before WebKit does its initial 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // layout. If we don't, the initial layout of background tabs will be 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // performed with a view width of 0, which may cause script outputs and 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // anchor link location calculations to be incorrect even after a new 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // layout with proper view dimensions. TabStripModel::AddWebContents() 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contains similar logic. 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents->GetView()->SizeContents( 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser->window()->GetRestoredBounds().size()); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents->WasHidden(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionService* session_service = 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionServiceFactory::GetForProfileIfExisting(browser->profile()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (session_service) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_service->TabRestored(web_contents, pin); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_contents; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochcontent::WebContents* ReplaceRestoredTab( 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser, 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<SerializedNavigationEntry>& navigations, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int selected_navigation, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool from_last_session, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_app_id, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::SessionStorageNamespace* session_storage_namespace, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_agent_override) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebContents* web_contents = CreateRestoredTab(browser, 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) navigations, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) selected_navigation, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_app_id, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) from_last_session, 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session_storage_namespace, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) user_agent_override); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ReplaceWebContentsAt won't animate in the restoration, so manually do the 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // equivalent of ReplaceWebContentsAt. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel* tab_strip = browser->tab_strip_model(); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int insertion_index = tab_strip->active_index(); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip->InsertWebContentsAt(insertion_index + 1, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_contents, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel::ADD_ACTIVE | 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabStripModel::ADD_INHERIT_GROUP); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab_strip->CloseWebContentsAt(insertion_index, TabStripModel::CLOSE_NONE); 1583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return web_contents; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace chrome 162