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); |