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. |
akalin
2011/09/29 21:59:55
clear sessions first? (or assert empty)
Nicolas Zea
2011/09/30 22:52:59
Done.
| |
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 = |
akalin
2011/09/29 21:59:55
nit: better to rewrite as for loop
Nicolas Zea
2011/09/30 22:52:59
Done.
| |
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()) { |
akalin
2011/09/29 21:59:55
store iterators, use that instead of []
Nicolas Zea
2011/09/30 22:52:59
Done.
| |
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( |
101 const std::string& session_tag, | 114 const std::string& session_tag) { |
102 SessionID::id_type tab_id, | 115 // Reset window tracking. |
103 bool has_window) { | 116 SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag); |
104 if (synced_tab_map_.find(session_tag) == synced_tab_map_.end()) | 117 if (window_iter != synced_window_map_.end()) { |
105 synced_tab_map_[session_tag] = new IDToSessionTabMap; | 118 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.
| |
106 scoped_ptr<SessionTab> tab; | 119 for (window_map_iter = window_iter->second.begin(); |
107 IDToSessionTabMap::iterator iter = | 120 window_map_iter != window_iter->second.end(); ++window_map_iter) { |
108 synced_tab_map_[session_tag]->find(tab_id); | 121 window_map_iter->second.used = false; |
109 if (iter != synced_tab_map_[session_tag]->end()) { | |
110 tab.reset(iter->second); | |
111 if (has_window) // This tab is linked to a window, so it's not an orphan. | |
112 unmapped_tabs_.erase(tab.get()); | |
113 if (tab->navigations.size() > 0) { | |
114 VLOG(1) << "Getting " | |
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 } | 122 } |
121 } else { | 123 } |
122 tab.reset(new SessionTab()); | 124 |
123 (*synced_tab_map_[session_tag])[tab_id] = tab.get(); | 125 // Reset tab tracking. |
124 if (!has_window) // This tab is not linked to a window, it's an orphan. | 126 SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag); |
125 unmapped_tabs_.insert(tab.get()); | 127 if (tab_iter != synced_tab_map_.end()) { |
128 IDToSessionTabMap::iterator tab_map_iter; | |
akalin
2011/09/29 21:59:55
here, too
Nicolas Zea
2011/09/30 22:52:59
Done.
| |
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; | |
179 DCHECK(synced_session_map_.find(session_tag) != synced_session_map_.end()); | |
180 synced_session = synced_session_map_[session_tag]; | |
181 | |
182 // Go through and delete any windows or tabs with a false value in their | |
183 // tracking boolean. | |
184 SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag); | |
185 if (window_iter != synced_window_map_.end()) { | |
186 // Go through and remove those windows from the session first. | |
187 IDToSessionWindowMap::iterator iter; | |
akalin
2011/09/29 21:59:55
move in for loop
Nicolas Zea
2011/09/30 22:52:59
Done.
| |
188 for (iter = window_iter->second.begin(); | |
189 iter != window_iter->second.end();) { | |
190 SessionWindowWrapper window_wrapper = iter->second; | |
191 if (ClearUnusedSessionWindow(window_wrapper, synced_session)) | |
192 window_iter->second.erase(iter++); | |
193 else | |
194 ++iter; | |
195 } | |
196 } | |
197 | |
198 SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag); | |
199 if (tab_iter != synced_tab_map_.end()) { | |
200 IDToSessionTabMap::iterator iter; | |
201 for (iter = tab_iter->second.begin(); | |
202 iter != tab_iter->second.end();) { | |
203 SessionTabWrapper tab_wrapper = iter->second; | |
204 if (ClearUnusedSessionTab(tab_wrapper)) | |
205 tab_iter->second.erase(iter++); | |
206 else | |
207 ++iter; | |
208 } | |
209 } | |
210 } | |
211 | |
212 SessionWindow* SyncedSessionTracker::GetWindow(const std::string& session_tag, | |
213 SessionID::id_type window_id) { | |
214 SessionWindow* window_ptr = NULL; | |
215 IDToSessionWindowMap::iterator iter = | |
216 synced_window_map_[session_tag].find(window_id); | |
217 if (iter != synced_window_map_[session_tag].end()) { | |
218 iter->second.used = true; | |
219 window_ptr = iter->second.window_ptr; | |
126 VLOG(1) << "Getting " | 220 VLOG(1) << "Getting " |
127 << (session_tag == local_session_tag_ ? | 221 << (session_tag == local_session_tag_ ? |
128 "local session" : session_tag) | 222 "local session" : session_tag) |
129 << "'s new tab " << tab_id << " at " << tab.get(); | 223 << "'s seen window " << window_id << " at " << window_ptr; |
224 } else { | |
225 // Create the window. | |
226 window_ptr = new SessionWindow(); | |
227 window_ptr->window_id.set_id(window_id); | |
228 synced_window_map_[session_tag][window_id] = | |
229 SessionWindowWrapper(window_ptr, true); | |
230 VLOG(1) << "Getting " | |
231 << (session_tag == local_session_tag_ ? | |
232 "local session" : session_tag) | |
233 << "'s new window " << window_id << " at " << window_ptr; | |
130 } | 234 } |
131 DCHECK(tab.get()); | 235 DCHECK(window_ptr); |
132 return tab.release(); | 236 DCHECK_EQ(window_ptr->window_id.id(), window_id); |
237 return window_ptr; | |
238 } | |
239 | |
240 SessionTab* SyncedSessionTracker::GetTabForWindow( | |
241 const std::string& session_tag, | |
242 SessionID::id_type window_id, | |
243 SessionID::id_type tab_id) { | |
244 SessionTab* tab_ptr = GetTab(session_tag, tab_id); | |
245 unmapped_tabs_.erase(tab_ptr); | |
246 synced_tab_map_[session_tag][tab_id].used = true; | |
247 tab_ptr->window_id.set_id(window_id); | |
248 VLOG(1) << " - tab " << tab_id << " noted as part of window "<< window_id; | |
249 return tab_ptr; | |
250 } | |
251 | |
252 SessionTab* SyncedSessionTracker::GetTab( | |
253 const std::string& session_tag, | |
254 SessionID::id_type tab_id) { | |
255 SessionTab* tab_ptr = NULL; | |
256 IDToSessionTabMap::iterator iter = | |
257 synced_tab_map_[session_tag].find(tab_id); | |
258 if (iter != synced_tab_map_[session_tag].end()) { | |
259 tab_ptr = iter->second.tab_ptr; | |
260 std::string title = ""; | |
261 if (tab_ptr->navigations.size() > 0) { | |
262 title = " (" + UTF16ToASCII( | |
263 tab_ptr->navigations[tab_ptr->navigations.size()-1].title()) + ")"; | |
264 } | |
265 VLOG(1) << "Getting " | |
266 << (session_tag == local_session_tag_ ? | |
267 "local session" : session_tag) | |
268 << "'s seen tab " << tab_id << " at " << tab_ptr << title; | |
269 } else { | |
270 tab_ptr = new SessionTab(); | |
271 tab_ptr->tab_id.set_id(tab_id); | |
272 synced_tab_map_[session_tag][tab_id] = SessionTabWrapper(tab_ptr, false); | |
273 unmapped_tabs_.insert(tab_ptr); | |
274 VLOG(1) << "Getting " | |
275 << (session_tag == local_session_tag_ ? | |
276 "local session" : session_tag) | |
277 << "'s new tab " << tab_id << " at " << tab_ptr; | |
278 } | |
279 DCHECK(tab_ptr); | |
280 DCHECK_EQ(tab_ptr->tab_id.id(), tab_id); | |
281 return tab_ptr; | |
133 } | 282 } |
134 | 283 |
135 void SyncedSessionTracker::clear() { | 284 void SyncedSessionTracker::clear() { |
136 // Delete SyncedSession objects (which also deletes all their windows/tabs). | 285 // Delete SyncedSession objects (which also deletes all their windows/tabs). |
137 STLDeleteContainerPairSecondPointers(synced_session_map_.begin(), | 286 STLDeleteContainerPairSecondPointers(synced_session_map_.begin(), |
138 synced_session_map_.end()); | 287 synced_session_map_.end()); |
139 synced_session_map_.clear(); | 288 synced_session_map_.clear(); |
140 | 289 |
141 // Delete IDToSessTab maps. Does not delete the SessionTab objects, because | |
142 // they should already be referenced through synced_session_map_. | |
143 STLDeleteContainerPairSecondPointers(synced_tab_map_.begin(), | |
144 synced_tab_map_.end()); | |
145 synced_tab_map_.clear(); | |
146 | |
147 // Go through and delete any tabs we had allocated but had not yet placed into | 290 // Go through and delete any tabs we had allocated but had not yet placed into |
148 // a SyncedSessionobject. | 291 // a SyncedSessionobject. |
149 STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end()); | 292 STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end()); |
150 unmapped_tabs_.clear(); | 293 unmapped_tabs_.clear(); |
151 | 294 |
295 // Get rid of our Window/Tab maps (does not delete the actual Window/Tabs | |
296 // themselves; they should have all been deleted above). | |
297 synced_window_map_.clear(); | |
298 synced_tab_map_.clear(); | |
299 | |
152 local_session_tag_.clear(); | 300 local_session_tag_.clear(); |
153 } | 301 } |
154 | 302 |
155 } // namespace browser_sync | 303 } // namespace browser_sync |
OLD | NEW |