Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: chrome/browser/sync/glue/synced_session_tracker.cc

Issue 7966020: [Sync] Fix Session's handling of windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698