Chromium Code Reviews| Index: sync/engine/syncer_util.cc |
| diff --git a/sync/engine/syncer_util.cc b/sync/engine/syncer_util.cc |
| index 7f63b37ddbdeeeb0a654b54a12ef6a597b67e34a..d97f34cc17039bcef680b6606ed185f905d95220 100644 |
| --- a/sync/engine/syncer_util.cc |
| +++ b/sync/engine/syncer_util.cc |
| @@ -184,7 +184,23 @@ syncable::Id FindLocalIdToUpdate( |
| return local_entry.GetId(); |
| } |
| + } else if (update.has_server_defined_unique_tag() && |
| + !update.server_defined_unique_tag().empty()) { |
| + // The client creates type root folders on demand with a local ID on |
|
Nicolas Zea
2015/01/26 23:21:53
nit: "on demand with a local id on demand"?
stanisc
2015/01/29 00:27:37
Done.
|
| + // demand when a progress marker for the given type is initially set. |
| + // The server might also attempt to send a type root folder for the same |
| + // type. It will does that during the transition period until support for |
|
Nicolas Zea
2015/01/26 23:21:53
nit: " will does"
stanisc
2015/01/29 00:27:37
Done.
|
| + // root folders is removed on the server for most types. After that the |
| + // server will still be creating type root folders for BOOKMARKS and |
| + // NIGORI types. |
| + syncable::Entry local_entry(trans, syncable::GET_BY_SERVER_TAG, |
| + update.server_defined_unique_tag()); |
| + if (local_entry.good() && !local_entry.GetId().ServerKnows()) { |
| + DCHECK(local_entry.GetId() != update_id); |
| + return local_entry.GetId(); |
| + } |
| } |
| + |
| // Fallback: target an entry having the server ID, creating one if needed. |
| return update_id; |
| } |
| @@ -227,16 +243,24 @@ UpdateAttemptResponse AttemptToUpdateEntry( |
| if (!entry->GetServerIsDel()) { |
| syncable::Id new_parent = entry->GetServerParentId(); |
| - Entry parent(trans, GET_BY_ID, new_parent); |
| - // A note on non-directory parents: |
| - // We catch most unfixable tree invariant errors at update receipt time, |
| - // however we deal with this case here because we may receive the child |
| - // first then the illegal parent. Instead of dealing with it twice in |
| - // different ways we deal with it once here to reduce the amount of code and |
| - // potential errors. |
| - if (!parent.good() || parent.GetIsDel() || !parent.GetIsDir()) { |
| - DVLOG(1) << "Entry has bad parent, returning conflict_hierarchy."; |
| - return CONFLICT_HIERARCHY; |
| + if (!new_parent.IsNull()) { |
| + // Perform this step only if the parent is specified. |
| + // The unset parent means that the implicit type root would be used. |
| + Entry parent(trans, GET_BY_ID, new_parent); |
| + // A note on non-directory parents: |
| + // We catch most unfixable tree invariant errors at update receipt time, |
| + // however we deal with this case here because we may receive the child |
| + // first then the illegal parent. Instead of dealing with it twice in |
| + // different ways we deal with it once here to reduce the amount of code |
| + // and |
| + // potential errors. |
|
Nicolas Zea
2015/01/26 23:21:53
nit: move to previous line
stanisc
2015/01/29 00:27:37
Done.
|
| + if (!parent.good() || parent.GetIsDel() || !parent.GetIsDir()) { |
| + DVLOG(1) << "Entry has bad parent, returning conflict_hierarchy."; |
| + return CONFLICT_HIERARCHY; |
| + } |
| + } else { |
| + DCHECK( |
| + !IsTypeWithServerGeneratedRoot(GetModelTypeFromSpecifics(specifics))); |
| } |
| if (entry->GetParentId() != new_parent) { |
| if (!entry->GetIsDel() && !IsLegalNewParent(trans, id, new_parent)) { |