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

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: Rebase + pass trans/cryptographer directly through 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 ff0127a6dc4dcb3fa18c6f08b03edcd91a80defb..e37ac36e2b0ae21e5719e15a8a71d4d106ce9297 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.
+ 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());
+ }
+ // TODO(zea): Find a better way of doing this. As it stands, we have to
+ // update this code whenever we add a new non-cryptographer related field
+ // to the nigori node.
+ 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
@@ -193,10 +230,10 @@ ConflictResolver::ProcessSimpleConflict(WriteTransaction* trans,
}
bool ConflictResolver::ResolveSimpleConflicts(
- const ScopedDirLookup& dir,
+ syncable::WriteTransaction* trans,
+ const Cryptographer* cryptographer,
const ConflictProgress& progress,
sessions::StatusController* status) {
- WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir);
bool forward_progress = false;
// First iterate over simple conflict items (those that belong to no set).
set<Id>::const_iterator conflicting_item_it;
@@ -209,7 +246,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:
break;
case SYNC_PROGRESS:
@@ -221,7 +258,8 @@ bool ConflictResolver::ResolveSimpleConflicts(
return forward_progress;
}
-bool ConflictResolver::ResolveConflicts(const ScopedDirLookup& dir,
+bool ConflictResolver::ResolveConflicts(syncable::WriteTransaction* trans,
+ const Cryptographer* cryptographer,
const ConflictProgress& progress,
sessions::StatusController* status) {
// TODO(rlarocque): A good amount of code related to the resolution of
@@ -238,7 +276,7 @@ bool ConflictResolver::ResolveConflicts(const ScopedDirLookup& dir,
<< " unprocessed conflict sets.";
}
- return ResolveSimpleConflicts(dir, progress, status);
+ return ResolveSimpleConflicts(trans, cryptographer, progress, status);
}
} // namespace browser_sync
« no previous file with comments | « chrome/browser/sync/engine/conflict_resolver.h ('k') | chrome/browser/sync/engine/resolve_conflicts_command.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698