| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "components/sync/engine_impl/syncer_proto_util.h" | 5 #include "components/sync/engine_impl/syncer_proto_util.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 11 #include "components/sync/base/model_type.h" | 11 #include "components/sync/base/model_type.h" |
| 12 #include "components/sync/base/time.h" | 12 #include "components/sync/base/time.h" |
| 13 #include "components/sync/engine_impl/cycle/sync_cycle.h" |
| 13 #include "components/sync/engine_impl/net/server_connection_manager.h" | 14 #include "components/sync/engine_impl/net/server_connection_manager.h" |
| 14 #include "components/sync/engine_impl/syncer.h" | 15 #include "components/sync/engine_impl/syncer.h" |
| 15 #include "components/sync/engine_impl/syncer_types.h" | 16 #include "components/sync/engine_impl/syncer_types.h" |
| 16 #include "components/sync/engine_impl/traffic_logger.h" | 17 #include "components/sync/engine_impl/traffic_logger.h" |
| 17 #include "components/sync/protocol/sync_enums.pb.h" | 18 #include "components/sync/protocol/sync_enums.pb.h" |
| 18 #include "components/sync/protocol/sync_protocol_error.h" | 19 #include "components/sync/protocol/sync_protocol_error.h" |
| 19 #include "components/sync/sessions_impl/sync_session.h" | |
| 20 #include "components/sync/syncable/directory.h" | 20 #include "components/sync/syncable/directory.h" |
| 21 #include "components/sync/syncable/entry.h" | 21 #include "components/sync/syncable/entry.h" |
| 22 #include "components/sync/syncable/syncable-inl.h" | 22 #include "components/sync/syncable/syncable-inl.h" |
| 23 #include "components/sync/syncable/syncable_proto_util.h" | 23 #include "components/sync/syncable/syncable_proto_util.h" |
| 24 #include "google_apis/google_api_keys.h" | 24 #include "google_apis/google_api_keys.h" |
| 25 | 25 |
| 26 using std::string; | 26 using std::string; |
| 27 using std::stringstream; | 27 using std::stringstream; |
| 28 using sync_pb::ClientToServerMessage; | 28 using sync_pb::ClientToServerMessage; |
| 29 using sync_pb::ClientToServerResponse; | 29 using sync_pb::ClientToServerResponse; |
| 30 | 30 |
| 31 namespace syncer { | 31 namespace syncer { |
| 32 | 32 |
| 33 using sessions::SyncSession; | |
| 34 using syncable::BASE_VERSION; | 33 using syncable::BASE_VERSION; |
| 35 using syncable::CTIME; | 34 using syncable::CTIME; |
| 36 using syncable::ID; | 35 using syncable::ID; |
| 37 using syncable::IS_DEL; | 36 using syncable::IS_DEL; |
| 38 using syncable::IS_DIR; | 37 using syncable::IS_DIR; |
| 39 using syncable::IS_UNSYNCED; | 38 using syncable::IS_UNSYNCED; |
| 40 using syncable::MTIME; | 39 using syncable::MTIME; |
| 41 using syncable::PARENT_ID; | 40 using syncable::PARENT_ID; |
| 42 | 41 |
| 43 namespace { | 42 namespace { |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 | 320 |
| 322 // static | 321 // static |
| 323 void SyncerProtoUtil::SetProtocolVersion(ClientToServerMessage* msg) { | 322 void SyncerProtoUtil::SetProtocolVersion(ClientToServerMessage* msg) { |
| 324 const int current_version = | 323 const int current_version = |
| 325 ClientToServerMessage::default_instance().protocol_version(); | 324 ClientToServerMessage::default_instance().protocol_version(); |
| 326 msg->set_protocol_version(current_version); | 325 msg->set_protocol_version(current_version); |
| 327 } | 326 } |
| 328 | 327 |
| 329 // static | 328 // static |
| 330 bool SyncerProtoUtil::PostAndProcessHeaders(ServerConnectionManager* scm, | 329 bool SyncerProtoUtil::PostAndProcessHeaders(ServerConnectionManager* scm, |
| 331 sessions::SyncSession* session, | 330 SyncCycle* cycle, |
| 332 const ClientToServerMessage& msg, | 331 const ClientToServerMessage& msg, |
| 333 ClientToServerResponse* response) { | 332 ClientToServerResponse* response) { |
| 334 ServerConnectionManager::PostBufferParams params; | 333 ServerConnectionManager::PostBufferParams params; |
| 335 DCHECK(msg.has_protocol_version()); | 334 DCHECK(msg.has_protocol_version()); |
| 336 DCHECK_EQ(msg.protocol_version(), | 335 DCHECK_EQ(msg.protocol_version(), |
| 337 ClientToServerMessage::default_instance().protocol_version()); | 336 ClientToServerMessage::default_instance().protocol_version()); |
| 338 msg.SerializeToString(¶ms.buffer_in); | 337 msg.SerializeToString(¶ms.buffer_in); |
| 339 | 338 |
| 340 // Fills in params.buffer_out and params.response. | 339 // Fills in params.buffer_out and params.response. |
| 341 if (!scm->PostBufferWithCachedAuth(¶ms)) { | 340 if (!scm->PostBufferWithCachedAuth(¶ms)) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 357 base::TimeDelta::FromSeconds(command.throttle_delay_seconds()); | 356 base::TimeDelta::FromSeconds(command.throttle_delay_seconds()); |
| 358 } | 357 } |
| 359 } | 358 } |
| 360 return throttle_delay; | 359 return throttle_delay; |
| 361 } | 360 } |
| 362 | 361 |
| 363 // static | 362 // static |
| 364 SyncerError SyncerProtoUtil::PostClientToServerMessage( | 363 SyncerError SyncerProtoUtil::PostClientToServerMessage( |
| 365 ClientToServerMessage* msg, | 364 ClientToServerMessage* msg, |
| 366 ClientToServerResponse* response, | 365 ClientToServerResponse* response, |
| 367 SyncSession* session, | 366 SyncCycle* cycle, |
| 368 ModelTypeSet* partial_failure_data_types) { | 367 ModelTypeSet* partial_failure_data_types) { |
| 369 CHECK(response); | 368 CHECK(response); |
| 370 DCHECK(!msg->get_updates().has_from_timestamp()); // Deprecated. | 369 DCHECK(!msg->get_updates().has_from_timestamp()); // Deprecated. |
| 371 DCHECK(!msg->get_updates().has_requested_types()); // Deprecated. | 370 DCHECK(!msg->get_updates().has_requested_types()); // Deprecated. |
| 372 | 371 |
| 373 // Add must-have fields. | 372 // Add must-have fields. |
| 374 SetProtocolVersion(msg); | 373 SetProtocolVersion(msg); |
| 375 AddRequestBirthday(session->context()->directory(), msg); | 374 AddRequestBirthday(cycle->context()->directory(), msg); |
| 376 DCHECK(msg->has_store_birthday() || !IsBirthdayRequired(*msg)); | 375 DCHECK(msg->has_store_birthday() || !IsBirthdayRequired(*msg)); |
| 377 AddBagOfChips(session->context()->directory(), msg); | 376 AddBagOfChips(cycle->context()->directory(), msg); |
| 378 msg->set_api_key(google_apis::GetAPIKey()); | 377 msg->set_api_key(google_apis::GetAPIKey()); |
| 379 msg->mutable_client_status()->CopyFrom(session->context()->client_status()); | 378 msg->mutable_client_status()->CopyFrom(cycle->context()->client_status()); |
| 380 msg->set_invalidator_client_id(session->context()->invalidator_client_id()); | 379 msg->set_invalidator_client_id(cycle->context()->invalidator_client_id()); |
| 381 | 380 |
| 382 syncable::Directory* dir = session->context()->directory(); | 381 syncable::Directory* dir = cycle->context()->directory(); |
| 383 | 382 |
| 384 LogClientToServerMessage(*msg); | 383 LogClientToServerMessage(*msg); |
| 385 if (!PostAndProcessHeaders(session->context()->connection_manager(), session, | 384 if (!PostAndProcessHeaders(cycle->context()->connection_manager(), cycle, |
| 386 *msg, response)) { | 385 *msg, response)) { |
| 387 // There was an error establishing communication with the server. | 386 // There was an error establishing communication with the server. |
| 388 // We can not proceed beyond this point. | 387 // We can not proceed beyond this point. |
| 389 const HttpResponse::ServerConnectionCode server_status = | 388 const HttpResponse::ServerConnectionCode server_status = |
| 390 session->context()->connection_manager()->server_status(); | 389 cycle->context()->connection_manager()->server_status(); |
| 391 | 390 |
| 392 DCHECK_NE(server_status, HttpResponse::NONE); | 391 DCHECK_NE(server_status, HttpResponse::NONE); |
| 393 DCHECK_NE(server_status, HttpResponse::SERVER_CONNECTION_OK); | 392 DCHECK_NE(server_status, HttpResponse::SERVER_CONNECTION_OK); |
| 394 | 393 |
| 395 return ServerConnectionErrorAsSyncerError(server_status); | 394 return ServerConnectionErrorAsSyncerError(server_status); |
| 396 } | 395 } |
| 397 LogClientToServerResponse(*response); | 396 LogClientToServerResponse(*response); |
| 398 | 397 |
| 399 // Persist a bag of chips if it has been sent by the server. | 398 // Persist a bag of chips if it has been sent by the server. |
| 400 PersistBagOfChips(dir, *response); | 399 PersistBagOfChips(dir, *response); |
| 401 | 400 |
| 402 SyncProtocolError sync_protocol_error = | 401 SyncProtocolError sync_protocol_error = |
| 403 GetProtocolErrorFromResponse(*response, dir); | 402 GetProtocolErrorFromResponse(*response, dir); |
| 404 | 403 |
| 405 // Inform the delegate of the error we got. | 404 // Inform the delegate of the error we got. |
| 406 session->delegate()->OnSyncProtocolError(sync_protocol_error); | 405 cycle->delegate()->OnSyncProtocolError(sync_protocol_error); |
| 407 | 406 |
| 408 // Update our state for any other commands we've received. | 407 // Update our state for any other commands we've received. |
| 409 if (response->has_client_command()) { | 408 if (response->has_client_command()) { |
| 410 const sync_pb::ClientCommand& command = response->client_command(); | 409 const sync_pb::ClientCommand& command = response->client_command(); |
| 411 if (command.has_max_commit_batch_size()) { | 410 if (command.has_max_commit_batch_size()) { |
| 412 session->context()->set_max_commit_batch_size( | 411 cycle->context()->set_max_commit_batch_size( |
| 413 command.max_commit_batch_size()); | 412 command.max_commit_batch_size()); |
| 414 } | 413 } |
| 415 | 414 |
| 416 if (command.has_set_sync_long_poll_interval()) { | 415 if (command.has_set_sync_long_poll_interval()) { |
| 417 session->delegate()->OnReceivedLongPollIntervalUpdate( | 416 cycle->delegate()->OnReceivedLongPollIntervalUpdate( |
| 418 base::TimeDelta::FromSeconds(command.set_sync_long_poll_interval())); | 417 base::TimeDelta::FromSeconds(command.set_sync_long_poll_interval())); |
| 419 } | 418 } |
| 420 | 419 |
| 421 if (command.has_set_sync_poll_interval()) { | 420 if (command.has_set_sync_poll_interval()) { |
| 422 session->delegate()->OnReceivedShortPollIntervalUpdate( | 421 cycle->delegate()->OnReceivedShortPollIntervalUpdate( |
| 423 base::TimeDelta::FromSeconds(command.set_sync_poll_interval())); | 422 base::TimeDelta::FromSeconds(command.set_sync_poll_interval())); |
| 424 } | 423 } |
| 425 | 424 |
| 426 if (command.has_sessions_commit_delay_seconds()) { | 425 if (command.has_sessions_commit_delay_seconds()) { |
| 427 std::map<ModelType, base::TimeDelta> delay_map; | 426 std::map<ModelType, base::TimeDelta> delay_map; |
| 428 delay_map[SESSIONS] = | 427 delay_map[SESSIONS] = |
| 429 base::TimeDelta::FromSeconds(command.sessions_commit_delay_seconds()); | 428 base::TimeDelta::FromSeconds(command.sessions_commit_delay_seconds()); |
| 430 session->delegate()->OnReceivedCustomNudgeDelays(delay_map); | 429 cycle->delegate()->OnReceivedCustomNudgeDelays(delay_map); |
| 431 } | 430 } |
| 432 | 431 |
| 433 if (command.has_client_invalidation_hint_buffer_size()) { | 432 if (command.has_client_invalidation_hint_buffer_size()) { |
| 434 session->delegate()->OnReceivedClientInvalidationHintBufferSize( | 433 cycle->delegate()->OnReceivedClientInvalidationHintBufferSize( |
| 435 command.client_invalidation_hint_buffer_size()); | 434 command.client_invalidation_hint_buffer_size()); |
| 436 } | 435 } |
| 437 | 436 |
| 438 if (command.has_gu_retry_delay_seconds()) { | 437 if (command.has_gu_retry_delay_seconds()) { |
| 439 session->delegate()->OnReceivedGuRetryDelay( | 438 cycle->delegate()->OnReceivedGuRetryDelay( |
| 440 base::TimeDelta::FromSeconds(command.gu_retry_delay_seconds())); | 439 base::TimeDelta::FromSeconds(command.gu_retry_delay_seconds())); |
| 441 } | 440 } |
| 442 | 441 |
| 443 if (command.custom_nudge_delays_size() > 0) { | 442 if (command.custom_nudge_delays_size() > 0) { |
| 444 // Note that because this happens after the sessions_commit_delay_seconds | 443 // Note that because this happens after the sessions_commit_delay_seconds |
| 445 // handling, any SESSIONS value in this map will override the one in | 444 // handling, any SESSIONS value in this map will override the one in |
| 446 // sessions_commit_delay_seconds. | 445 // sessions_commit_delay_seconds. |
| 447 std::map<ModelType, base::TimeDelta> delay_map; | 446 std::map<ModelType, base::TimeDelta> delay_map; |
| 448 for (int i = 0; i < command.custom_nudge_delays_size(); ++i) { | 447 for (int i = 0; i < command.custom_nudge_delays_size(); ++i) { |
| 449 ModelType type = GetModelTypeFromSpecificsFieldNumber( | 448 ModelType type = GetModelTypeFromSpecificsFieldNumber( |
| 450 command.custom_nudge_delays(i).datatype_id()); | 449 command.custom_nudge_delays(i).datatype_id()); |
| 451 if (ProtocolTypes().Has(type)) { | 450 if (ProtocolTypes().Has(type)) { |
| 452 delay_map[type] = base::TimeDelta::FromMilliseconds( | 451 delay_map[type] = base::TimeDelta::FromMilliseconds( |
| 453 command.custom_nudge_delays(i).delay_ms()); | 452 command.custom_nudge_delays(i).delay_ms()); |
| 454 } | 453 } |
| 455 } | 454 } |
| 456 session->delegate()->OnReceivedCustomNudgeDelays(delay_map); | 455 cycle->delegate()->OnReceivedCustomNudgeDelays(delay_map); |
| 457 } | 456 } |
| 458 } | 457 } |
| 459 | 458 |
| 460 // Now do any special handling for the error type and decide on the return | 459 // Now do any special handling for the error type and decide on the return |
| 461 // value. | 460 // value. |
| 462 switch (sync_protocol_error.error_type) { | 461 switch (sync_protocol_error.error_type) { |
| 463 case UNKNOWN_ERROR: | 462 case UNKNOWN_ERROR: |
| 464 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " | 463 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " |
| 465 << "recent version."; | 464 << "recent version."; |
| 466 return SERVER_RETURN_UNKNOWN_ERROR; | 465 return SERVER_RETURN_UNKNOWN_ERROR; |
| 467 case SYNC_SUCCESS: | 466 case SYNC_SUCCESS: |
| 468 LogResponseProfilingData(*response); | 467 LogResponseProfilingData(*response); |
| 469 return SYNCER_OK; | 468 return SYNCER_OK; |
| 470 case THROTTLED: | 469 case THROTTLED: |
| 471 if (sync_protocol_error.error_data_types.Empty()) { | 470 if (sync_protocol_error.error_data_types.Empty()) { |
| 472 DLOG(WARNING) << "Client fully throttled by syncer."; | 471 DLOG(WARNING) << "Client fully throttled by syncer."; |
| 473 session->delegate()->OnThrottled(GetThrottleDelay(*response)); | 472 cycle->delegate()->OnThrottled(GetThrottleDelay(*response)); |
| 474 } else { | 473 } else { |
| 475 DLOG(WARNING) << "Some types throttled by syncer."; | 474 DLOG(WARNING) << "Some types throttled by syncer."; |
| 476 session->delegate()->OnTypesThrottled( | 475 cycle->delegate()->OnTypesThrottled( |
| 477 sync_protocol_error.error_data_types, GetThrottleDelay(*response)); | 476 sync_protocol_error.error_data_types, GetThrottleDelay(*response)); |
| 478 } | 477 } |
| 479 return SERVER_RETURN_THROTTLED; | 478 return SERVER_RETURN_THROTTLED; |
| 480 case TRANSIENT_ERROR: | 479 case TRANSIENT_ERROR: |
| 481 return SERVER_RETURN_TRANSIENT_ERROR; | 480 return SERVER_RETURN_TRANSIENT_ERROR; |
| 482 case MIGRATION_DONE: | 481 case MIGRATION_DONE: |
| 483 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size()) | 482 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size()) |
| 484 << "MIGRATION_DONE but no types specified."; | 483 << "MIGRATION_DONE but no types specified."; |
| 485 session->delegate()->OnReceivedMigrationRequest( | 484 cycle->delegate()->OnReceivedMigrationRequest( |
| 486 GetTypesToMigrate(*response)); | 485 GetTypesToMigrate(*response)); |
| 487 return SERVER_RETURN_MIGRATION_DONE; | 486 return SERVER_RETURN_MIGRATION_DONE; |
| 488 case CLEAR_PENDING: | 487 case CLEAR_PENDING: |
| 489 return SERVER_RETURN_CLEAR_PENDING; | 488 return SERVER_RETURN_CLEAR_PENDING; |
| 490 case NOT_MY_BIRTHDAY: | 489 case NOT_MY_BIRTHDAY: |
| 491 return SERVER_RETURN_NOT_MY_BIRTHDAY; | 490 return SERVER_RETURN_NOT_MY_BIRTHDAY; |
| 492 case DISABLED_BY_ADMIN: | 491 case DISABLED_BY_ADMIN: |
| 493 return SERVER_RETURN_DISABLED_BY_ADMIN; | 492 return SERVER_RETURN_DISABLED_BY_ADMIN; |
| 494 case PARTIAL_FAILURE: | 493 case PARTIAL_FAILURE: |
| 495 // This only happens when partial throttling during GetUpdates. | 494 // This only happens when partial throttling during GetUpdates. |
| 496 if (!sync_protocol_error.error_data_types.Empty()) { | 495 if (!sync_protocol_error.error_data_types.Empty()) { |
| 497 DLOG(WARNING) << "Some types throttled by syncer during GetUpdates."; | 496 DLOG(WARNING) << "Some types throttled by syncer during GetUpdates."; |
| 498 session->delegate()->OnTypesThrottled( | 497 cycle->delegate()->OnTypesThrottled( |
| 499 sync_protocol_error.error_data_types, GetThrottleDelay(*response)); | 498 sync_protocol_error.error_data_types, GetThrottleDelay(*response)); |
| 500 } | 499 } |
| 501 if (partial_failure_data_types != NULL) { | 500 if (partial_failure_data_types != NULL) { |
| 502 *partial_failure_data_types = sync_protocol_error.error_data_types; | 501 *partial_failure_data_types = sync_protocol_error.error_data_types; |
| 503 } | 502 } |
| 504 return SERVER_RETURN_PARTIAL_FAILURE; | 503 return SERVER_RETURN_PARTIAL_FAILURE; |
| 505 case CLIENT_DATA_OBSOLETE: | 504 case CLIENT_DATA_OBSOLETE: |
| 506 return SERVER_RETURN_CLIENT_DATA_OBSOLETE; | 505 return SERVER_RETURN_CLIENT_DATA_OBSOLETE; |
| 507 default: | 506 default: |
| 508 NOTREACHED(); | 507 NOTREACHED(); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 std::string SyncerProtoUtil::ClientToServerResponseDebugString( | 593 std::string SyncerProtoUtil::ClientToServerResponseDebugString( |
| 595 const ClientToServerResponse& response) { | 594 const ClientToServerResponse& response) { |
| 596 // Add more handlers as needed. | 595 // Add more handlers as needed. |
| 597 std::string output; | 596 std::string output; |
| 598 if (response.has_get_updates()) | 597 if (response.has_get_updates()) |
| 599 output.append(GetUpdatesResponseString(response.get_updates())); | 598 output.append(GetUpdatesResponseString(response.get_updates())); |
| 600 return output; | 599 return output; |
| 601 } | 600 } |
| 602 | 601 |
| 603 } // namespace syncer | 602 } // namespace syncer |
| OLD | NEW |