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