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 |