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(); |
} |