| Index: chrome/browser/sync/glue/synced_session_tracker.cc
|
| diff --git a/chrome/browser/sync/glue/synced_session_tracker.cc b/chrome/browser/sync/glue/synced_session_tracker.cc
|
| index 5d2c1081a253b270b76fbafeb8eb8ceedf14a194..3a869d59ddb5f1e96b653ebb9e42b878cf417fd7 100644
|
| --- a/chrome/browser/sync/glue/synced_session_tracker.cc
|
| +++ b/chrome/browser/sync/glue/synced_session_tracker.cc
|
| @@ -2,12 +2,14 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include <algorithm>
|
| +
|
| +#include "base/string_util.h"
|
| #include "chrome/browser/sync/glue/synced_session_tracker.h"
|
| #include "chrome/browser/sync/glue/session_model_associator.h"
|
|
|
| namespace browser_sync {
|
|
|
| -
|
| SyncedSessionTracker::SyncedSessionTracker() {
|
| }
|
|
|
| @@ -29,10 +31,19 @@ bool SyncedSessionTracker::LookupAllForeignSessions(
|
| // Only include foreign sessions with open tabs.
|
| SyncedSession* foreign_session = i->second;
|
| if (i->first != local_session_tag_ &&
|
| - !foreign_session->windows.empty() &&
|
| - !SessionModelAssociator::SessionWindowHasNoTabsToSync(
|
| - *foreign_session->windows[0])) {
|
| - sessions->push_back(foreign_session);
|
| + !foreign_session->windows.empty()) {
|
| + bool found_tabs = false;
|
| + for (SyncedSession::SyncedWindowMap::const_iterator iter =
|
| + foreign_session->windows.begin();
|
| + iter != foreign_session->windows.end(); ++iter) {
|
| + if (!SessionModelAssociator::SessionWindowHasNoTabsToSync(
|
| + *(iter->second))) {
|
| + found_tabs = true;
|
| + break;
|
| + }
|
| + }
|
| + if (found_tabs)
|
| + sessions->push_back(foreign_session);
|
| }
|
| }
|
|
|
| @@ -46,7 +57,11 @@ bool SyncedSessionTracker::LookupSessionWindows(
|
| SyncedSessionMap::iterator iter = synced_session_map_.find(session_tag);
|
| if (iter == synced_session_map_.end())
|
| return false;
|
| - *windows = iter->second->windows;
|
| + SyncedSession::SyncedWindowMap::iterator window_iter =
|
| + iter->second->windows.begin();
|
| + windows->clear();
|
| + while (window_iter != iter->second->windows.end())
|
| + windows->push_back((window_iter++)->second);
|
| return true;
|
| }
|
|
|
| @@ -65,7 +80,7 @@ bool SyncedSessionTracker::LookupSessionTab(
|
| *tab = NULL;
|
| return false;
|
| }
|
| - *tab = (*synced_tab_map_[tag])[tab_id];
|
| + *tab = (*synced_tab_map_[tag])[tab_id].first;
|
| return true;
|
| }
|
|
|
| @@ -97,39 +112,178 @@ bool SyncedSessionTracker::DeleteSession(
|
| }
|
| }
|
|
|
| -SessionTab* SyncedSessionTracker::GetSessionTab(
|
| +void SyncedSessionTracker::ResetSessionTracking(
|
| + const std::string& session_tag) {
|
| + // Reset window tracking.
|
| + SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag);
|
| + if (window_iter != synced_window_map_.end()) {
|
| + IDToSessionWindowMap::iterator window_map_iter;
|
| + for (window_map_iter = window_iter->second->begin();
|
| + window_map_iter != window_iter->second->end(); ++window_map_iter) {
|
| + window_map_iter->second.second = false;
|
| + }
|
| + }
|
| +
|
| + // Reset tab tracking.
|
| + SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag);
|
| + if (tab_iter != synced_tab_map_.end()) {
|
| + IDToSessionTabMap::iterator tab_map_iter;
|
| + for (tab_map_iter = tab_iter->second->begin();
|
| + tab_map_iter != tab_iter->second->end(); ++tab_map_iter) {
|
| + tab_map_iter->second.second = false;
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool SyncedSessionTracker::ClearUnusedSessionWindow(SessionWindowPair p,
|
| + SyncedSession* session) {
|
| + // Clear the tabs first, since we don't want the destructor to destroy
|
| + // them. Their deletion will be handled by ClearUnusedSessionTab below.
|
| + if (!p.second) {
|
| + if (session) {
|
| + // If we have a session object, erase the window from that object (does
|
| + // not free any memory).
|
| + session->windows.erase(p.first->window_id.id());
|
| + }
|
| + VLOG(1) << "Deleting closed window " << p.first->window_id.id()
|
| + << (session ? " from both" : "from memory");
|
| + p.first->tabs.clear();
|
| + delete p.first;
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool SyncedSessionTracker::ClearUnusedSessionTab(SessionTabPair p) {
|
| + if (!p.second) {
|
| + if (VLOG_IS_ON(1)) {
|
| + SessionTab* tab_ptr = p.first;
|
| + std::string title = "";
|
| + if (tab_ptr->navigations.size() > 0) {
|
| + title = " (" + UTF16ToASCII(
|
| + tab_ptr->navigations[tab_ptr->navigations.size()-1].title()) + ")";
|
| + }
|
| + VLOG(1) << "Deleting closed tab " << tab_ptr->tab_id.id() << title
|
| + << " from window " << tab_ptr->window_id.id();
|
| + }
|
| + unmapped_tabs_.erase(p.first);
|
| + delete p.first;
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +void SyncedSessionTracker::CleanupSession(const std::string& session_tag) {
|
| + SyncedSession* synced_session = NULL;
|
| + if (synced_session_map_.find(session_tag) !=
|
| + synced_session_map_.end()) {
|
| + synced_session = synced_session_map_[session_tag];
|
| + }
|
| +
|
| + // Go through and delete any windows or tabs with a false value in their
|
| + // tracking pair.
|
| + SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag);
|
| + if (window_iter != synced_window_map_.end()) {
|
| + // Go through and remove those windows from the session first.
|
| + IDToSessionWindowMap::iterator iter;
|
| + for (iter = window_iter->second->begin();
|
| + iter != window_iter->second->end();) {
|
| + SessionWindowPair p = iter->second;
|
| + if (ClearUnusedSessionWindow(p, synced_session))
|
| + window_iter->second->erase(iter++);
|
| + else
|
| + ++iter;
|
| + }
|
| + }
|
| +
|
| + SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag);
|
| + if (tab_iter != synced_tab_map_.end()) {
|
| + IDToSessionTabMap::iterator iter;
|
| + for (iter = tab_iter->second->begin();
|
| + iter != tab_iter->second->end();) {
|
| + SessionTabPair p = iter->second;
|
| + if (ClearUnusedSessionTab(p))
|
| + tab_iter->second->erase(iter++);
|
| + else
|
| + ++iter;
|
| + }
|
| + }
|
| +}
|
| +
|
| +SessionWindow* SyncedSessionTracker::GetWindow(const std::string& session_tag,
|
| + SessionID::id_type window_id) {
|
| + SessionWindow* window_ptr = NULL;
|
| + if (synced_window_map_.find(session_tag) == synced_window_map_.end())
|
| + synced_window_map_[session_tag] = new IDToSessionWindowMap;
|
| + IDToSessionWindowMap::iterator iter =
|
| + synced_window_map_[session_tag]->find(window_id);
|
| + if (iter != synced_window_map_[session_tag]->end()) {
|
| + iter->second.second = true;
|
| + window_ptr = iter->second.first;
|
| + VLOG(1) << "Getting "
|
| + << (session_tag == local_session_tag_ ?
|
| + "local session" : session_tag)
|
| + << "'s seen window " << window_id << " at " << window_ptr;
|
| + } else {
|
| + // Create the window.
|
| + window_ptr = new SessionWindow();
|
| + window_ptr->window_id.set_id(window_id);
|
| + (*synced_window_map_[session_tag])[window_id] =
|
| + std::make_pair(window_ptr, true);
|
| + VLOG(1) << "Getting "
|
| + << (session_tag == local_session_tag_ ?
|
| + "local session" : session_tag)
|
| + << "'s new window " << window_id << " at " << window_ptr;
|
| + }
|
| + DCHECK(window_ptr);
|
| + DCHECK_EQ(window_ptr->window_id.id(), window_id);
|
| + return window_ptr;
|
| +}
|
| +
|
| +SessionTab* SyncedSessionTracker::GetTabForWindow(
|
| const std::string& session_tag,
|
| - SessionID::id_type tab_id,
|
| - bool has_window) {
|
| + SessionID::id_type window_id,
|
| + SessionID::id_type tab_id) {
|
| + SessionTab* tab_ptr = GetTab(session_tag, tab_id);
|
| + unmapped_tabs_.erase(tab_ptr);
|
| + (*synced_tab_map_[session_tag])[tab_id].second = true;
|
| + tab_ptr->window_id.set_id(window_id);
|
| + VLOG(1) << " - tab " << tab_id << " noted as part of window "<< window_id;
|
| + return tab_ptr;
|
| +}
|
| +
|
| +SessionTab* SyncedSessionTracker::GetTab(
|
| + const std::string& session_tag,
|
| + SessionID::id_type tab_id) {
|
| if (synced_tab_map_.find(session_tag) == synced_tab_map_.end())
|
| synced_tab_map_[session_tag] = new IDToSessionTabMap;
|
| - scoped_ptr<SessionTab> tab;
|
| + SessionTab* tab_ptr = NULL;
|
| IDToSessionTabMap::iterator iter =
|
| synced_tab_map_[session_tag]->find(tab_id);
|
| if (iter != synced_tab_map_[session_tag]->end()) {
|
| - tab.reset(iter->second);
|
| - if (has_window) // This tab is linked to a window, so it's not an orphan.
|
| - unmapped_tabs_.erase(tab.get());
|
| - if (tab->navigations.size() > 0) {
|
| - VLOG(1) << "Getting "
|
| - << (session_tag == local_session_tag_ ?
|
| - "local session" : session_tag)
|
| - << "'s seen tab " << tab_id << " ("
|
| - << tab->navigations[tab->navigations.size()-1].title()
|
| - << ")";
|
| + tab_ptr = iter->second.first;
|
| + std::string title = "";
|
| + if (tab_ptr->navigations.size() > 0) {
|
| + title = " (" + UTF16ToASCII(
|
| + tab_ptr->navigations[tab_ptr->navigations.size()-1].title()) + ")";
|
| }
|
| + VLOG(1) << "Getting "
|
| + << (session_tag == local_session_tag_ ?
|
| + "local session" : session_tag)
|
| + << "'s seen tab " << tab_id << " at " << tab_ptr << title;
|
| } else {
|
| - tab.reset(new SessionTab());
|
| - (*synced_tab_map_[session_tag])[tab_id] = tab.get();
|
| - if (!has_window) // This tab is not linked to a window, it's an orphan.
|
| - unmapped_tabs_.insert(tab.get());
|
| + tab_ptr = new SessionTab();
|
| + tab_ptr->tab_id.set_id(tab_id);
|
| + (*synced_tab_map_[session_tag])[tab_id] = std::make_pair(tab_ptr, false);
|
| + unmapped_tabs_.insert(tab_ptr);
|
| VLOG(1) << "Getting "
|
| << (session_tag == local_session_tag_ ?
|
| "local session" : session_tag)
|
| - << "'s new tab " << tab_id << " at " << tab.get();
|
| + << "'s new tab " << tab_id << " at " << tab_ptr;
|
| }
|
| - DCHECK(tab.get());
|
| - return tab.release();
|
| + DCHECK(tab_ptr);
|
| + DCHECK_EQ(tab_ptr->tab_id.id(), tab_id);
|
| + return tab_ptr;
|
| }
|
|
|
| void SyncedSessionTracker::clear() {
|
| @@ -138,7 +292,13 @@ void SyncedSessionTracker::clear() {
|
| synced_session_map_.end());
|
| synced_session_map_.clear();
|
|
|
| - // Delete IDToSessTab maps. Does not delete the SessionTab objects, because
|
| + // Delete IDToSessionWindow maps. Does not delete the SessionWindow objects,
|
| + // because they should already be referenced through synced_session_map_.
|
| + STLDeleteContainerPairSecondPointers(synced_window_map_.begin(),
|
| + synced_window_map_.end());
|
| + synced_window_map_.clear();
|
| +
|
| + // Delete IDToSessionTab maps. Does not delete the SessionTab objects, because
|
| // they should already be referenced through synced_session_map_.
|
| STLDeleteContainerPairSecondPointers(synced_tab_map_.begin(),
|
| synced_tab_map_.end());
|
|
|