OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |