| Index: chrome/browser/sessions/tab_restore_service_helper.cc
|
| diff --git a/chrome/browser/sessions/tab_restore_service.cc b/chrome/browser/sessions/tab_restore_service_helper.cc
|
| similarity index 33%
|
| copy from chrome/browser/sessions/tab_restore_service.cc
|
| copy to chrome/browser/sessions/tab_restore_service_helper.cc
|
| index 4003edb3ad7f707fa978dfab25a33896f38fcf50..27e841a47e266f2d474a5eb2da6a04e4a5d4a25b 100644
|
| --- a/chrome/browser/sessions/tab_restore_service.cc
|
| +++ b/chrome/browser/sessions/tab_restore_service_helper.cc
|
| @@ -2,24 +2,17 @@
|
| // 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/tab_restore_service_helper.h"
|
|
|
| #include <algorithm>
|
| #include <iterator>
|
| -#include <map>
|
|
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/callback.h"
|
| -#include "base/memory/scoped_vector.h"
|
| +#include "base/logging.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 "chrome/browser/profiles/profile.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"
|
| @@ -31,139 +24,16 @@
|
| #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;
|
|
|
| -// TimeFactory-----------------------------------------------------------------
|
| -
|
| -TabRestoreService::TimeFactory::~TimeFactory() {}
|
| -
|
| -// Entry ----------------------------------------------------------------------
|
| -
|
| -// ID of the next Entry.
|
| -static SessionID::id_type next_entry_id = 1;
|
| -
|
| -TabRestoreService::Entry::Entry()
|
| - : id(next_entry_id++),
|
| - type(TAB),
|
| - from_last_session(false) {}
|
| -
|
| -TabRestoreService::Entry::Entry(Type type)
|
| - : id(next_entry_id++),
|
| - type(type),
|
| - from_last_session(false) {}
|
| -
|
| -TabRestoreService::Entry::~Entry() {}
|
| -
|
| -// TabRestoreService ----------------------------------------------------------
|
| -
|
| -// static
|
| -const size_t TabRestoreService::kMaxEntries = 25;
|
| -
|
| -// 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
|
| -// pinned and kCommandSetExtensionAppID if the tab has an app id and
|
| -// the user agent override if it was using one. This is
|
| -// followed by any number of kCommandUpdateTabNavigation commands (1 per
|
| -// navigation entry).
|
| -// . When the user closes a window a kCommandSelectedNavigationInTab command
|
| -// is written out and followed by n tab closed sequences (as previoulsy
|
| -// 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;
|
| -
|
| -// Number of entries (not commands) before we clobber the file and write
|
| -// everything.
|
| -static const int kEntriesPerReset = 40;
|
| -
|
| namespace {
|
|
|
| -// Payload structures.
|
| -
|
| -typedef int32 RestoredEntryPayload;
|
| -
|
| -// 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;
|
| -};
|
| -
|
| -// 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;
|
| -};
|
| -
|
| -// Payload used for the start of a window close. This struct must be POD,
|
| -// because we memset the contents.
|
| -struct WindowPayload2 : WindowPayload {
|
| - int64 timestamp;
|
| -};
|
| -
|
| -// Payload used for the start of a tab close.
|
| -struct SelectedNavigationInTabPayload2 : SelectedNavigationInTabPayload {
|
| - int64 timestamp;
|
| -};
|
| -
|
| -// Only written if the tab is pinned.
|
| -typedef bool PinnedStatePayload;
|
| -
|
| -typedef std::map<SessionID::id_type, TabRestoreService::Entry*> IDToEntry;
|
| -
|
| -// 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;
|
| - }
|
| -
|
| - // 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;
|
| - }
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| void RecordAppLaunch(Profile* profile, const TabRestoreService::Tab& tab) {
|
| +#if !defined(OS_ANDROID)
|
| GURL url = tab.navigations.at(tab.current_navigation_index).virtual_url();
|
| DCHECK(profile->GetExtensionService());
|
| if (!profile->GetExtensionService()->IsInstalledApp(url))
|
| @@ -171,56 +41,60 @@ void RecordAppLaunch(Profile* profile, const TabRestoreService::Tab& tab) {
|
|
|
| AppLauncherHandler::RecordAppLaunchType(
|
| extension_misc::APP_LAUNCH_NTP_RECENTLY_CLOSED);
|
| +#endif // !defined(OS_ANDROID)
|
| }
|
|
|
| } // namespace
|
|
|
| -TabRestoreService::Tab::Tab()
|
| - : Entry(TAB),
|
| - current_navigation_index(-1),
|
| - browser_id(0),
|
| - tabstrip_index(-1),
|
| - pinned(false) {
|
| -}
|
| +// TabRestoreServiceHelper::Observer -------------------------------------------
|
|
|
| -TabRestoreService::Tab::~Tab() {
|
| -}
|
| +TabRestoreServiceHelper::Observer::~Observer() {}
|
|
|
| -TabRestoreService::Window::Window() : Entry(WINDOW), selected_tab_index(-1) {
|
| -}
|
| +void TabRestoreServiceHelper::Observer::OnClearEntries() {}
|
|
|
| -TabRestoreService::Window::~Window() {
|
| +void TabRestoreServiceHelper::Observer::OnRestoreEntryById(
|
| + SessionID::id_type id,
|
| + Entries::const_iterator entry_iterator) {
|
| }
|
|
|
| -TabRestoreService::TabRestoreService(Profile* profile,
|
| +void TabRestoreServiceHelper::Observer::OnAddEntry() {}
|
| +
|
| +// TabRestoreServiceHelper -----------------------------------------------------
|
| +
|
| +const size_t TabRestoreServiceHelper::kMaxEntries = 25;
|
| +
|
| +TabRestoreServiceHelper::TabRestoreServiceHelper(
|
| + TabRestoreService* tab_restore_service,
|
| + Observer* observer,
|
| + Profile* profile,
|
| TabRestoreService::TimeFactory* time_factory)
|
| - : BaseSessionService(BaseSessionService::TAB_RESTORE, profile,
|
| - FilePath()),
|
| - load_state_(NOT_LOADED),
|
| + : tab_restore_service_(tab_restore_service),
|
| + observer_(observer),
|
| + profile_(profile),
|
| restoring_(false),
|
| - entries_to_write_(0),
|
| - entries_written_(0),
|
| time_factory_(time_factory) {
|
| + DCHECK(tab_restore_service_);
|
| }
|
|
|
| -TabRestoreService::~TabRestoreService() {
|
| +TabRestoreServiceHelper::~TabRestoreServiceHelper() {
|
| FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_,
|
| - TabRestoreServiceDestroyed(this));
|
| + TabRestoreServiceDestroyed(tab_restore_service_));
|
| STLDeleteElements(&entries_);
|
| - STLDeleteElements(&staging_entries_);
|
| - time_factory_ = NULL;
|
| }
|
|
|
| -void TabRestoreService::AddObserver(TabRestoreServiceObserver* observer) {
|
| +void TabRestoreServiceHelper::AddObserver(
|
| + TabRestoreServiceObserver* observer) {
|
| observer_list_.AddObserver(observer);
|
| }
|
|
|
| -void TabRestoreService::RemoveObserver(TabRestoreServiceObserver* observer) {
|
| +void TabRestoreServiceHelper::RemoveObserver(
|
| + TabRestoreServiceObserver* observer) {
|
| observer_list_.RemoveObserver(observer);
|
| }
|
|
|
| -void TabRestoreService::CreateHistoricalTab(content::WebContents* contents,
|
| - int index) {
|
| +void TabRestoreServiceHelper::CreateHistoricalTab(
|
| + content::WebContents* contents,
|
| + int index) {
|
| if (restoring_)
|
| return;
|
|
|
| @@ -237,7 +111,8 @@ void TabRestoreService::CreateHistoricalTab(content::WebContents* contents,
|
| AddEntry(local_tab.release(), true, true);
|
| }
|
|
|
| -void TabRestoreService::BrowserClosing(TabRestoreServiceDelegate* delegate) {
|
| +void TabRestoreServiceHelper::BrowserClosing(
|
| + TabRestoreServiceDelegate* delegate) {
|
| closing_delegates_.insert(delegate);
|
|
|
| scoped_ptr<Window> window(new Window());
|
| @@ -276,33 +151,23 @@ void TabRestoreService::BrowserClosing(TabRestoreServiceDelegate* delegate) {
|
| }
|
| }
|
|
|
| -void TabRestoreService::BrowserClosed(TabRestoreServiceDelegate* delegate) {
|
| +void TabRestoreServiceHelper::BrowserClosed(
|
| + TabRestoreServiceDelegate* delegate) {
|
| closing_delegates_.erase(delegate);
|
| }
|
|
|
| -void TabRestoreService::ClearEntries() {
|
| - // 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)
|
| - ScheduleCommand(CreateRestoredEntryCommand((*i)->id));
|
| -
|
| - entries_to_write_ = 0;
|
| -
|
| - // Schedule a pending reset so that we nuke the file on next write.
|
| - set_pending_reset(true);
|
| -
|
| - // Schedule a command, otherwise if there are no pending commands Save does
|
| - // nothing.
|
| - ScheduleCommand(CreateRestoredEntryCommand(1));
|
| -
|
| +void TabRestoreServiceHelper::ClearEntries() {
|
| + if (observer_)
|
| + observer_->OnClearEntries();
|
| STLDeleteElements(&entries_);
|
| NotifyTabsChanged();
|
| }
|
|
|
| -const TabRestoreService::Entries& TabRestoreService::entries() const {
|
| +const TabRestoreService::Entries& TabRestoreServiceHelper::entries() const {
|
| return entries_;
|
| }
|
|
|
| -void TabRestoreService::RestoreMostRecentEntry(
|
| +void TabRestoreServiceHelper::RestoreMostRecentEntry(
|
| TabRestoreServiceDelegate* delegate) {
|
| if (entries_.empty())
|
| return;
|
| @@ -310,14 +175,14 @@ void TabRestoreService::RestoreMostRecentEntry(
|
| RestoreEntryById(delegate, entries_.front()->id, UNKNOWN);
|
| }
|
|
|
| -TabRestoreService::Tab* TabRestoreService::RemoveTabEntryById(
|
| +TabRestoreService::Tab* TabRestoreServiceHelper::RemoveTabEntryById(
|
| SessionID::id_type id) {
|
| Entries::iterator i = GetEntryIteratorById(id);
|
| if (i == entries_.end())
|
| return NULL;
|
|
|
| Entry* entry = *i;
|
| - if (entry->type != TAB)
|
| + if (entry->type != TabRestoreService::TAB)
|
| return NULL;
|
|
|
| Tab* tab = static_cast<Tab*>(entry);
|
| @@ -325,43 +190,37 @@ TabRestoreService::Tab* TabRestoreService::RemoveTabEntryById(
|
| return tab;
|
| }
|
|
|
| -void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate,
|
| - SessionID::id_type id,
|
| - WindowOpenDisposition disposition) {
|
| - Entries::iterator i = GetEntryIteratorById(id);
|
| - if (i == entries_.end()) {
|
| +void TabRestoreServiceHelper::RestoreEntryById(
|
| + TabRestoreServiceDelegate* delegate,
|
| + SessionID::id_type id,
|
| + WindowOpenDisposition disposition) {
|
| + Entries::iterator entry_iterator = GetEntryIteratorById(id);
|
| + if (entry_iterator == entries_.end())
|
| // Don't hoark here, we allow an invalid id.
|
| return;
|
| - }
|
| -
|
| - size_t index = 0;
|
| - for (Entries::iterator j = entries_.begin(); j != i && j != entries_.end();
|
| - ++j, ++index) {}
|
| - if (static_cast<int>(index) < entries_to_write_)
|
| - entries_to_write_--;
|
| -
|
| - ScheduleCommand(CreateRestoredEntryCommand(id));
|
|
|
| + if (observer_)
|
| + observer_->OnRestoreEntryById(id, entry_iterator);
|
| restoring_ = true;
|
| - Entry* entry = *i;
|
| + Entry* entry = *entry_iterator;
|
|
|
| // 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();
|
| + entries_.erase(entry_iterator);
|
| + entry_iterator = 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) {
|
| + if (entry->type == TabRestoreService::TAB) {
|
| Tab* tab = static_cast<Tab*>(entry);
|
| delegate = RestoreTab(*tab, delegate, disposition);
|
| delegate->ShowBrowserWindow();
|
| - } else if (entry->type == WINDOW) {
|
| + } else if (entry->type == TabRestoreService::WINDOW) {
|
| TabRestoreServiceDelegate* current_delegate = delegate;
|
| Window* window = static_cast<Window*>(entry);
|
|
|
| @@ -369,7 +228,7 @@ void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate,
|
| // 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);
|
| + 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 =
|
| @@ -383,7 +242,7 @@ void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate,
|
| tab.user_agent_override);
|
| if (restored_tab) {
|
| restored_tab->GetController().LoadIfNecessary();
|
| - RecordAppLaunch(profile(), tab);
|
| + RecordAppLaunch(profile_, tab);
|
| }
|
| }
|
| // All the window's tabs had the same former browser_id.
|
| @@ -403,7 +262,7 @@ void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate,
|
| // If restoring the tab leaves the window with nothing else, delete it
|
| // as well.
|
| if (!window->tabs.size()) {
|
| - entries_.erase(i);
|
| + entries_.erase(entry_iterator);
|
| delete entry;
|
| } else {
|
| // Update the browser ID of the rest of the tabs in the window so if
|
| @@ -438,140 +297,14 @@ void TabRestoreService::RestoreEntryById(TabRestoreServiceDelegate* delegate,
|
| NotifyTabsChanged();
|
| }
|
|
|
| -void TabRestoreService::LoadTabsFromLastSession() {
|
| - if (load_state_ != NOT_LOADED || entries_.size() == kMaxEntries)
|
| - return;
|
| -
|
| -#if !defined(ENABLE_SESSION_SERVICE)
|
| - // If sessions are not stored in the SessionService, default to
|
| - // |LOADED_LAST_SESSION| state.
|
| - 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)) {
|
| - // The previous session crashed and wasn't restored, or was a forced
|
| - // shutdown. Both of which won't have notified us of the browser close so
|
| - // that we need to load the windows from session service (which will have
|
| - // saved them).
|
| - session_service->GetLastSession(
|
| - &crash_consumer_,
|
| - base::Bind(&TabRestoreService::OnGotPreviousSession,
|
| - base::Unretained(this)));
|
| - } else {
|
| - load_state_ |= LOADED_LAST_SESSION;
|
| - }
|
| -#endif
|
| -
|
| - // Request the tabs closed in the last session. If the last session crashed,
|
| - // this won't contain the tabs/window that were open at the point of the
|
| - // crash (the call to GetLastSession above requests those).
|
| - ScheduleGetLastSessionCommands(
|
| - new InternalGetCommandsRequest(
|
| - base::Bind(&TabRestoreService::OnGotLastSessionCommands,
|
| - base::Unretained(this))),
|
| - &load_consumer_);
|
| -}
|
| -
|
| -bool TabRestoreService::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() {
|
| +void TabRestoreServiceHelper::NotifyTabsChanged() {
|
| FOR_EACH_OBSERVER(TabRestoreServiceObserver, observer_list_,
|
| - TabRestoreServiceChanged(this));
|
| + TabRestoreServiceChanged(tab_restore_service_));
|
| }
|
|
|
| -void TabRestoreService::AddEntry(Entry* entry, bool notify, bool to_front) {
|
| +void TabRestoreServiceHelper::AddEntry(Entry* entry,
|
| + bool notify,
|
| + bool to_front) {
|
| if (!FilterEntry(entry) || (entries_.size() >= kMaxEntries && !to_front)) {
|
| delete entry;
|
| return;
|
| @@ -587,12 +320,11 @@ void TabRestoreService::AddEntry(Entry* entry, bool notify, bool to_front) {
|
| if (notify)
|
| NotifyTabsChanged();
|
|
|
| - // Start the save timer, when it fires we'll generate the commands.
|
| - StartSaveTimer();
|
| - entries_to_write_++;
|
| + if (observer_)
|
| + observer_->OnAddEntry();
|
| }
|
|
|
| -void TabRestoreService::PruneEntries() {
|
| +void TabRestoreServiceHelper::PruneEntries() {
|
| Entries new_entries;
|
|
|
| for (TabRestoreService::Entries::const_iterator iter = entries_.begin();
|
| @@ -610,15 +342,15 @@ void TabRestoreService::PruneEntries() {
|
| entries_ = new_entries;
|
| }
|
|
|
| -TabRestoreService::Entries::iterator TabRestoreService::GetEntryIteratorById(
|
| - SessionID::id_type id) {
|
| +TabRestoreService::Entries::iterator
|
| +TabRestoreServiceHelper::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) {
|
| + if ((*i)->type == TabRestoreService::WINDOW) {
|
| std::vector<Tab>& tabs = static_cast<Window*>(*i)->tabs;
|
| for (std::vector<Tab>::iterator j = tabs.begin();
|
| j != tabs.end(); ++j) {
|
| @@ -631,368 +363,66 @@ TabRestoreService::Entries::iterator TabRestoreService::GetEntryIteratorById(
|
| return entries_.end();
|
| }
|
|
|
| -void TabRestoreService::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; // No tabs to persist.
|
| -
|
| - 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 TabRestoreService::ScheduleCommandsForTab(const Tab& tab,
|
| - int selected_index) {
|
| - const std::vector<TabNavigation>& navigations = tab.navigations;
|
| - int max_index = static_cast<int>(navigations.size());
|
| -
|
| - // Determine the first navigation we'll persist.
|
| - 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++;
|
| - }
|
| - }
|
| -
|
| - // Write the command that identifies the selected tab.
|
| - 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));
|
| - }
|
| -
|
| - // Then write the navigations.
|
| - 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* TabRestoreService::CreateWindowCommand(SessionID::id_type id,
|
| - int selected_tab_index,
|
| - int num_tabs,
|
| - Time timestamp) {
|
| - WindowPayload2 payload;
|
| - // |timestamp| is aligned on a 16 byte boundary, leaving 4 bytes of
|
| - // uninitialized memory in the struct.
|
| - 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;
|
| -}
|
| +// static
|
| +bool TabRestoreServiceHelper::ValidateEntry(Entry* entry) {
|
| + if (entry->type == TabRestoreService::TAB)
|
| + return ValidateTab(static_cast<Tab*>(entry));
|
|
|
| -SessionCommand* TabRestoreService::CreateSelectedNavigationInTabCommand(
|
| - SessionID::id_type tab_id,
|
| - int32 index,
|
| - 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;
|
| -}
|
| + if (entry->type == TabRestoreService::WINDOW)
|
| + return ValidateWindow(static_cast<Window*>(entry));
|
|
|
| -SessionCommand* TabRestoreService::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;
|
| + NOTREACHED();
|
| + return false;
|
| }
|
|
|
| -int TabRestoreService::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());
|
| -
|
| - // Find the first navigation to persist. We won't persist the selected
|
| - // navigation if ShouldTrackEntry returns false.
|
| - while (selected_index >= 0 &&
|
| - !ShouldTrackEntry(navigations[selected_index].virtual_url())) {
|
| - selected_index--;
|
| +void TabRestoreServiceHelper::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;
|
|
|
| - if (selected_index != -1)
|
| - return selected_index;
|
| -
|
| - // Couldn't find a navigation to persist going back, go forward.
|
| - selected_index = tab.current_navigation_index + 1;
|
| - while (selected_index < max_index &&
|
| - !ShouldTrackEntry(navigations[selected_index].virtual_url())) {
|
| - selected_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();
|
| }
|
|
|
| - return (selected_index == max_index) ? -1 : selected_index;
|
| -}
|
| -
|
| -void TabRestoreService::OnGotLastSessionCommands(
|
| - Handle handle,
|
| - scoped_refptr<InternalGetCommandsRequest> request) {
|
| - std::vector<Entry*> entries;
|
| - CreateEntriesFromCommands(request, &entries);
|
| - // Closed tabs always go to the end.
|
| - staging_entries_.insert(staging_entries_.end(), entries.begin(),
|
| - entries.end());
|
| - load_state_ |= LOADED_LAST_TABS;
|
| - LoadStateChanged();
|
| -}
|
| -
|
| -void TabRestoreService::CreateEntriesFromCommands(
|
| - scoped_refptr<InternalGetCommandsRequest> request,
|
| - std::vector<Entry*>* loaded_entries) {
|
| - if (request->canceled() || entries_.size() == kMaxEntries)
|
| - return;
|
| -
|
| - std::vector<SessionCommand*>& commands = request->commands;
|
| - // Iterate through the commands populating entries and id_to_entry.
|
| - ScopedVector<Entry> entries;
|
| - IDToEntry id_to_entry;
|
| - // If non-null we're processing the navigations of this tab.
|
| - Tab* current_tab = NULL;
|
| - // If non-null we're processing the tabs of this window.
|
| - Window* current_window = NULL;
|
| - // If > 0, we've gotten a window command but not all the tabs yet.
|
| - 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) {
|
| - // Should never receive a restored command while waiting for all the
|
| - // tabs in a window.
|
| - 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) {
|
| - // Should never receive a window command while waiting for all the
|
| - // tabs in a window.
|
| - return;
|
| - }
|
| -
|
| - // Try the new payload first
|
| - if (!command.GetPayload(&payload, sizeof(payload))) {
|
| - // then the old payload
|
| - WindowPayload old_payload;
|
| - if (!command.GetPayload(&old_payload, sizeof(old_payload)))
|
| - return;
|
| -
|
| - // Copy the old payload data to the new payload.
|
| - payload.window_id = old_payload.window_id;
|
| - payload.selected_tab_index = old_payload.selected_tab_index;
|
| - payload.num_tabs = old_payload.num_tabs;
|
| - // Since we don't have a time use time 0 which is used to mark as an
|
| - // unknown timestamp.
|
| - payload.timestamp = 0;
|
| - }
|
| -
|
| - pending_window_tabs = payload.num_tabs;
|
| - if (pending_window_tabs <= 0) {
|
| - // Should always have at least 1 tab. Likely indicates corruption.
|
| - 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 = 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;
|
| - // Since we don't have a time use time 0 which is used to mark as an
|
| - // unknown timestamp.
|
| - payload.timestamp = 0;
|
| - }
|
| -
|
| - if (pending_window_tabs > 0) {
|
| - if (!current_window) {
|
| - // We should have created a window already.
|
| - 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 = Time::FromInternalValue(payload.timestamp);
|
| - entries.push_back(current_tab);
|
| - }
|
| - current_tab->current_navigation_index = payload.index;
|
| - break;
|
| - }
|
| -
|
| - case kCommandUpdateTabNavigation: {
|
| - if (!current_tab) {
|
| - // Should be in a tab when we get this.
|
| - 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) {
|
| - // Should be in a tab when we get this.
|
| - return;
|
| - }
|
| - // NOTE: payload doesn't matter. kCommandPinnedState is only written if
|
| - // tab is pinned.
|
| - current_tab->pinned = true;
|
| - break;
|
| - }
|
| -
|
| - case kCommandSetWindowAppName: {
|
| - if (!current_window) {
|
| - // We should have created a window already.
|
| - 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) {
|
| - // Should be in a tab when we get this.
|
| - 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;
|
| - }
|
| + tab->user_agent_override =
|
| + controller->GetWebContents()->GetUserAgentOverride();
|
|
|
| - case kCommandSetTabUserAgentOverride: {
|
| - if (!current_tab) {
|
| - // Should be in a tab when we get this.
|
| - 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;
|
| - }
|
| + // TODO(ajwong): This does not correctly handle storage for isolated apps.
|
| + tab->session_storage_namespace =
|
| + controller->GetDefaultSessionStorageNamespace();
|
|
|
| - default:
|
| - // Unknown type, usually indicates corruption of file. Ignore it.
|
| - return;
|
| - }
|
| + // Delegate may be NULL during unit tests.
|
| + if (delegate) {
|
| + tab->browser_id = delegate->GetSessionID().id();
|
| + tab->pinned = delegate->IsTabPinned(tab->tabstrip_index);
|
| }
|
| -
|
| - // If there was corruption some of the entries won't be valid.
|
| - ValidateAndDeleteEmptyEntries(&(entries.get()));
|
| -
|
| - loaded_entries->swap(entries.get());
|
| }
|
|
|
| -TabRestoreServiceDelegate* TabRestoreService::RestoreTab(
|
| +TabRestoreServiceDelegate* TabRestoreServiceHelper::RestoreTab(
|
| const Tab& tab,
|
| TabRestoreServiceDelegate* delegate,
|
| WindowOpenDisposition disposition) {
|
| @@ -1016,7 +446,7 @@ TabRestoreServiceDelegate* TabRestoreService::RestoreTab(
|
| if (delegate && disposition != NEW_WINDOW) {
|
| tab_index = tab.tabstrip_index;
|
| } else {
|
| - delegate = TabRestoreServiceDelegate::Create(profile(), std::string());
|
| + delegate = TabRestoreServiceDelegate::Create(profile_, std::string());
|
| if (tab.has_browser())
|
| UpdateTabBrowserIDs(tab.browser_id, delegate->GetSessionID().id());
|
| }
|
| @@ -1040,12 +470,12 @@ TabRestoreServiceDelegate* TabRestoreService::RestoreTab(
|
| tab.user_agent_override);
|
| web_contents->GetController().LoadIfNecessary();
|
| }
|
| - RecordAppLaunch(profile(), tab);
|
| + RecordAppLaunch(profile_, tab);
|
| return delegate;
|
| }
|
|
|
|
|
| -bool TabRestoreService::ValidateTab(Tab* tab) {
|
| +bool TabRestoreServiceHelper::ValidateTab(Tab* tab) {
|
| if (tab->navigations.empty())
|
| return false;
|
|
|
| @@ -1056,7 +486,7 @@ bool TabRestoreService::ValidateTab(Tab* tab) {
|
| return true;
|
| }
|
|
|
| -bool TabRestoreService::ValidateWindow(Window* window) {
|
| +bool TabRestoreServiceHelper::ValidateWindow(Window* window) {
|
| window->selected_tab_index =
|
| std::max(0, std::min(window->selected_tab_index,
|
| static_cast<int>(window->tabs.size() - 1)));
|
| @@ -1082,18 +512,7 @@ bool TabRestoreService::ValidateWindow(Window* window) {
|
| 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) {
|
| +bool TabRestoreServiceHelper::IsTabInteresting(const Tab* tab) {
|
| if (tab->navigations.empty())
|
| return false;
|
|
|
| @@ -1105,7 +524,7 @@ bool TabRestoreService::IsTabInteresting(const Tab* tab) {
|
| GURL(chrome::kChromeUINewTabURL);
|
| }
|
|
|
| -bool TabRestoreService::IsWindowInteresting(const Window* window) {
|
| +bool TabRestoreServiceHelper::IsWindowInteresting(const Window* window) {
|
| if (window->tabs.empty())
|
| return false;
|
|
|
| @@ -1115,44 +534,24 @@ bool TabRestoreService::IsWindowInteresting(const Window* window) {
|
| return IsTabInteresting(&window->tabs[0]);
|
| }
|
|
|
| -bool TabRestoreService::FilterEntry(Entry* entry) {
|
| +bool TabRestoreServiceHelper::FilterEntry(Entry* entry) {
|
| if (!ValidateEntry(entry))
|
| return false;
|
|
|
| - if (entry->type == TAB)
|
| + if (entry->type == TabRestoreService::TAB)
|
| return IsTabInteresting(static_cast<Tab*>(entry));
|
| - else if (entry->type == WINDOW)
|
| + else if (entry->type == TabRestoreService::WINDOW)
|
| return IsWindowInteresting(static_cast<Window*>(entry));
|
|
|
| NOTREACHED();
|
| return false;
|
| }
|
|
|
| -void TabRestoreService::ValidateAndDeleteEmptyEntries(
|
| - std::vector<Entry*>* entries) {
|
| - std::vector<Entry*> valid_entries;
|
| - std::vector<Entry*> invalid_entries;
|
| -
|
| - // 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))
|
| - valid_entries.push_back(*i);
|
| - else
|
| - invalid_entries.push_back(*i);
|
| - }
|
| - // NOTE: at this point the entries are ordered with newest at the front.
|
| - entries->swap(valid_entries);
|
| -
|
| - // Delete the remaining entries.
|
| - STLDeleteElements(&invalid_entries);
|
| -}
|
| -
|
| -void TabRestoreService::UpdateTabBrowserIDs(SessionID::id_type old_id,
|
| - SessionID::id_type new_id) {
|
| +void TabRestoreServiceHelper::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) {
|
| + if (entry->type == TabRestoreService::TAB) {
|
| Tab* tab = static_cast<Tab*>(entry);
|
| if (tab->browser_id == old_id)
|
| tab->browser_id = new_id;
|
| @@ -1160,103 +559,6 @@ void TabRestoreService::UpdateTabBrowserIDs(SessionID::id_type old_id,
|
| }
|
| }
|
|
|
| -void TabRestoreService::OnGotPreviousSession(
|
| - Handle handle,
|
| - std::vector<SessionWindow*>* windows,
|
| - SessionID::id_type ignored_active_window) {
|
| - std::vector<Entry*> entries;
|
| - CreateEntriesFromWindows(windows, &entries);
|
| - // Previous session tabs go first.
|
| - staging_entries_.insert(staging_entries_.begin(), entries.begin(),
|
| - entries.end());
|
| - load_state_ |= LOADED_LAST_SESSION;
|
| - 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(
|
| - 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 = 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 = Time();
|
| - return true;
|
| -}
|
| -
|
| -void TabRestoreService::LoadStateChanged() {
|
| - if ((load_state_ & (LOADED_LAST_TABS | LOADED_LAST_SESSION)) !=
|
| - (LOADED_LAST_TABS | LOADED_LAST_SESSION)) {
|
| - // Still waiting on previous session or previous tabs.
|
| - return;
|
| - }
|
| -
|
| - // We're done loading.
|
| - load_state_ ^= LOADING;
|
| -
|
| - if (staging_entries_.empty() || entries_.size() >= kMaxEntries) {
|
| - STLDeleteElements(&staging_entries_);
|
| - return;
|
| - }
|
| -
|
| - 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();
|
| - CHECK_LE(0, surplus);
|
| - CHECK_GE(static_cast<int>(staging_entries_.size()), surplus);
|
| - STLDeleteContainerPointers(
|
| - staging_entries_.begin() + (kMaxEntries - entries_.size()),
|
| - staging_entries_.end());
|
| - staging_entries_.erase(
|
| - 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);
|
| - }
|
| -
|
| - // AddEntry takes ownership of the entry, need to clear out entries so that
|
| - // it doesn't delete them.
|
| - staging_entries_.clear();
|
| -
|
| - // Make it so we rewrite all the tabs. We need to do this otherwise we won't
|
| - // correctly write out the entries when Save is invoked (Save starts from
|
| - // the front, not the end and we just added the entries to the end).
|
| - entries_to_write_ = staging_entries_.size();
|
| -
|
| - PruneEntries();
|
| - NotifyTabsChanged();
|
| -}
|
| -
|
| -Time TabRestoreService::TimeNow() const {
|
| - return time_factory_ ? time_factory_->TimeNow() : Time::Now();
|
| +base::Time TabRestoreServiceHelper::TimeNow() const {
|
| + return time_factory_ ? time_factory_->TimeNow() : base::Time::Now();
|
| }
|
|
|