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