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/sessions/tab_restore_service_helper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <iterator> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/session_types.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service_delegate.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service_observer.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/session_storage_namespace.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/web_contents.h" 22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/tab_helper.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/common/extensions/extension_constants.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/extension_registry.h" 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension.h" 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_set.h" 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RecordAppLaunch(Profile* profile, const TabRestoreService::Tab& tab) { 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_EXTENSIONS) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url = tab.navigations.at(tab.current_navigation_index).virtual_url(); 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const extensions::Extension* extension = 42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extensions::ExtensionRegistry::Get(profile) 43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->enabled_extensions().GetAppByURL(url); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch CoreAppLauncherHandler::RecordAppLaunchType( 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_misc::APP_LAUNCH_NTP_RECENTLY_CLOSED, 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->GetType()); 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // defined(ENABLE_EXTENSIONS) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabRestoreServiceHelper::Observer ------------------------------------------- 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabRestoreServiceHelper::Observer::~Observer() {} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::Observer::OnClearEntries() {} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::Observer::OnRestoreEntryById( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type id, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entries::const_iterator entry_iterator) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::Observer::OnAddEntry() {} 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TabRestoreServiceHelper ----------------------------------------------------- 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabRestoreServiceHelper::TabRestoreServiceHelper( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreService* tab_restore_service, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Observer* observer, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreService::TimeFactory* time_factory) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : tab_restore_service_(tab_restore_service), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_(observer), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_(profile), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restoring_(false), 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_factory_(time_factory) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(tab_restore_service_); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabRestoreServiceHelper::~TabRestoreServiceHelper() { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDestroyed(tab_restore_service_)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&entries_); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::AddObserver( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceObserver* observer) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_.AddObserver(observer); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::RemoveObserver( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceObserver* observer) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_.RemoveObserver(observer); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::CreateHistoricalTab( 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WebContents* contents, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restoring_) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate* delegate = 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate::FindDelegateForWebContents(contents); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (closing_delegates_.find(delegate) != closing_delegates_.end()) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Tab> local_tab(new Tab()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopulateTab(local_tab.get(), index, delegate, &contents->GetController()); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (local_tab->navigations.empty()) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddEntry(local_tab.release(), true, true); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::BrowserClosing( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate* delegate) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closing_delegates_.insert(delegate); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Window> window(new Window()); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->selected_tab_index = delegate->GetSelectedIndex(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->timestamp = TimeNow(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->app_name = delegate->GetAppName(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't use std::vector::resize() because it will push copies of an empty tab 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into the vector, which will give all tabs in a window the same ID. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < delegate->GetTabCount(); ++i) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->tabs.push_back(Tab()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t entry_index = 0; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int tab_index = 0; tab_index < delegate->GetTabCount(); ++tab_index) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PopulateTab(&(window->tabs[entry_index]), 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_index, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &delegate->GetWebContentsAt(tab_index)->GetController()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window->tabs[entry_index].navigations.empty()) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->tabs.erase(window->tabs.begin() + entry_index); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->tabs[entry_index].browser_id = delegate->GetSessionID().id(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_index++; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window->tabs.size() == 1 && window->app_name.empty()) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Short-circuit creating a Window if only 1 tab was present. This fixes 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/56744. Copy the Tab because it's owned by an object on 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the stack. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddEntry(new Tab(window->tabs[0]), true, true); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!window->tabs.empty()) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->selected_tab_index = 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(static_cast<int>(window->tabs.size() - 1), 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->selected_tab_index); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddEntry(window.release(), true, true); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::BrowserClosed( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate* delegate) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) closing_delegates_.erase(delegate); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::ClearEntries() { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnClearEntries(); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&entries_); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyTabsChanged(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const TabRestoreService::Entries& TabRestoreServiceHelper::entries() const { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entries_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1743240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::vector<content::WebContents*> 1753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben MurdochTabRestoreServiceHelper::RestoreMostRecentEntry( 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TabRestoreServiceDelegate* delegate, 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entries_.empty()) 1793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return std::vector<WebContents*>(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return RestoreEntryById(delegate, entries_.front()->id, host_desktop_type, 1823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch UNKNOWN); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabRestoreService::Tab* TabRestoreServiceHelper::RemoveTabEntryById( 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type id) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entries::iterator i = GetEntryIteratorById(id); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i == entries_.end()) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry* entry = *i; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->type != TabRestoreService::TAB) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tab* tab = static_cast<Tab*>(entry); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.erase(i); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tab; 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochstd::vector<content::WebContents*> TabRestoreServiceHelper::RestoreEntryById( 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate* delegate, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type id, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowOpenDisposition disposition) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entries::iterator entry_iterator = GetEntryIteratorById(id); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry_iterator == entries_.end()) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't hoark here, we allow an invalid id. 2083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return std::vector<WebContents*>(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnRestoreEntryById(id, entry_iterator); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restoring_ = true; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry* entry = *entry_iterator; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the entry's ID does not match the ID that is being restored, then the 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // entry is a window from which a single tab will be restored. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool restoring_tab_in_window = entry->id != id; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!restoring_tab_in_window) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.erase(entry_iterator); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_iterator = entries_.end(); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |delegate| will be NULL in cases where one isn't already available (eg, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when invoked on Mac OS X with no windows open). In this case, create a 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new browser into which we restore the tabs. 2273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch std::vector<WebContents*> web_contents; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->type == TabRestoreService::TAB) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tab* tab = static_cast<Tab*>(entry); 2303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WebContents* restored_tab = NULL; 2313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch delegate = RestoreTab(*tab, delegate, host_desktop_type, disposition, 2323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch &restored_tab); 2333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch web_contents.push_back(restored_tab); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate->ShowBrowserWindow(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (entry->type == TabRestoreService::WINDOW) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate* current_delegate = delegate; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Window* window = static_cast<Window*>(entry); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When restoring a window, either the entire window can be restored, or a 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // single tab within it. If the entry's ID matches the one to restore, then 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the entire window will be restored. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!restoring_tab_in_window) { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate = TabRestoreServiceDelegate::Create(profile_, host_desktop_type, 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window->app_name); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Tab& tab = window->tabs[tab_i]; 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebContents* restored_tab = delegate->AddRestoredTab( 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tab.navigations, 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) delegate->GetTabCount(), 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tab.current_navigation_index, 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tab.extension_app_id, 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<int>(tab_i) == window->selected_tab_index, 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tab.pinned, 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tab.from_last_session, 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tab.session_storage_namespace.get(), 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) tab.user_agent_override); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restored_tab) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restored_tab->GetController().LoadIfNecessary(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAppLaunch(profile_, tab); 2603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch web_contents.push_back(restored_tab); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All the window's tabs had the same former browser_id. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window->tabs[0].has_browser()) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateTabBrowserIDs(window->tabs[0].browser_id, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate->GetSessionID().id()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restore a single tab from the window. Find the tab that matches the ID 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the window and restore it. 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_i != window->tabs.end(); ++tab_i) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Tab& tab = *tab_i; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab.id == id) { 2753240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WebContents* restored_tab = NULL; 2763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch delegate = RestoreTab(tab, delegate, host_desktop_type, disposition, 2773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch &restored_tab); 2783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch web_contents.push_back(restored_tab); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->tabs.erase(tab_i); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If restoring the tab leaves the window with nothing else, delete it 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as well. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!window->tabs.size()) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.erase(entry_iterator); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete entry; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the browser ID of the rest of the tabs in the window so if 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any one is restored, it goes into the same window as the tab 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // being restored now. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateTabBrowserIDs(tab.browser_id, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate->GetSessionID().id()); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<Tab>::iterator tab_j = window->tabs.begin(); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_j != window->tabs.end(); ++tab_j) { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*tab_j).browser_id = delegate->GetSessionID().id(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate->ShowBrowserWindow(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == CURRENT_TAB && current_delegate && 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_delegate->GetActiveWebContents()) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_delegate->CloseTab(); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!restoring_tab_in_window) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete entry; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restoring_ = false; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyTabsChanged(); 3163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return web_contents; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::NotifyTabsChanged() { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceChanged(tab_restore_service_)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 324a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void TabRestoreServiceHelper::NotifyLoaded() { 325a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_, 326a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) TabRestoreServiceLoaded(tab_restore_service_)); 327a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 328a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::AddEntry(Entry* entry, 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool notify, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool to_front) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!FilterEntry(entry) || (entries_.size() >= kMaxEntries && !to_front)) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete entry; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (to_front) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.push_front(entry); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_.push_back(entry); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PruneEntries(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (notify) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyTabsChanged(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_->OnAddEntry(); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::PruneEntries() { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entries new_entries; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (TabRestoreService::Entries::const_iterator iter = entries_.begin(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != entries_.end(); ++iter) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreService::Entry* entry = *iter; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FilterEntry(entry) && 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_entries.size() < kMaxEntries) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_entries.push_back(entry); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete entry; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries_ = new_entries; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabRestoreService::Entries::iterator 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabRestoreServiceHelper::GetEntryIteratorById(SessionID::id_type id) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i)->id == id) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For Window entries, see if the ID matches a tab. If so, report the window 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as the Entry. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i)->type == TabRestoreService::WINDOW) { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Tab>& tabs = static_cast<Window*>(*i)->tabs; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<Tab>::iterator j = tabs.begin(); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j != tabs.end(); ++j) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*j).id == id) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return entries_.end(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabRestoreServiceHelper::ValidateEntry(Entry* entry) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->type == TabRestoreService::TAB) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ValidateTab(static_cast<Tab*>(entry)); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->type == TabRestoreService::WINDOW) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ValidateWindow(static_cast<Window*>(entry)); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::PopulateTab( 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tab* tab, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate* delegate, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationController* controller) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int pending_index = controller->GetPendingEntryIndex(); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int entry_count = controller->GetEntryCount(); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry_count == 0 && pending_index == 0) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_count++; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->navigations.resize(static_cast<int>(entry_count)); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < entry_count; ++i) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NavigationEntry* entry = (i == pending_index) ? 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->GetPendingEntry() : controller->GetEntryAtIndex(i); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->navigations[i] = 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sessions::SerializedNavigationEntry::FromNavigationEntry(i, *entry); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->timestamp = TimeNow(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->current_navigation_index = controller->GetCurrentEntryIndex(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab->current_navigation_index == -1 && entry_count > 0) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->current_navigation_index = 0; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->tabstrip_index = index; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::TabHelper* extensions_tab_helper = 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::TabHelper::FromWebContents(controller->GetWebContents()); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extensions_tab_helper is NULL in some browser tests. 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extensions_tab_helper) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::Extension* extension = 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions_tab_helper->extension_app(); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->extension_app_id = extension->id(); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->user_agent_override = 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->GetWebContents()->GetUserAgentOverride(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // TODO(ajwong): This does not correctly handle storage for isolated apps. 440ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch tab->session_storage_namespace = 441ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch controller->GetDefaultSessionStorageNamespace(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delegate may be NULL during unit tests. 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->browser_id = delegate->GetSessionID().id(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->pinned = delegate->IsTabPinned(tab->tabstrip_index); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TabRestoreServiceDelegate* TabRestoreServiceHelper::RestoreTab( 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Tab& tab, 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TabRestoreServiceDelegate* delegate, 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type, 4543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WindowOpenDisposition disposition, 4553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WebContents** contents) { 4563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch WebContents* web_contents; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disposition == CURRENT_TAB && delegate) { 4583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch web_contents = delegate->ReplaceRestoredTab( 4593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.navigations, 4603240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.current_navigation_index, 4613240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.from_last_session, 4623240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.extension_app_id, 4633240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.session_storage_namespace.get(), 4643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.user_agent_override); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only respsect the tab's original browser if there's no disposition. 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (disposition == UNKNOWN && tab.has_browser()) { 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate = TabRestoreServiceDelegate::FindDelegateWithID( 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tab.browser_id, host_desktop_type); 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int tab_index = -1; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |delegate| will be NULL in cases where one isn't already available (eg, 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when invoked on Mac OS X with no windows open). In this case, create a 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new browser into which we restore the tabs. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delegate && disposition != NEW_WINDOW) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_index = tab.tabstrip_index; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate = TabRestoreServiceDelegate::Create(profile_, host_desktop_type, 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string()); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab.has_browser()) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id()); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Place the tab at the end if the tab index is no longer valid or 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we were passed a specific disposition. 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab_index < 0 || tab_index > delegate->GetTabCount() || 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disposition != UNKNOWN) { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_index = delegate->GetTabCount(); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch web_contents = delegate->AddRestoredTab(tab.navigations, 4943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab_index, 4953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.current_navigation_index, 4963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.extension_app_id, 4973240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch disposition != NEW_BACKGROUND_TAB, 4983240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.pinned, 4993240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.from_last_session, 5003240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.session_storage_namespace.get(), 5013240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch tab.user_agent_override); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_contents->GetController().LoadIfNecessary(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecordAppLaunch(profile_, tab); 5053240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if (contents) 5063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch *contents = web_contents; 5073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return delegate; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabRestoreServiceHelper::ValidateTab(Tab* tab) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab->navigations.empty()) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->current_navigation_index = 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(0, std::min(tab->current_navigation_index, 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(tab->navigations.size()) - 1)); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabRestoreServiceHelper::ValidateWindow(Window* window) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->selected_tab_index = 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::max(0, std::min(window->selected_tab_index, 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(window->tabs.size() - 1))); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = 0; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<Tab>::iterator tab_i = window->tabs.begin(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_i != window->tabs.end();) { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ValidateTab(&(*tab_i))) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab_i = window->tabs.erase(tab_i); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i < window->selected_tab_index) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->selected_tab_index--; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (i == window->selected_tab_index) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->selected_tab_index = 0; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++tab_i; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++i; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window->tabs.empty()) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabRestoreServiceHelper::IsTabInteresting(const Tab* tab) { 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab->navigations.empty()) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab->navigations.size() > 1) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tab->pinned || 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->navigations.at(0).virtual_url() != 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(chrome::kChromeUINewTabURL); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabRestoreServiceHelper::IsWindowInteresting(const Window* window) { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window->tabs.empty()) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window->tabs.size() > 1) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsTabInteresting(&window->tabs[0]); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TabRestoreServiceHelper::FilterEntry(Entry* entry) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ValidateEntry(entry)) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->type == TabRestoreService::TAB) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsTabInteresting(static_cast<Tab*>(entry)); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (entry->type == TabRestoreService::WINDOW) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsWindowInteresting(static_cast<Window*>(entry)); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TabRestoreServiceHelper::UpdateTabBrowserIDs(SessionID::id_type old_id, 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SessionID::id_type new_id) { 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) { 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Entry* entry = *i; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry->type == TabRestoreService::TAB) { 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tab* tab = static_cast<Tab*>(entry); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tab->browser_id == old_id) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab->browser_id = new_id; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time TabRestoreServiceHelper::TimeNow() const { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return time_factory_ ? time_factory_->TimeNow() : base::Time::Now(); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 599