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

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

Issue 3825005: Fix syncing of sessions. Numerous changes have been made. Currently, the mode... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Rebased again Created 10 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
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "chrome/browser/sync/glue/session_model_associator.h" 5 #include "chrome/browser/sync/glue/session_model_associator.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 19 matching lines...) Expand all
30 SessionModelAssociator::SessionModelAssociator( 30 SessionModelAssociator::SessionModelAssociator(
31 ProfileSyncService* sync_service) : sync_service_(sync_service) { 31 ProfileSyncService* sync_service) : sync_service_(sync_service) {
32 DCHECK(CalledOnValidThread()); 32 DCHECK(CalledOnValidThread());
33 DCHECK(sync_service_); 33 DCHECK(sync_service_);
34 } 34 }
35 35
36 SessionModelAssociator::~SessionModelAssociator() { 36 SessionModelAssociator::~SessionModelAssociator() {
37 DCHECK(CalledOnValidThread()); 37 DCHECK(CalledOnValidThread());
38 } 38 }
39 39
40 // Sends a notification to ForeignSessionHandler to update the UI, because
41 // the session corresponding to the id given has changed state.
42 void SessionModelAssociator::Associate(
43 const sync_pb::SessionSpecifics* specifics, int64 sync_id) {
44 DCHECK(CalledOnValidThread());
45 NotificationService::current()->Notify(
46 NotificationType::FOREIGN_SESSION_UPDATED,
47 NotificationService::AllSources(),
48 Details<int64>(&sync_id));
49 }
50
51 bool SessionModelAssociator::AssociateModels() { 40 bool SessionModelAssociator::AssociateModels() {
52 DCHECK(CalledOnValidThread()); 41 DCHECK(CalledOnValidThread());
42
43 // Make sure we have a machine tag.
44 if (current_machine_tag_.empty())
45 InitializeCurrentMachineTag(); // Creates a syncable::BaseTransaction.
46
47 {
48 // Do an initial update from sync model (in case we just re-enabled and
49 // already had data).
50 sync_api::ReadTransaction trans(
51 sync_service_->backend()->GetUserShareHandle());
52 UpdateFromSyncModel(&trans);
53 }
54
55 // Check if anything has changed on the client side.
53 UpdateSyncModelDataFromClient(); 56 UpdateSyncModelDataFromClient();
54 return true; 57 return true;
55 } 58 }
56 59
57 bool SessionModelAssociator::ChromeModelHasUserCreatedNodes( 60 bool SessionModelAssociator::ChromeModelHasUserCreatedNodes(
58 bool* has_nodes) { 61 bool* has_nodes) {
59 DCHECK(CalledOnValidThread()); 62 DCHECK(CalledOnValidThread());
60 CHECK(has_nodes); 63 CHECK(has_nodes);
61 // This is wrong, but this function is unused, anyway. 64 // This is wrong, but this function is unused, anyway.
62 *has_nodes = true; 65 *has_nodes = true;
63 return true; 66 return true;
64 } 67 }
65 68
66 // Sends a notification to ForeignSessionHandler to update the UI, because 69 bool SessionModelAssociator::DisassociateModels() {
67 // the session corresponding to the id given has been deleted. 70 specifics_.clear();
68 void SessionModelAssociator::Disassociate(int64 sync_id) { 71
72 // There is no local model stored with which to disassociate, just notify
73 // foreign session handlers.
69 NotificationService::current()->Notify( 74 NotificationService::current()->Notify(
70 NotificationType::FOREIGN_SESSION_DELETED, 75 NotificationType::FOREIGN_SESSION_DISABLED,
71 NotificationService::AllSources(), 76 NotificationService::AllSources(),
72 Details<int64>(&sync_id)); 77 NotificationService::NoDetails());
78 return true;
73 } 79 }
74 80
75 const sync_pb::SessionSpecifics* SessionModelAssociator:: 81 const sync_pb::SessionSpecifics* SessionModelAssociator::
76 GetChromeNodeFromSyncId(int64 sync_id) { 82 GetChromeNodeFromSyncId(int64 sync_id) {
77 sync_api::ReadTransaction trans( 83 sync_api::ReadTransaction trans(
78 sync_service_->backend()->GetUserShareHandle()); 84 sync_service_->backend()->GetUserShareHandle());
79 sync_api::ReadNode node(&trans); 85 sync_api::ReadNode node(&trans);
80 if (!node.InitByIdLookup(sync_id)) 86 if (!node.InitByIdLookup(sync_id))
81 return NULL; 87 return NULL;
82 return new sync_pb::SessionSpecifics(node.GetSessionSpecifics()); 88 return new sync_pb::SessionSpecifics(node.GetSessionSpecifics());
(...skipping 30 matching lines...) Expand all
113 LOG(ERROR) << kNoSessionsFolderError; 119 LOG(ERROR) << kNoSessionsFolderError;
114 return false; 120 return false;
115 } 121 }
116 // The sync model has user created nodes iff the sessions folder has 122 // The sync model has user created nodes iff the sessions folder has
117 // any children. 123 // any children.
118 *has_nodes = root.GetFirstChildId() != sync_api::kInvalidId; 124 *has_nodes = root.GetFirstChildId() != sync_api::kInvalidId;
119 return true; 125 return true;
120 } 126 }
121 127
122 std::string SessionModelAssociator::GetCurrentMachineTag() { 128 std::string SessionModelAssociator::GetCurrentMachineTag() {
123 if (current_machine_tag_.empty())
124 InitializeCurrentMachineTag();
125 DCHECK(!current_machine_tag_.empty()); 129 DCHECK(!current_machine_tag_.empty());
126 return current_machine_tag_; 130 return current_machine_tag_;
127 } 131 }
128 132
129 void SessionModelAssociator::AppendForeignSessionFromSpecifics(
130 const sync_pb::SessionSpecifics* specifics,
131 std::vector<ForeignSession*>* session) {
132 ForeignSession* foreign_session = new ForeignSession();
133 foreign_session->foreign_tession_tag = specifics->session_tag();
134 session->insert(session->end(), foreign_session);
135 for (int i = 0; i < specifics->session_window_size(); i++) {
136 const sync_pb::SessionWindow* window = &specifics->session_window(i);
137 SessionWindow* session_window = new SessionWindow();
138 PopulateSessionWindowFromSpecifics(session_window, window);
139 foreign_session->windows.insert(
140 foreign_session->windows.end(), session_window);
141 }
142 }
143
144 // Fills the given vector with foreign session windows to restore.
145 void SessionModelAssociator::AppendForeignSessionWithID(int64 id,
146 std::vector<ForeignSession*>* session, sync_api::BaseTransaction* trans) {
147 if (id == sync_api::kInvalidId)
148 return;
149 sync_api::ReadNode node(trans);
150 if (!node.InitByIdLookup(id))
151 return;
152 const sync_pb::SessionSpecifics* ref = &node.GetSessionSpecifics();
153 AppendForeignSessionFromSpecifics(ref, session);
154 }
155
156 void SessionModelAssociator::UpdateSyncModelDataFromClient() { 133 void SessionModelAssociator::UpdateSyncModelDataFromClient() {
157 DCHECK(CalledOnValidThread()); 134 DCHECK(CalledOnValidThread());
158 SessionService::SessionCallback* callback = 135 SessionService::SessionCallback* callback =
159 NewCallback(this, &SessionModelAssociator::OnGotSession); 136 NewCallback(this, &SessionModelAssociator::OnGotSession);
160 // TODO(jerrica): Stop current race condition, possibly make new method in 137 // TODO(jerrica): Stop current race condition, possibly make new method in
161 // session service, which only grabs the windows from memory. 138 // session service, which only grabs the windows from memory.
162 GetSessionService()->GetCurrentSession(&consumer_, callback); 139 GetSessionService()->GetCurrentSession(&consumer_, callback);
163 } 140 }
164 141
165 bool SessionModelAssociator::GetSessionDataFromSyncModel( 142 // TODO(zea): Don't recreate sessions_ vector from scratch each time. This
166 std::vector<ForeignSession*>* sessions) { 143 // will involve knowing which sessions have been changed (a different data
167 std::vector<const sync_pb::SessionSpecifics*> specifics; 144 // structure will probably be better too).
145 bool SessionModelAssociator::UpdateFromSyncModel(
146 const sync_api::BaseTransaction* trans) {
168 DCHECK(CalledOnValidThread()); 147 DCHECK(CalledOnValidThread());
169 sync_api::ReadTransaction trans( 148
170 sync_service_->backend()->GetUserShareHandle()); 149 // Rebuild specifics_ vector
171 sync_api::ReadNode root(&trans); 150 specifics_.clear();
151 if (!QuerySyncModel(trans, specifics_)) {
152 LOG(ERROR) << "SessionModelAssociator failed to updated from sync model";
153 return false;
154 }
155
156 return true;
157 }
158
159 bool SessionModelAssociator::QuerySyncModel(
160 const sync_api::BaseTransaction* trans,
161 std::vector<const sync_pb::SessionSpecifics*>& specifics) {
162 DCHECK(CalledOnValidThread());
163 sync_api::ReadNode root(trans);
172 if (!root.InitByTagLookup(kSessionsTag)) { 164 if (!root.InitByTagLookup(kSessionsTag)) {
173 LOG(ERROR) << kNoSessionsFolderError; 165 LOG(ERROR) << kNoSessionsFolderError;
174 return false; 166 return false;
175 } 167 }
176 sync_api::ReadNode current_machine(&trans); 168 sync_api::ReadNode current_machine(trans);
177 int64 current_id = (current_machine.InitByClientTagLookup(syncable::SESSIONS, 169 int64 current_id = (current_machine.InitByClientTagLookup(syncable::SESSIONS,
178 GetCurrentMachineTag())) ? current_machine.GetId() : sync_api::kInvalidId; 170 GetCurrentMachineTag())) ? current_machine.GetId() : sync_api::kInvalidId;
171
179 // Iterate through the nodes and populate the session model. 172 // Iterate through the nodes and populate the session model.
180 int64 id = root.GetFirstChildId(); 173 int64 id = root.GetFirstChildId();
181 while (id != sync_api::kInvalidId) { 174 while (id != sync_api::kInvalidId) {
182 sync_api::ReadNode sync_node(&trans); 175 sync_api::ReadNode sync_node(trans);
183 if (!sync_node.InitByIdLookup(id)) { 176 if (!sync_node.InitByIdLookup(id)) {
184 LOG(ERROR) << "Failed to fetch sync node for id " << id; 177 LOG(ERROR) << "Failed to fetch sync node for id " << id;
185 return false; 178 return false;
186 } 179 }
187 if (id != current_id) { 180 if (id != current_id) {
188 specifics.insert(specifics.end(), &sync_node.GetSessionSpecifics()); 181 specifics.insert(specifics.end(), &sync_node.GetSessionSpecifics());
189 } 182 }
190 id = sync_node.GetSuccessorId(); 183 id = sync_node.GetSuccessorId();
191 } 184 }
185 return true;
186 }
187
188 bool SessionModelAssociator::GetSessionData(
189 std::vector<ForeignSession*>* sessions) {
190 DCHECK(CalledOnValidThread());
191
192 // Build vector of sessions from specifics data
192 for (std::vector<const sync_pb::SessionSpecifics*>::const_iterator i = 193 for (std::vector<const sync_pb::SessionSpecifics*>::const_iterator i =
193 specifics.begin(); i != specifics.end(); ++i) { 194 specifics_.begin(); i != specifics_.end(); ++i) {
194 AppendForeignSessionFromSpecifics(*i, sessions); 195 AppendForeignSessionFromSpecifics(*i, sessions);
195 } 196 }
197
196 return true; 198 return true;
197 } 199 }
198 200
201 void SessionModelAssociator::AppendForeignSessionFromSpecifics(
202 const sync_pb::SessionSpecifics* specifics,
203 std::vector<ForeignSession*>* session) {
204 ForeignSession* foreign_session = new ForeignSession();
205 foreign_session->foreign_tession_tag = specifics->session_tag();
206 session->insert(session->end(), foreign_session);
207 for (int i = 0; i < specifics->session_window_size(); i++) {
208 const sync_pb::SessionWindow* window = &specifics->session_window(i);
209 SessionWindow* session_window = new SessionWindow();
210 PopulateSessionWindowFromSpecifics(session_window, window);
211 foreign_session->windows.insert(
212 foreign_session->windows.end(), session_window);
213 }
214 }
215
216 // Fills the given vector with foreign session windows to restore.
217 void SessionModelAssociator::AppendForeignSessionWithID(int64 id,
218 std::vector<ForeignSession*>* session, sync_api::BaseTransaction* trans) {
219 if (id == sync_api::kInvalidId)
220 return;
221 sync_api::ReadNode node(trans);
222 if (!node.InitByIdLookup(id))
223 return;
224 const sync_pb::SessionSpecifics* ref = &node.GetSessionSpecifics();
225 AppendForeignSessionFromSpecifics(ref, session);
226 }
227
199 SessionService* SessionModelAssociator::GetSessionService() { 228 SessionService* SessionModelAssociator::GetSessionService() {
200 DCHECK(sync_service_); 229 DCHECK(sync_service_);
201 Profile* profile = sync_service_->profile(); 230 Profile* profile = sync_service_->profile();
202 DCHECK(profile); 231 DCHECK(profile);
203 SessionService* sessions_service = profile->GetSessionService(); 232 SessionService* sessions_service = profile->GetSessionService();
204 DCHECK(sessions_service); 233 DCHECK(sessions_service);
205 return sessions_service; 234 return sessions_service;
206 } 235 }
207 236
208 void SessionModelAssociator::InitializeCurrentMachineTag() { 237 void SessionModelAssociator::InitializeCurrentMachineTag() {
209 sync_api::WriteTransaction trans(sync_service_->backend()-> 238 sync_api::WriteTransaction trans(sync_service_->backend()->
210 GetUserShareHandle()); 239 GetUserShareHandle());
211 syncable::Directory* dir = 240 syncable::Directory* dir =
212 trans.GetWrappedWriteTrans()->directory(); 241 trans.GetWrappedWriteTrans()->directory();
242
243 // TODO(zea): We need a better way of creating a machine tag. The directory
244 // kernel's cache_guid changes every time syncing is turned on and off. This
245 // will result in session's associated with stale machine tags persisting on
246 // the server since that tag will not be reused. Eventually this should
247 // become some string identifiable to the user. (Home, Work, Laptop, etc.)
248 // See issue 59672
213 current_machine_tag_ = "session_sync"; 249 current_machine_tag_ = "session_sync";
214 current_machine_tag_.append(dir->cache_guid()); 250 current_machine_tag_.append(dir->cache_guid());
251 LOG(INFO) << "Creating machine tag: " << current_machine_tag_;
215 } 252 }
216 253
217 // See PopulateSessionSpecificsTab for use. May add functionality that includes 254 // See PopulateSessionSpecificsTab for use. May add functionality that includes
218 // the state later. 255 // the state later.
219 void SessionModelAssociator::PopulateSessionSpecificsNavigation( 256 void SessionModelAssociator::PopulateSessionSpecificsNavigation(
220 const TabNavigation* navigation, sync_pb::TabNavigation* tab_navigation) { 257 const TabNavigation* navigation, sync_pb::TabNavigation* tab_navigation) {
221 tab_navigation->set_index(navigation->index()); 258 tab_navigation->set_index(navigation->index());
222 tab_navigation->set_virtual_url(navigation->virtual_url().spec()); 259 tab_navigation->set_virtual_url(navigation->virtual_url().spec());
223 tab_navigation->set_referrer(navigation->referrer().spec()); 260 tab_navigation->set_referrer(navigation->referrer().spec());
224 tab_navigation->set_title(UTF16ToUTF8(navigation->title())); 261 tab_navigation->set_title(UTF16ToUTF8(navigation->title()));
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 return false; 555 return false;
519 } 556 }
520 create_node.SetSessionSpecifics(*session_data); 557 create_node.SetSessionSpecifics(*session_data);
521 return true; 558 return true;
522 } 559 }
523 write_node.SetSessionSpecifics(*session_data); 560 write_node.SetSessionSpecifics(*session_data);
524 return true; 561 return true;
525 } 562 }
526 563
527 } // namespace browser_sync 564 } // namespace browser_sync
528
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/session_model_associator.h ('k') | chrome/browser/sync/profile_sync_service_session_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698