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

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

Issue 93433006: sync: Introduce ModelTypeRegistry and helpers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Renames and moves Created 6 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/download.h" 5 #include "sync/engine/download.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "sync/engine/process_updates_util.h" 10 #include "sync/engine/process_updates_util.h"
tim (not reviewing) 2014/01/16 18:28:22 I don't think we need this here now.
rlarocque 2014/01/16 20:28:42 Removed.
11 #include "sync/engine/sync_directory_update_handler.h"
12 #include "sync/engine/syncer.h" 11 #include "sync/engine/syncer.h"
13 #include "sync/engine/syncer_proto_util.h" 12 #include "sync/engine/syncer_proto_util.h"
14 #include "sync/sessions/nudge_tracker.h" 13 #include "sync/sessions/nudge_tracker.h"
15 #include "sync/syncable/directory.h" 14 #include "sync/syncable/directory.h"
16 #include "sync/syncable/nigori_handler.h" 15 #include "sync/syncable/nigori_handler.h"
17 #include "sync/syncable/syncable_read_transaction.h" 16 #include "sync/syncable/syncable_read_transaction.h"
18 17
19 namespace syncer { 18 namespace syncer {
20 19
21 using sessions::StatusController; 20 using sessions::StatusController;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 get_updates->set_create_mobile_bookmarks_folder( 96 get_updates->set_create_mobile_bookmarks_folder(
98 create_mobile_bookmarks_folder); 97 create_mobile_bookmarks_folder);
99 bool need_encryption_key = ShouldRequestEncryptionKey(session->context()); 98 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
100 get_updates->set_need_encryption_key(need_encryption_key); 99 get_updates->set_need_encryption_key(need_encryption_key);
101 100
102 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. 101 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
103 get_updates->mutable_caller_info()->set_notifications_enabled( 102 get_updates->mutable_caller_info()->set_notifications_enabled(
104 session->context()->notifications_enabled()); 103 session->context()->notifications_enabled());
105 } 104 }
106 105
107 void InitDownloadUpdatesProgress(
108 ModelTypeSet proto_request_types,
109 UpdateHandlerMap* handler_map,
110 sync_pb::GetUpdatesMessage* get_updates) {
111 for (ModelTypeSet::Iterator it = proto_request_types.First();
112 it.Good(); it.Inc()) {
113 UpdateHandlerMap::iterator handler_it = handler_map->find(it.Get());
114 DCHECK(handler_it != handler_map->end());
115 sync_pb::DataTypeProgressMarker* progress_marker =
116 get_updates->add_from_progress_marker();
117 handler_it->second->GetDownloadProgress(progress_marker);
118 }
119 }
120
121 // Builds a map of ModelTypes to indices to progress markers in the given
122 // |gu_response| message. The map is returned in the |index_map| parameter.
123 void PartitionProgressMarkersByType(
124 const sync_pb::GetUpdatesResponse& gu_response,
125 ModelTypeSet request_types,
126 TypeToIndexMap* index_map) {
127 for (int i = 0; i < gu_response.new_progress_marker_size(); ++i) {
128 int field_number = gu_response.new_progress_marker(i).data_type_id();
129 ModelType model_type = GetModelTypeFromSpecificsFieldNumber(field_number);
130 if (!IsRealDataType(model_type)) {
131 DLOG(WARNING) << "Unknown field number " << field_number;
132 continue;
133 }
134 if (!request_types.Has(model_type)) {
135 DLOG(WARNING)
136 << "Skipping unexpected progress marker for non-enabled type "
137 << ModelTypeToString(model_type);
138 continue;
139 }
140 index_map->insert(std::make_pair(model_type, i));
141 }
142 }
143
144 // Examines the contents of the GetUpdates response message and forwards
145 // relevant data to the UpdateHandlers for processing and persisting.
146 bool ProcessUpdateResponseContents(
147 const sync_pb::GetUpdatesResponse& gu_response,
148 ModelTypeSet proto_request_types,
149 UpdateHandlerMap* handler_map,
150 StatusController* status) {
151 TypeSyncEntityMap updates_by_type;
152 PartitionUpdatesByType(gu_response, proto_request_types, &updates_by_type);
153 DCHECK_EQ(proto_request_types.Size(), updates_by_type.size());
154
155 TypeToIndexMap progress_index_by_type;
156 PartitionProgressMarkersByType(gu_response,
157 proto_request_types,
158 &progress_index_by_type);
159 if (proto_request_types.Size() != progress_index_by_type.size()) {
160 NOTREACHED() << "Missing progress markers in GetUpdates response.";
161 return false;
162 }
163
164 // Iterate over these maps in parallel, processing updates for each type.
165 TypeToIndexMap::iterator progress_marker_iter =
166 progress_index_by_type.begin();
167 TypeSyncEntityMap::iterator updates_iter = updates_by_type.begin();
168 for ( ; (progress_marker_iter != progress_index_by_type.end()
169 && updates_iter != updates_by_type.end());
170 ++progress_marker_iter, ++updates_iter) {
171 DCHECK_EQ(progress_marker_iter->first, updates_iter->first);
172 ModelType type = progress_marker_iter->first;
173
174 UpdateHandlerMap::iterator update_handler_iter = handler_map->find(type);
175
176 if (update_handler_iter != handler_map->end()) {
177 update_handler_iter->second->ProcessGetUpdatesResponse(
178 gu_response.new_progress_marker(progress_marker_iter->second),
179 updates_iter->second,
180 status);
181 } else {
182 DLOG(WARNING)
183 << "Ignoring received updates of a type we can't handle. "
184 << "Type is: " << ModelTypeToString(type);
185 continue;
186 }
187 }
188 DCHECK(progress_marker_iter == progress_index_by_type.end()
189 && updates_iter == updates_by_type.end());
190
191 return true;
192 }
193
194 } // namespace 106 } // namespace
195 107
196 void BuildNormalDownloadUpdates( 108 void BuildNormalDownloadUpdates(
197 SyncSession* session, 109 SyncSession* session,
110 GetUpdatesProcessor* get_updates_processor,
198 bool create_mobile_bookmarks_folder, 111 bool create_mobile_bookmarks_folder,
199 ModelTypeSet request_types, 112 ModelTypeSet request_types,
200 const sessions::NudgeTracker& nudge_tracker, 113 const sessions::NudgeTracker& nudge_tracker,
201 sync_pb::ClientToServerMessage* client_to_server_message) { 114 sync_pb::ClientToServerMessage* client_to_server_message) {
202 // Request updates for all requested types. 115 // Request updates for all requested types.
203 DVLOG(1) << "Getting updates for types " 116 DVLOG(1) << "Getting updates for types "
204 << ModelTypeSetToString(request_types); 117 << ModelTypeSetToString(request_types);
205 DCHECK(!request_types.Empty()); 118 DCHECK(!request_types.Empty());
206 119
207 InitDownloadUpdatesContext( 120 InitDownloadUpdatesContext(
208 session, 121 session,
209 create_mobile_bookmarks_folder, 122 create_mobile_bookmarks_folder,
210 client_to_server_message); 123 client_to_server_message);
211 124
212 BuildNormalDownloadUpdatesImpl( 125 BuildNormalDownloadUpdatesImpl(
213 Intersection(request_types, ProtocolTypes()), 126 Intersection(request_types, ProtocolTypes()),
214 session->context()->update_handler_map(), 127 get_updates_processor,
215 nudge_tracker, 128 nudge_tracker,
216 client_to_server_message->mutable_get_updates()); 129 client_to_server_message->mutable_get_updates());
217 } 130 }
218 131
219 void BuildNormalDownloadUpdatesImpl( 132 void BuildNormalDownloadUpdatesImpl(
220 ModelTypeSet proto_request_types, 133 ModelTypeSet proto_request_types,
221 UpdateHandlerMap* update_handler_map, 134 GetUpdatesProcessor* get_updates_processor,
222 const sessions::NudgeTracker& nudge_tracker, 135 const sessions::NudgeTracker& nudge_tracker,
223 sync_pb::GetUpdatesMessage* get_updates) { 136 sync_pb::GetUpdatesMessage* get_updates) {
224 DCHECK(!proto_request_types.Empty()); 137 DCHECK(!proto_request_types.Empty());
225 138
226 InitDownloadUpdatesProgress( 139 // Get progress markers and other data for requested types.
227 proto_request_types, 140 get_updates_processor->PrepareGetUpdates(proto_request_types, get_updates);
228 update_handler_map,
229 get_updates);
230 141
231 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. 142 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
232 get_updates->mutable_caller_info()->set_source( 143 get_updates->mutable_caller_info()->set_source(
233 nudge_tracker.updates_source()); 144 nudge_tracker.updates_source());
234 145
235 // Set the new and improved version of source, too. 146 // Set the new and improved version of source, too.
236 get_updates->set_get_updates_origin(sync_pb::SyncEnums::GU_TRIGGER); 147 get_updates->set_get_updates_origin(sync_pb::SyncEnums::GU_TRIGGER);
237 148
238 // Fill in the notification hints. 149 // Fill in the notification hints.
239 for (int i = 0; i < get_updates->from_progress_marker_size(); ++i) { 150 for (int i = 0; i < get_updates->from_progress_marker_size(); ++i) {
240 sync_pb::DataTypeProgressMarker* progress_marker = 151 sync_pb::DataTypeProgressMarker* progress_marker =
241 get_updates->mutable_from_progress_marker(i); 152 get_updates->mutable_from_progress_marker(i);
242 ModelType type = GetModelTypeFromSpecificsFieldNumber( 153 ModelType type = GetModelTypeFromSpecificsFieldNumber(
243 progress_marker->data_type_id()); 154 progress_marker->data_type_id());
244 155
245 DCHECK(!nudge_tracker.IsTypeThrottled(type)) 156 DCHECK(!nudge_tracker.IsTypeThrottled(type))
246 << "Throttled types should have been removed from the request_types."; 157 << "Throttled types should have been removed from the request_types.";
247 158
248 nudge_tracker.SetLegacyNotificationHint(type, progress_marker); 159 nudge_tracker.SetLegacyNotificationHint(type, progress_marker);
249 nudge_tracker.FillProtoMessage( 160 nudge_tracker.FillProtoMessage(
250 type, 161 type,
251 progress_marker->mutable_get_update_triggers()); 162 progress_marker->mutable_get_update_triggers());
252 } 163 }
253 } 164 }
254 165
255 void BuildDownloadUpdatesForConfigure( 166 void BuildDownloadUpdatesForConfigure(
256 SyncSession* session, 167 SyncSession* session,
168 GetUpdatesProcessor* get_updates_processor,
257 bool create_mobile_bookmarks_folder, 169 bool create_mobile_bookmarks_folder,
258 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, 170 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source,
259 ModelTypeSet request_types, 171 ModelTypeSet request_types,
260 sync_pb::ClientToServerMessage* client_to_server_message) { 172 sync_pb::ClientToServerMessage* client_to_server_message) {
261 // Request updates for all enabled types. 173 // Request updates for all enabled types.
262 DVLOG(1) << "Initial download for types " 174 DVLOG(1) << "Initial download for types "
263 << ModelTypeSetToString(request_types); 175 << ModelTypeSetToString(request_types);
264 176
265 InitDownloadUpdatesContext( 177 InitDownloadUpdatesContext(
266 session, 178 session,
267 create_mobile_bookmarks_folder, 179 create_mobile_bookmarks_folder,
268 client_to_server_message); 180 client_to_server_message);
269 BuildDownloadUpdatesForConfigureImpl( 181 BuildDownloadUpdatesForConfigureImpl(
270 Intersection(request_types, ProtocolTypes()), 182 Intersection(request_types, ProtocolTypes()),
271 session->context()->update_handler_map(), 183 get_updates_processor,
272 source, 184 source,
273 client_to_server_message->mutable_get_updates()); 185 client_to_server_message->mutable_get_updates());
274 } 186 }
275 187
276 void BuildDownloadUpdatesForConfigureImpl( 188 void BuildDownloadUpdatesForConfigureImpl(
277 ModelTypeSet proto_request_types, 189 ModelTypeSet proto_request_types,
278 UpdateHandlerMap* update_handler_map, 190 GetUpdatesProcessor* get_updates_processor,
279 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, 191 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source,
280 sync_pb::GetUpdatesMessage* get_updates) { 192 sync_pb::GetUpdatesMessage* get_updates) {
281 DCHECK(!proto_request_types.Empty()); 193 DCHECK(!proto_request_types.Empty());
282 194
283 InitDownloadUpdatesProgress( 195 // Get progress markers and other data for requested types.
284 proto_request_types, 196 get_updates_processor->PrepareGetUpdates(proto_request_types, get_updates);
285 update_handler_map,
286 get_updates);
287 197
288 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. 198 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
289 get_updates->mutable_caller_info()->set_source(source); 199 get_updates->mutable_caller_info()->set_source(source);
290 200
291 // Set the new and improved version of source, too. 201 // Set the new and improved version of source, too.
292 sync_pb::SyncEnums::GetUpdatesOrigin origin = 202 sync_pb::SyncEnums::GetUpdatesOrigin origin =
293 ConvertConfigureSourceToOrigin(source); 203 ConvertConfigureSourceToOrigin(source);
294 get_updates->set_get_updates_origin(origin); 204 get_updates->set_get_updates_origin(origin);
295 } 205 }
296 206
297 void BuildDownloadUpdatesForPoll( 207 void BuildDownloadUpdatesForPoll(
298 SyncSession* session, 208 SyncSession* session,
209 GetUpdatesProcessor* get_updates_processor,
299 bool create_mobile_bookmarks_folder, 210 bool create_mobile_bookmarks_folder,
300 ModelTypeSet request_types, 211 ModelTypeSet request_types,
301 sync_pb::ClientToServerMessage* client_to_server_message) { 212 sync_pb::ClientToServerMessage* client_to_server_message) {
302 DVLOG(1) << "Polling for types " 213 DVLOG(1) << "Polling for types "
303 << ModelTypeSetToString(request_types); 214 << ModelTypeSetToString(request_types);
304 215
305 InitDownloadUpdatesContext( 216 InitDownloadUpdatesContext(
306 session, 217 session,
307 create_mobile_bookmarks_folder, 218 create_mobile_bookmarks_folder,
308 client_to_server_message); 219 client_to_server_message);
309 BuildDownloadUpdatesForPollImpl( 220 BuildDownloadUpdatesForPollImpl(
310 Intersection(request_types, ProtocolTypes()), 221 Intersection(request_types, ProtocolTypes()),
311 session->context()->update_handler_map(), 222 get_updates_processor,
312 client_to_server_message->mutable_get_updates()); 223 client_to_server_message->mutable_get_updates());
313 } 224 }
314 225
315 void BuildDownloadUpdatesForPollImpl( 226 void BuildDownloadUpdatesForPollImpl(
316 ModelTypeSet proto_request_types, 227 ModelTypeSet proto_request_types,
317 UpdateHandlerMap* update_handler_map, 228 GetUpdatesProcessor* get_updates_processor,
318 sync_pb::GetUpdatesMessage* get_updates) { 229 sync_pb::GetUpdatesMessage* get_updates) {
319 DCHECK(!proto_request_types.Empty()); 230 DCHECK(!proto_request_types.Empty());
320 231
321 InitDownloadUpdatesProgress( 232 // Get progress markers and other data for requested types.
322 proto_request_types, 233 get_updates_processor->PrepareGetUpdates(proto_request_types, get_updates);
323 update_handler_map,
324 get_updates);
325 234
326 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. 235 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information.
327 get_updates->mutable_caller_info()->set_source( 236 get_updates->mutable_caller_info()->set_source(
328 sync_pb::GetUpdatesCallerInfo::PERIODIC); 237 sync_pb::GetUpdatesCallerInfo::PERIODIC);
329 238
330 // Set the new and improved version of source, too. 239 // Set the new and improved version of source, too.
331 get_updates->set_get_updates_origin(sync_pb::SyncEnums::PERIODIC); 240 get_updates->set_get_updates_origin(sync_pb::SyncEnums::PERIODIC);
332 } 241 }
333 242
334 SyncerError ExecuteDownloadUpdates( 243 SyncerError ExecuteDownloadUpdates(
335 ModelTypeSet request_types, 244 ModelTypeSet request_types,
336 SyncSession* session, 245 SyncSession* session,
246 GetUpdatesProcessor* get_updates_processor,
337 sync_pb::ClientToServerMessage* msg) { 247 sync_pb::ClientToServerMessage* msg) {
338 sync_pb::ClientToServerResponse update_response; 248 sync_pb::ClientToServerResponse update_response;
339 StatusController* status = session->mutable_status_controller(); 249 StatusController* status = session->mutable_status_controller();
340 bool need_encryption_key = ShouldRequestEncryptionKey(session->context()); 250 bool need_encryption_key = ShouldRequestEncryptionKey(session->context());
341 251
342 if (session->context()->debug_info_getter()) { 252 if (session->context()->debug_info_getter()) {
343 sync_pb::DebugInfo* debug_info = msg->mutable_debug_info(); 253 sync_pb::DebugInfo* debug_info = msg->mutable_debug_info();
344 CopyClientDebugInfo(session->context()->debug_info_getter(), debug_info); 254 CopyClientDebugInfo(session->context()->debug_info_getter(), debug_info);
345 } 255 }
346 256
(...skipping 27 matching lines...) Expand all
374 syncable::Directory* dir = session->context()->directory(); 284 syncable::Directory* dir = session->context()->directory();
375 status->set_last_get_key_result( 285 status->set_last_get_key_result(
376 HandleGetEncryptionKeyResponse(update_response, dir)); 286 HandleGetEncryptionKeyResponse(update_response, dir));
377 } 287 }
378 288
379 const ModelTypeSet proto_request_types = 289 const ModelTypeSet proto_request_types =
380 Intersection(request_types, ProtocolTypes()); 290 Intersection(request_types, ProtocolTypes());
381 291
382 return ProcessResponse(update_response.get_updates(), 292 return ProcessResponse(update_response.get_updates(),
383 proto_request_types, 293 proto_request_types,
384 session->context()->update_handler_map(), 294 get_updates_processor,
385 status); 295 status);
386 } 296 }
387 297
388 SyncerError ProcessResponse( 298 SyncerError ProcessResponse(
389 const sync_pb::GetUpdatesResponse& gu_response, 299 const sync_pb::GetUpdatesResponse& gu_response,
390 ModelTypeSet proto_request_types, 300 ModelTypeSet proto_request_types,
391 UpdateHandlerMap* handler_map, 301 GetUpdatesProcessor* get_updates_processor,
392 StatusController* status) { 302 StatusController* status) {
393 status->increment_num_updates_downloaded_by(gu_response.entries_size()); 303 status->increment_num_updates_downloaded_by(gu_response.entries_size());
394 304
395 // The changes remaining field is used to prevent the client from looping. If 305 // The changes remaining field is used to prevent the client from looping. If
396 // that field is being set incorrectly, we're in big trouble. 306 // that field is being set incorrectly, we're in big trouble.
397 if (!gu_response.has_changes_remaining()) { 307 if (!gu_response.has_changes_remaining()) {
398 return SERVER_RESPONSE_VALIDATION_FAILED; 308 return SERVER_RESPONSE_VALIDATION_FAILED;
399 } 309 }
400 status->set_num_server_changes_remaining(gu_response.changes_remaining()); 310 status->set_num_server_changes_remaining(gu_response.changes_remaining());
401 311
402 312
403 if (!ProcessUpdateResponseContents(gu_response, 313 if (!get_updates_processor->ProcessGetUpdatesResponse(proto_request_types,
404 proto_request_types, 314 gu_response,
405 handler_map, 315 status)) {
406 status)) {
407 return SERVER_RESPONSE_VALIDATION_FAILED; 316 return SERVER_RESPONSE_VALIDATION_FAILED;
408 } 317 }
409 318
410 if (gu_response.changes_remaining() == 0) { 319 if (gu_response.changes_remaining() == 0) {
411 return SYNCER_OK; 320 return SYNCER_OK;
412 } else { 321 } else {
413 return SERVER_MORE_TO_DOWNLOAD; 322 return SERVER_MORE_TO_DOWNLOAD;
414 } 323 }
415 } 324 }
416 325
417 void CopyClientDebugInfo( 326 void CopyClientDebugInfo(
418 sessions::DebugInfoGetter* debug_info_getter, 327 sessions::DebugInfoGetter* debug_info_getter,
419 sync_pb::DebugInfo* debug_info) { 328 sync_pb::DebugInfo* debug_info) {
420 DVLOG(1) << "Copying client debug info to send."; 329 DVLOG(1) << "Copying client debug info to send.";
421 debug_info_getter->GetDebugInfo(debug_info); 330 debug_info_getter->GetDebugInfo(debug_info);
422 } 331 }
423 332
424 } // namespace download 333 } // namespace download
425 334
426 } // namespace syncer 335 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698