Chromium Code Reviews| 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" |
| 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, |
| 198 bool create_mobile_bookmarks_folder, | 110 bool create_mobile_bookmarks_folder, |
| 199 ModelTypeSet request_types, | 111 ModelTypeSet request_types, |
| 200 const sessions::NudgeTracker& nudge_tracker, | 112 const sessions::NudgeTracker& nudge_tracker, |
| 201 sync_pb::ClientToServerMessage* client_to_server_message) { | 113 sync_pb::ClientToServerMessage* client_to_server_message) { |
| 202 // Request updates for all requested types. | 114 // Request updates for all requested types. |
| 203 DVLOG(1) << "Getting updates for types " | 115 DVLOG(1) << "Getting updates for types " |
| 204 << ModelTypeSetToString(request_types); | 116 << ModelTypeSetToString(request_types); |
| 205 DCHECK(!request_types.Empty()); | 117 DCHECK(!request_types.Empty()); |
| 206 | 118 |
| 207 InitDownloadUpdatesContext( | 119 InitDownloadUpdatesContext( |
| 208 session, | 120 session, |
| 209 create_mobile_bookmarks_folder, | 121 create_mobile_bookmarks_folder, |
| 210 client_to_server_message); | 122 client_to_server_message); |
| 211 | 123 |
| 212 BuildNormalDownloadUpdatesImpl( | 124 BuildNormalDownloadUpdatesImpl( |
| 213 Intersection(request_types, ProtocolTypes()), | 125 Intersection(request_types, ProtocolTypes()), |
| 214 session->context()->update_handler_map(), | 126 session->context()->updater_list(), |
| 215 nudge_tracker, | 127 nudge_tracker, |
| 216 client_to_server_message->mutable_get_updates()); | 128 client_to_server_message->mutable_get_updates()); |
| 217 } | 129 } |
| 218 | 130 |
| 219 void BuildNormalDownloadUpdatesImpl( | 131 void BuildNormalDownloadUpdatesImpl( |
| 220 ModelTypeSet proto_request_types, | 132 ModelTypeSet proto_request_types, |
| 221 UpdateHandlerMap* update_handler_map, | 133 UpdaterList* updater_list, |
| 222 const sessions::NudgeTracker& nudge_tracker, | 134 const sessions::NudgeTracker& nudge_tracker, |
| 223 sync_pb::GetUpdatesMessage* get_updates) { | 135 sync_pb::GetUpdatesMessage* get_updates) { |
| 224 DCHECK(!proto_request_types.Empty()); | 136 DCHECK(!proto_request_types.Empty()); |
| 225 | 137 |
| 226 InitDownloadUpdatesProgress( | 138 // Get progress markers and other data for requested types. |
| 227 proto_request_types, | 139 updater_list->PrepareGetUpdates(proto_request_types, get_updates); |
|
Nicolas Zea
2013/12/18 22:36:10
remind me why this is named proto_request_types, a
rlarocque
2014/01/03 01:46:41
"request": Because not all enabled types are asked
| |
| 228 update_handler_map, | |
| 229 get_updates); | |
| 230 | 140 |
| 231 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. | 141 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. |
| 232 get_updates->mutable_caller_info()->set_source( | 142 get_updates->mutable_caller_info()->set_source( |
| 233 nudge_tracker.updates_source()); | 143 nudge_tracker.updates_source()); |
| 234 | 144 |
| 235 // Set the new and improved version of source, too. | 145 // Set the new and improved version of source, too. |
| 236 get_updates->set_get_updates_origin(sync_pb::SyncEnums::GU_TRIGGER); | 146 get_updates->set_get_updates_origin(sync_pb::SyncEnums::GU_TRIGGER); |
| 237 | 147 |
| 238 // Fill in the notification hints. | 148 // Fill in the notification hints. |
| 239 for (int i = 0; i < get_updates->from_progress_marker_size(); ++i) { | 149 for (int i = 0; i < get_updates->from_progress_marker_size(); ++i) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 261 // Request updates for all enabled types. | 171 // Request updates for all enabled types. |
| 262 DVLOG(1) << "Initial download for types " | 172 DVLOG(1) << "Initial download for types " |
| 263 << ModelTypeSetToString(request_types); | 173 << ModelTypeSetToString(request_types); |
| 264 | 174 |
| 265 InitDownloadUpdatesContext( | 175 InitDownloadUpdatesContext( |
| 266 session, | 176 session, |
| 267 create_mobile_bookmarks_folder, | 177 create_mobile_bookmarks_folder, |
| 268 client_to_server_message); | 178 client_to_server_message); |
| 269 BuildDownloadUpdatesForConfigureImpl( | 179 BuildDownloadUpdatesForConfigureImpl( |
| 270 Intersection(request_types, ProtocolTypes()), | 180 Intersection(request_types, ProtocolTypes()), |
| 271 session->context()->update_handler_map(), | 181 session->context()->updater_list(), |
| 272 source, | 182 source, |
| 273 client_to_server_message->mutable_get_updates()); | 183 client_to_server_message->mutable_get_updates()); |
| 274 } | 184 } |
| 275 | 185 |
| 276 void BuildDownloadUpdatesForConfigureImpl( | 186 void BuildDownloadUpdatesForConfigureImpl( |
| 277 ModelTypeSet proto_request_types, | 187 ModelTypeSet proto_request_types, |
| 278 UpdateHandlerMap* update_handler_map, | 188 UpdaterList* updater_list, |
| 279 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, | 189 sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, |
| 280 sync_pb::GetUpdatesMessage* get_updates) { | 190 sync_pb::GetUpdatesMessage* get_updates) { |
| 281 DCHECK(!proto_request_types.Empty()); | 191 DCHECK(!proto_request_types.Empty()); |
| 282 | 192 |
| 283 InitDownloadUpdatesProgress( | 193 // Get progress markers and other data for requested types. |
| 284 proto_request_types, | 194 updater_list->PrepareGetUpdates(proto_request_types, get_updates); |
| 285 update_handler_map, | |
| 286 get_updates); | |
| 287 | 195 |
| 288 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. | 196 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. |
| 289 get_updates->mutable_caller_info()->set_source(source); | 197 get_updates->mutable_caller_info()->set_source(source); |
| 290 | 198 |
| 291 // Set the new and improved version of source, too. | 199 // Set the new and improved version of source, too. |
| 292 sync_pb::SyncEnums::GetUpdatesOrigin origin = | 200 sync_pb::SyncEnums::GetUpdatesOrigin origin = |
| 293 ConvertConfigureSourceToOrigin(source); | 201 ConvertConfigureSourceToOrigin(source); |
| 294 get_updates->set_get_updates_origin(origin); | 202 get_updates->set_get_updates_origin(origin); |
| 295 } | 203 } |
| 296 | 204 |
| 297 void BuildDownloadUpdatesForPoll( | 205 void BuildDownloadUpdatesForPoll( |
| 298 SyncSession* session, | 206 SyncSession* session, |
| 299 bool create_mobile_bookmarks_folder, | 207 bool create_mobile_bookmarks_folder, |
| 300 ModelTypeSet request_types, | 208 ModelTypeSet request_types, |
| 301 sync_pb::ClientToServerMessage* client_to_server_message) { | 209 sync_pb::ClientToServerMessage* client_to_server_message) { |
| 302 DVLOG(1) << "Polling for types " | 210 DVLOG(1) << "Polling for types " |
| 303 << ModelTypeSetToString(request_types); | 211 << ModelTypeSetToString(request_types); |
| 304 | 212 |
| 305 InitDownloadUpdatesContext( | 213 InitDownloadUpdatesContext( |
| 306 session, | 214 session, |
| 307 create_mobile_bookmarks_folder, | 215 create_mobile_bookmarks_folder, |
| 308 client_to_server_message); | 216 client_to_server_message); |
| 309 BuildDownloadUpdatesForPollImpl( | 217 BuildDownloadUpdatesForPollImpl( |
| 310 Intersection(request_types, ProtocolTypes()), | 218 Intersection(request_types, ProtocolTypes()), |
| 311 session->context()->update_handler_map(), | 219 session->context()->updater_list(), |
| 312 client_to_server_message->mutable_get_updates()); | 220 client_to_server_message->mutable_get_updates()); |
| 313 } | 221 } |
| 314 | 222 |
| 315 void BuildDownloadUpdatesForPollImpl( | 223 void BuildDownloadUpdatesForPollImpl( |
| 316 ModelTypeSet proto_request_types, | 224 ModelTypeSet proto_request_types, |
| 317 UpdateHandlerMap* update_handler_map, | 225 UpdaterList* updater_list, |
| 318 sync_pb::GetUpdatesMessage* get_updates) { | 226 sync_pb::GetUpdatesMessage* get_updates) { |
| 319 DCHECK(!proto_request_types.Empty()); | 227 DCHECK(!proto_request_types.Empty()); |
| 320 | 228 |
| 321 InitDownloadUpdatesProgress( | 229 // Get progress markers and other data for requested types. |
| 322 proto_request_types, | 230 updater_list->PrepareGetUpdates(proto_request_types, get_updates); |
| 323 update_handler_map, | |
| 324 get_updates); | |
| 325 | 231 |
| 326 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. | 232 // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. |
| 327 get_updates->mutable_caller_info()->set_source( | 233 get_updates->mutable_caller_info()->set_source( |
| 328 sync_pb::GetUpdatesCallerInfo::PERIODIC); | 234 sync_pb::GetUpdatesCallerInfo::PERIODIC); |
| 329 | 235 |
| 330 // Set the new and improved version of source, too. | 236 // Set the new and improved version of source, too. |
| 331 get_updates->set_get_updates_origin(sync_pb::SyncEnums::PERIODIC); | 237 get_updates->set_get_updates_origin(sync_pb::SyncEnums::PERIODIC); |
| 332 } | 238 } |
| 333 | 239 |
| 334 SyncerError ExecuteDownloadUpdates( | 240 SyncerError ExecuteDownloadUpdates( |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 syncable::Directory* dir = session->context()->directory(); | 280 syncable::Directory* dir = session->context()->directory(); |
| 375 status->set_last_get_key_result( | 281 status->set_last_get_key_result( |
| 376 HandleGetEncryptionKeyResponse(update_response, dir)); | 282 HandleGetEncryptionKeyResponse(update_response, dir)); |
| 377 } | 283 } |
| 378 | 284 |
| 379 const ModelTypeSet proto_request_types = | 285 const ModelTypeSet proto_request_types = |
| 380 Intersection(request_types, ProtocolTypes()); | 286 Intersection(request_types, ProtocolTypes()); |
| 381 | 287 |
| 382 return ProcessResponse(update_response.get_updates(), | 288 return ProcessResponse(update_response.get_updates(), |
| 383 proto_request_types, | 289 proto_request_types, |
| 384 session->context()->update_handler_map(), | 290 session->context()->updater_list(), |
| 385 status); | 291 status); |
| 386 } | 292 } |
| 387 | 293 |
| 388 SyncerError ProcessResponse( | 294 SyncerError ProcessResponse( |
| 389 const sync_pb::GetUpdatesResponse& gu_response, | 295 const sync_pb::GetUpdatesResponse& gu_response, |
| 390 ModelTypeSet proto_request_types, | 296 ModelTypeSet proto_request_types, |
| 391 UpdateHandlerMap* handler_map, | 297 UpdaterList* updater_list, |
| 392 StatusController* status) { | 298 StatusController* status) { |
| 393 status->increment_num_updates_downloaded_by(gu_response.entries_size()); | 299 status->increment_num_updates_downloaded_by(gu_response.entries_size()); |
| 394 | 300 |
| 395 // The changes remaining field is used to prevent the client from looping. If | 301 // 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. | 302 // that field is being set incorrectly, we're in big trouble. |
| 397 if (!gu_response.has_changes_remaining()) { | 303 if (!gu_response.has_changes_remaining()) { |
| 398 return SERVER_RESPONSE_VALIDATION_FAILED; | 304 return SERVER_RESPONSE_VALIDATION_FAILED; |
| 399 } | 305 } |
| 400 status->set_num_server_changes_remaining(gu_response.changes_remaining()); | 306 status->set_num_server_changes_remaining(gu_response.changes_remaining()); |
| 401 | 307 |
| 402 | 308 |
| 403 if (!ProcessUpdateResponseContents(gu_response, | 309 if (!updater_list->ProcessGetUpdatesResponse(proto_request_types, |
| 404 proto_request_types, | 310 gu_response, |
| 405 handler_map, | 311 status)) { |
| 406 status)) { | |
| 407 return SERVER_RESPONSE_VALIDATION_FAILED; | 312 return SERVER_RESPONSE_VALIDATION_FAILED; |
| 408 } | 313 } |
| 409 | 314 |
| 410 if (gu_response.changes_remaining() == 0) { | 315 if (gu_response.changes_remaining() == 0) { |
| 411 return SYNCER_OK; | 316 return SYNCER_OK; |
| 412 } else { | 317 } else { |
| 413 return SERVER_MORE_TO_DOWNLOAD; | 318 return SERVER_MORE_TO_DOWNLOAD; |
| 414 } | 319 } |
| 415 } | 320 } |
| 416 | 321 |
| 417 void CopyClientDebugInfo( | 322 void CopyClientDebugInfo( |
| 418 sessions::DebugInfoGetter* debug_info_getter, | 323 sessions::DebugInfoGetter* debug_info_getter, |
| 419 sync_pb::DebugInfo* debug_info) { | 324 sync_pb::DebugInfo* debug_info) { |
| 420 DVLOG(1) << "Copying client debug info to send."; | 325 DVLOG(1) << "Copying client debug info to send."; |
| 421 debug_info_getter->GetDebugInfo(debug_info); | 326 debug_info_getter->GetDebugInfo(debug_info); |
| 422 } | 327 } |
| 423 | 328 |
| 424 } // namespace download | 329 } // namespace download |
| 425 | 330 |
| 426 } // namespace syncer | 331 } // namespace syncer |
| OLD | NEW |