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

Unified Diff: chrome/browser/sync/glue/synced_session_tracker.cc

Issue 7966020: [Sync] Fix Session's handling of windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments Created 9 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/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..26fe4e58345c6f2823eaa16a792df4468e32d81f 100644
--- a/chrome/browser/sync/glue/synced_session_tracker.cc
+++ b/chrome/browser/sync/glue/synced_session_tracker.cc
@@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#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() {
}
SyncedSessionTracker::~SyncedSessionTracker() {
- clear();
+ Clear();
}
void SyncedSessionTracker::SetLocalSessionTag(
@@ -21,18 +20,26 @@ void SyncedSessionTracker::SetLocalSessionTag(
}
bool SyncedSessionTracker::LookupAllForeignSessions(
- std::vector<const SyncedSession*>* sessions) {
+ std::vector<const SyncedSession*>* sessions) const {
DCHECK(sessions);
+ sessions->clear();
// Fill vector of sessions from our synced session map.
for (SyncedSessionMap::const_iterator i =
synced_session_map_.begin(); i != synced_session_map_.end(); ++i) {
// 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);
+ if (i->first != local_session_tag_ && !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 (!SessionWindowHasNoTabsToSync(*(iter->second))) {
+ found_tabs = true;
+ break;
+ }
+ }
+ if (found_tabs)
+ sessions->push_back(foreign_session);
}
}
@@ -41,47 +48,56 @@ bool SyncedSessionTracker::LookupAllForeignSessions(
bool SyncedSessionTracker::LookupSessionWindows(
const std::string& session_tag,
- std::vector<SessionWindow*>* windows) {
+ std::vector<const SessionWindow*>* windows) const {
DCHECK(windows);
- SyncedSessionMap::iterator iter = synced_session_map_.find(session_tag);
+ windows->clear();
+ SyncedSessionMap::const_iterator iter = synced_session_map_.find(session_tag);
if (iter == synced_session_map_.end())
return false;
- *windows = iter->second->windows;
+ windows->clear();
+ for (SyncedSession::SyncedWindowMap::const_iterator window_iter =
+ iter->second->windows.begin();
+ window_iter != iter->second->windows.end(); window_iter++) {
+ windows->push_back(window_iter->second);
+ }
return true;
}
bool SyncedSessionTracker::LookupSessionTab(
const std::string& tag,
SessionID::id_type tab_id,
- const SessionTab** tab) {
+ const SessionTab** tab) const {
DCHECK(tab);
- if (synced_tab_map_.find(tag) == synced_tab_map_.end()) {
+ SyncedTabMap::const_iterator tab_map_iter = synced_tab_map_.find(tag);
+ if (tab_map_iter == synced_tab_map_.end()) {
// We have no record of this session.
*tab = NULL;
return false;
}
- if (synced_tab_map_[tag]->find(tab_id) == synced_tab_map_[tag]->end()) {
+ IDToSessionTabMap::const_iterator tab_iter =
+ tab_map_iter->second.find(tab_id);
+ if (tab_iter == tab_map_iter->second.end()) {
// We have no record of this tab.
*tab = NULL;
return false;
}
- *tab = (*synced_tab_map_[tag])[tab_id];
+ *tab = tab_iter->second.tab_ptr;
return true;
}
SyncedSession* SyncedSessionTracker::GetSession(
const std::string& session_tag) {
- scoped_ptr<SyncedSession> synced_session;
+ SyncedSession* synced_session = NULL;
if (synced_session_map_.find(session_tag) !=
synced_session_map_.end()) {
- synced_session.reset(synced_session_map_[session_tag]);
+ synced_session = synced_session_map_[session_tag];
} else {
- synced_session.reset(new SyncedSession);
+ synced_session = new SyncedSession;
synced_session->session_tag = session_tag;
- synced_session_map_[session_tag] = synced_session.get();
+ synced_session_map_[session_tag] = synced_session;
}
- DCHECK(synced_session.get());
- return synced_session.release();
+ DCHECK(synced_session);
+ return synced_session;
}
bool SyncedSessionTracker::DeleteSession(
@@ -97,58 +113,189 @@ bool SyncedSessionTracker::DeleteSession(
}
}
-SessionTab* SyncedSessionTracker::GetSessionTab(
+void SyncedSessionTracker::ResetSessionTracking(
+ const std::string& session_tag) {
+ // Reset window tracking.
+ GetSession(session_tag)->windows.clear();
+ SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag);
+ if (window_iter != synced_window_map_.end()) {
+ for (IDToSessionWindowMap::iterator window_map_iter =
+ window_iter->second.begin();
+ window_map_iter != window_iter->second.end(); ++window_map_iter) {
+ window_map_iter->second.owned = false;
+ // We clear out the tabs to prevent double referencing of the same tab.
+ // All tabs that are in use will be added back as needed.
+ window_map_iter->second.window_ptr->tabs.clear();
+ }
+ }
+
+ // Reset tab tracking.
+ SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag);
+ if (tab_iter != synced_tab_map_.end()) {
+ for (IDToSessionTabMap::iterator tab_map_iter =
+ tab_iter->second.begin();
+ tab_map_iter != tab_iter->second.end(); ++tab_map_iter) {
+ tab_map_iter->second.owned = false;
+ }
+ }
+}
+
+bool SyncedSessionTracker::DeleteOldSessionWindowIfNecessary(
+ SessionWindowWrapper window_wrapper) {
+ // Clear the tabs first, since we don't want the destructor to destroy
+ // them. Their deletion will be handled by DeleteOldSessionTab below.
+ if (!window_wrapper.owned) {
+ VLOG(1) << "Deleting closed window "
+ << window_wrapper.window_ptr->window_id.id();
+ window_wrapper.window_ptr->tabs.clear();
+ delete window_wrapper.window_ptr;
+ return true;
+ }
+ return false;
+}
+
+bool SyncedSessionTracker::DeleteOldSessionTabIfNecessary(
+ SessionTabWrapper tab_wrapper) {
+ if (!tab_wrapper.owned) {
+ if (VLOG_IS_ON(1)) {
+ SessionTab* tab_ptr = tab_wrapper.tab_ptr;
+ 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(tab_wrapper.tab_ptr);
+ delete tab_wrapper.tab_ptr;
+ return true;
+ }
+ return false;
+}
+
+void SyncedSessionTracker::CleanupSession(const std::string& session_tag) {
+ // Go through and delete any windows or tabs without owners.
+ SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag);
+ if (window_iter != synced_window_map_.end()) {
+ for (IDToSessionWindowMap::iterator iter = window_iter->second.begin();
+ iter != window_iter->second.end();) {
+ SessionWindowWrapper window_wrapper = iter->second;
+ if (DeleteOldSessionWindowIfNecessary(window_wrapper))
+ window_iter->second.erase(iter++);
+ else
+ ++iter;
+ }
+ }
+
+ SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag);
+ if (tab_iter != synced_tab_map_.end()) {
+ for (IDToSessionTabMap::iterator iter = tab_iter->second.begin();
+ iter != tab_iter->second.end();) {
+ SessionTabWrapper tab_wrapper = iter->second;
+ if (DeleteOldSessionTabIfNecessary(tab_wrapper))
+ tab_iter->second.erase(iter++);
+ else
+ ++iter;
+ }
+ }
+}
+
+void SyncedSessionTracker::PutWindowInSession(const std::string& session_tag,
+ SessionID::id_type window_id) {
+ SessionWindow* window_ptr = NULL;
+ IDToSessionWindowMap::iterator iter =
+ synced_window_map_[session_tag].find(window_id);
+ if (iter != synced_window_map_[session_tag].end()) {
+ iter->second.owned = true;
+ window_ptr = iter->second.window_ptr;
+ VLOG(1) << "Putting seen window " << window_id << " at " << window_ptr
+ << "in " << (session_tag == local_session_tag_ ?
+ "local session" : session_tag);
+ } else {
+ // Create the window.
+ window_ptr = new SessionWindow();
+ window_ptr->window_id.set_id(window_id);
+ synced_window_map_[session_tag][window_id] =
+ SessionWindowWrapper(window_ptr, true);
+ VLOG(1) << "Putting new window " << window_id << " at " << window_ptr
+ << "in " << (session_tag == local_session_tag_ ?
+ "local session" : session_tag);
+ }
+ DCHECK(window_ptr);
+ DCHECK_EQ(window_ptr->window_id.id(), window_id);
+ DCHECK_EQ((SessionWindow*)NULL, GetSession(session_tag)->windows[window_id]);
+ GetSession(session_tag)->windows[window_id] = window_ptr;
+}
+
+void SyncedSessionTracker::PutTabInWindow(const std::string& session_tag,
+ SessionID::id_type window_id,
+ SessionID::id_type tab_id,
+ size_t tab_index) {
+ SessionTab* tab_ptr = GetTab(session_tag, tab_id);
+ unmapped_tabs_.erase(tab_ptr);
+ synced_tab_map_[session_tag][tab_id].owned = true;
+ tab_ptr->window_id.set_id(window_id);
+ VLOG(1) << " - tab " << tab_id << " added to window "<< window_id;
+ DCHECK(GetSession(session_tag)->windows.find(window_id) !=
+ GetSession(session_tag)->windows.end());
+ std::vector<SessionTab*>& window_tabs =
+ GetSession(session_tag)->windows[window_id]->tabs;
+ if (window_tabs.size() <= tab_index) {
+ window_tabs.resize(tab_index+1, NULL);
+ }
+ DCHECK_EQ((SessionTab*)NULL, window_tabs[tab_index]);
+ window_tabs[tab_index] = tab_ptr;
+}
+
+SessionTab* SyncedSessionTracker::GetTab(
const std::string& session_tag,
- SessionID::id_type tab_id,
- bool has_window) {
- if (synced_tab_map_.find(session_tag) == synced_tab_map_.end())
- synced_tab_map_[session_tag] = new IDToSessionTabMap;
- scoped_ptr<SessionTab> tab;
+ SessionID::id_type tab_id) {
+ 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()
- << ")";
+ synced_tab_map_[session_tag].find(tab_id);
+ if (iter != synced_tab_map_[session_tag].end()) {
+ tab_ptr = iter->second.tab_ptr;
+ 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] = SessionTabWrapper(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() {
+void SyncedSessionTracker::Clear() {
// Delete SyncedSession objects (which also deletes all their windows/tabs).
STLDeleteContainerPairSecondPointers(synced_session_map_.begin(),
synced_session_map_.end());
synced_session_map_.clear();
- // Delete IDToSessTab 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());
- synced_tab_map_.clear();
-
// Go through and delete any tabs we had allocated but had not yet placed into
// a SyncedSessionobject.
STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end());
unmapped_tabs_.clear();
+ // Get rid of our Window/Tab maps (does not delete the actual Window/Tabs
+ // themselves; they should have all been deleted above).
+ synced_window_map_.clear();
+ synced_tab_map_.clear();
+
local_session_tag_.clear();
}

Powered by Google App Engine
This is Rietveld 408576698