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

Side by Side Diff: chrome/browser/sync/engine/process_commit_response_command.cc

Issue 2844037: Fix handling of undeletion within the syncer. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Whitespace. Created 10 years, 5 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
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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/engine/process_commit_response_command.h" 5 #include "chrome/browser/sync/engine/process_commit_response_command.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 15 matching lines...) Expand all
26 using std::vector; 26 using std::vector;
27 27
28 using syncable::BASE_VERSION; 28 using syncable::BASE_VERSION;
29 using syncable::GET_BY_ID; 29 using syncable::GET_BY_ID;
30 using syncable::ID; 30 using syncable::ID;
31 using syncable::IS_DEL; 31 using syncable::IS_DEL;
32 using syncable::IS_DIR; 32 using syncable::IS_DIR;
33 using syncable::IS_UNAPPLIED_UPDATE; 33 using syncable::IS_UNAPPLIED_UPDATE;
34 using syncable::IS_UNSYNCED; 34 using syncable::IS_UNSYNCED;
35 using syncable::PARENT_ID; 35 using syncable::PARENT_ID;
36 using syncable::SERVER_IS_DEL;
36 using syncable::SERVER_PARENT_ID; 37 using syncable::SERVER_PARENT_ID;
37 using syncable::SERVER_POSITION_IN_PARENT; 38 using syncable::SERVER_POSITION_IN_PARENT;
39 using syncable::SERVER_VERSION;
38 using syncable::SYNCER; 40 using syncable::SYNCER;
39 using syncable::SYNCING; 41 using syncable::SYNCING;
40 42
41 namespace browser_sync { 43 namespace browser_sync {
42 44
43 using sessions::OrderedCommitSet; 45 using sessions::OrderedCommitSet;
44 using sessions::StatusController; 46 using sessions::StatusController;
45 using sessions::SyncSession; 47 using sessions::SyncSession;
46 using sessions::ConflictProgress; 48 using sessions::ConflictProgress;
47 49
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 ScopedDirLookup dir(session->context()->directory_manager(), 113 ScopedDirLookup dir(session->context()->directory_manager(),
112 session->context()->account_name()); 114 session->context()->account_name());
113 if (!dir.good()) { 115 if (!dir.good()) {
114 LOG(ERROR) << "Scoped dir lookup failed!"; 116 LOG(ERROR) << "Scoped dir lookup failed!";
115 return; 117 return;
116 } 118 }
117 119
118 StatusController* status = session->status_controller(); 120 StatusController* status = session->status_controller();
119 const ClientToServerResponse& response(status->commit_response()); 121 const ClientToServerResponse& response(status->commit_response());
120 const CommitResponse& cr = response.commit(); 122 const CommitResponse& cr = response.commit();
123 const sync_pb::CommitMessage& commit_message =
124 status->commit_message().commit();
121 125
122 // If we try to commit a parent and child together and the parent conflicts 126 // If we try to commit a parent and child together and the parent conflicts
123 // the child will have a bad parent causing an error. As this is not a 127 // the child will have a bad parent causing an error. As this is not a
124 // critical error, we trap it and don't LOG(ERROR). To enable this we keep 128 // critical error, we trap it and don't LOG(ERROR). To enable this we keep
125 // a map of conflicting new folders. 129 // a map of conflicting new folders.
126 int transient_error_commits = 0; 130 int transient_error_commits = 0;
127 int conflicting_commits = 0; 131 int conflicting_commits = 0;
128 int error_commits = 0; 132 int error_commits = 0;
129 int successes = 0; 133 int successes = 0;
130 bool over_quota = false; 134 bool over_quota = false;
131 set<syncable::Id> conflicting_new_folder_ids; 135 set<syncable::Id> conflicting_new_folder_ids;
132 set<syncable::Id> deleted_folders; 136 set<syncable::Id> deleted_folders;
133 ConflictProgress* conflict_progress = status->mutable_conflict_progress(); 137 ConflictProgress* conflict_progress = status->mutable_conflict_progress();
134 OrderedCommitSet::Projection proj = status->commit_id_projection(); 138 OrderedCommitSet::Projection proj = status->commit_id_projection();
135 { // Scope for WriteTransaction. 139 { // Scope for WriteTransaction.
136 WriteTransaction trans(dir, SYNCER, __FILE__, __LINE__); 140 WriteTransaction trans(dir, SYNCER, __FILE__, __LINE__);
137 for (size_t i = 0; i < proj.size(); i++) { 141 for (size_t i = 0; i < proj.size(); i++) {
138 CommitResponse::ResponseType response_type = 142 CommitResponse::ResponseType response_type =
139 ProcessSingleCommitResponse(&trans, cr.entryresponse(proj[i]), 143 ProcessSingleCommitResponse(&trans, cr.entryresponse(proj[i]),
144 commit_message.entries(proj[i]),
140 status->GetCommitIdAt(proj[i]), 145 status->GetCommitIdAt(proj[i]),
141 &conflicting_new_folder_ids, 146 &conflicting_new_folder_ids,
142 &deleted_folders); 147 &deleted_folders);
143 switch (response_type) { 148 switch (response_type) {
144 case CommitResponse::INVALID_MESSAGE: 149 case CommitResponse::INVALID_MESSAGE:
145 ++error_commits; 150 ++error_commits;
146 break; 151 break;
147 case CommitResponse::CONFLICT: 152 case CommitResponse::CONFLICT:
148 ++conflicting_commits; 153 ++conflicting_commits;
149 // Only server CONFLICT responses will activate conflict resolution. 154 // Only server CONFLICT responses will activate conflict resolution.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 if (res.has_error_message()) 204 if (res.has_error_message())
200 LOG(WARNING) << " " << res.error_message(); 205 LOG(WARNING) << " " << res.error_message();
201 else 206 else
202 LOG(WARNING) << " No detailed error message returned from server"; 207 LOG(WARNING) << " No detailed error message returned from server";
203 } 208 }
204 209
205 CommitResponse::ResponseType 210 CommitResponse::ResponseType
206 ProcessCommitResponseCommand::ProcessSingleCommitResponse( 211 ProcessCommitResponseCommand::ProcessSingleCommitResponse(
207 syncable::WriteTransaction* trans, 212 syncable::WriteTransaction* trans,
208 const sync_pb::CommitResponse_EntryResponse& pb_server_entry, 213 const sync_pb::CommitResponse_EntryResponse& pb_server_entry,
214 const sync_pb::SyncEntity& commit_request_entry,
209 const syncable::Id& pre_commit_id, 215 const syncable::Id& pre_commit_id,
210 std::set<syncable::Id>* conflicting_new_folder_ids, 216 std::set<syncable::Id>* conflicting_new_folder_ids,
211 set<syncable::Id>* deleted_folders) { 217 set<syncable::Id>* deleted_folders) {
212 218
213 const CommitResponse_EntryResponse& server_entry = 219 const CommitResponse_EntryResponse& server_entry =
214 *static_cast<const CommitResponse_EntryResponse*>(&pb_server_entry); 220 *static_cast<const CommitResponse_EntryResponse*>(&pb_server_entry);
215 MutableEntry local_entry(trans, GET_BY_ID, pre_commit_id); 221 MutableEntry local_entry(trans, GET_BY_ID, pre_commit_id);
216 CHECK(local_entry.good()); 222 CHECK(local_entry.good());
217 bool syncing_was_set = local_entry.Get(SYNCING); 223 bool syncing_was_set = local_entry.Get(SYNCING);
218 local_entry.Put(SYNCING, false); 224 local_entry.Put(SYNCING, false);
(...skipping 10 matching lines...) Expand all
229 LogServerError(server_entry); 235 LogServerError(server_entry);
230 return CommitResponse::TRANSIENT_ERROR; 236 return CommitResponse::TRANSIENT_ERROR;
231 } 237 }
232 if (CommitResponse::INVALID_MESSAGE == response) { 238 if (CommitResponse::INVALID_MESSAGE == response) {
233 LOG(ERROR) << "Error Commiting: " << local_entry; 239 LOG(ERROR) << "Error Commiting: " << local_entry;
234 LogServerError(server_entry); 240 LogServerError(server_entry);
235 return response; 241 return response;
236 } 242 }
237 if (CommitResponse::CONFLICT == response) { 243 if (CommitResponse::CONFLICT == response) {
238 LOG(INFO) << "Conflict Committing: " << local_entry; 244 LOG(INFO) << "Conflict Committing: " << local_entry;
245 // TODO(nick): conflicting_new_folder_ids is a purposeless anachronism.
239 if (!pre_commit_id.ServerKnows() && local_entry.Get(IS_DIR)) { 246 if (!pre_commit_id.ServerKnows() && local_entry.Get(IS_DIR)) {
240 conflicting_new_folder_ids->insert(pre_commit_id); 247 conflicting_new_folder_ids->insert(pre_commit_id);
241 } 248 }
242 return response; 249 return response;
243 } 250 }
244 if (CommitResponse::RETRY == response) { 251 if (CommitResponse::RETRY == response) {
245 LOG(INFO) << "Retry Committing: " << local_entry; 252 LOG(INFO) << "Retry Committing: " << local_entry;
246 return response; 253 return response;
247 } 254 }
248 if (CommitResponse::OVER_QUOTA == response) { 255 if (CommitResponse::OVER_QUOTA == response) {
(...skipping 15 matching lines...) Expand all
264 LOG(ERROR) << "Got duplicate id when commiting id: " << pre_commit_id << 271 LOG(ERROR) << "Got duplicate id when commiting id: " << pre_commit_id <<
265 ". Treating as an error return"; 272 ". Treating as an error return";
266 return CommitResponse::INVALID_MESSAGE; 273 return CommitResponse::INVALID_MESSAGE;
267 } 274 }
268 } 275 }
269 276
270 if (server_entry.version() == 0) { 277 if (server_entry.version() == 0) {
271 LOG(WARNING) << "Server returned a zero version on a commit response."; 278 LOG(WARNING) << "Server returned a zero version on a commit response.";
272 } 279 }
273 280
274 ProcessSuccessfulCommitResponse(trans, server_entry, pre_commit_id, 281 ProcessSuccessfulCommitResponse(commit_request_entry, server_entry,
275 &local_entry, syncing_was_set, 282 pre_commit_id, &local_entry, syncing_was_set, deleted_folders);
276 deleted_folders);
277 return response; 283 return response;
278 } 284 }
279 285
280 void ProcessCommitResponseCommand::ProcessSuccessfulCommitResponse( 286 const string& ProcessCommitResponseCommand::GetResultingPostCommitName(
281 syncable::WriteTransaction* trans, 287 const sync_pb::SyncEntity& committed_entry,
282 const CommitResponse_EntryResponse& server_entry, 288 const CommitResponse_EntryResponse& entry_response) {
283 const syncable::Id& pre_commit_id, syncable::MutableEntry* local_entry, 289 const string& response_name =
284 bool syncing_was_set, set<syncable::Id>* deleted_folders) { 290 SyncerProtoUtil::NameFromCommitEntryResponse(entry_response);
291 if (!response_name.empty())
292 return response_name;
293 return SyncerProtoUtil::NameFromSyncEntity(committed_entry);
294 }
295
296 bool ProcessCommitResponseCommand::UpdateVersionAfterCommit(
297 const sync_pb::SyncEntity& committed_entry,
298 const CommitResponse_EntryResponse& entry_response,
299 const syncable::Id& pre_commit_id,
300 syncable::MutableEntry* local_entry) {
285 int64 old_version = local_entry->Get(BASE_VERSION); 301 int64 old_version = local_entry->Get(BASE_VERSION);
286 int64 new_version = server_entry.version(); 302 int64 new_version = entry_response.version();
287 bool bad_commit_version = false; 303 bool bad_commit_version = false;
288 // TODO(sync): The !server_entry.has_id_string() clauses below were 304 if (committed_entry.deleted() &&
289 // introduced when working with the new protocol. 305 !local_entry->Get(syncable::UNIQUE_CLIENT_TAG).empty()) {
290 if (!pre_commit_id.ServerKnows()) 306 // If the item was deleted, and it's undeletable (uses the client tag),
307 // change the version back to zero. We must set the version to zero so
308 // that the server knows to re-create the item if it gets committed
309 // later for undeletion.
310 new_version = 0;
311 } else if (!pre_commit_id.ServerKnows()) {
291 bad_commit_version = 0 == new_version; 312 bad_commit_version = 0 == new_version;
292 else 313 } else {
293 bad_commit_version = old_version > new_version; 314 bad_commit_version = old_version > new_version;
315 }
294 if (bad_commit_version) { 316 if (bad_commit_version) {
295 LOG(ERROR) << "Bad version in commit return for " << *local_entry << 317 LOG(ERROR) << "Bad version in commit return for " << *local_entry
296 " new_id:" << server_entry.id() << " new_version:" << 318 << " new_id:" << entry_response.id() << " new_version:"
297 server_entry.version(); 319 << entry_response.version();
298 return; 320 return false;
299 } 321 }
300 if (server_entry.id() != pre_commit_id) { 322
323 // Update the base version and server version. The base version must change
324 // here, even if syncing_was_set is false; that's because local changes were
325 // on top of the successfully committed version.
326 local_entry->Put(BASE_VERSION, new_version);
327 LOG(INFO) << "Commit is changing base version of "
328 << local_entry->Get(ID) << " to: " << new_version;
329 local_entry->Put(SERVER_VERSION, new_version);
330 return true;
331 }
332
333 bool ProcessCommitResponseCommand::ChangeIdAfterCommit(
334 const CommitResponse_EntryResponse& entry_response,
335 const syncable::Id& pre_commit_id,
336 syncable::MutableEntry* local_entry) {
337 syncable::WriteTransaction* trans = local_entry->write_transaction();
338 if (entry_response.id() != pre_commit_id) {
301 if (pre_commit_id.ServerKnows()) { 339 if (pre_commit_id.ServerKnows()) {
302 // TODO(sync): In future it's possible that we'll want the opportunity 340 // The server can sometimes generate a new ID on commit; for example,
303 // to do a server triggered move aside here. 341 // when committing an undeletion.
304 LOG(ERROR) << " ID change but not committing a new entry. " << 342 LOG(INFO) << " ID changed while committing an old entry. "
305 pre_commit_id << " became " << server_entry.id() << "."; 343 << pre_commit_id << " became " << entry_response.id() << ".";
306 return;
307 } 344 }
308 if (!server_entry.id().ServerKnows()) { 345 MutableEntry same_id(trans, GET_BY_ID, entry_response.id());
309 LOG(ERROR) << " New entries id < 0." << pre_commit_id << " became " << 346 // We should trap this before this function.
310 server_entry.id() << "."; 347 if (same_id.good()) {
311 return; 348 LOG(ERROR) << "ID clash with id " << entry_response.id()
349 << " during commit " << same_id;
350 return false;
312 } 351 }
313 MutableEntry same_id(trans, GET_BY_ID, server_entry.id());
314 // We should trap this before this function.
315 CHECK(!same_id.good()) << "ID clash with id " << server_entry.id() <<
316 " during commit " << same_id;
317 SyncerUtil::ChangeEntryIDAndUpdateChildren( 352 SyncerUtil::ChangeEntryIDAndUpdateChildren(
318 trans, local_entry, server_entry.id()); 353 trans, local_entry, entry_response.id());
319 LOG(INFO) << "Changing ID to " << server_entry.id(); 354 LOG(INFO) << "Changing ID to " << entry_response.id();
320 } 355 }
321 356 return true;
322 local_entry->Put(BASE_VERSION, new_version); 357 }
323 LOG(INFO) << "Commit is changing base version of " << 358
324 local_entry->Get(ID) << " to: " << new_version; 359 void ProcessCommitResponseCommand::UpdateServerFieldsAfterCommit(
360 const sync_pb::SyncEntity& committed_entry,
361 const CommitResponse_EntryResponse& entry_response,
362 syncable::MutableEntry* local_entry) {
363
364 // We just committed an entry successfully, and now we want to make our view
365 // of the server state consistent with the server state. We must be careful;
366 // |entry_response| and |committed_entry| have some identically named
367 // fields. We only want to consider fields from |committed_entry| when there
368 // is not an overriding field in the |entry_response|. We do not want to
369 // update the server data from the local data in the entry -- it's possible
370 // that the local data changed during the commit, and even if not, the server
371 // has the last word on the values of several properties.
372
373 local_entry->Put(SERVER_IS_DEL, committed_entry.deleted());
374 if (committed_entry.deleted()) {
375 // Don't clobber any other fields of deleted objects.
376 return;
377 }
378
379 local_entry->Put(syncable::SERVER_IS_DIR,
380 (committed_entry.folder() ||
381 committed_entry.bookmarkdata().bookmark_folder()));
382 local_entry->Put(syncable::SERVER_SPECIFICS,
383 committed_entry.specifics());
384 local_entry->Put(syncable::SERVER_MTIME,
385 committed_entry.mtime());
386 local_entry->Put(syncable::SERVER_CTIME,
387 committed_entry.ctime());
388 local_entry->Put(syncable::SERVER_POSITION_IN_PARENT,
389 entry_response.position_in_parent());
390 // TODO(nick): The server doesn't set entry_response.server_parent_id in
391 // practice; to update SERVER_PARENT_ID appropriately here we'd need to
392 // get the post-commit ID of the parent indicated by
393 // committed_entry.parent_id_string(). That should be inferrable from the
394 // information we have, but it's a bit convoluted to pull it out directly.
395 // Getting this right is important: SERVER_PARENT_ID gets fed back into
396 // old_parent_id during the next commit.
397 local_entry->Put(syncable::SERVER_PARENT_ID,
398 local_entry->Get(syncable::PARENT_ID));
399 local_entry->Put(syncable::SERVER_NON_UNIQUE_NAME,
400 GetResultingPostCommitName(committed_entry, entry_response));
325 401
326 if (local_entry->Get(IS_UNAPPLIED_UPDATE)) { 402 if (local_entry->Get(IS_UNAPPLIED_UPDATE)) {
327 // This is possible, but very unlikely. 403 // This shouldn't happen; an unapplied update shouldn't be committed, and
404 // if it were, the commit should have failed. But if it does happen: we've
405 // just overwritten the update info, so clear the flag.
328 local_entry->Put(IS_UNAPPLIED_UPDATE, false); 406 local_entry->Put(IS_UNAPPLIED_UPDATE, false);
329 } 407 }
330 408 }
331 if (server_entry.has_name()) { 409
332 if (syncing_was_set) { 410 void ProcessCommitResponseCommand::OverrideClientFieldsAfterCommit(
333 PerformCommitTimeNameAside(trans, server_entry, local_entry); 411 const sync_pb::SyncEntity& committed_entry,
334 } else { 412 const CommitResponse_EntryResponse& entry_response,
335 // IS_UNSYNCED will ensure that this entry gets committed again, even if 413 syncable::MutableEntry* local_entry) {
336 // we skip this name aside. IS_UNSYNCED was probably previously set, but 414 if (committed_entry.deleted()) {
337 // let's just set it anyway. 415 // If an entry's been deleted, nothing else matters.
338 local_entry->Put(IS_UNSYNCED, true); 416 DCHECK(local_entry->Get(IS_DEL));
339 LOG(INFO) << "Skipping commit time name aside because" << 417 return;
340 " entry was changed during commit."; 418 }
341 } 419
342 } 420 // Update the name.
343 421 const string& server_name =
344 if (syncing_was_set && server_entry.has_position_in_parent()) { 422 GetResultingPostCommitName(committed_entry, entry_response);
345 // The server has the final say on positioning, so apply the absolute 423 const string& old_name =
346 // position that it returns. 424 local_entry->Get(syncable::NON_UNIQUE_NAME);
347 local_entry->Put(SERVER_POSITION_IN_PARENT, 425
348 server_entry.position_in_parent()); 426 if (!server_name.empty() && old_name != server_name) {
427 LOG(INFO) << "During commit, server changed name: " << old_name
428 << " to new name: " << server_name;
429 local_entry->Put(syncable::NON_UNIQUE_NAME, server_name);
430 }
431
432 // The server has the final say on positioning, so apply the absolute
433 // position that it returns.
434 if (entry_response.has_position_in_parent()) {
435 // The SERVER_ field should already have been written.
436 DCHECK_EQ(entry_response.position_in_parent(),
437 local_entry->Get(SERVER_POSITION_IN_PARENT));
349 438
350 // We just committed successfully, so we assume that the position 439 // We just committed successfully, so we assume that the position
351 // value we got applies to the PARENT_ID we submitted. 440 // value we got applies to the PARENT_ID we submitted.
352 syncable::Id new_prev = SyncerUtil::ComputePrevIdFromServerPosition( 441 syncable::Id new_prev = SyncerUtil::ComputePrevIdFromServerPosition(
353 trans, local_entry, local_entry->Get(PARENT_ID)); 442 local_entry->write_transaction(), local_entry,
443 local_entry->Get(PARENT_ID));
354 if (!local_entry->PutPredecessor(new_prev)) { 444 if (!local_entry->PutPredecessor(new_prev)) {
355 LOG(WARNING) << "PutPredecessor failed after successful commit"; 445 LOG(WARNING) << "PutPredecessor failed after successful commit";
356 } 446 }
357 } 447 }
358 448 }
449
450 void ProcessCommitResponseCommand::ProcessSuccessfulCommitResponse(
451 const sync_pb::SyncEntity& committed_entry,
452 const CommitResponse_EntryResponse& entry_response,
453 const syncable::Id& pre_commit_id, syncable::MutableEntry* local_entry,
454 bool syncing_was_set, set<syncable::Id>* deleted_folders) {
455 DCHECK(local_entry->Get(IS_UNSYNCED));
456
457 // Update SERVER_VERSION and BASE_VERSION.
458 if (!UpdateVersionAfterCommit(committed_entry, entry_response, pre_commit_id,
459 local_entry)) {
460 LOG(ERROR) << "Bad version in commit return for " << *local_entry
461 << " new_id:" << entry_response.id() << " new_version:"
462 << entry_response.version();
463 return;
464 }
465
466 // If the server gave us a new ID, apply it.
467 if (!ChangeIdAfterCommit(entry_response, pre_commit_id, local_entry)) {
468 return;
469 }
470
471 // Update our stored copy of the server state.
472 UpdateServerFieldsAfterCommit(committed_entry, entry_response, local_entry);
473
474 // If the item doesn't need to be committed again (a situation that
475 // happens if it changed locally during the commit), we can remove
476 // it from the unsynced list. Also, we should change the locally-
477 // visible properties to apply any canonicalizations or fixups
478 // that the server introduced during the commit.
359 if (syncing_was_set) { 479 if (syncing_was_set) {
480 OverrideClientFieldsAfterCommit(committed_entry, entry_response,
481 local_entry);
360 local_entry->Put(IS_UNSYNCED, false); 482 local_entry->Put(IS_UNSYNCED, false);
361 } 483 }
484
485 // Make a note of any deleted folders, whose children would have
486 // been recursively deleted.
487 // TODO(nick): Here, commit_message.deleted() would be more correct than
488 // local_entry->Get(IS_DEL). For example, an item could be renamed, and then
489 // deleted during the commit of the rename. Unit test & fix.
362 if (local_entry->Get(IS_DIR) && local_entry->Get(IS_DEL)) { 490 if (local_entry->Get(IS_DIR) && local_entry->Get(IS_DEL)) {
363 deleted_folders->insert(local_entry->Get(ID)); 491 deleted_folders->insert(local_entry->Get(ID));
364 } 492 }
365 } 493 }
366 494
367 void ProcessCommitResponseCommand::PerformCommitTimeNameAside(
368 syncable::WriteTransaction* trans,
369 const CommitResponse_EntryResponse& server_entry,
370 syncable::MutableEntry* local_entry) {
371 string old_name = local_entry->Get(syncable::NON_UNIQUE_NAME);
372 const string server_name =
373 SyncerProtoUtil::NameFromCommitEntryResponse(server_entry);
374
375 if (!server_name.empty() && old_name != server_name) {
376 LOG(INFO) << "Server commit moved aside entry: " << old_name
377 << " to new name " << server_name;
378 // Should be safe since we're in a "commit lock."
379 local_entry->Put(syncable::NON_UNIQUE_NAME, server_name);
380 }
381 }
382
383 } // namespace browser_sync 495 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/process_commit_response_command.h ('k') | chrome/browser/sync/engine/syncer_proto_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698