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..7936843aaf3845e28ef2e7c90476e4e8894c7a70 100644 |
--- a/chrome/browser/sync/glue/synced_session_tracker.cc |
+++ b/chrome/browser/sync/glue/synced_session_tracker.cc |
@@ -2,12 +2,12 @@ |
// 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() { |
} |
@@ -29,10 +29,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 +55,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 = |
akalin
2011/09/29 21:59:55
nit: better to rewrite as for loop
Nicolas Zea
2011/09/30 22:52:59
Done.
|
+ iter->second->windows.begin(); |
+ windows->clear(); |
+ while (window_iter != iter->second->windows.end()) |
+ windows->push_back((window_iter++)->second); |
return true; |
} |
@@ -60,12 +73,12 @@ bool SyncedSessionTracker::LookupSessionTab( |
*tab = NULL; |
return false; |
} |
- if (synced_tab_map_[tag]->find(tab_id) == synced_tab_map_[tag]->end()) { |
+ if (synced_tab_map_[tag].find(tab_id) == synced_tab_map_[tag].end()) { |
// We have no record of this tab. |
*tab = NULL; |
return false; |
} |
- *tab = (*synced_tab_map_[tag])[tab_id]; |
+ *tab = synced_tab_map_[tag][tab_id].tab_ptr; |
return true; |
} |
@@ -97,39 +110,175 @@ 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; |
akalin
2011/09/29 21:59:55
move this var in for loop (can rename to it)
Nicolas Zea
2011/09/30 22:52:59
Done.
|
+ for (window_map_iter = window_iter->second.begin(); |
+ window_map_iter != window_iter->second.end(); ++window_map_iter) { |
+ window_map_iter->second.used = 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; |
akalin
2011/09/29 21:59:55
here, too
Nicolas Zea
2011/09/30 22:52:59
Done.
|
+ for (tab_map_iter = tab_iter->second.begin(); |
+ tab_map_iter != tab_iter->second.end(); ++tab_map_iter) { |
+ tab_map_iter->second.used = false; |
+ } |
+ } |
+} |
+ |
+bool SyncedSessionTracker::ClearUnusedSessionWindow( |
+ SessionWindowWrapper window_wrapper, |
+ 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 (!window_wrapper.used) { |
+ if (session) { |
+ // If we have a session object, erase the window from that object (does |
+ // not free any memory). |
+ session->windows.erase(window_wrapper.window_ptr->window_id.id()); |
+ } |
+ VLOG(1) << "Deleting closed window " |
+ << window_wrapper.window_ptr->window_id.id() |
+ << (session ? " from both" : "from memory"); |
+ window_wrapper.window_ptr->tabs.clear(); |
+ delete window_wrapper.window_ptr; |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+bool SyncedSessionTracker::ClearUnusedSessionTab( |
+ SessionTabWrapper tab_wrapper) { |
+ if (!tab_wrapper.used) { |
+ 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) { |
+ SyncedSession* synced_session = NULL; |
+ DCHECK(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 boolean. |
+ 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; |
akalin
2011/09/29 21:59:55
move in for loop
Nicolas Zea
2011/09/30 22:52:59
Done.
|
+ for (iter = window_iter->second.begin(); |
+ iter != window_iter->second.end();) { |
+ SessionWindowWrapper window_wrapper = iter->second; |
+ if (ClearUnusedSessionWindow(window_wrapper, 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();) { |
+ SessionTabWrapper tab_wrapper = iter->second; |
+ if (ClearUnusedSessionTab(tab_wrapper)) |
+ tab_iter->second.erase(iter++); |
+ else |
+ ++iter; |
+ } |
+ } |
+} |
+ |
+SessionWindow* SyncedSessionTracker::GetWindow(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.used = true; |
+ window_ptr = iter->second.window_ptr; |
+ 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] = |
+ SessionWindowWrapper(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) { |
- 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 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].used = 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) { |
+ 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() { |
@@ -138,17 +287,16 @@ void SyncedSessionTracker::clear() { |
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(); |
} |