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

Unified Diff: chrome/browser/sync/engine/conflict_resolver.cc

Issue 8917031: [Sync] Add nigori node conflict resolution. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Re-add some lines lost in the split Created 9 years 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/sync/engine/conflict_resolver.cc
diff --git a/chrome/browser/sync/engine/conflict_resolver.cc b/chrome/browser/sync/engine/conflict_resolver.cc
index e06d02d06ed4b4f153838f88c8f2d512ad29c884..91c3d46e3e3a40a657f96c9478de0a551cba4741 100644
--- a/chrome/browser/sync/engine/conflict_resolver.cc
+++ b/chrome/browser/sync/engine/conflict_resolver.cc
@@ -12,10 +12,12 @@
#include "base/metrics/histogram.h"
#include "chrome/browser/sync/engine/syncer.h"
#include "chrome/browser/sync/engine/syncer_util.h"
+#include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
#include "chrome/browser/sync/protocol/service_constants.h"
#include "chrome/browser/sync/sessions/status_controller.h"
#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/browser/sync/syncable/syncable.h"
+#include "chrome/browser/sync/util/cryptographer.h"
using std::map;
using std::set;
@@ -43,6 +45,7 @@ enum SimpleConflictResolutions {
UNDELETE, // Resolved by undeleting local item.
IGNORE_ENCRYPTION, // Resolved by ignoring an encryption-only server
// change. TODO(zea): implement and use this.
+ NIGORI_MERGE, // Resolved by merging nigori nodes.
CONFLICT_RESOLUTION_SIZE,
};
@@ -78,6 +81,7 @@ void ConflictResolver::OverwriteServerChanges(WriteTransaction* trans,
ConflictResolver::ProcessSimpleConflictResult
ConflictResolver::ProcessSimpleConflict(WriteTransaction* trans,
const Id& id,
+ const Cryptographer* cryptographer,
StatusController* status) {
MutableEntry entry(trans, syncable::GET_BY_ID, id);
// Must be good as the entry won't have been cleaned up.
@@ -124,7 +128,40 @@ ConflictResolver::ProcessSimpleConflict(WriteTransaction* trans,
entry.Get(syncable::SERVER_PARENT_ID);
bool entry_deleted = entry.Get(syncable::IS_DEL);
- if (!entry_deleted && name_matches && parent_matches) {
+ // We manually merge nigori data.
+ // TODO(zea): Find a better way of doing this. As it stands, we have to
tim (not reviewing) 2011/12/20 17:54:05 Maybe move this comment down to the set_sync_tabs
Nicolas Zea 2011/12/20 19:54:10 Done.
+ // update this code whenever we add a new non-cryptographer related field to
+ // the nigori node.
+ if (entry.GetModelType() == syncable::NIGORI) {
+ // Create a new set of specifics based on the server specifics (which
+ // preserves their encryption keys).
+ sync_pb::EntitySpecifics specifics =
+ entry.Get(syncable::SERVER_SPECIFICS);
+ sync_pb::NigoriSpecifics* nigori =
+ specifics.MutableExtension(sync_pb::nigori);
+ // Store the merged set of encrypted types (cryptographer->Update(..) will
+ // have merged the local types already).
+ cryptographer->UpdateNigoriFromEncryptedTypes(nigori);
+ // The local set of keys is already merged with the server's set within
+ // the cryptographer. If we don't have pending keys we can store the
+ // merged set back immediately. Else we preserve the server keys and will
+ // update the nigori when the user provides the pending passphrase via
+ // SetPassphrase(..).
+ if (cryptographer->is_ready()) {
+ cryptographer->GetKeys(nigori->mutable_encrypted());
+ }
+ if (entry.Get(syncable::SPECIFICS).GetExtension(sync_pb::nigori)
+ .sync_tabs()) {
+ nigori->set_sync_tabs(true);
+ }
+ entry.Put(syncable::SPECIFICS, specifics);
+ DVLOG(1) << "Resovling simple conflict, merging nigori nodes: " << entry;
+ status->increment_num_server_overwrites();
+ OverwriteServerChanges(trans, &entry);
+ UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict",
+ NIGORI_MERGE,
+ CONFLICT_RESOLUTION_SIZE);
+ } else if (!entry_deleted && name_matches && parent_matches) {
// TODO(zea): We may prefer to choose the local changes over the server
// if we know the local changes happened before (or vice versa).
// See http://crbug.com/76596
@@ -460,6 +497,7 @@ bool ConflictResolver::ResolveSimpleConflicts(
const ConflictProgress& progress,
sessions::StatusController* status) {
WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir);
+ Cryptographer* cryptographer = dir.manager()->GetCryptographer(&trans);
tim (not reviewing) 2011/12/20 17:54:05 Is manager() or the cryptographer really not avail
Nicolas Zea 2011/12/20 19:54:10 Neither the status controller nor the conflict pro
bool forward_progress = false;
// First iterate over simple conflict items (those that belong to no set).
set<Id>::const_iterator conflicting_item_it;
@@ -472,7 +510,7 @@ bool ConflictResolver::ResolveSimpleConflicts(
if (item_set_it == progress.IdToConflictSetEnd() ||
0 == item_set_it->second) {
// We have a simple conflict.
- switch (ProcessSimpleConflict(&trans, id, status)) {
+ switch (ProcessSimpleConflict(&trans, id, cryptographer, status)) {
case NO_SYNC_PROGRESS:
{
int conflict_count = (simple_conflict_count_map_[id] += 2);

Powered by Google App Engine
This is Rietveld 408576698