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

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: 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 7
8 namespace browser_sync { 8 namespace browser_sync {
9 9
10
11 SyncedSessionTracker::SyncedSessionTracker() { 10 SyncedSessionTracker::SyncedSessionTracker() {
12 } 11 }
13 12
14 SyncedSessionTracker::~SyncedSessionTracker() { 13 SyncedSessionTracker::~SyncedSessionTracker() {
15 clear(); 14 Clear();
16 } 15 }
17 16
18 void SyncedSessionTracker::SetLocalSessionTag( 17 void SyncedSessionTracker::SetLocalSessionTag(
19 const std::string& local_session_tag) { 18 const std::string& local_session_tag) {
20 local_session_tag_ = local_session_tag; 19 local_session_tag_ = local_session_tag;
21 } 20 }
22 21
23 bool SyncedSessionTracker::LookupAllForeignSessions( 22 bool SyncedSessionTracker::LookupAllForeignSessions(
24 std::vector<const SyncedSession*>* sessions) { 23 std::vector<const SyncedSession*>* sessions) const {
25 DCHECK(sessions); 24 DCHECK(sessions);
25 sessions->clear();
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_ && !foreign_session->windows.empty()) {
32 !foreign_session->windows.empty() && 32 bool found_tabs = false;
33 !SessionModelAssociator::SessionWindowHasNoTabsToSync( 33 for (SyncedSession::SyncedWindowMap::const_iterator iter =
34 *foreign_session->windows[0])) { 34 foreign_session->windows.begin();
35 sessions->push_back(foreign_session); 35 iter != foreign_session->windows.end(); ++iter) {
36 if (!SessionWindowHasNoTabsToSync(*(iter->second))) {
37 found_tabs = true;
38 break;
39 }
40 }
41 if (found_tabs)
42 sessions->push_back(foreign_session);
36 } 43 }
37 } 44 }
38 45
39 return !sessions->empty(); 46 return !sessions->empty();
40 } 47 }
41 48
42 bool SyncedSessionTracker::LookupSessionWindows( 49 bool SyncedSessionTracker::LookupSessionWindows(
43 const std::string& session_tag, 50 const std::string& session_tag,
44 std::vector<SessionWindow*>* windows) { 51 std::vector<const SessionWindow*>* windows) const {
45 DCHECK(windows); 52 DCHECK(windows);
46 SyncedSessionMap::iterator iter = synced_session_map_.find(session_tag); 53 windows->clear();
54 SyncedSessionMap::const_iterator iter = synced_session_map_.find(session_tag);
47 if (iter == synced_session_map_.end()) 55 if (iter == synced_session_map_.end())
48 return false; 56 return false;
49 *windows = iter->second->windows; 57 windows->clear();
58 for (SyncedSession::SyncedWindowMap::const_iterator window_iter =
59 iter->second->windows.begin();
60 window_iter != iter->second->windows.end(); window_iter++) {
61 windows->push_back(window_iter->second);
62 }
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) const {
57 DCHECK(tab); 70 DCHECK(tab);
58 if (synced_tab_map_.find(tag) == synced_tab_map_.end()) { 71 SyncedTabMap::const_iterator tab_map_iter = synced_tab_map_.find(tag);
72 if (tab_map_iter == synced_tab_map_.end()) {
59 // We have no record of this session. 73 // We have no record of this session.
60 *tab = NULL; 74 *tab = NULL;
61 return false; 75 return false;
62 } 76 }
63 if (synced_tab_map_[tag]->find(tab_id) == synced_tab_map_[tag]->end()) { 77 IDToSessionTabMap::const_iterator tab_iter =
78 tab_map_iter->second.find(tab_id);
79 if (tab_iter == tab_map_iter->second.end()) {
64 // We have no record of this tab. 80 // We have no record of this tab.
65 *tab = NULL; 81 *tab = NULL;
66 return false; 82 return false;
67 } 83 }
68 *tab = (*synced_tab_map_[tag])[tab_id]; 84 *tab = tab_iter->second.tab_ptr;
69 return true; 85 return true;
70 } 86 }
71 87
72 SyncedSession* SyncedSessionTracker::GetSession( 88 SyncedSession* SyncedSessionTracker::GetSession(
73 const std::string& session_tag) { 89 const std::string& session_tag) {
74 scoped_ptr<SyncedSession> synced_session; 90 SyncedSession* synced_session = NULL;
75 if (synced_session_map_.find(session_tag) != 91 if (synced_session_map_.find(session_tag) !=
76 synced_session_map_.end()) { 92 synced_session_map_.end()) {
77 synced_session.reset(synced_session_map_[session_tag]); 93 synced_session = synced_session_map_[session_tag];
78 } else { 94 } else {
79 synced_session.reset(new SyncedSession); 95 synced_session = new SyncedSession;
80 synced_session->session_tag = session_tag; 96 synced_session->session_tag = session_tag;
81 synced_session_map_[session_tag] = synced_session.get(); 97 synced_session_map_[session_tag] = synced_session;
82 } 98 }
83 DCHECK(synced_session.get()); 99 DCHECK(synced_session);
84 return synced_session.release(); 100 return synced_session;
85 } 101 }
86 102
87 bool SyncedSessionTracker::DeleteSession( 103 bool SyncedSessionTracker::DeleteSession(
88 const std::string& session_tag) { 104 const std::string& session_tag) {
89 SyncedSessionMap::iterator iter = 105 SyncedSessionMap::iterator iter =
90 synced_session_map_.find(session_tag); 106 synced_session_map_.find(session_tag);
91 if (iter != synced_session_map_.end()) { 107 if (iter != synced_session_map_.end()) {
92 delete iter->second; // Delete the SyncedSession object. 108 delete iter->second; // Delete the SyncedSession object.
93 synced_session_map_.erase(iter); 109 synced_session_map_.erase(iter);
94 return true; 110 return true;
95 } else { 111 } else {
96 return false; 112 return false;
97 } 113 }
98 } 114 }
99 115
100 SessionTab* SyncedSessionTracker::GetSessionTab( 116 void SyncedSessionTracker::ResetSessionTracking(
117 const std::string& session_tag) {
118 // Reset window tracking.
119 GetSession(session_tag)->windows.clear();
120 SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag);
121 if (window_iter != synced_window_map_.end()) {
122 for (IDToSessionWindowMap::iterator window_map_iter =
123 window_iter->second.begin();
124 window_map_iter != window_iter->second.end(); ++window_map_iter) {
125 window_map_iter->second.owned = false;
126 // We clear out the tabs to prevent double referencing of the same tab.
127 // All tabs that are in use will be added back as needed.
128 window_map_iter->second.window_ptr->tabs.clear();
129 }
130 }
131
132 // Reset tab tracking.
133 SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag);
134 if (tab_iter != synced_tab_map_.end()) {
135 for (IDToSessionTabMap::iterator tab_map_iter =
136 tab_iter->second.begin();
137 tab_map_iter != tab_iter->second.end(); ++tab_map_iter) {
138 tab_map_iter->second.owned = false;
139 }
140 }
141 }
142
143 bool SyncedSessionTracker::DeleteOldSessionWindowIfNecessary(
144 SessionWindowWrapper window_wrapper) {
145 // Clear the tabs first, since we don't want the destructor to destroy
146 // them. Their deletion will be handled by DeleteOldSessionTab below.
147 if (!window_wrapper.owned) {
148 VLOG(1) << "Deleting closed window "
149 << window_wrapper.window_ptr->window_id.id();
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::DeleteOldSessionTabIfNecessary(
158 SessionTabWrapper tab_wrapper) {
159 if (!tab_wrapper.owned) {
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 // Go through and delete any windows or tabs without owners.
179 SyncedWindowMap::iterator window_iter = synced_window_map_.find(session_tag);
180 if (window_iter != synced_window_map_.end()) {
181 for (IDToSessionWindowMap::iterator iter = window_iter->second.begin();
182 iter != window_iter->second.end();) {
183 SessionWindowWrapper window_wrapper = iter->second;
184 if (DeleteOldSessionWindowIfNecessary(window_wrapper))
185 window_iter->second.erase(iter++);
186 else
187 ++iter;
188 }
189 }
190
191 SyncedTabMap::iterator tab_iter = synced_tab_map_.find(session_tag);
192 if (tab_iter != synced_tab_map_.end()) {
193 for (IDToSessionTabMap::iterator iter = tab_iter->second.begin();
194 iter != tab_iter->second.end();) {
195 SessionTabWrapper tab_wrapper = iter->second;
196 if (DeleteOldSessionTabIfNecessary(tab_wrapper))
197 tab_iter->second.erase(iter++);
198 else
199 ++iter;
200 }
201 }
202 }
203
204 void SyncedSessionTracker::PutWindowInSession(const std::string& session_tag,
205 SessionID::id_type window_id) {
206 SessionWindow* window_ptr = NULL;
207 IDToSessionWindowMap::iterator iter =
208 synced_window_map_[session_tag].find(window_id);
209 if (iter != synced_window_map_[session_tag].end()) {
210 iter->second.owned = true;
211 window_ptr = iter->second.window_ptr;
212 VLOG(1) << "Putting seen window " << window_id << " at " << window_ptr
213 << "in " << (session_tag == local_session_tag_ ?
214 "local session" : session_tag);
215 } else {
216 // Create the window.
217 window_ptr = new SessionWindow();
218 window_ptr->window_id.set_id(window_id);
219 synced_window_map_[session_tag][window_id] =
220 SessionWindowWrapper(window_ptr, true);
221 VLOG(1) << "Putting new window " << window_id << " at " << window_ptr
222 << "in " << (session_tag == local_session_tag_ ?
223 "local session" : session_tag);
224 }
225 DCHECK(window_ptr);
226 DCHECK_EQ(window_ptr->window_id.id(), window_id);
227 DCHECK_EQ((SessionWindow*)NULL, GetSession(session_tag)->windows[window_id]);
228 GetSession(session_tag)->windows[window_id] = window_ptr;
229 }
230
231 void SyncedSessionTracker::PutTabInWindow(const std::string& session_tag,
232 SessionID::id_type window_id,
233 SessionID::id_type tab_id,
234 size_t tab_index) {
235 SessionTab* tab_ptr = GetTab(session_tag, tab_id);
236 unmapped_tabs_.erase(tab_ptr);
237 synced_tab_map_[session_tag][tab_id].owned = true;
238 tab_ptr->window_id.set_id(window_id);
239 VLOG(1) << " - tab " << tab_id << " added to window "<< window_id;
240 DCHECK(GetSession(session_tag)->windows.find(window_id) !=
241 GetSession(session_tag)->windows.end());
242 std::vector<SessionTab*>& window_tabs =
243 GetSession(session_tag)->windows[window_id]->tabs;
244 if (window_tabs.size() <= tab_index) {
245 window_tabs.resize(tab_index+1, NULL);
246 }
247 DCHECK_EQ((SessionTab*)NULL, window_tabs[tab_index]);
248 window_tabs[tab_index] = tab_ptr;
249 }
250
251 SessionTab* SyncedSessionTracker::GetTab(
101 const std::string& session_tag, 252 const std::string& session_tag,
102 SessionID::id_type tab_id, 253 SessionID::id_type tab_id) {
103 bool has_window) { 254 SessionTab* tab_ptr = NULL;
104 if (synced_tab_map_.find(session_tag) == synced_tab_map_.end())
105 synced_tab_map_[session_tag] = new IDToSessionTabMap;
106 scoped_ptr<SessionTab> tab;
107 IDToSessionTabMap::iterator iter = 255 IDToSessionTabMap::iterator iter =
108 synced_tab_map_[session_tag]->find(tab_id); 256 synced_tab_map_[session_tag].find(tab_id);
109 if (iter != synced_tab_map_[session_tag]->end()) { 257 if (iter != synced_tab_map_[session_tag].end()) {
110 tab.reset(iter->second); 258 tab_ptr = iter->second.tab_ptr;
111 if (has_window) // This tab is linked to a window, so it's not an orphan. 259 std::string title = "";
112 unmapped_tabs_.erase(tab.get()); 260 if (tab_ptr->navigations.size() > 0) {
113 if (tab->navigations.size() > 0) { 261 title = " (" + UTF16ToASCII(
114 VLOG(1) << "Getting " 262 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 } 263 }
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 " 264 VLOG(1) << "Getting "
127 << (session_tag == local_session_tag_ ? 265 << (session_tag == local_session_tag_ ?
128 "local session" : session_tag) 266 "local session" : session_tag)
129 << "'s new tab " << tab_id << " at " << tab.get(); 267 << "'s seen tab " << tab_id << " at " << tab_ptr << title;
268 } else {
269 tab_ptr = new SessionTab();
270 tab_ptr->tab_id.set_id(tab_id);
271 synced_tab_map_[session_tag][tab_id] = SessionTabWrapper(tab_ptr, false);
272 unmapped_tabs_.insert(tab_ptr);
273 VLOG(1) << "Getting "
274 << (session_tag == local_session_tag_ ?
275 "local session" : session_tag)
276 << "'s new tab " << tab_id << " at " << tab_ptr;
130 } 277 }
131 DCHECK(tab.get()); 278 DCHECK(tab_ptr);
132 return tab.release(); 279 DCHECK_EQ(tab_ptr->tab_id.id(), tab_id);
280 return tab_ptr;
133 } 281 }
134 282
135 void SyncedSessionTracker::clear() { 283 void SyncedSessionTracker::Clear() {
136 // Delete SyncedSession objects (which also deletes all their windows/tabs). 284 // Delete SyncedSession objects (which also deletes all their windows/tabs).
137 STLDeleteContainerPairSecondPointers(synced_session_map_.begin(), 285 STLDeleteContainerPairSecondPointers(synced_session_map_.begin(),
138 synced_session_map_.end()); 286 synced_session_map_.end());
139 synced_session_map_.clear(); 287 synced_session_map_.clear();
140 288
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 289 // Go through and delete any tabs we had allocated but had not yet placed into
148 // a SyncedSessionobject. 290 // a SyncedSessionobject.
149 STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end()); 291 STLDeleteContainerPointers(unmapped_tabs_.begin(), unmapped_tabs_.end());
150 unmapped_tabs_.clear(); 292 unmapped_tabs_.clear();
151 293
294 // Get rid of our Window/Tab maps (does not delete the actual Window/Tabs
295 // themselves; they should have all been deleted above).
296 synced_window_map_.clear();
297 synced_tab_map_.clear();
298
152 local_session_tag_.clear(); 299 local_session_tag_.clear();
153 } 300 }
154 301
155 } // namespace browser_sync 302 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698