Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1279)

Unified Diff: chrome/browser/sessions/persistent_tab_restore_service.cc

Issue 10989027: Split TabRestoreService into InMemoryTRS and PersistentTRS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix some comments Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sessions/persistent_tab_restore_service.cc
diff --git a/chrome/browser/sessions/tab_restore_service.cc b/chrome/browser/sessions/persistent_tab_restore_service.cc
similarity index 50%
copy from chrome/browser/sessions/tab_restore_service.cc
copy to chrome/browser/sessions/persistent_tab_restore_service.cc
index 4003edb3ad7f707fa978dfab25a33896f38fcf50..9d9002bd89d71c861abb1be67b9651d2a18581f5 100644
--- a/chrome/browser/sessions/tab_restore_service.cc
+++ b/chrome/browser/sessions/persistent_tab_restore_service.cc
@@ -2,69 +2,84 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/sessions/tab_restore_service.h"
+#include "chrome/browser/sessions/persistent_tab_restore_service.h"
-#include <algorithm>
-#include <iterator>
-#include <map>
+#include <cstring> // memcpy
+#include <vector>
+#include "base/basictypes.h"
#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
+#include "base/compiler_specific.h"
+#include "base/file_path.h"
+#include "base/logging.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
-#include "base/metrics/histogram.h"
#include "base/stl_util.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/tab_helper.h"
+#include "base/time.h"
+#include "chrome/browser/common/cancelable_request.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sessions/base_session_service.h"
#include "chrome/browser/sessions/session_command.h"
#include "chrome/browser/sessions/session_service.h"
#include "chrome/browser/sessions/session_service_factory.h"
-#include "chrome/browser/sessions/session_types.h"
-#include "chrome/browser/sessions/tab_restore_service_delegate.h"
-#include "chrome/browser/sessions/tab_restore_service_observer.h"
-#include "chrome/browser/ui/tab_contents/tab_contents.h"
-#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
-#include "chrome/common/extensions/extension.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/url_constants.h"
-#include "content/public/browser/navigation_controller.h"
-#include "content/public/browser/navigation_entry.h"
-#include "content/public/browser/web_contents.h"
+#include "content/public/browser/session_storage_namespace.h"
-using base::Time;
-using content::NavigationController;
-using content::NavigationEntry;
-using content::WebContents;
+namespace {
+
+// Only written if the tab is pinned.
+typedef bool PinnedStatePayload;
+
+typedef int32 RestoredEntryPayload;
-// TimeFactory-----------------------------------------------------------------
+typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry;
-TabRestoreService::TimeFactory::~TimeFactory() {}
+// Payload used for the start of a tab close. This is the old struct that is
+// used for backwards compat when it comes to reading the session files.
+struct SelectedNavigationInTabPayload {
+ SessionID::id_type id;
+ int32 index;
+};
-// Entry ----------------------------------------------------------------------
+// Payload used for the start of a window close. This is the old struct that is
+// used for backwards compat when it comes to reading the session files. This
+// struct must be POD, because we memset the contents.
+struct WindowPayload {
+ SessionID::id_type window_id;
+ int32 selected_tab_index;
+ int32 num_tabs;
+};
-// ID of the next Entry.
-static SessionID::id_type next_entry_id = 1;
+// Payload used for the start of a window close. This struct must be POD,
+// because we memset the contents.
+struct WindowPayload2 : WindowPayload {
+ int64 timestamp;
+};
-TabRestoreService::Entry::Entry()
- : id(next_entry_id++),
- type(TAB),
- from_last_session(false) {}
+// Payload used for the start of a tab close.
+struct SelectedNavigationInTabPayload2 : SelectedNavigationInTabPayload {
+ int64 timestamp;
+};
-TabRestoreService::Entry::Entry(Type type)
- : id(next_entry_id++),
- type(type),
- from_last_session(false) {}
+// Used to indicate what has loaded.
+enum LoadState {
+ // Indicates we haven't loaded anything.
+ NOT_LOADED = 1 << 0,
-TabRestoreService::Entry::~Entry() {}
+ // Indicates we've asked for the last sessions and tabs but haven't gotten the
+ // result back yet.
+ LOADING = 1 << 2,
-// TabRestoreService ----------------------------------------------------------
+ // Indicates we finished loading the last tabs (but not necessarily the last
+ // session).
+ LOADED_LAST_TABS = 1 << 3,
-// static
-const size_t TabRestoreService::kMaxEntries = 25;
+ // Indicates we finished loading the last session (but not necessarily the
+ // last tabs).
+ LOADED_LAST_SESSION = 1 << 4
+};
-// Identifier for commands written to file.
-// The ordering in the file is as follows:
+// Identifier for commands written to file. The ordering in the file is as
+// follows:
// . When the user closes a tab a command of type
// kCommandSelectedNavigationInTab is written identifying the tab and
// the selected index, then a kCommandPinnedState command if the tab was
@@ -77,212 +92,205 @@ const size_t TabRestoreService::kMaxEntries = 25;
// described).
// . When the user restores an entry a command of type kCommandRestoredEntry
// is written.
-static const SessionCommand::id_type kCommandUpdateTabNavigation = 1;
-static const SessionCommand::id_type kCommandRestoredEntry = 2;
-static const SessionCommand::id_type kCommandWindow = 3;
-static const SessionCommand::id_type kCommandSelectedNavigationInTab = 4;
-static const SessionCommand::id_type kCommandPinnedState = 5;
-static const SessionCommand::id_type kCommandSetExtensionAppID = 6;
-static const SessionCommand::id_type kCommandSetWindowAppName = 7;
-static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 8;
+const SessionCommand::id_type kCommandUpdateTabNavigation = 1;
+const SessionCommand::id_type kCommandRestoredEntry = 2;
+const SessionCommand::id_type kCommandWindow = 3;
+const SessionCommand::id_type kCommandSelectedNavigationInTab = 4;
+const SessionCommand::id_type kCommandPinnedState = 5;
+const SessionCommand::id_type kCommandSetExtensionAppID = 6;
+const SessionCommand::id_type kCommandSetWindowAppName = 7;
+const SessionCommand::id_type kCommandSetTabUserAgentOverride = 8;
// Number of entries (not commands) before we clobber the file and write
// everything.
-static const int kEntriesPerReset = 40;
+const int kEntriesPerReset = 40;
-namespace {
+const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries;
-// Payload structures.
+} // namespace
-typedef int32 RestoredEntryPayload;
+// PersistentTabRestoreService::Delegate ---------------------------------------
+
+class PersistentTabRestoreService::Delegate
+ : public BaseSessionService,
sky 2012/10/24 13:51:25 Can we remove ProfileKeyedService as a superclass
Philippe 2012/10/24 15:42:47 Good point. Done. I had to make some small changes
+ public TabRestoreServiceHelper::Observer {
+ public:
+ explicit Delegate(Profile* profile);
+
+ virtual ~Delegate();
+
+ // BaseSessionService:
+ virtual void Save() OVERRIDE;
+
+ // TabRestoreServiceHelper::Observer:
+ virtual void OnClearEntries() OVERRIDE;
+ virtual void OnRestoreEntryById(
+ SessionID::id_type id,
+ Entries::const_iterator entry_iterator) OVERRIDE;
+ virtual void OnAddEntry() OVERRIDE;
+
+ void set_tab_restore_service_helper(
+ TabRestoreServiceHelper* tab_restore_service_helper) {
+ tab_restore_service_helper_ = tab_restore_service_helper;
+ }
-// Payload used for the start of a window close. This is the old struct that is
-// used for backwards compat when it comes to reading the session files. This
-// struct must be POD, because we memset the contents.
-struct WindowPayload {
- SessionID::id_type window_id;
- int32 selected_tab_index;
- int32 num_tabs;
-};
+ void LoadTabsFromLastSession();
+
+ bool IsLoaded() const;
-// Payload used for the start of a tab close. This is the old struct that is
-// used for backwards compat when it comes to reading the session files.
-struct SelectedNavigationInTabPayload {
- SessionID::id_type id;
- int32 index;
-};
+ // Creates and add entries to |entries| for each of the windows in |windows|.
+ static void CreateEntriesFromWindows(std::vector<SessionWindow*>* windows,
+ std::vector<Entry*>* entries);
-// Payload used for the start of a window close. This struct must be POD,
-// because we memset the contents.
-struct WindowPayload2 : WindowPayload {
- int64 timestamp;
-};
+ void Shutdown();
-// Payload used for the start of a tab close.
-struct SelectedNavigationInTabPayload2 : SelectedNavigationInTabPayload {
- int64 timestamp;
-};
+ // Schedules the commands for a window close.
+ void ScheduleCommandsForWindow(const Window& window);
-// Only written if the tab is pinned.
-typedef bool PinnedStatePayload;
+ // Schedules the commands for a tab close. |selected_index| gives the index of
+ // the selected navigation.
+ void ScheduleCommandsForTab(const Tab& tab, int selected_index);
-typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry;
+ // Creates a window close command.
+ static SessionCommand* CreateWindowCommand(SessionID::id_type id,
+ int selected_tab_index,
+ int num_tabs,
+ base::Time timestamp);
-// If |id_to_entry| contains an entry for |id| the corresponding entry is
-// deleted and removed from both |id_to_entry| and |entries|. This is used
-// when creating entries from the backend file.
-void RemoveEntryByID(SessionID::id_type id,
- IDToEntry* id_to_entry,
- std::vector<TabRestoreService::Entry*>* entries) {
- // Look for the entry in the map. If it is present, erase it from both
- // collections and return.
- IDToEntry::iterator i = id_to_entry->find(id);
- if (i != id_to_entry->end()) {
- entries->erase(std::find(entries->begin(), entries->end(), i->second));
- delete i->second;
- id_to_entry->erase(i);
- return;
- }
+ // Creates a tab close command.
+ static SessionCommand* CreateSelectedNavigationInTabCommand(
+ SessionID::id_type tab_id,
+ int32 index,
+ base::Time timestamp);
- // Otherwise, loop over all items in the map and see if any of the Windows
- // have Tabs with the |id|.
- for (IDToEntry::iterator i = id_to_entry->begin(); i != id_to_entry->end();
- ++i) {
- if (i->second->type == TabRestoreService::WINDOW) {
- TabRestoreService::Window* window =
- static_cast<TabRestoreService::Window*>(i->second);
- std::vector<TabRestoreService::Tab>::iterator j = window->tabs.begin();
- for ( ; j != window->tabs.end(); ++j) {
- // If the ID matches one of this window's tabs, remove it from the list.
- if ((*j).id == id) {
- window->tabs.erase(j);
- return;
- }
- }
- }
- }
-}
+ // Creates a restore command.
+ static SessionCommand* CreateRestoredEntryCommand(
+ SessionID::id_type entry_id);
-void RecordAppLaunch(Profile* profile, const TabRestoreService::Tab& tab) {
- GURL url = tab.navigations.at(tab.current_navigation_index).virtual_url();
- DCHECK(profile->GetExtensionService());
- if (!profile->GetExtensionService()->IsInstalledApp(url))
- return;
+ // Returns the index to persist as the selected index. This is the same as
+ // |tab.current_navigation_index| unless the entry at
+ // |tab.current_navigation_index| shouldn't be persisted. Returns -1 if no
+ // valid navigation to persist.
+ int GetSelectedNavigationIndexToPersist(const Tab& tab);
- AppLauncherHandler::RecordAppLaunchType(
- extension_misc::APP_LAUNCH_NTP_RECENTLY_CLOSED);
-}
+ // Invoked when we've loaded the session commands that identify the previously
+ // closed tabs. This creates entries, adds them to staging_entries_, and
+ // invokes LoadState.
+ void OnGotLastSessionCommands(
+ Handle handle,
+ scoped_refptr<InternalGetCommandsRequest> request);
-} // namespace
+ // Populates |loaded_entries| with Entries from |request|.
+ void CreateEntriesFromCommands(
+ scoped_refptr<InternalGetCommandsRequest> request,
+ std::vector<Entry*>* loaded_entries);
-TabRestoreService::Tab::Tab()
- : Entry(TAB),
- current_navigation_index(-1),
- browser_id(0),
- tabstrip_index(-1),
- pinned(false) {
-}
+ // Validates all entries in |entries|, deleting any with no navigations. This
+ // also deletes any entries beyond the max number of entries we can hold.
+ static void ValidateAndDeleteEmptyEntries(std::vector<Entry*>* entries);
-TabRestoreService::Tab::~Tab() {
-}
+ // Callback from SessionService when we've received the windows from the
+ // previous session. This creates and add entries to |staging_entries_| and
+ // invokes LoadStateChanged. |ignored_active_window| is ignored because we
+ // don't need to restore activation.
+ void OnGotPreviousSession(Handle handle,
+ std::vector<SessionWindow*>* windows,
+ SessionID::id_type ignored_active_window);
-TabRestoreService::Window::Window() : Entry(WINDOW), selected_tab_index(-1) {
-}
+ // Converts a SessionWindow into a Window, returning true on success. We use 0
+ // as the timestamp here since we do not know when the window/tab was closed.
+ static bool ConvertSessionWindowToWindow(SessionWindow* session_window,
+ Window* window);
-TabRestoreService::Window::~Window() {
-}
+ // Invoked when previous tabs or session is loaded. If both have finished
+ // loading the entries in |staging_entries_| are added to entries and
+ // observers are notified.
+ void LoadStateChanged();
+
+ // If |id_to_entry| contains an entry for |id| the corresponding entry is
+ // deleted and removed from both |id_to_entry| and |entries|. This is used
+ // when creating entries from the backend file.
+ void RemoveEntryByID(SessionID::id_type id,
+ IDToEntry* id_to_entry,
+ std::vector<TabRestoreService::Entry*>* entries);
+
+ private:
+ TabRestoreServiceHelper* tab_restore_service_helper_;
-TabRestoreService::TabRestoreService(Profile* profile,
- TabRestoreService::TimeFactory* time_factory)
+ // The number of entries to write.
+ int entries_to_write_;
+
+ // Number of entries we've written.
+ int entries_written_;
+
+ // Whether we've loaded the last session.
+ int load_state_;
+
+ // Results from previously closed tabs/sessions is first added here. When the
+ // results from both us and the session restore service have finished loading
+ // LoadStateChanged is invoked, which adds these entries to entries_.
+ std::vector<Entry*> staging_entries_;
+
+ // Used when loading previous tabs/session.
+ CancelableRequestConsumer load_consumer_;
+
+ // Used when loading open tabs/session when recovering from a crash.
+ CancelableRequestConsumer crash_consumer_;
+
+ DISALLOW_COPY_AND_ASSIGN(Delegate);
+};
+
+PersistentTabRestoreService::Delegate::Delegate(Profile* profile)
: BaseSessionService(BaseSessionService::TAB_RESTORE, profile,
FilePath()),
- load_state_(NOT_LOADED),
- restoring_(false),
+ tab_restore_service_helper_(NULL),
entries_to_write_(0),
entries_written_(0),
- time_factory_(time_factory) {
+ load_state_(NOT_LOADED) {
}
-TabRestoreService::~TabRestoreService() {
- FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_,
- TabRestoreServiceDestroyed(this));
- STLDeleteElements(&entries_);
+PersistentTabRestoreService::Delegate::~Delegate() {
STLDeleteElements(&staging_entries_);
- time_factory_ = NULL;
-}
-
-void TabRestoreService::AddObserver(TabRestoreServiceObserver* observer) {
- observer_list_.AddObserver(observer);
-}
-
-void TabRestoreService::RemoveObserver(TabRestoreServiceObserver* observer) {
- observer_list_.RemoveObserver(observer);
-}
-
-void TabRestoreService::CreateHistoricalTab(content::WebContents* contents,
- int index) {
- if (restoring_)
- return;
-
- TabRestoreServiceDelegate* delegate =
- TabRestoreServiceDelegate::FindDelegateForWebContents(contents);
- if (closing_delegates_.find(delegate) != closing_delegates_.end())
- return;
-
- scoped_ptr<Tab> local_tab(new Tab());
- PopulateTab(local_tab.get(), index, delegate, &contents->GetController());
- if (local_tab->navigations.empty())
- return;
-
- AddEntry(local_tab.release(), true, true);
}
-void TabRestoreService::BrowserClosing(TabRestoreServiceDelegate* delegate) {
- closing_delegates_.insert(delegate);
-
- scoped_ptr<Window> window(new Window());
- window->selected_tab_index = delegate->GetSelectedIndex();
- window->timestamp = TimeNow();
- window->app_name = delegate->GetAppName();
-
- // Don't use std::vector::resize() because it will push copies of an empty tab
- // into the vector, which will give all tabs in a window the same ID.
- for (int i = 0; i < delegate->GetTabCount(); ++i) {
- window->tabs.push_back(Tab());
+void PersistentTabRestoreService::Delegate::Save() {
+ const Entries& entries = tab_restore_service_helper_->entries();
+ int to_write_count = std::min(entries_to_write_,
+ static_cast<int>(entries.size()));
+ entries_to_write_ = 0;
+ if (entries_written_ + to_write_count > kEntriesPerReset) {
+ to_write_count = entries.size();
+ set_pending_reset(true);
}
- size_t entry_index = 0;
- for (int tab_index = 0; tab_index < delegate->GetTabCount(); ++tab_index) {
- PopulateTab(&(window->tabs[entry_index]),
- tab_index,
- delegate,
- &delegate->GetWebContentsAt(tab_index)->GetController());
- if (window->tabs[entry_index].navigations.empty()) {
- window->tabs.erase(window->tabs.begin() + entry_index);
- } else {
- window->tabs[entry_index].browser_id = delegate->GetSessionID().id();
- entry_index++;
+ if (to_write_count) {
+ // Write the to_write_count most recently added entries out. The most
+ // recently added entry is at the front, so we use a reverse iterator to
+ // write in the order the entries were added.
+ Entries::const_reverse_iterator i = entries.rbegin();
+ DCHECK(static_cast<size_t>(to_write_count) <= entries.size());
+ std::advance(i, entries.size() - static_cast<int>(to_write_count));
+ for (; i != entries.rend(); ++i) {
+ Entry* entry = *i;
+ if (entry->type == TAB) {
+ Tab* tab = static_cast<Tab*>(entry);
+ int selected_index = GetSelectedNavigationIndexToPersist(*tab);
+ if (selected_index != -1)
+ ScheduleCommandsForTab(*tab, selected_index);
+ } else {
+ ScheduleCommandsForWindow(*static_cast<Window*>(entry));
+ }
+ entries_written_++;
}
}
- if (window->tabs.size() == 1 && window->app_name.empty()) {
- // Short-circuit creating a Window if only 1 tab was present. This fixes
- // http://crbug.com/56744. Copy the Tab because it's owned by an object on
- // the stack.
- AddEntry(new Tab(window->tabs[0]), true, true);
- } else if (!window->tabs.empty()) {
- window->selected_tab_index =
- std::min(static_cast<int>(window->tabs.size() - 1),
- window->selected_tab_index);
- AddEntry(window.release(), true, true);
- }
-}
-
-void TabRestoreService::BrowserClosed(TabRestoreServiceDelegate* delegate) {
- closing_delegates_.erase(delegate);
+ if (pending_reset())
+ entries_written_ = 0;
+ BaseSessionService::Save();
}
-void TabRestoreService::ClearEntries() {
+void PersistentTabRestoreService::Delegate::OnClearEntries() {
// Mark all the tabs as closed so that we don't attempt to restore them.
- for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i)
+ const Entries& entries = tab_restore_service_helper_->entries();
+ for (Entries::const_iterator i = entries.begin(); i != entries.end(); ++i)
ScheduleCommand(CreateRestoredEntryCommand((*i)->id));
entries_to_write_ = 0;
@@ -293,153 +301,31 @@ void TabRestoreService::ClearEntries() {
// Schedule a command, otherwise if there are no pending commands Save does
// nothing.
ScheduleCommand(CreateRestoredEntryCommand(1));
-
- STLDeleteElements(&entries_);
- NotifyTabsChanged();
-}
-
-const TabRestoreService::Entries& TabRestoreService::entries() const {
- return entries_;
-}
-
-void TabRestoreService::RestoreMostRecentEntry(
- TabRestoreServiceDelegate* delegate) {
- if (entries_.empty())
- return;
-
- RestoreEntryById(delegate, entries_.front()->id, UNKNOWN);
-}
-
-TabRestoreService::Tab* TabRestoreService::RemoveTabEntryById(
- SessionID::id_type id) {
- Entries::iterator i = GetEntryIteratorById(id);
- if (i == entries_.end())
- return NULL;
-
- Entry* entry = *i;
- if (entry->type != TAB)
- return NULL;
-
- Tab* tab = static_cast<Tab*>(entry);
- entries_.erase(i);
- return tab;
}
-void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate,
- SessionID::id_type id,
- WindowOpenDisposition disposition) {
- Entries::iterator i = GetEntryIteratorById(id);
- if (i == entries_.end()) {
- // Don't hoark here, we allow an invalid id.
- return;
- }
-
+void PersistentTabRestoreService::Delegate::OnRestoreEntryById(
+ SessionID::id_type id,
+ Entries::const_iterator entry_iterator) {
size_t index = 0;
- for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end();
+ const Entries& entries = tab_restore_service_helper_->entries();
+ for (Entries::const_iterator j = entries.begin();
+ j != entry_iterator && j != entries.end();
++j, ++index) {}
if (static_cast<int>(index) < entries_to_write_)
entries_to_write_--;
ScheduleCommand(CreateRestoredEntryCommand(id));
+}
- restoring_ = true;
- Entry* entry = *i;
-
- // If the entry's ID does not match the ID that is being restored, then the
- // entry is a window from which a single tab will be restored.
- bool restoring_tab_in_window = entry->id != id;
-
- if (!restoring_tab_in_window) {
- entries_.erase(i);
- i = entries_.end();
- }
-
- // |delegate| will be NULL in cases where one isn't already available (eg,
- // when invoked on Mac OS X with no windows open). In this case, create a
- // new browser into which we restore the tabs.
- if (entry->type == TAB) {
- Tab* tab = static_cast<Tab*>(entry);
- delegate = RestoreTab(*tab, delegate, disposition);
- delegate->ShowBrowserWindow();
- } else if (entry->type == WINDOW) {
- TabRestoreServiceDelegate* current_delegate = delegate;
- Window* window = static_cast<Window*>(entry);
-
- // When restoring a window, either the entire window can be restored, or a
- // single tab within it. If the entry's ID matches the one to restore, then
- // the entire window will be restored.
- if (!restoring_tab_in_window) {
- delegate = TabRestoreServiceDelegate::Create(profile(), window->app_name);
- for (size_t tab_i = 0; tab_i < window->tabs.size(); ++tab_i) {
- const Tab& tab = window->tabs[tab_i];
- WebContents* restored_tab =
- delegate->AddRestoredTab(tab.navigations, delegate->GetTabCount(),
- tab.current_navigation_index,
- tab.extension_app_id,
- static_cast<int>(tab_i) ==
- window->selected_tab_index,
- tab.pinned, tab.from_last_session,
- tab.session_storage_namespace,
- tab.user_agent_override);
- if (restored_tab) {
- restored_tab->GetController().LoadIfNecessary();
- RecordAppLaunch(profile(), tab);
- }
- }
- // All the window's tabs had the same former browser_id.
- if (window->tabs[0].has_browser()) {
- UpdateTabBrowserIDs(window->tabs[0].browser_id,
- delegate->GetSessionID().id());
- }
- } else {
- // Restore a single tab from the window. Find the tab that matches the ID
- // in the window and restore it.
- for (std::vector<Tab>::iterator tab_i = window->tabs.begin();
- tab_i != window->tabs.end(); ++tab_i) {
- const Tab& tab = *tab_i;
- if (tab.id == id) {
- delegate = RestoreTab(tab, delegate, disposition);
- window->tabs.erase(tab_i);
- // If restoring the tab leaves the window with nothing else, delete it
- // as well.
- if (!window->tabs.size()) {
- entries_.erase(i);
- delete entry;
- } else {
- // Update the browser ID of the rest of the tabs in the window so if
- // any one is restored, it goes into the same window as the tab
- // being restored now.
- UpdateTabBrowserIDs(tab.browser_id,
- delegate->GetSessionID().id());
- for (std::vector<Tab>::iterator tab_j = window->tabs.begin();
- tab_j != window->tabs.end(); ++tab_j) {
- (*tab_j).browser_id = delegate->GetSessionID().id();
- }
- }
- break;
- }
- }
- }
- delegate->ShowBrowserWindow();
-
- if (disposition == CURRENT_TAB && current_delegate &&
- current_delegate->GetActiveWebContents()) {
- current_delegate->CloseTab();
- }
- } else {
- NOTREACHED();
- }
-
- if (!restoring_tab_in_window) {
- delete entry;
- }
-
- restoring_ = false;
- NotifyTabsChanged();
+void PersistentTabRestoreService::Delegate::OnAddEntry() {
+ // Start the save timer, when it fires we'll generate the commands.
+ StartSaveTimer();
+ entries_to_write_++;
}
-void TabRestoreService::LoadTabsFromLastSession() {
- if (load_state_ != NOT_LOADED || entries_.size() == kMaxEntries)
+void PersistentTabRestoreService::Delegate::LoadTabsFromLastSession() {
+ if (load_state_ != NOT_LOADED ||
+ tab_restore_service_helper_->entries().size() == kMaxEntries)
return;
#if !defined(ENABLE_SESSION_SERVICE)
@@ -461,8 +347,7 @@ void TabRestoreService::LoadTabsFromLastSession() {
// saved them).
session_service->GetLastSession(
&crash_consumer_,
- base::Bind(&TabRestoreService::OnGotPreviousSession,
- base::Unretained(this)));
+ base::Bind(&Delegate::OnGotPreviousSession, base::Unretained(this)));
} else {
load_state_ |= LOADED_LAST_SESSION;
}
@@ -473,165 +358,33 @@ void TabRestoreService::LoadTabsFromLastSession() {
// crash (the call to GetLastSession above requests those).
ScheduleGetLastSessionCommands(
new InternalGetCommandsRequest(
- base::Bind(&TabRestoreService::OnGotLastSessionCommands,
+ base::Bind(&Delegate::OnGotLastSessionCommands,
base::Unretained(this))),
&load_consumer_);
}
-bool TabRestoreService::IsLoaded() const {
+bool PersistentTabRestoreService::Delegate::IsLoaded() const {
return !(load_state_ & (NOT_LOADED | LOADING));
}
-void TabRestoreService::Shutdown() {
- if (backend())
- Save();
-}
-
-void TabRestoreService::Save() {
- int to_write_count = std::min(entries_to_write_,
- static_cast<int>(entries_.size()));
- entries_to_write_ = 0;
- if (entries_written_ + to_write_count > kEntriesPerReset) {
- to_write_count = entries_.size();
- set_pending_reset(true);
- }
- if (to_write_count) {
- // Write the to_write_count most recently added entries out. The most
- // recently added entry is at the front, so we use a reverse iterator to
- // write in the order the entries were added.
- Entries::reverse_iterator i = entries_.rbegin();
- DCHECK(static_cast<size_t>(to_write_count) <= entries_.size());
- std::advance(i, entries_.size() - static_cast<int>(to_write_count));
- for (; i != entries_.rend(); ++i) {
- Entry* entry = *i;
- if (entry->type == TAB) {
- Tab* tab = static_cast<Tab*>(entry);
- int selected_index = GetSelectedNavigationIndexToPersist(*tab);
- if (selected_index != -1)
- ScheduleCommandsForTab(*tab, selected_index);
- } else {
- ScheduleCommandsForWindow(*static_cast<Window*>(entry));
- }
- entries_written_++;
- }
- }
- if (pending_reset())
- entries_written_ = 0;
- BaseSessionService::Save();
-}
-
-void TabRestoreService::PopulateTab(Tab* tab,
- int index,
- TabRestoreServiceDelegate* delegate,
- NavigationController* controller) {
- const int pending_index = controller->GetPendingEntryIndex();
- int entry_count = controller->GetEntryCount();
- if (entry_count == 0 && pending_index == 0)
- entry_count++;
- tab->navigations.resize(static_cast<int>(entry_count));
- for (int i = 0; i < entry_count; ++i) {
- NavigationEntry* entry = (i == pending_index) ?
- controller->GetPendingEntry() : controller->GetEntryAtIndex(i);
- tab->navigations[i] =
- TabNavigation::FromNavigationEntry(i, *entry);
- }
- tab->timestamp = TimeNow();
- tab->current_navigation_index = controller->GetCurrentEntryIndex();
- if (tab->current_navigation_index == -1 && entry_count > 0)
- tab->current_navigation_index = 0;
- tab->tabstrip_index = index;
-
- TabContents* tab_contents =
- TabContents::FromWebContents(controller->GetWebContents());
- // tab_contents is NULL in some browser tests.
- if (tab_contents) {
- const extensions::Extension* extension =
- extensions::TabHelper::FromWebContents(controller->GetWebContents())->
- extension_app();
- if (extension)
- tab->extension_app_id = extension->id();
- }
-
- tab->user_agent_override =
- controller->GetWebContents()->GetUserAgentOverride();
-
- // TODO(ajwong): This does not correctly handle storage for isolated apps.
- tab->session_storage_namespace =
- controller->GetDefaultSessionStorageNamespace();
-
- // Delegate may be NULL during unit tests.
- if (delegate) {
- tab->browser_id = delegate->GetSessionID().id();
- tab->pinned = delegate->IsTabPinned(tab->tabstrip_index);
- }
-}
-
-void TabRestoreService::NotifyTabsChanged() {
- FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_,
- TabRestoreServiceChanged(this));
-}
-
-void TabRestoreService::AddEntry(Entry* entry, bool notify, bool to_front) {
- if (!FilterEntry(entry) || (entries_.size() >= kMaxEntries && !to_front)) {
- delete entry;
- return;
- }
-
- if (to_front)
- entries_.push_front(entry);
- else
- entries_.push_back(entry);
-
- PruneEntries();
-
- if (notify)
- NotifyTabsChanged();
-
- // Start the save timer, when it fires we'll generate the commands.
- StartSaveTimer();
- entries_to_write_++;
-}
-
-void TabRestoreService::PruneEntries() {
- Entries new_entries;
-
- for (TabRestoreService::Entries::const_iterator iter = entries_.begin();
- iter != entries_.end(); ++iter) {
- TabRestoreService::Entry* entry = *iter;
-
- if (FilterEntry(entry) &&
- new_entries.size() < kMaxEntries) {
- new_entries.push_back(entry);
- } else {
- delete entry;
- }
+// static
+void PersistentTabRestoreService::Delegate::CreateEntriesFromWindows(
+ std::vector<SessionWindow*>* windows,
+ std::vector<Entry*>* entries) {
+ for (size_t i = 0; i < windows->size(); ++i) {
+ scoped_ptr<Window> window(new Window());
+ if (ConvertSessionWindowToWindow((*windows)[i], window.get()))
+ entries->push_back(window.release());
}
-
- entries_ = new_entries;
}
-TabRestoreService::Entries::iterator TabRestoreService::GetEntryIteratorById(
- SessionID::id_type id) {
- for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) {
- if ((*i)->id == id)
- return i;
-
- // For Window entries, see if the ID matches a tab. If so, report the window
- // as the Entry.
- if ((*i)->type == WINDOW) {
- std::vector<Tab>& tabs = static_cast<Window*>(*i)->tabs;
- for (std::vector<Tab>::iterator j = tabs.begin();
- j != tabs.end(); ++j) {
- if ((*j).id == id) {
- return i;
- }
- }
- }
- }
- return entries_.end();
+void PersistentTabRestoreService::Delegate::Shutdown() {
+ if (backend())
+ Save();
}
-void TabRestoreService::ScheduleCommandsForWindow(const Window& window) {
+void PersistentTabRestoreService::Delegate::ScheduleCommandsForWindow(
+ const Window& window) {
DCHECK(!window.tabs.empty());
int selected_tab = window.selected_tab_index;
int valid_tab_count = 0;
@@ -666,8 +419,9 @@ void TabRestoreService::ScheduleCommandsForWindow(const Window& window) {
}
}
-void TabRestoreService::ScheduleCommandsForTab(const Tab& tab,
- int selected_index) {
+void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab(
+ const Tab& tab,
+ int selected_index) {
const std::vector<TabNavigation>& navigations = tab.navigations;
int max_index = static_cast<int>(navigations.size());
@@ -719,10 +473,12 @@ void TabRestoreService::ScheduleCommandsForTab(const Tab& tab,
}
}
-SessionCommand* TabRestoreService::CreateWindowCommand(SessionID::id_type id,
- int selected_tab_index,
- int num_tabs,
- Time timestamp) {
+// static
+SessionCommand* PersistentTabRestoreService::Delegate::CreateWindowCommand(
+ SessionID::id_type id,
+ int selected_tab_index,
+ int num_tabs,
+ base::Time timestamp) {
WindowPayload2 payload;
// |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of
// uninitialized memory in the struct.
@@ -738,10 +494,12 @@ SessionCommand* TabRestoreService::CreateWindowCommand(SessionID::id_type id,
return command;
}
-SessionCommand* TabRestoreService::CreateSelectedNavigationInTabCommand(
+// static
+SessionCommand*
+PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand(
SessionID::id_type tab_id,
int32 index,
- Time timestamp) {
+ base::Time timestamp) {
SelectedNavigationInTabPayload2 payload;
payload.id = tab_id;
payload.index = index;
@@ -752,7 +510,9 @@ SessionCommand* TabRestoreService::CreateSelectedNavigationInTabCommand(
return command;
}
-SessionCommand* TabRestoreService::CreateRestoredEntryCommand(
+// static
+SessionCommand*
+PersistentTabRestoreService::Delegate::CreateRestoredEntryCommand(
SessionID::id_type entry_id) {
RestoredEntryPayload payload = entry_id;
SessionCommand* command =
@@ -761,7 +521,8 @@ SessionCommand* TabRestoreService::CreateRestoredEntryCommand(
return command;
}
-int TabRestoreService::GetSelectedNavigationIndexToPersist(const Tab& tab) {
+int PersistentTabRestoreService::Delegate::GetSelectedNavigationIndexToPersist(
+ const Tab& tab) {
const std::vector<TabNavigation>& navigations = tab.navigations;
int selected_index = tab.current_navigation_index;
int max_index = static_cast<int>(navigations.size());
@@ -786,7 +547,7 @@ int TabRestoreService::GetSelectedNavigationIndexToPersist(const Tab& tab) {
return (selected_index == max_index) ? -1 : selected_index;
}
-void TabRestoreService::OnGotLastSessionCommands(
+void PersistentTabRestoreService::Delegate::OnGotLastSessionCommands(
Handle handle,
scoped_refptr<InternalGetCommandsRequest> request) {
std::vector<Entry*> entries;
@@ -798,10 +559,11 @@ void TabRestoreService::OnGotLastSessionCommands(
LoadStateChanged();
}
-void TabRestoreService::CreateEntriesFromCommands(
+void PersistentTabRestoreService::Delegate::CreateEntriesFromCommands(
scoped_refptr<InternalGetCommandsRequest> request,
std::vector<Entry*>* loaded_entries) {
- if (request->canceled() || entries_.size() == kMaxEntries)
+ if (request->canceled() ||
+ tab_restore_service_helper_->entries().size() == kMaxEntries)
return;
std::vector<SessionCommand*>& commands = request->commands;
@@ -869,7 +631,8 @@ void TabRestoreService::CreateEntriesFromCommands(
current_window = new Window();
current_window->selected_tab_index = payload.selected_tab_index;
- current_window->timestamp = Time::FromInternalValue(payload.timestamp);
+ current_window->timestamp =
+ base::Time::FromInternalValue(payload.timestamp);
entries.push_back(current_window);
id_to_entry[payload.window_id] = current_window;
break;
@@ -902,7 +665,8 @@ void TabRestoreService::CreateEntriesFromCommands(
RemoveEntryByID(payload.id, &id_to_entry, &(entries.get()));
current_tab = new Tab();
id_to_entry[payload.id] = current_tab;
- current_tab->timestamp = Time::FromInternalValue(payload.timestamp);
+ current_tab->timestamp =
+ base::Time::FromInternalValue(payload.timestamp);
entries.push_back(current_tab);
}
current_tab->current_navigation_index = payload.index;
@@ -992,143 +756,8 @@ void TabRestoreService::CreateEntriesFromCommands(
loaded_entries->swap(entries.get());
}
-TabRestoreServiceDelegate* TabRestoreService::RestoreTab(
- const Tab& tab,
- TabRestoreServiceDelegate* delegate,
- WindowOpenDisposition disposition) {
- if (disposition == CURRENT_TAB && delegate) {
- delegate->ReplaceRestoredTab(tab.navigations,
- tab.current_navigation_index,
- tab.from_last_session,
- tab.extension_app_id,
- tab.session_storage_namespace,
- tab.user_agent_override);
- } else {
- // We only respsect the tab's original browser if there's no disposition.
- if (disposition == UNKNOWN && tab.has_browser())
- delegate = TabRestoreServiceDelegate::FindDelegateWithID(tab.browser_id);
-
- int tab_index = -1;
-
- // |delegate| will be NULL in cases where one isn't already available (eg,
- // when invoked on Mac OS X with no windows open). In this case, create a
- // new browser into which we restore the tabs.
- if (delegate && disposition != NEW_WINDOW) {
- tab_index = tab.tabstrip_index;
- } else {
- delegate = TabRestoreServiceDelegate::Create(profile(), std::string());
- if (tab.has_browser())
- UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id());
- }
-
- // Place the tab at the end if the tab index is no longer valid or
- // we were passed a specific disposition.
- if (tab_index < 0 || tab_index > delegate->GetTabCount() ||
- disposition != UNKNOWN) {
- tab_index = delegate->GetTabCount();
- }
-
- WebContents* web_contents = delegate->AddRestoredTab(
- tab.navigations,
- tab_index,
- tab.current_navigation_index,
- tab.extension_app_id,
- disposition != NEW_BACKGROUND_TAB,
- tab.pinned,
- tab.from_last_session,
- tab.session_storage_namespace,
- tab.user_agent_override);
- web_contents->GetController().LoadIfNecessary();
- }
- RecordAppLaunch(profile(), tab);
- return delegate;
-}
-
-
-bool TabRestoreService::ValidateTab(Tab* tab) {
- if (tab->navigations.empty())
- return false;
-
- tab->current_navigation_index =
- std::max(0, std::min(tab->current_navigation_index,
- static_cast<int>(tab->navigations.size()) - 1));
-
- return true;
-}
-
-bool TabRestoreService::ValidateWindow(Window* window) {
- window->selected_tab_index =
- std::max(0, std::min(window->selected_tab_index,
- static_cast<int>(window->tabs.size() - 1)));
-
- int i = 0;
- for (std::vector<Tab>::iterator tab_i = window->tabs.begin();
- tab_i != window->tabs.end();) {
- if (!ValidateTab(&(*tab_i))) {
- tab_i = window->tabs.erase(tab_i);
- if (i < window->selected_tab_index)
- window->selected_tab_index--;
- else if (i == window->selected_tab_index)
- window->selected_tab_index = 0;
- } else {
- ++tab_i;
- ++i;
- }
- }
-
- if (window->tabs.empty())
- return false;
-
- return true;
-}
-
-bool TabRestoreService::ValidateEntry(Entry* entry) {
- if (entry->type == TAB)
- return ValidateTab(static_cast<Tab*>(entry));
-
- if (entry->type == WINDOW)
- return ValidateWindow(static_cast<Window*>(entry));
-
- NOTREACHED();
- return false;
-}
-
-bool TabRestoreService::IsTabInteresting(const Tab* tab) {
- if (tab->navigations.empty())
- return false;
-
- if (tab->navigations.size() > 1)
- return true;
-
- return tab->pinned ||
- tab->navigations.at(0).virtual_url() !=
- GURL(chrome::kChromeUINewTabURL);
-}
-
-bool TabRestoreService::IsWindowInteresting(const Window* window) {
- if (window->tabs.empty())
- return false;
-
- if (window->tabs.size() > 1)
- return true;
-
- return IsTabInteresting(&window->tabs[0]);
-}
-
-bool TabRestoreService::FilterEntry(Entry* entry) {
- if (!ValidateEntry(entry))
- return false;
-
- if (entry->type == TAB)
- return IsTabInteresting(static_cast<Tab*>(entry));
- else if (entry->type == WINDOW)
- return IsWindowInteresting(static_cast<Window*>(entry));
-
- NOTREACHED();
- return false;
-}
-
-void TabRestoreService::ValidateAndDeleteEmptyEntries(
+// static
+void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries(
std::vector<Entry*>* entries) {
std::vector<Entry*> valid_entries;
std::vector<Entry*> invalid_entries;
@@ -1136,7 +765,7 @@ void TabRestoreService::ValidateAndDeleteEmptyEntries(
// Iterate from the back so that we keep the most recently closed entries.
for (std::vector<Entry*>::reverse_iterator i = entries->rbegin();
i != entries->rend(); ++i) {
- if (ValidateEntry(*i))
+ if (TabRestoreServiceHelper::ValidateEntry(*i))
valid_entries.push_back(*i);
else
invalid_entries.push_back(*i);
@@ -1148,19 +777,7 @@ void TabRestoreService::ValidateAndDeleteEmptyEntries(
STLDeleteElements(&invalid_entries);
}
-void TabRestoreService::UpdateTabBrowserIDs(SessionID::id_type old_id,
- SessionID::id_type new_id) {
- for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) {
- Entry* entry = *i;
- if (entry->type == TAB) {
- Tab* tab = static_cast<Tab*>(entry);
- if (tab->browser_id == old_id)
- tab->browser_id = new_id;
- }
- }
-}
-
-void TabRestoreService::OnGotPreviousSession(
+void PersistentTabRestoreService::Delegate::OnGotPreviousSession(
Handle handle,
std::vector<SessionWindow*>* windows,
SessionID::id_type ignored_active_window) {
@@ -1173,17 +790,7 @@ void TabRestoreService::OnGotPreviousSession(
LoadStateChanged();
}
-void TabRestoreService::CreateEntriesFromWindows(
- std::vector<SessionWindow*>* windows,
- std::vector<Entry*>* entries) {
- for (size_t i = 0; i < windows->size(); ++i) {
- scoped_ptr<Window> window(new Window());
- if (ConvertSessionWindowToWindow((*windows)[i], window.get()))
- entries->push_back(window.release());
- }
-}
-
-bool TabRestoreService::ConvertSessionWindowToWindow(
+bool PersistentTabRestoreService::Delegate::ConvertSessionWindowToWindow(
SessionWindow* session_window,
Window* window) {
for (size_t i = 0; i < session_window->tabs.size(); ++i) {
@@ -1195,7 +802,7 @@ bool TabRestoreService::ConvertSessionWindowToWindow(
tab.current_navigation_index =
session_window->tabs[i]->current_navigation_index;
tab.extension_app_id = session_window->tabs[i]->extension_app_id;
- tab.timestamp = Time();
+ tab.timestamp = base::Time();
}
}
if (window->tabs.empty())
@@ -1204,11 +811,11 @@ bool TabRestoreService::ConvertSessionWindowToWindow(
window->selected_tab_index =
std::min(session_window->selected_tab_index,
static_cast<int>(window->tabs.size() - 1));
- window->timestamp = Time();
+ window->timestamp = base::Time();
return true;
}
-void TabRestoreService::LoadStateChanged() {
+void PersistentTabRestoreService::Delegate::LoadStateChanged() {
if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) !=
(LOADED_LAST_TABS | LOADED_LAST_SESSION)) {
// Still waiting on previous session or previous tabs.
@@ -1218,30 +825,31 @@ void TabRestoreService::LoadStateChanged() {
// We're done loading.
load_state_ ^= LOADING;
- if (staging_entries_.empty() || entries_.size() >= kMaxEntries) {
+ const Entries& entries = tab_restore_service_helper_->entries();
+ if (staging_entries_.empty() || entries.size() >= kMaxEntries) {
STLDeleteElements(&staging_entries_);
return;
}
- if (staging_entries_.size() + entries_.size() > kMaxEntries) {
+ if (staging_entries_.size() + entries.size() > kMaxEntries) {
// If we add all the staged entries we'll end up with more than
- // kMaxEntries. Delete entries such that we only end up with
- // at most kMaxEntries.
- int surplus = kMaxEntries - entries_.size();
+ // kMaxEntries. Delete entries such that we only end up with at most
+ // kMaxEntries.
+ int surplus = kMaxEntries - entries.size();
CHECK_LE(0, surplus);
CHECK_GE(static_cast<int>(staging_entries_.size()), surplus);
STLDeleteContainerPointers(
- staging_entries_.begin() + (kMaxEntries - entries_.size()),
+ staging_entries_.begin() + (kMaxEntries - entries.size()),
staging_entries_.end());
staging_entries_.erase(
- staging_entries_.begin() + (kMaxEntries - entries_.size()),
+ staging_entries_.begin() + (kMaxEntries - entries.size()),
staging_entries_.end());
}
// And add them.
for (size_t i = 0; i < staging_entries_.size(); ++i) {
staging_entries_[i]->from_last_session = true;
- AddEntry(staging_entries_[i], false, false);
+ tab_restore_service_helper_->AddEntry(staging_entries_[i], false, false);
}
// AddEntry takes ownership of the entry, need to clear out entries so that
@@ -1253,10 +861,128 @@ void TabRestoreService::LoadStateChanged() {
// the front, not the end and we just added the entries to the end).
entries_to_write_ = staging_entries_.size();
- PruneEntries();
- NotifyTabsChanged();
+ tab_restore_service_helper_->PruneEntries();
+ tab_restore_service_helper_->NotifyTabsChanged();
+}
+
+void PersistentTabRestoreService::Delegate::RemoveEntryByID(
+ SessionID::id_type id,
+ IDToEntry* id_to_entry,
+ std::vector<TabRestoreService::Entry*>* entries) {
+ // Look for the entry in the map. If it is present, erase it from both
+ // collections and return.
+ IDToEntry::iterator i = id_to_entry->find(id);
+ if (i != id_to_entry->end()) {
+ entries->erase(std::find(entries->begin(), entries->end(), i->second));
+ delete i->second;
+ id_to_entry->erase(i);
+ return;
+ }
+
+ // Otherwise, loop over all items in the map and see if any of the Windows
+ // have Tabs with the |id|.
+ for (IDToEntry::iterator i = id_to_entry->begin(); i != id_to_entry->end();
+ ++i) {
+ if (i->second->type == TabRestoreService::WINDOW) {
+ TabRestoreService::Window* window =
+ static_cast<TabRestoreService::Window*>(i->second);
+ std::vector<TabRestoreService::Tab>::iterator j = window->tabs.begin();
+ for ( ; j != window->tabs.end(); ++j) {
+ // If the ID matches one of this window's tabs, remove it from the
+ // list.
+ if ((*j).id == id) {
+ window->tabs.erase(j);
+ return;
+ }
+ }
+ }
+ }
+}
+
+// PersistentTabRestoreService -------------------------------------------------
+
+PersistentTabRestoreService::PersistentTabRestoreService(
+ Profile* profile,
+ TimeFactory* time_factory)
+ : delegate_(new Delegate(profile)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(
+ helper_(this, delegate_.get(), profile, time_factory)) {
+ delegate_->set_tab_restore_service_helper(&helper_);
+}
+
+PersistentTabRestoreService::~PersistentTabRestoreService() {}
+
+void PersistentTabRestoreService::AddObserver(
+ TabRestoreServiceObserver* observer) {
+ helper_.AddObserver(observer);
+}
+
+void PersistentTabRestoreService::RemoveObserver(
+ TabRestoreServiceObserver* observer) {
+ helper_.RemoveObserver(observer);
+}
+
+void PersistentTabRestoreService::CreateHistoricalTab(
+ content::WebContents* contents,
+ int index) {
+ helper_.CreateHistoricalTab(contents, index);
+}
+
+void PersistentTabRestoreService::BrowserClosing(
+ TabRestoreServiceDelegate* delegate) {
+ helper_.BrowserClosing(delegate);
+}
+
+void PersistentTabRestoreService::BrowserClosed(
+ TabRestoreServiceDelegate* delegate) {
+ helper_.BrowserClosed(delegate);
+}
+
+void PersistentTabRestoreService::ClearEntries() {
+ helper_.ClearEntries();
+}
+
+const TabRestoreService::Entries& PersistentTabRestoreService::entries() const {
+ return helper_.entries();
+}
+
+void PersistentTabRestoreService::RestoreMostRecentEntry(
+ TabRestoreServiceDelegate* delegate) {
+ helper_.RestoreMostRecentEntry(delegate);
+}
+
+TabRestoreService::Tab* PersistentTabRestoreService::RemoveTabEntryById(
+ SessionID::id_type id) {
+ return helper_.RemoveTabEntryById(id);
+}
+
+void PersistentTabRestoreService::RestoreEntryById(
+ TabRestoreServiceDelegate* delegate,
+ SessionID::id_type id,
+ WindowOpenDisposition disposition) {
+ helper_.RestoreEntryById(delegate, id, disposition);
+}
+
+bool PersistentTabRestoreService::IsLoaded() const {
+ return delegate_->IsLoaded();
+}
+
+void PersistentTabRestoreService::DeleteLastSession() {
+ return delegate_->DeleteLastSession();
+}
+
+void PersistentTabRestoreService::Shutdown() {
+ return delegate_->Shutdown();
+}
+
+void PersistentTabRestoreService::LoadTabsFromLastSession() {
+ delegate_->LoadTabsFromLastSession();
+}
+
+TabRestoreService::Entries* PersistentTabRestoreService::mutable_entries() {
+ return &helper_.entries_;
}
-Time TabRestoreService::TimeNow() const {
- return time_factory_ ? time_factory_->TimeNow() : Time::Now();
+void PersistentTabRestoreService::PruneEntries() {
+ helper_.PruneEntries();
}

Powered by Google App Engine
This is Rietveld 408576698