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

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: Fix perf tests Created 9 years, 3 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 <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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698