Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/string_util.h" | |
| 5 #include "chrome/browser/sync/glue/synced_session_tracker.h" | 6 #include "chrome/browser/sync/glue/synced_session_tracker.h" |
| 6 #include "chrome/browser/sync/glue/session_model_associator.h" | 7 #include "chrome/browser/sync/glue/session_model_associator.h" |
| 7 | 8 |
| 8 namespace browser_sync { | 9 namespace browser_sync { |
| 9 | 10 |
| 10 | |
| 11 SyncedSessionTracker::SyncedSessionTracker() { | 11 SyncedSessionTracker::SyncedSessionTracker() { |
| 12 } | 12 } |
| 13 | 13 |
| 14 SyncedSessionTracker::~SyncedSessionTracker() { | 14 SyncedSessionTracker::~SyncedSessionTracker() { |
| 15 clear(); | 15 clear(); |
| 16 } | 16 } |
| 17 | 17 |
| 18 void SyncedSessionTracker::SetLocalSessionTag( | 18 void SyncedSessionTracker::SetLocalSessionTag( |
| 19 const std::string& local_session_tag) { | 19 const std::string& local_session_tag) { |
| 20 local_session_tag_ = local_session_tag; | 20 local_session_tag_ = local_session_tag; |
| 21 } | 21 } |
| 22 | 22 |
| 23 bool SyncedSessionTracker::LookupAllForeignSessions( | 23 bool SyncedSessionTracker::LookupAllForeignSessions( |
| 24 std::vector<const SyncedSession*>* sessions) { | 24 std::vector<const SyncedSession*>* sessions) { |
| 25 DCHECK(sessions); | 25 DCHECK(sessions); |
| 26 // Fill vector of sessions from our synced session map. | 26 // Fill vector of sessions from our synced session map. |
| 27 for (SyncedSessionMap::const_iterator i = | 27 for (SyncedSessionMap::const_iterator i = |
| 28 synced_session_map_.begin(); i != synced_session_map_.end(); ++i) { | 28 synced_session_map_.begin(); i != synced_session_map_.end(); ++i) { |
| 29 // Only include foreign sessions with open tabs. | 29 // Only include foreign sessions with open tabs. |
| 30 SyncedSession* foreign_session = i->second; | 30 SyncedSession* foreign_session = i->second; |
| 31 if (i->first != local_session_tag_ && | 31 if (i->first != local_session_tag_ && |
| 32 !foreign_session->windows.empty() && | 32 !foreign_session->windows.empty()) { |
| 33 !SessionModelAssociator::SessionWindowHasNoTabsToSync( | 33 bool found_tabs = false; |
| 34 *foreign_session->windows[0])) { | 34 for (SyncedSession::SyncedWindowMap::const_iterator iter = |
| 35 sessions->push_back(foreign_session); | 35 foreign_session->windows.begin(); |
| 36 iter != foreign_session->windows.end(); ++iter) { | |
| 37 if (!SessionModelAssociator::SessionWindowHasNoTabsToSync( | |
| 38 *(iter->second))) { | |
| 39 found_tabs = true; | |
| 40 break; | |
| 41 } | |
| 42 } | |
| 43 if (found_tabs) | |
| 44 sessions->push_back(foreign_session); | |
| 36 } | 45 } |
| 37 } | 46 } |
| 38 | 47 |
| 39 return !sessions->empty(); | 48 return !sessions->empty(); |
| 40 } | 49 } |
| 41 | 50 |
| 42 bool SyncedSessionTracker::LookupSessionWindows( | 51 bool SyncedSessionTracker::LookupSessionWindows( |
| 43 const std::string& session_tag, | 52 const std::string& session_tag, |
| 44 std::vector<SessionWindow*>* windows) { | 53 std::vector<SessionWindow*>* windows) { |
| 45 DCHECK(windows); | 54 DCHECK(windows); |
| 46 SyncedSessionMap::iterator iter = synced_session_map_.find(session_tag); | 55 SyncedSessionMap::iterator iter = synced_session_map_.find(session_tag); |
| 47 if (iter == synced_session_map_.end()) | 56 if (iter == synced_session_map_.end()) |
| 48 return false; | 57 return false; |
| 49 *windows = iter->second->windows; | 58 SyncedSession::SyncedWindowMap::iterator window_iter = |
| 59 iter->second->windows.begin(); | |
| 60 windows->clear(); | |
| 61 while (window_iter != iter->second->windows.end()) | |
| 62 windows->push_back((window_iter++)->second); | |
| 50 return true; | 63 return true; |
| 51 } | 64 } |
| 52 | 65 |
| 53 bool SyncedSessionTracker::LookupSessionTab( | 66 bool SyncedSessionTracker::LookupSessionTab( |
| 54 const std::string& tag, | 67 const std::string& tag, |
| 55 SessionID::id_type tab_id, | 68 SessionID::id_type tab_id, |
| 56 const SessionTab** tab) { | 69 const SessionTab** tab) { |
| 57 DCHECK(tab); | 70 DCHECK(tab); |
| 58 if (synced_tab_map_.find(tag) == synced_tab_map_.end()) { | 71 if (synced_tab_map_.find(tag) == synced_tab_map_.end()) { |
| 59 // We have no record of this session. | 72 // We have no record of this session. |
| 60 *tab = NULL; | 73 *tab = NULL; |
| 61 return false; | 74 return false; |
| 62 } | 75 } |
| 63 if (synced_tab_map_[tag]->find(tab_id) == synced_tab_map_[tag]->end()) { | 76 if (synced_tab_map_[tag]->find(tab_id) == synced_tab_map_[tag]->end()) { |
| 64 // We have no record of this tab. | 77 // We have no record of this tab. |
| 65 *tab = NULL; | 78 *tab = NULL; |
| 66 return false; | 79 return false; |
| 67 } | 80 } |
| 68 *tab = (*synced_tab_map_[tag])[tab_id]; | 81 *tab = (*synced_tab_map_[tag])[tab_id].tab_ptr; |
| 69 return true; | 82 return true; |
| 70 } | 83 } |
| 71 | 84 |
| 72 SyncedSession* SyncedSessionTracker::GetSession( | 85 SyncedSession* SyncedSessionTracker::GetSession( |
| 73 const std::string& session_tag) { | 86 const std::string& session_tag) { |
| 74 scoped_ptr<SyncedSession> synced_session; | 87 scoped_ptr<SyncedSession> synced_session; |
| 75 if (synced_session_map_.find(session_tag) != | 88 if (synced_session_map_.find(session_tag) != |
| 76 synced_session_map_.end()) { | 89 synced_session_map_.end()) { |
| 77 synced_session.reset(synced_session_map_[session_tag]); | 90 synced_session.reset(synced_session_map_[session_tag]); |
| 78 } else { | 91 } else { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 90 synced_session_map_.find(session_tag); | 103 synced_session_map_.find(session_tag); |
| 91 if (iter != synced_session_map_.end()) { | 104 if (iter != synced_session_map_.end()) { |
| 92 delete iter->second; // Delete the SyncedSession object. | 105 delete iter->second; // Delete the SyncedSession object. |
| 93 synced_session_map_.erase(iter); | 106 synced_session_map_.erase(iter); |
| 94 return true; | 107 return true; |
| 95 } else { | 108 } else { |
| 96 return false; | 109 return false; |
| 97 } | 110 } |
| 98 } | 111 } |
| 99 | 112 |
| 100 SessionTab* SyncedSessionTracker::GetSessionTab( | 113 void SyncedSessionTracker::ResetSessionTracking( |
| 114 const std::string& session_tag) { | |
| 115 // Reset window tracking. | |
| 116 SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag); | |
| 117 if (window_iter != synced_window_map_.end()) { | |
| 118 IDToSessionWindowMap::iterator window_map_iter; | |
| 119 for (window_map_iter = window_iter->second->begin(); | |
| 120 window_map_iter != window_iter->second->end(); ++window_map_iter) { | |
| 121 window_map_iter->second.used = false; | |
| 122 } | |
| 123 } | |
| 124 | |
| 125 // Reset tab tracking. | |
| 126 SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag); | |
| 127 if (tab_iter != synced_tab_map_.end()) { | |
| 128 IDToSessionTabMap::iterator tab_map_iter; | |
| 129 for (tab_map_iter = tab_iter->second->begin(); | |
| 130 tab_map_iter != tab_iter->second->end(); ++tab_map_iter) { | |
| 131 tab_map_iter->second.used = false; | |
| 132 } | |
| 133 } | |
| 134 } | |
| 135 | |
| 136 bool SyncedSessionTracker::ClearUnusedSessionWindow( | |
| 137 SessionWindowWrapper window_wrapper, | |
| 138 SyncedSession* session) { | |
| 139 // Clear the tabs first, since we don't want the destructor to destroy | |
| 140 // them. Their deletion will be handled by ClearUnusedSessionTab below. | |
| 141 if (!window_wrapper.used) { | |
| 142 if (session) { | |
| 143 // If we have a session object, erase the window from that object (does | |
| 144 // not free any memory). | |
| 145 session->windows.erase(window_wrapper.window_ptr->window_id.id()); | |
| 146 } | |
| 147 VLOG(1) << "Deleting closed window " | |
| 148 << window_wrapper.window_ptr->window_id.id() | |
| 149 << (session ? " from both" : "from memory"); | |
| 150 window_wrapper.window_ptr->tabs.clear(); | |
| 151 delete window_wrapper.window_ptr; | |
| 152 return true; | |
| 153 } | |
| 154 return false; | |
| 155 } | |
| 156 | |
| 157 bool SyncedSessionTracker::ClearUnusedSessionTab( | |
| 158 SessionTabWrapper tab_wrapper) { | |
| 159 if (!tab_wrapper.used) { | |
| 160 if (VLOG_IS_ON(1)) { | |
| 161 SessionTab* tab_ptr = tab_wrapper.tab_ptr; | |
| 162 std::string title = ""; | |
| 163 if (tab_ptr->navigations.size() > 0) { | |
| 164 title = " (" + UTF16ToASCII( | |
| 165 tab_ptr->navigations[tab_ptr->navigations.size()-1].title()) + ")"; | |
| 166 } | |
| 167 VLOG(1) << "Deleting closed tab " << tab_ptr->tab_id.id() << title | |
| 168 << " from window " << tab_ptr->window_id.id(); | |
| 169 } | |
| 170 unmapped_tabs_.erase(tab_wrapper.tab_ptr); | |
| 171 delete tab_wrapper.tab_ptr; | |
| 172 return true; | |
| 173 } | |
| 174 return false; | |
| 175 } | |
| 176 | |
| 177 void SyncedSessionTracker::CleanupSession(const std::string& session_tag) { | |
| 178 SyncedSession* synced_session = NULL; | |
|
akalin
2011/09/26 21:57:24
move this closer to where it's used?
Nicolas Zea
2011/09/26 22:55:26
It's set in the if here, then used in the Window l
| |
| 179 if (synced_session_map_.find(session_tag) != | |
| 180 synced_session_map_.end()) { | |
| 181 synced_session = synced_session_map_[session_tag]; | |
| 182 } | |
| 183 | |
| 184 // Go through and delete any windows or tabs with a false value in their | |
| 185 // tracking boolean. | |
| 186 SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag); | |
| 187 if (window_iter != synced_window_map_.end()) { | |
| 188 // Go through and remove those windows from the session first. | |
| 189 IDToSessionWindowMap::iterator iter; | |
| 190 for (iter = window_iter->second->begin(); | |
| 191 iter != window_iter->second->end();) { | |
| 192 SessionWindowWrapper window_wrapper = iter->second; | |
| 193 if (ClearUnusedSessionWindow(window_wrapper, synced_session)) | |
| 194 window_iter->second->erase(iter++); | |
| 195 else | |
| 196 ++iter; | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag); | |
| 201 if (tab_iter != synced_tab_map_.end()) { | |
| 202 IDToSessionTabMap::iterator iter; | |
| 203 for (iter = tab_iter->second->begin(); | |
| 204 iter != tab_iter->second->end();) { | |
| 205 SessionTabWrapper tab_wrapper = iter->second; | |
| 206 if (ClearUnusedSessionTab(tab_wrapper)) | |
| 207 tab_iter->second->erase(iter++); | |
| 208 else | |
| 209 ++iter; | |
| 210 } | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 SessionWindow* SyncedSessionTracker::GetWindow(const std::string& session_tag, | |
| 215 SessionID::id_type window_id) { | |
| 216 SessionWindow* window_ptr = NULL; | |
| 217 if (synced_window_map_.find(session_tag) == synced_window_map_.end()) | |
| 218 synced_window_map_[session_tag] = new IDToSessionWindowMap; | |
| 219 IDToSessionWindowMap::iterator iter = | |
| 220 synced_window_map_[session_tag]->find(window_id); | |
| 221 if (iter != synced_window_map_[session_tag]->end()) { | |
| 222 iter->second.used = true; | |
| 223 window_ptr = iter->second.window_ptr; | |
| 224 VLOG(1) << "Getting " | |
| 225 << (session_tag == local_session_tag_ ? | |
| 226 "local session" : session_tag) | |
| 227 << "'s seen window " << window_id << " at " << window_ptr; | |
| 228 } else { | |
| 229 // Create the window. | |
| 230 window_ptr = new SessionWindow(); | |
| 231 window_ptr->window_id.set_id(window_id); | |
| 232 (*synced_window_map_[session_tag])[window_id] = | |
| 233 SessionWindowWrapper(window_ptr, true); | |
| 234 VLOG(1) << "Getting " | |
| 235 << (session_tag == local_session_tag_ ? | |
| 236 "local session" : session_tag) | |
| 237 << "'s new window " << window_id << " at " << window_ptr; | |
| 238 } | |
| 239 DCHECK(window_ptr); | |
| 240 DCHECK_EQ(window_ptr->window_id.id(), window_id); | |
| 241 return window_ptr; | |
| 242 } | |
| 243 | |
| 244 SessionTab* SyncedSessionTracker::GetTabForWindow( | |
| 101 const std::string& session_tag, | 245 const std::string& session_tag, |
| 102 SessionID::id_type tab_id, | 246 SessionID::id_type window_id, |
| 103 bool has_window) { | 247 SessionID::id_type tab_id) { |
| 248 SessionTab* tab_ptr = GetTab(session_tag, tab_id); | |
| 249 unmapped_tabs_.erase(tab_ptr); | |
| 250 (*synced_tab_map_[session_tag])[tab_id].used = true; | |
| 251 tab_ptr->window_id.set_id(window_id); | |
| 252 VLOG(1) << " - tab " << tab_id << " noted as part of window "<< window_id; | |
| 253 return tab_ptr; | |
| 254 } | |
| 255 | |
| 256 SessionTab* SyncedSessionTracker::GetTab( | |
| 257 const std::string& session_tag, | |
| 258 SessionID::id_type tab_id) { | |
| 104 if (synced_tab_map_.find(session_tag) == synced_tab_map_.end()) | 259 if (synced_tab_map_.find(session_tag) == synced_tab_map_.end()) |
| 105 synced_tab_map_[session_tag] = new IDToSessionTabMap; | 260 synced_tab_map_[session_tag] = new IDToSessionTabMap; |
| 106 scoped_ptr<SessionTab> tab; | 261 SessionTab* tab_ptr = NULL; |
| 107 IDToSessionTabMap::iterator iter = | 262 IDToSessionTabMap::iterator iter = |
| 108 synced_tab_map_[session_tag]->find(tab_id); | 263 synced_tab_map_[session_tag]->find(tab_id); |
| 109 if (iter != synced_tab_map_[session_tag]->end()) { | 264 if (iter != synced_tab_map_[session_tag]->end()) { |
| 110 tab.reset(iter->second); | 265 tab_ptr = iter->second.tab_ptr; |
| 111 if (has_window) // This tab is linked to a window, so it's not an orphan. | 266 std::string title = ""; |
|
akalin
2011/09/26 21:57:24
wrap this in if (VLOG_IS_ON(1)) ?
Nicolas Zea
2011/09/26 22:55:26
Done.
| |
| 112 unmapped_tabs_.erase(tab.get()); | 267 if (tab_ptr->navigations.size() > 0) { |
| 113 if (tab->navigations.size() > 0) { | 268 title = " (" + UTF16ToASCII( |
| 114 VLOG(1) << "Getting " | 269 tab_ptr->navigations[tab_ptr->navigations.size()-1].title()) + ")"; |
| 115 << (session_tag == local_session_tag_ ? | |
| 116 "local session" : session_tag) | |
| 117 << "'s seen tab " << tab_id << " (" | |
| 118 << tab->navigations[tab->navigations.size()-1].title() | |
| 119 << ")"; | |
| 120 } | 270 } |
| 121 } else { | |
| 122 tab.reset(new SessionTab()); | |
| 123 (*synced_tab_map_[session_tag])[tab_id] = tab.get(); | |
| 124 if (!has_window) // This tab is not linked to a window, it's an orphan. | |
| 125 unmapped_tabs_.insert(tab.get()); | |
| 126 VLOG(1) << "Getting " | 271 VLOG(1) << "Getting " |
| 127 << (session_tag == local_session_tag_ ? | 272 << (session_tag == local_session_tag_ ? |
| 128 "local session" : session_tag) | 273 "local session" : session_tag) |
| 129 << "'s new tab " << tab_id << " at " << tab.get(); | 274 << "'s seen tab " << tab_id << " at " << tab_ptr << title; |
| 275 } else { | |
| 276 tab_ptr = new SessionTab(); | |
| 277 tab_ptr->tab_id.set_id(tab_id); | |
| 278 (*synced_tab_map_[session_tag])[tab_id] = SessionTabWrapper(tab_ptr, false); | |
| 279 unmapped_tabs_.insert(tab_ptr); | |
| 280 VLOG(1) << "Getting " | |
| 281 << (session_tag == local_session_tag_ ? | |
| 282 "local session" : session_tag) | |
| 283 << "'s new tab " << tab_id << " at " << tab_ptr; | |
| 130 } | 284 } |
| 131 DCHECK(tab.get()); | 285 DCHECK(tab_ptr); |
| 132 return tab.release(); | 286 DCHECK_EQ(tab_ptr->tab_id.id(), tab_id); |
| 287 return tab_ptr; | |
| 133 } | 288 } |
| 134 | 289 |
| 135 void SyncedSessionTracker::clear() { | 290 void SyncedSessionTracker::clear() { |
| 136 // Delete SyncedSession objects (which also deletes all their windows/tabs). | 291 // Delete SyncedSession objects (which also deletes all their windows/tabs). |
| 137 STLDeleteContainerPairSecondPointers(synced_session_map_.begin(), | 292 STLDeleteContainerPairSecondPointers(synced_session_map_.begin(), |
| 138 synced_session_map_.end()); | 293 synced_session_map_.end()); |
| 139 synced_session_map_.clear(); | 294 synced_session_map_.clear(); |
| 140 | 295 |
| 141 // Delete IDToSessTab maps. Does not delete the SessionTab objects, because | 296 // Delete IDToSessionWindow maps. Does not delete the SessionWindow objects, |
| 297 // because they should already be referenced through synced_session_map_. | |
| 298 STLDeleteContainerPairSecondPointers(synced_window_map_.begin(), | |
| 299 synced_window_map_.end()); | |
| 300 synced_window_map_.clear(); | |
| 301 | |
| 302 // Delete IDToSessionTab maps. Does not delete the SessionTab objects, because | |
| 142 // they should already be referenced through synced_session_map_. | 303 // they should already be referenced through synced_session_map_. |
| 143 STLDeleteContainerPairSecondPointers(synced_tab_map_.begin(), | 304 STLDeleteContainerPairSecondPointers(synced_tab_map_.begin(), |
| 144 synced_tab_map_.end()); | 305 synced_tab_map_.end()); |
| 145 synced_tab_map_.clear(); | 306 synced_tab_map_.clear(); |
| 146 | 307 |
| 147 // Go through and delete any tabs we had allocated but had not yet placed into | 308 // Go through and delete any tabs we had allocated but had not yet placed into |
| 148 // a SyncedSessionobject. | 309 // a SyncedSessionobject. |
| 149 STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end()); | 310 STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end()); |
| 150 unmapped_tabs_.clear(); | 311 unmapped_tabs_.clear(); |
| 151 | 312 |
| 152 local_session_tag_.clear(); | 313 local_session_tag_.clear(); |
| 153 } | 314 } |
| 154 | 315 |
| 155 } // namespace browser_sync | 316 } // namespace browser_sync |
| OLD | NEW |