| OLD | NEW |
| 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 "chrome/browser/sync/engine/syncer_util.h" | 5 #include "chrome/browser/sync/engine/syncer_util.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 syncable::ProcessUnsyncedChangesForEncryption(trans, | 304 syncable::ProcessUnsyncedChangesForEncryption(trans, |
| 305 cryptographer); | 305 cryptographer); |
| 306 } | 306 } |
| 307 } | 307 } |
| 308 | 308 |
| 309 // Only apply updates that we can decrypt. If we can't decrypt the update, it | 309 // Only apply updates that we can decrypt. If we can't decrypt the update, it |
| 310 // is likely because the passphrase has not arrived yet. Because the | 310 // is likely because the passphrase has not arrived yet. Because the |
| 311 // passphrase may not arrive within this GetUpdates, we can't just return | 311 // passphrase may not arrive within this GetUpdates, we can't just return |
| 312 // conflict, else we try to perform normal conflict resolution prematurely or | 312 // conflict, else we try to perform normal conflict resolution prematurely or |
| 313 // the syncer may get stuck. As such, we return CONFLICT_ENCRYPTION, which is | 313 // the syncer may get stuck. As such, we return CONFLICT_ENCRYPTION, which is |
| 314 // treated as a non-blocking conflict. See the description in syncer_types.h. | 314 // treated as an unresolvable conflict. See the description in syncer_types.h. |
| 315 // This prevents any unsynced changes from commiting and postpones conflict | 315 // This prevents any unsynced changes from commiting and postpones conflict |
| 316 // resolution until all data can be decrypted. | 316 // resolution until all data can be decrypted. |
| 317 if (specifics.has_encrypted() && | 317 if (specifics.has_encrypted() && |
| 318 !cryptographer->CanDecrypt(specifics.encrypted())) { | 318 !cryptographer->CanDecrypt(specifics.encrypted())) { |
| 319 // We can't decrypt this node yet. | 319 // We can't decrypt this node yet. |
| 320 DVLOG(1) << "Received an undecryptable " | 320 DVLOG(1) << "Received an undecryptable " |
| 321 << syncable::ModelTypeToString(entry->GetServerModelType()) | 321 << syncable::ModelTypeToString(entry->GetServerModelType()) |
| 322 << " update, returning encryption_conflict."; | 322 << " update, returning encryption_conflict."; |
| 323 return CONFLICT_ENCRYPTION; | 323 return CONFLICT_ENCRYPTION; |
| 324 } else if (specifics.HasExtension(sync_pb::password) && | 324 } else if (specifics.HasExtension(sync_pb::password) && |
| 325 entry->Get(UNIQUE_SERVER_TAG).empty()) { | 325 entry->Get(UNIQUE_SERVER_TAG).empty()) { |
| 326 // Passwords use their own legacy encryption scheme. | 326 // Passwords use their own legacy encryption scheme. |
| 327 const sync_pb::PasswordSpecifics& password = | 327 const sync_pb::PasswordSpecifics& password = |
| 328 specifics.GetExtension(sync_pb::password); | 328 specifics.GetExtension(sync_pb::password); |
| 329 if (!cryptographer->CanDecrypt(password.encrypted())) { | 329 if (!cryptographer->CanDecrypt(password.encrypted())) { |
| 330 DVLOG(1) << "Received an undecryptable password update, returning " | 330 DVLOG(1) << "Received an undecryptable password update, returning " |
| 331 << "encryption_conflict."; | 331 << "encryption_conflict."; |
| 332 return CONFLICT_ENCRYPTION; | 332 return CONFLICT_ENCRYPTION; |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 | 335 |
| 336 if (entry->Get(IS_UNSYNCED)) { | |
| 337 DVLOG(1) << "Skipping update, returning conflict for: " << id | |
| 338 << " ; it's unsynced."; | |
| 339 return CONFLICT; | |
| 340 } | |
| 341 if (!entry->Get(SERVER_IS_DEL)) { | 336 if (!entry->Get(SERVER_IS_DEL)) { |
| 342 syncable::Id new_parent = entry->Get(SERVER_PARENT_ID); | 337 syncable::Id new_parent = entry->Get(SERVER_PARENT_ID); |
| 343 Entry parent(trans, GET_BY_ID, new_parent); | 338 Entry parent(trans, GET_BY_ID, new_parent); |
| 344 // A note on non-directory parents: | 339 // A note on non-directory parents: |
| 345 // We catch most unfixable tree invariant errors at update receipt time, | 340 // We catch most unfixable tree invariant errors at update receipt time, |
| 346 // however we deal with this case here because we may receive the child | 341 // however we deal with this case here because we may receive the child |
| 347 // first then the illegal parent. Instead of dealing with it twice in | 342 // first then the illegal parent. Instead of dealing with it twice in |
| 348 // different ways we deal with it once here to reduce the amount of code and | 343 // different ways we deal with it once here to reduce the amount of code and |
| 349 // potential errors. | 344 // potential errors. |
| 350 if (!parent.good() || parent.Get(IS_DEL) || !parent.Get(IS_DIR)) { | 345 if (!parent.good() || parent.Get(IS_DEL) || !parent.Get(IS_DIR)) { |
| 351 return CONFLICT; | 346 return CONFLICT_HIERARCHY; |
| 352 } | 347 } |
| 353 if (entry->Get(PARENT_ID) != new_parent) { | 348 if (entry->Get(PARENT_ID) != new_parent) { |
| 354 if (!entry->Get(IS_DEL) && !IsLegalNewParent(trans, id, new_parent)) { | 349 if (!entry->Get(IS_DEL) && !IsLegalNewParent(trans, id, new_parent)) { |
| 355 DVLOG(1) << "Not updating item " << id | 350 DVLOG(1) << "Not updating item " << id |
| 356 << ", illegal new parent (would cause loop)."; | 351 << ", illegal new parent (would cause loop)."; |
| 357 return CONFLICT; | 352 return CONFLICT_HIERARCHY; |
| 358 } | 353 } |
| 359 } | 354 } |
| 360 } else if (entry->Get(IS_DIR)) { | 355 } else if (entry->Get(IS_DIR)) { |
| 361 Directory::ChildHandles handles; | 356 Directory::ChildHandles handles; |
| 362 trans->directory()->GetChildHandlesById(trans, id, &handles); | 357 trans->directory()->GetChildHandlesById(trans, id, &handles); |
| 363 if (!handles.empty()) { | 358 if (!handles.empty()) { |
| 364 // If we have still-existing children, then we need to deal with | 359 // If we have still-existing children, then we need to deal with |
| 365 // them before we can process this change. | 360 // them before we can process this change. |
| 366 DVLOG(1) << "Not deleting directory; it's not empty " << *entry; | 361 DVLOG(1) << "Not deleting directory; it's not empty " << *entry; |
| 367 return CONFLICT; | 362 return CONFLICT_HIERARCHY; |
| 368 } | 363 } |
| 369 } | 364 } |
| 370 | 365 |
| 366 if (entry->Get(IS_UNSYNCED)) { |
| 367 DVLOG(1) << "Skipping update, returning conflict for: " << id |
| 368 << " ; it's unsynced."; |
| 369 return CONFLICT_SIMPLE; |
| 370 } |
| 371 |
| 371 if (specifics.has_encrypted()) { | 372 if (specifics.has_encrypted()) { |
| 372 DVLOG(2) << "Received a decryptable " | 373 DVLOG(2) << "Received a decryptable " |
| 373 << syncable::ModelTypeToString(entry->GetServerModelType()) | 374 << syncable::ModelTypeToString(entry->GetServerModelType()) |
| 374 << " update, applying normally."; | 375 << " update, applying normally."; |
| 375 } else { | 376 } else { |
| 376 DVLOG(2) << "Received an unencrypted " | 377 DVLOG(2) << "Received an unencrypted " |
| 377 << syncable::ModelTypeToString(entry->GetServerModelType()) | 378 << syncable::ModelTypeToString(entry->GetServerModelType()) |
| 378 << " update, applying normally."; | 379 << " update, applying normally."; |
| 379 } | 380 } |
| 380 | 381 |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 if (update.version() < target->Get(SERVER_VERSION)) { | 772 if (update.version() < target->Get(SERVER_VERSION)) { |
| 772 LOG(WARNING) << "Update older than current server version for " | 773 LOG(WARNING) << "Update older than current server version for " |
| 773 << *target << " Update:" | 774 << *target << " Update:" |
| 774 << SyncerProtoUtil::SyncEntityDebugString(update); | 775 << SyncerProtoUtil::SyncEntityDebugString(update); |
| 775 return VERIFY_SUCCESS; // Expected in new sync protocol. | 776 return VERIFY_SUCCESS; // Expected in new sync protocol. |
| 776 } | 777 } |
| 777 return VERIFY_UNDECIDED; | 778 return VERIFY_UNDECIDED; |
| 778 } | 779 } |
| 779 | 780 |
| 780 } // namespace browser_sync | 781 } // namespace browser_sync |
| OLD | NEW |