OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/directory_update_handler.h" | 5 #include "sync/engine/directory_update_handler.h" |
6 | 6 |
7 #include "sync/engine/conflict_resolver.h" | 7 #include "sync/engine/conflict_resolver.h" |
8 #include "sync/engine/process_updates_util.h" | 8 #include "sync/engine/process_updates_util.h" |
9 #include "sync/engine/update_applicator.h" | 9 #include "sync/engine/update_applicator.h" |
10 #include "sync/sessions/directory_type_debug_info_emitter.h" | 10 #include "sync/sessions/directory_type_debug_info_emitter.h" |
11 #include "sync/syncable/directory.h" | 11 #include "sync/syncable/directory.h" |
| 12 #include "sync/syncable/model_neutral_mutable_entry.h" |
12 #include "sync/syncable/syncable_model_neutral_write_transaction.h" | 13 #include "sync/syncable/syncable_model_neutral_write_transaction.h" |
13 #include "sync/syncable/syncable_write_transaction.h" | 14 #include "sync/syncable/syncable_write_transaction.h" |
14 | 15 |
15 namespace syncer { | 16 namespace syncer { |
16 | 17 |
17 using syncable::SYNCER; | 18 using syncable::SYNCER; |
18 | 19 |
19 DirectoryUpdateHandler::DirectoryUpdateHandler( | 20 DirectoryUpdateHandler::DirectoryUpdateHandler( |
20 syncable::Directory* dir, | 21 syncable::Directory* dir, |
21 ModelType type, | 22 ModelType type, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 // TODO(zea): trigger the datatype's UpdateDataTypeContext method. | 59 // TODO(zea): trigger the datatype's UpdateDataTypeContext method. |
59 } else if (mutated_context.version() < local_context.version()) { | 60 } else if (mutated_context.version() < local_context.version()) { |
60 // A GetUpdates using the old context was in progress when the context was | 61 // A GetUpdates using the old context was in progress when the context was |
61 // set. Fail this get updates cycle, to force a retry. | 62 // set. Fail this get updates cycle, to force a retry. |
62 DVLOG(1) << "GU Context conflict detected, forcing GU retry."; | 63 DVLOG(1) << "GU Context conflict detected, forcing GU retry."; |
63 debug_info_emitter_->EmitUpdateCountersUpdate(); | 64 debug_info_emitter_->EmitUpdateCountersUpdate(); |
64 return DATATYPE_TRIGGERED_RETRY; | 65 return DATATYPE_TRIGGERED_RETRY; |
65 } | 66 } |
66 } | 67 } |
67 | 68 |
| 69 // Auto-create permanent folder for the type if the progress marker |
| 70 // changes from empty to non-empty. |
| 71 if (!IsTypeWithServerGeneratedRoot(type_) && |
| 72 dir_->HasEmptyDownloadProgress(type_) && |
| 73 IsValidProgressMarker(progress_marker)) { |
| 74 CreateTypeRoot(&trans); |
| 75 } |
| 76 |
68 UpdateSyncEntities(&trans, applicable_updates, status); | 77 UpdateSyncEntities(&trans, applicable_updates, status); |
69 | 78 |
70 if (IsValidProgressMarker(progress_marker)) { | 79 if (IsValidProgressMarker(progress_marker)) { |
71 ExpireEntriesIfNeeded(&trans, progress_marker); | 80 ExpireEntriesIfNeeded(&trans, progress_marker); |
72 UpdateProgressMarker(progress_marker); | 81 UpdateProgressMarker(progress_marker); |
73 } | 82 } |
| 83 |
74 debug_info_emitter_->EmitUpdateCountersUpdate(); | 84 debug_info_emitter_->EmitUpdateCountersUpdate(); |
75 return SYNCER_OK; | 85 return SYNCER_OK; |
76 } | 86 } |
77 | 87 |
| 88 void DirectoryUpdateHandler::CreateTypeRoot( |
| 89 syncable::ModelNeutralWriteTransaction* trans) { |
| 90 syncable::ModelNeutralMutableEntry entry( |
| 91 trans, syncable::CREATE_NEW_TYPE_ROOT, type_); |
| 92 if (!entry.good()) { |
| 93 // This will fail only if matching entry already exists, for example |
| 94 // if the type gets disabled and its progress marker gets cleared, |
| 95 // then the type gets re-enabled again. |
| 96 DVLOG(1) << "Type root folder " << ModelTypeToRootTag(type_) |
| 97 << " already exists."; |
| 98 return; |
| 99 } |
| 100 |
| 101 entry.PutServerIsDir(true); |
| 102 entry.PutUniqueServerTag(ModelTypeToRootTag(type_)); |
| 103 } |
| 104 |
78 void DirectoryUpdateHandler::ApplyUpdates(sessions::StatusController* status) { | 105 void DirectoryUpdateHandler::ApplyUpdates(sessions::StatusController* status) { |
79 if (!IsApplyUpdatesRequired()) { | 106 if (!IsApplyUpdatesRequired()) { |
80 return; | 107 return; |
81 } | 108 } |
82 | 109 |
83 // This will invoke handlers that belong to the model and its thread, so we | 110 // This will invoke handlers that belong to the model and its thread, so we |
84 // switch to the appropriate thread before we start this work. | 111 // switch to the appropriate thread before we start this work. |
85 WorkCallback c = base::Bind( | 112 WorkCallback c = base::Bind( |
86 &DirectoryUpdateHandler::ApplyUpdatesImpl, | 113 &DirectoryUpdateHandler::ApplyUpdatesImpl, |
87 // We wait until the callback is executed. We can safely use Unretained. | 114 // We wait until the callback is executed. We can safely use Unretained. |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 const SyncEntityList& applicable_updates, | 225 const SyncEntityList& applicable_updates, |
199 sessions::StatusController* status) { | 226 sessions::StatusController* status) { |
200 UpdateCounters* counters = debug_info_emitter_->GetMutableUpdateCounters(); | 227 UpdateCounters* counters = debug_info_emitter_->GetMutableUpdateCounters(); |
201 counters->num_updates_received += applicable_updates.size(); | 228 counters->num_updates_received += applicable_updates.size(); |
202 ProcessDownloadedUpdates(dir_, trans, type_, | 229 ProcessDownloadedUpdates(dir_, trans, type_, |
203 applicable_updates, status, counters); | 230 applicable_updates, status, counters); |
204 } | 231 } |
205 | 232 |
206 bool DirectoryUpdateHandler::IsValidProgressMarker( | 233 bool DirectoryUpdateHandler::IsValidProgressMarker( |
207 const sync_pb::DataTypeProgressMarker& progress_marker) const { | 234 const sync_pb::DataTypeProgressMarker& progress_marker) const { |
| 235 if (progress_marker.token().empty()) { |
| 236 return false; |
| 237 } |
208 int field_number = progress_marker.data_type_id(); | 238 int field_number = progress_marker.data_type_id(); |
209 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number); | 239 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number); |
210 if (!IsRealDataType(model_type) || type_ != model_type) { | 240 if (!IsRealDataType(model_type) || type_ != model_type) { |
211 NOTREACHED() | 241 NOTREACHED() |
212 << "Update handler of type " << ModelTypeToString(type_) | 242 << "Update handler of type " << ModelTypeToString(type_) |
213 << " asked to process progress marker with invalid type " | 243 << " asked to process progress marker with invalid type " |
214 << field_number; | 244 << field_number; |
215 return false; | 245 return false; |
216 } | 246 } |
217 return true; | 247 return true; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 new_gc_directive.version_watermark())) { | 282 new_gc_directive.version_watermark())) { |
253 ExpireEntriesByVersion(dir_, trans, type_, | 283 ExpireEntriesByVersion(dir_, trans, type_, |
254 new_gc_directive.version_watermark()); | 284 new_gc_directive.version_watermark()); |
255 } | 285 } |
256 | 286 |
257 cached_gc_directive_.reset( | 287 cached_gc_directive_.reset( |
258 new sync_pb::GarbageCollectionDirective(new_gc_directive)); | 288 new sync_pb::GarbageCollectionDirective(new_gc_directive)); |
259 } | 289 } |
260 | 290 |
261 } // namespace syncer | 291 } // namespace syncer |
OLD | NEW |