This source file includes following definitions.
- set_tab_restore_service_helper
- load_state_
- Save
- OnClearEntries
- OnRestoreEntryById
- OnAddEntry
- LoadTabsFromLastSession
- IsLoaded
- CreateEntriesFromWindows
- Shutdown
- ScheduleCommandsForWindow
- ScheduleCommandsForTab
- CreateWindowCommand
- CreateSelectedNavigationInTabCommand
- CreateRestoredEntryCommand
- GetSelectedNavigationIndexToPersist
- OnGotLastSessionCommands
- CreateEntriesFromCommands
- ValidateAndDeleteEmptyEntries
- OnGotPreviousSession
- ConvertSessionWindowToWindow
- LoadStateChanged
- RemoveEntryByID
- helper_
- AddObserver
- RemoveObserver
- CreateHistoricalTab
- BrowserClosing
- BrowserClosed
- ClearEntries
- entries
- RestoreMostRecentEntry
- RemoveTabEntryById
- RestoreEntryById
- IsLoaded
- DeleteLastSession
- Shutdown
- LoadTabsFromLastSession
- mutable_entries
- PruneEntries
- BuildServiceInstanceFor
#include "chrome/browser/sessions/persistent_tab_restore_service.h"
#include <cstring>
#include <vector>
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/stl_util.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/time/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/tab_restore_service_factory.h"
#include "content/public/browser/session_storage_namespace.h"
namespace {
typedef bool PinnedStatePayload;
typedef int32 RestoredEntryPayload;
typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry;
struct SelectedNavigationInTabPayload {
SessionID::id_type id;
int32 index;
};
struct WindowPayload {
SessionID::id_type window_id;
int32 selected_tab_index;
int32 num_tabs;
};
struct WindowPayload2 : WindowPayload {
int64 timestamp;
};
struct SelectedNavigationInTabPayload2 : SelectedNavigationInTabPayload {
int64 timestamp;
};
enum LoadState {
NOT_LOADED = 1 << 0,
LOADING = 1 << 2,
LOADED_LAST_TABS = 1 << 3,
LOADED_LAST_SESSION = 1 << 4
};
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;
const int kEntriesPerReset = 40;
const size_t kMaxEntries = TabRestoreServiceHelper::kMaxEntries;
}
class PersistentTabRestoreService::Delegate
: public BaseSessionService,
public TabRestoreServiceHelper::Observer {
public:
explicit Delegate(Profile* profile);
virtual ~Delegate();
virtual void Save() OVERRIDE;
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;
}
void LoadTabsFromLastSession();
bool IsLoaded() const;
static void CreateEntriesFromWindows(std::vector<SessionWindow*>* windows,
std::vector<Entry*>* entries);
void Shutdown();
void ScheduleCommandsForWindow(const Window& window);
void ScheduleCommandsForTab(const Tab& tab, int selected_index);
static SessionCommand* CreateWindowCommand(SessionID::id_type id,
int selected_tab_index,
int num_tabs,
base::Time timestamp);
static SessionCommand* CreateSelectedNavigationInTabCommand(
SessionID::id_type tab_id,
int32 index,
base::Time timestamp);
static SessionCommand* CreateRestoredEntryCommand(
SessionID::id_type entry_id);
int GetSelectedNavigationIndexToPersist(const Tab& tab);
void OnGotLastSessionCommands(ScopedVector<SessionCommand> commands);
void CreateEntriesFromCommands(const std::vector<SessionCommand*>& commands,
std::vector<Entry*>* loaded_entries);
static void ValidateAndDeleteEmptyEntries(std::vector<Entry*>* entries);
void OnGotPreviousSession(ScopedVector<SessionWindow> windows,
SessionID::id_type ignored_active_window);
static bool ConvertSessionWindowToWindow(SessionWindow* session_window,
Window* window);
void LoadStateChanged();
void RemoveEntryByID(SessionID::id_type id,
IDToEntry* id_to_entry,
std::vector<TabRestoreService::Entry*>* entries);
private:
TabRestoreServiceHelper* tab_restore_service_helper_;
int entries_to_write_;
int entries_written_;
int load_state_;
ScopedVector<Entry> staging_entries_;
base::CancelableTaskTracker cancelable_task_tracker_;
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
PersistentTabRestoreService::Delegate::Delegate(Profile* profile)
: BaseSessionService(BaseSessionService::TAB_RESTORE, profile,
base::FilePath()),
tab_restore_service_helper_(NULL),
entries_to_write_(0),
entries_written_(0),
load_state_(NOT_LOADED) {
}
PersistentTabRestoreService::Delegate::~Delegate() {}
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);
}
if (to_write_count) {
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 (pending_reset())
entries_written_ = 0;
BaseSessionService::Save();
}
void PersistentTabRestoreService::Delegate::OnClearEntries() {
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;
set_pending_reset(true);
ScheduleCommand(CreateRestoredEntryCommand(1));
}
void PersistentTabRestoreService::Delegate::OnRestoreEntryById(
SessionID::id_type id,
Entries::const_iterator entry_iterator) {
size_t index = 0;
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));
}
void PersistentTabRestoreService::Delegate::OnAddEntry() {
StartSaveTimer();
entries_to_write_++;
}
void PersistentTabRestoreService::Delegate::LoadTabsFromLastSession() {
if (load_state_ != NOT_LOADED)
return;
if (tab_restore_service_helper_->entries().size() == kMaxEntries) {
load_state_ = (LOADING | LOADED_LAST_SESSION | LOADED_LAST_TABS);
LoadStateChanged();
return;
}
#if !defined(ENABLE_SESSION_SERVICE)
load_state_ = LOADING | LOADED_LAST_SESSION;
#else
load_state_ = LOADING;
SessionService* session_service =
SessionServiceFactory::GetForProfile(profile());
Profile::ExitType exit_type = profile()->GetLastSessionExitType();
if (!profile()->restored_last_session() && session_service &&
(exit_type == Profile::EXIT_CRASHED ||
exit_type == Profile::EXIT_SESSION_ENDED)) {
session_service->GetLastSession(
base::Bind(&Delegate::OnGotPreviousSession, base::Unretained(this)),
&cancelable_task_tracker_);
} else {
load_state_ |= LOADED_LAST_SESSION;
}
#endif
ScheduleGetLastSessionCommands(
base::Bind(&Delegate::OnGotLastSessionCommands, base::Unretained(this)),
&cancelable_task_tracker_);
}
bool PersistentTabRestoreService::Delegate::IsLoaded() const {
return !(load_state_ & (NOT_LOADED | LOADING));
}
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());
}
}
void PersistentTabRestoreService::Delegate::Shutdown() {
if (backend())
Save();
}
void PersistentTabRestoreService::Delegate::ScheduleCommandsForWindow(
const Window& window) {
DCHECK(!window.tabs.empty());
int selected_tab = window.selected_tab_index;
int valid_tab_count = 0;
int real_selected_tab = selected_tab;
for (size_t i = 0; i < window.tabs.size(); ++i) {
if (GetSelectedNavigationIndexToPersist(window.tabs[i]) != -1) {
valid_tab_count++;
} else if (static_cast<int>(i) < selected_tab) {
real_selected_tab--;
}
}
if (valid_tab_count == 0)
return;
ScheduleCommand(
CreateWindowCommand(window.id,
std::min(real_selected_tab, valid_tab_count - 1),
valid_tab_count,
window.timestamp));
if (!window.app_name.empty()) {
ScheduleCommand(
CreateSetWindowAppNameCommand(kCommandSetWindowAppName,
window.id,
window.app_name));
}
for (size_t i = 0; i < window.tabs.size(); ++i) {
int selected_index = GetSelectedNavigationIndexToPersist(window.tabs[i]);
if (selected_index != -1)
ScheduleCommandsForTab(window.tabs[i], selected_index);
}
}
void PersistentTabRestoreService::Delegate::ScheduleCommandsForTab(
const Tab& tab,
int selected_index) {
const std::vector<sessions::SerializedNavigationEntry>& navigations =
tab.navigations;
int max_index = static_cast<int>(navigations.size());
int valid_count_before_selected = 0;
int first_index_to_persist = selected_index;
for (int i = selected_index - 1; i >= 0 &&
valid_count_before_selected < max_persist_navigation_count; --i) {
if (ShouldTrackEntry(navigations[i].virtual_url())) {
first_index_to_persist = i;
valid_count_before_selected++;
}
}
ScheduleCommand(
CreateSelectedNavigationInTabCommand(tab.id,
valid_count_before_selected,
tab.timestamp));
if (tab.pinned) {
PinnedStatePayload payload = true;
SessionCommand* command =
new SessionCommand(kCommandPinnedState, sizeof(payload));
memcpy(command->contents(), &payload, sizeof(payload));
ScheduleCommand(command);
}
if (!tab.extension_app_id.empty()) {
ScheduleCommand(
CreateSetTabExtensionAppIDCommand(kCommandSetExtensionAppID, tab.id,
tab.extension_app_id));
}
if (!tab.user_agent_override.empty()) {
ScheduleCommand(
CreateSetTabUserAgentOverrideCommand(kCommandSetTabUserAgentOverride,
tab.id, tab.user_agent_override));
}
for (int i = first_index_to_persist, wrote_count = 0;
i < max_index && wrote_count < 2 * max_persist_navigation_count; ++i) {
if (ShouldTrackEntry(navigations[i].virtual_url())) {
ScheduleCommand(
CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation, tab.id,
navigations[i]));
}
}
}
SessionCommand* PersistentTabRestoreService::Delegate::CreateWindowCommand(
SessionID::id_type id,
int selected_tab_index,
int num_tabs,
base::Time timestamp) {
WindowPayload2 payload;
memset(&payload, 0, sizeof(payload));
payload.window_id = id;
payload.selected_tab_index = selected_tab_index;
payload.num_tabs = num_tabs;
payload.timestamp = timestamp.ToInternalValue();
SessionCommand* command =
new SessionCommand(kCommandWindow, sizeof(payload));
memcpy(command->contents(), &payload, sizeof(payload));
return command;
}
SessionCommand*
PersistentTabRestoreService::Delegate::CreateSelectedNavigationInTabCommand(
SessionID::id_type tab_id,
int32 index,
base::Time timestamp) {
SelectedNavigationInTabPayload2 payload;
payload.id = tab_id;
payload.index = index;
payload.timestamp = timestamp.ToInternalValue();
SessionCommand* command =
new SessionCommand(kCommandSelectedNavigationInTab, sizeof(payload));
memcpy(command->contents(), &payload, sizeof(payload));
return command;
}
SessionCommand*
PersistentTabRestoreService::Delegate::CreateRestoredEntryCommand(
SessionID::id_type entry_id) {
RestoredEntryPayload payload = entry_id;
SessionCommand* command =
new SessionCommand(kCommandRestoredEntry, sizeof(payload));
memcpy(command->contents(), &payload, sizeof(payload));
return command;
}
int PersistentTabRestoreService::Delegate::GetSelectedNavigationIndexToPersist(
const Tab& tab) {
const std::vector<sessions::SerializedNavigationEntry>& navigations =
tab.navigations;
int selected_index = tab.current_navigation_index;
int max_index = static_cast<int>(navigations.size());
while (selected_index >= 0 &&
!ShouldTrackEntry(navigations[selected_index].virtual_url())) {
selected_index--;
}
if (selected_index != -1)
return selected_index;
selected_index = tab.current_navigation_index + 1;
while (selected_index < max_index &&
!ShouldTrackEntry(navigations[selected_index].virtual_url())) {
selected_index++;
}
return (selected_index == max_index) ? -1 : selected_index;
}
void PersistentTabRestoreService::Delegate::OnGotLastSessionCommands(
ScopedVector<SessionCommand> commands) {
std::vector<Entry*> entries;
CreateEntriesFromCommands(commands.get(), &entries);
staging_entries_.insert(staging_entries_.end(), entries.begin(),
entries.end());
load_state_ |= LOADED_LAST_TABS;
LoadStateChanged();
}
void PersistentTabRestoreService::Delegate::CreateEntriesFromCommands(
const std::vector<SessionCommand*>& commands,
std::vector<Entry*>* loaded_entries) {
if (tab_restore_service_helper_->entries().size() == kMaxEntries)
return;
ScopedVector<Entry> entries;
IDToEntry id_to_entry;
Tab* current_tab = NULL;
Window* current_window = NULL;
int pending_window_tabs = 0;
for (std::vector<SessionCommand*>::const_iterator i = commands.begin();
i != commands.end(); ++i) {
const SessionCommand& command = *(*i);
switch (command.id()) {
case kCommandRestoredEntry: {
if (pending_window_tabs > 0) {
return;
}
current_tab = NULL;
current_window = NULL;
RestoredEntryPayload payload;
if (!command.GetPayload(&payload, sizeof(payload)))
return;
RemoveEntryByID(payload, &id_to_entry, &(entries.get()));
break;
}
case kCommandWindow: {
WindowPayload2 payload;
if (pending_window_tabs > 0) {
return;
}
if (!command.GetPayload(&payload, sizeof(payload))) {
WindowPayload old_payload;
if (!command.GetPayload(&old_payload, sizeof(old_payload)))
return;
payload.window_id = old_payload.window_id;
payload.selected_tab_index = old_payload.selected_tab_index;
payload.num_tabs = old_payload.num_tabs;
payload.timestamp = 0;
}
pending_window_tabs = payload.num_tabs;
if (pending_window_tabs <= 0) {
return;
}
RemoveEntryByID(payload.window_id, &id_to_entry, &(entries.get()));
current_window = new Window();
current_window->selected_tab_index = payload.selected_tab_index;
current_window->timestamp =
base::Time::FromInternalValue(payload.timestamp);
entries.push_back(current_window);
id_to_entry[payload.window_id] = current_window;
break;
}
case kCommandSelectedNavigationInTab: {
SelectedNavigationInTabPayload2 payload;
if (!command.GetPayload(&payload, sizeof(payload))) {
SelectedNavigationInTabPayload old_payload;
if (!command.GetPayload(&old_payload, sizeof(old_payload)))
return;
payload.id = old_payload.id;
payload.index = old_payload.index;
payload.timestamp = 0;
}
if (pending_window_tabs > 0) {
if (!current_window) {
NOTREACHED();
return;
}
current_window->tabs.resize(current_window->tabs.size() + 1);
current_tab = &(current_window->tabs.back());
if (--pending_window_tabs == 0)
current_window = NULL;
} else {
RemoveEntryByID(payload.id, &id_to_entry, &(entries.get()));
current_tab = new Tab();
id_to_entry[payload.id] = current_tab;
current_tab->timestamp =
base::Time::FromInternalValue(payload.timestamp);
entries.push_back(current_tab);
}
current_tab->current_navigation_index = payload.index;
break;
}
case kCommandUpdateTabNavigation: {
if (!current_tab) {
return;
}
current_tab->navigations.resize(current_tab->navigations.size() + 1);
SessionID::id_type tab_id;
if (!RestoreUpdateTabNavigationCommand(
command, ¤t_tab->navigations.back(), &tab_id)) {
return;
}
break;
}
case kCommandPinnedState: {
if (!current_tab) {
return;
}
current_tab->pinned = true;
break;
}
case kCommandSetWindowAppName: {
if (!current_window) {
NOTREACHED();
return;
}
SessionID::id_type window_id;
std::string app_name;
if (!RestoreSetWindowAppNameCommand(command, &window_id, &app_name))
return;
current_window->app_name.swap(app_name);
break;
}
case kCommandSetExtensionAppID: {
if (!current_tab) {
return;
}
SessionID::id_type tab_id;
std::string extension_app_id;
if (!RestoreSetTabExtensionAppIDCommand(command, &tab_id,
&extension_app_id)) {
return;
}
current_tab->extension_app_id.swap(extension_app_id);
break;
}
case kCommandSetTabUserAgentOverride: {
if (!current_tab) {
return;
}
SessionID::id_type tab_id;
std::string user_agent_override;
if (!RestoreSetTabUserAgentOverrideCommand(command, &tab_id,
&user_agent_override)) {
return;
}
current_tab->user_agent_override.swap(user_agent_override);
break;
}
default:
return;
}
}
ValidateAndDeleteEmptyEntries(&(entries.get()));
loaded_entries->swap(entries.get());
}
void PersistentTabRestoreService::Delegate::ValidateAndDeleteEmptyEntries(
std::vector<Entry*>* entries) {
std::vector<Entry*> valid_entries;
std::vector<Entry*> invalid_entries;
for (std::vector<Entry*>::reverse_iterator i = entries->rbegin();
i != entries->rend(); ++i) {
if (TabRestoreServiceHelper::ValidateEntry(*i))
valid_entries.push_back(*i);
else
invalid_entries.push_back(*i);
}
entries->swap(valid_entries);
STLDeleteElements(&invalid_entries);
}
void PersistentTabRestoreService::Delegate::OnGotPreviousSession(
ScopedVector<SessionWindow> windows,
SessionID::id_type ignored_active_window) {
std::vector<Entry*> entries;
CreateEntriesFromWindows(&windows.get(), &entries);
staging_entries_.insert(staging_entries_.begin(), entries.begin(),
entries.end());
load_state_ |= LOADED_LAST_SESSION;
LoadStateChanged();
}
bool PersistentTabRestoreService::Delegate::ConvertSessionWindowToWindow(
SessionWindow* session_window,
Window* window) {
for (size_t i = 0; i < session_window->tabs.size(); ++i) {
if (!session_window->tabs[i]->navigations.empty()) {
window->tabs.resize(window->tabs.size() + 1);
Tab& tab = window->tabs.back();
tab.pinned = session_window->tabs[i]->pinned;
tab.navigations.swap(session_window->tabs[i]->navigations);
tab.current_navigation_index =
session_window->tabs[i]->current_navigation_index;
tab.extension_app_id = session_window->tabs[i]->extension_app_id;
tab.timestamp = base::Time();
}
}
if (window->tabs.empty())
return false;
window->selected_tab_index =
std::min(session_window->selected_tab_index,
static_cast<int>(window->tabs.size() - 1));
window->timestamp = base::Time();
return true;
}
void PersistentTabRestoreService::Delegate::LoadStateChanged() {
if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) !=
(LOADED_LAST_TABS | LOADED_LAST_SESSION)) {
return;
}
load_state_ ^= LOADING;
const Entries& entries = tab_restore_service_helper_->entries();
if (staging_entries_.empty() || entries.size() >= kMaxEntries) {
staging_entries_.clear();
tab_restore_service_helper_->NotifyLoaded();
return;
}
if (staging_entries_.size() + entries.size() > kMaxEntries) {
int surplus = kMaxEntries - entries.size();
CHECK_LE(0, surplus);
CHECK_GE(static_cast<int>(staging_entries_.size()), surplus);
staging_entries_.erase(
staging_entries_.begin() + (kMaxEntries - entries.size()),
staging_entries_.end());
}
for (size_t i = 0; i < staging_entries_.size(); ++i) {
staging_entries_[i]->from_last_session = true;
tab_restore_service_helper_->AddEntry(staging_entries_[i], false, false);
}
staging_entries_.weak_clear();
entries_to_write_ = staging_entries_.size();
tab_restore_service_helper_->PruneEntries();
tab_restore_service_helper_->NotifyTabsChanged();
tab_restore_service_helper_->NotifyLoaded();
}
void PersistentTabRestoreService::Delegate::RemoveEntryByID(
SessionID::id_type id,
IDToEntry* id_to_entry,
std::vector<TabRestoreService::Entry*>* entries) {
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;
}
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 ((*j).id == id) {
window->tabs.erase(j);
return;
}
}
}
}
}
PersistentTabRestoreService::PersistentTabRestoreService(
Profile* profile,
TimeFactory* time_factory)
: delegate_(new Delegate(profile)),
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();
}
std::vector<content::WebContents*>
PersistentTabRestoreService::RestoreMostRecentEntry(
TabRestoreServiceDelegate* delegate,
chrome::HostDesktopType host_desktop_type) {
return helper_.RestoreMostRecentEntry(delegate, host_desktop_type);
}
TabRestoreService::Tab* PersistentTabRestoreService::RemoveTabEntryById(
SessionID::id_type id) {
return helper_.RemoveTabEntryById(id);
}
std::vector<content::WebContents*>
PersistentTabRestoreService::RestoreEntryById(
TabRestoreServiceDelegate* delegate,
SessionID::id_type id,
chrome::HostDesktopType host_desktop_type,
WindowOpenDisposition disposition) {
return helper_.RestoreEntryById(delegate, id, host_desktop_type, 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_;
}
void PersistentTabRestoreService::PruneEntries() {
helper_.PruneEntries();
}
KeyedService* TabRestoreServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* profile) const {
return new PersistentTabRestoreService(static_cast<Profile*>(profile), NULL);
}