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