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

Side by Side Diff: sync/engine/conflict_resolver.cc

Issue 1664643003: Change sync conflict resolution for extensions (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moved entry type check lower down in ProcessSimpleConflict Created 4 years, 10 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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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 "sync/engine/conflict_resolver.h" 5 #include "sync/engine/conflict_resolver.h"
6 6
7 #include <list> 7 #include <list>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 10
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // d) If the server_specifics match specifics, server_specifics are 109 // d) If the server_specifics match specifics, server_specifics are
110 // encrypted with the default key, and all other visible properties match, 110 // encrypted with the default key, and all other visible properties match,
111 // then we can safely ignore the local changes as redundant. 111 // then we can safely ignore the local changes as redundant.
112 // e) Otherwise if the base_server_specifics match the server_specifics, no 112 // e) Otherwise if the base_server_specifics match the server_specifics, no
113 // functional change must have been made server-side (else 113 // functional change must have been made server-side (else
114 // base_server_specifics would have been cleared), and we can therefore 114 // base_server_specifics would have been cleared), and we can therefore
115 // safely ignore the server changes as redundant. 115 // safely ignore the server changes as redundant.
116 // f) Otherwise, it's in general safer to ignore local changes, with the 116 // f) Otherwise, it's in general safer to ignore local changes, with the
117 // exception of deletion conflicts (choose to undelete) and conflicts 117 // exception of deletion conflicts (choose to undelete) and conflicts
118 // where the non_unique_name or parent don't match. 118 // where the non_unique_name or parent don't match.
119 // e) Except for the case of extensions and apps, where we want uninstalls to
120 // win over local modifications to avoid "back from the dead" reinstalls.
119 if (!entry.GetServerIsDel()) { 121 if (!entry.GetServerIsDel()) {
120 // TODO(nick): The current logic is arbitrary; instead, it ought to be made 122 // TODO(nick): The current logic is arbitrary; instead, it ought to be made
121 // consistent with the ModelAssociator behavior for a datatype. It would 123 // consistent with the ModelAssociator behavior for a datatype. It would
122 // be nice if we could route this back to ModelAssociator code to pick one 124 // be nice if we could route this back to ModelAssociator code to pick one
123 // of three options: CLIENT, SERVER, or MERGE. Some datatypes (autofill) 125 // of three options: CLIENT, SERVER, or MERGE. Some datatypes (autofill)
124 // are easily mergeable. 126 // are easily mergeable.
125 // See http://crbug.com/77339. 127 // See http://crbug.com/77339.
126 bool name_matches = entry.GetNonUniqueName() == 128 bool name_matches = entry.GetNonUniqueName() ==
127 entry.GetServerNonUniqueName(); 129 entry.GetServerNonUniqueName();
128 // The parent is implicit type root folder or the parent ID matches. 130 // The parent is implicit type root folder or the parent ID matches.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 status->increment_num_local_overwrites(); 223 status->increment_num_local_overwrites();
222 counters->num_local_overwrites++; 224 counters->num_local_overwrites++;
223 UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict", 225 UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict",
224 OVERWRITE_LOCAL, 226 OVERWRITE_LOCAL,
225 CONFLICT_RESOLUTION_SIZE); 227 CONFLICT_RESOLUTION_SIZE);
226 } 228 }
227 // Now that we've resolved the conflict, clear the prev server 229 // Now that we've resolved the conflict, clear the prev server
228 // specifics. 230 // specifics.
229 entry.PutBaseServerSpecifics(sync_pb::EntitySpecifics()); 231 entry.PutBaseServerSpecifics(sync_pb::EntitySpecifics());
230 } else { // SERVER_IS_DEL is true 232 } else { // SERVER_IS_DEL is true
231 if (entry.GetIsDir()) { 233 ModelType type = entry.GetModelType();
232 Directory::Metahandles children; 234 if (type == EXTENSIONS || type == APPS) {
233 trans->directory()->GetChildHandlesById(trans, 235 // Ignore local changes for extensions/apps when server had a delete, to
234 entry.GetId(), 236 // avoid unwanted reinstall of an uninstalled extension.
235 &children); 237 DVLOG(1) << "Resolving simple conflict, ignoring local changes for "
236 // If a server deleted folder has local contents it should be a hierarchy 238 << "extension/app: " << entry;
237 // conflict. Hierarchy conflicts should not be processed by this 239 conflict_util::IgnoreLocalChanges(&entry);
238 // function. 240 status->increment_num_local_overwrites();
239 DCHECK(children.empty()); 241 counters->num_local_overwrites++;
242 UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict",
243 OVERWRITE_LOCAL,
244 CONFLICT_RESOLUTION_SIZE);
245 } else {
246 if (entry.GetIsDir()) {
247 Directory::Metahandles children;
248 trans->directory()->GetChildHandlesById(trans,
249 entry.GetId(),
250 &children);
251 // If a server deleted folder has local contents it should be a
252 // hierarchy conflict. Hierarchy conflicts should not be processed by
253 // this function.
254 DCHECK(children.empty());
255 }
256
257 // The entry is deleted on the server but still exists locally.
258 // We undelete it by overwriting the server's tombstone with the local
259 // data.
260 conflict_util::OverwriteServerChanges(&entry);
261 status->increment_num_server_overwrites();
262 counters->num_server_overwrites++;
263 DVLOG(1) << "Resolving simple conflict, undeleting server entry: "
264 << entry;
265 UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict",
266 UNDELETE,
267 CONFLICT_RESOLUTION_SIZE);
240 } 268 }
241
242 // The entry is deleted on the server but still exists locally.
243 // We undelete it by overwriting the server's tombstone with the local
244 // data.
245 conflict_util::OverwriteServerChanges(&entry);
246 status->increment_num_server_overwrites();
247 counters->num_server_overwrites++;
248 DVLOG(1) << "Resolving simple conflict, undeleting server entry: "
249 << entry;
250 UMA_HISTOGRAM_ENUMERATION("Sync.ResolveSimpleConflict",
251 UNDELETE,
252 CONFLICT_RESOLUTION_SIZE);
253 } 269 }
254 } 270 }
255 271
256 void ConflictResolver::ResolveConflicts( 272 void ConflictResolver::ResolveConflicts(
257 syncable::WriteTransaction* trans, 273 syncable::WriteTransaction* trans,
258 const Cryptographer* cryptographer, 274 const Cryptographer* cryptographer,
259 const std::set<syncable::Id>& simple_conflict_ids, 275 const std::set<syncable::Id>& simple_conflict_ids,
260 sessions::StatusController* status, 276 sessions::StatusController* status,
261 UpdateCounters* counters) { 277 UpdateCounters* counters) {
262 // Iterate over simple conflict items. 278 // Iterate over simple conflict items.
263 set<Id>::const_iterator it; 279 set<Id>::const_iterator it;
264 for (it = simple_conflict_ids.begin(); 280 for (it = simple_conflict_ids.begin();
265 it != simple_conflict_ids.end(); 281 it != simple_conflict_ids.end();
266 ++it) { 282 ++it) {
267 // We don't resolve conflicts for control types here. 283 // We don't resolve conflicts for control types here.
268 Entry conflicting_node(trans, syncable::GET_BY_ID, *it); 284 Entry conflicting_node(trans, syncable::GET_BY_ID, *it);
269 CHECK(conflicting_node.good()); 285 CHECK(conflicting_node.good());
270 if (IsControlType( 286 if (IsControlType(
271 GetModelTypeFromSpecifics(conflicting_node.GetSpecifics()))) { 287 GetModelTypeFromSpecifics(conflicting_node.GetSpecifics()))) {
272 continue; 288 continue;
273 } 289 }
274 290
275 ProcessSimpleConflict(trans, *it, cryptographer, status, counters); 291 ProcessSimpleConflict(trans, *it, cryptographer, status, counters);
276 } 292 }
277 return; 293 return;
278 } 294 }
279 295
280 } // namespace syncer 296 } // namespace syncer
OLDNEW
« no previous file with comments | « chrome/browser/sync/test/integration/single_client_extensions_sync_test.cc ('k') | sync/engine/syncer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698