| 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 "sync/engine/syncer_proto_util.h" | 5 #include "sync/engine/syncer_proto_util.h" |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
| 9 #include "sync/engine/net/server_connection_manager.h" | 9 #include "sync/engine/net/server_connection_manager.h" |
| 10 #include "sync/engine/syncer.h" | 10 #include "sync/engine/syncer.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 } | 107 } |
| 108 | 108 |
| 109 } // namespace | 109 } // namespace |
| 110 | 110 |
| 111 // static | 111 // static |
| 112 void SyncerProtoUtil::HandleMigrationDoneResponse( | 112 void SyncerProtoUtil::HandleMigrationDoneResponse( |
| 113 const ClientToServerResponse* response, | 113 const ClientToServerResponse* response, |
| 114 sessions::SyncSession* session) { | 114 sessions::SyncSession* session) { |
| 115 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size()) | 115 LOG_IF(ERROR, 0 >= response->migrated_data_type_id_size()) |
| 116 << "MIGRATION_DONE but no types specified."; | 116 << "MIGRATION_DONE but no types specified."; |
| 117 syncer::ModelTypeSet to_migrate; | 117 ModelTypeSet to_migrate; |
| 118 for (int i = 0; i < response->migrated_data_type_id_size(); i++) { | 118 for (int i = 0; i < response->migrated_data_type_id_size(); i++) { |
| 119 to_migrate.Put(syncer::GetModelTypeFromSpecificsFieldNumber( | 119 to_migrate.Put(GetModelTypeFromSpecificsFieldNumber( |
| 120 response->migrated_data_type_id(i))); | 120 response->migrated_data_type_id(i))); |
| 121 } | 121 } |
| 122 // TODO(akalin): This should be a set union. | 122 // TODO(akalin): This should be a set union. |
| 123 session->mutable_status_controller()-> | 123 session->mutable_status_controller()-> |
| 124 set_types_needing_local_migration(to_migrate); | 124 set_types_needing_local_migration(to_migrate); |
| 125 } | 125 } |
| 126 | 126 |
| 127 // static | 127 // static |
| 128 bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir, | 128 bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir, |
| 129 const ClientToServerResponse* response) { | 129 const ClientToServerResponse* response) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 } | 223 } |
| 224 } | 224 } |
| 225 return throttle_delay; | 225 return throttle_delay; |
| 226 } | 226 } |
| 227 | 227 |
| 228 void SyncerProtoUtil::HandleThrottleError( | 228 void SyncerProtoUtil::HandleThrottleError( |
| 229 const SyncProtocolError& error, | 229 const SyncProtocolError& error, |
| 230 const base::TimeTicks& throttled_until, | 230 const base::TimeTicks& throttled_until, |
| 231 ThrottledDataTypeTracker* tracker, | 231 ThrottledDataTypeTracker* tracker, |
| 232 sessions::SyncSession::Delegate* delegate) { | 232 sessions::SyncSession::Delegate* delegate) { |
| 233 DCHECK_EQ(error.error_type, syncer::THROTTLED); | 233 DCHECK_EQ(error.error_type, THROTTLED); |
| 234 if (error.error_data_types.Empty()) { | 234 if (error.error_data_types.Empty()) { |
| 235 // No datatypes indicates the client should be completely throttled. | 235 // No datatypes indicates the client should be completely throttled. |
| 236 delegate->OnSilencedUntil(throttled_until); | 236 delegate->OnSilencedUntil(throttled_until); |
| 237 } else { | 237 } else { |
| 238 tracker->SetUnthrottleTime(error.error_data_types, throttled_until); | 238 tracker->SetUnthrottleTime(error.error_data_types, throttled_until); |
| 239 } | 239 } |
| 240 } | 240 } |
| 241 | 241 |
| 242 namespace { | 242 namespace { |
| 243 | 243 |
| 244 // Helper function for an assertion in PostClientToServerMessage. | 244 // Helper function for an assertion in PostClientToServerMessage. |
| 245 bool IsVeryFirstGetUpdates(const ClientToServerMessage& message) { | 245 bool IsVeryFirstGetUpdates(const ClientToServerMessage& message) { |
| 246 if (!message.has_get_updates()) | 246 if (!message.has_get_updates()) |
| 247 return false; | 247 return false; |
| 248 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); | 248 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); |
| 249 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { | 249 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { |
| 250 if (!message.get_updates().from_progress_marker(i).token().empty()) | 250 if (!message.get_updates().from_progress_marker(i).token().empty()) |
| 251 return false; | 251 return false; |
| 252 } | 252 } |
| 253 return true; | 253 return true; |
| 254 } | 254 } |
| 255 | 255 |
| 256 SyncProtocolErrorType ConvertSyncProtocolErrorTypePBToLocalType( | 256 SyncProtocolErrorType ConvertSyncProtocolErrorTypePBToLocalType( |
| 257 const sync_pb::SyncEnums::ErrorType& error_type) { | 257 const sync_pb::SyncEnums::ErrorType& error_type) { |
| 258 switch (error_type) { | 258 switch (error_type) { |
| 259 case sync_pb::SyncEnums::SUCCESS: | 259 case sync_pb::SyncEnums::SUCCESS: |
| 260 return syncer::SYNC_SUCCESS; | 260 return SYNC_SUCCESS; |
| 261 case sync_pb::SyncEnums::NOT_MY_BIRTHDAY: | 261 case sync_pb::SyncEnums::NOT_MY_BIRTHDAY: |
| 262 return syncer::NOT_MY_BIRTHDAY; | 262 return NOT_MY_BIRTHDAY; |
| 263 case sync_pb::SyncEnums::THROTTLED: | 263 case sync_pb::SyncEnums::THROTTLED: |
| 264 return syncer::THROTTLED; | 264 return THROTTLED; |
| 265 case sync_pb::SyncEnums::CLEAR_PENDING: | 265 case sync_pb::SyncEnums::CLEAR_PENDING: |
| 266 return syncer::CLEAR_PENDING; | 266 return CLEAR_PENDING; |
| 267 case sync_pb::SyncEnums::TRANSIENT_ERROR: | 267 case sync_pb::SyncEnums::TRANSIENT_ERROR: |
| 268 return syncer::TRANSIENT_ERROR; | 268 return TRANSIENT_ERROR; |
| 269 case sync_pb::SyncEnums::MIGRATION_DONE: | 269 case sync_pb::SyncEnums::MIGRATION_DONE: |
| 270 return syncer::MIGRATION_DONE; | 270 return MIGRATION_DONE; |
| 271 case sync_pb::SyncEnums::UNKNOWN: | 271 case sync_pb::SyncEnums::UNKNOWN: |
| 272 return syncer::UNKNOWN_ERROR; | 272 return UNKNOWN_ERROR; |
| 273 case sync_pb::SyncEnums::USER_NOT_ACTIVATED: | 273 case sync_pb::SyncEnums::USER_NOT_ACTIVATED: |
| 274 case sync_pb::SyncEnums::AUTH_INVALID: | 274 case sync_pb::SyncEnums::AUTH_INVALID: |
| 275 case sync_pb::SyncEnums::ACCESS_DENIED: | 275 case sync_pb::SyncEnums::ACCESS_DENIED: |
| 276 return syncer::INVALID_CREDENTIAL; | 276 return INVALID_CREDENTIAL; |
| 277 default: | 277 default: |
| 278 NOTREACHED(); | 278 NOTREACHED(); |
| 279 return syncer::UNKNOWN_ERROR; | 279 return UNKNOWN_ERROR; |
| 280 } | 280 } |
| 281 } | 281 } |
| 282 | 282 |
| 283 syncer::ClientAction ConvertClientActionPBToLocalClientAction( | 283 ClientAction ConvertClientActionPBToLocalClientAction( |
| 284 const sync_pb::SyncEnums::Action& action) { | 284 const sync_pb::SyncEnums::Action& action) { |
| 285 switch (action) { | 285 switch (action) { |
| 286 case sync_pb::SyncEnums::UPGRADE_CLIENT: | 286 case sync_pb::SyncEnums::UPGRADE_CLIENT: |
| 287 return syncer::UPGRADE_CLIENT; | 287 return UPGRADE_CLIENT; |
| 288 case sync_pb::SyncEnums::CLEAR_USER_DATA_AND_RESYNC: | 288 case sync_pb::SyncEnums::CLEAR_USER_DATA_AND_RESYNC: |
| 289 return syncer::CLEAR_USER_DATA_AND_RESYNC; | 289 return CLEAR_USER_DATA_AND_RESYNC; |
| 290 case sync_pb::SyncEnums::ENABLE_SYNC_ON_ACCOUNT: | 290 case sync_pb::SyncEnums::ENABLE_SYNC_ON_ACCOUNT: |
| 291 return syncer::ENABLE_SYNC_ON_ACCOUNT; | 291 return ENABLE_SYNC_ON_ACCOUNT; |
| 292 case sync_pb::SyncEnums::STOP_AND_RESTART_SYNC: | 292 case sync_pb::SyncEnums::STOP_AND_RESTART_SYNC: |
| 293 return syncer::STOP_AND_RESTART_SYNC; | 293 return STOP_AND_RESTART_SYNC; |
| 294 case sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT: | 294 case sync_pb::SyncEnums::DISABLE_SYNC_ON_CLIENT: |
| 295 return syncer::DISABLE_SYNC_ON_CLIENT; | 295 return DISABLE_SYNC_ON_CLIENT; |
| 296 case sync_pb::SyncEnums::UNKNOWN_ACTION: | 296 case sync_pb::SyncEnums::UNKNOWN_ACTION: |
| 297 return syncer::UNKNOWN_ACTION; | 297 return UNKNOWN_ACTION; |
| 298 default: | 298 default: |
| 299 NOTREACHED(); | 299 NOTREACHED(); |
| 300 return syncer::UNKNOWN_ACTION; | 300 return UNKNOWN_ACTION; |
| 301 } | 301 } |
| 302 } | 302 } |
| 303 | 303 |
| 304 syncer::SyncProtocolError ConvertErrorPBToLocalType( | 304 SyncProtocolError ConvertErrorPBToLocalType( |
| 305 const ClientToServerResponse::Error& error) { | 305 const ClientToServerResponse::Error& error) { |
| 306 syncer::SyncProtocolError sync_protocol_error; | 306 SyncProtocolError sync_protocol_error; |
| 307 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType( | 307 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType( |
| 308 error.error_type()); | 308 error.error_type()); |
| 309 sync_protocol_error.error_description = error.error_description(); | 309 sync_protocol_error.error_description = error.error_description(); |
| 310 sync_protocol_error.url = error.url(); | 310 sync_protocol_error.url = error.url(); |
| 311 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction( | 311 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction( |
| 312 error.action()); | 312 error.action()); |
| 313 | 313 |
| 314 if (error.error_data_type_ids_size() > 0) { | 314 if (error.error_data_type_ids_size() > 0) { |
| 315 // THROTTLED is currently the only error code that uses |error_data_types|. | 315 // THROTTLED is currently the only error code that uses |error_data_types|. |
| 316 DCHECK_EQ(error.error_type(), sync_pb::SyncEnums::THROTTLED); | 316 DCHECK_EQ(error.error_type(), sync_pb::SyncEnums::THROTTLED); |
| 317 for (int i = 0; i < error.error_data_type_ids_size(); ++i) { | 317 for (int i = 0; i < error.error_data_type_ids_size(); ++i) { |
| 318 sync_protocol_error.error_data_types.Put( | 318 sync_protocol_error.error_data_types.Put( |
| 319 syncer::GetModelTypeFromSpecificsFieldNumber( | 319 GetModelTypeFromSpecificsFieldNumber( |
| 320 error.error_data_type_ids(i))); | 320 error.error_data_type_ids(i))); |
| 321 } | 321 } |
| 322 } | 322 } |
| 323 | 323 |
| 324 return sync_protocol_error; | 324 return sync_protocol_error; |
| 325 } | 325 } |
| 326 | 326 |
| 327 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067. | 327 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067. |
| 328 syncer::SyncProtocolError ConvertLegacyErrorCodeToNewError( | 328 SyncProtocolError ConvertLegacyErrorCodeToNewError( |
| 329 const sync_pb::SyncEnums::ErrorType& error_type) { | 329 const sync_pb::SyncEnums::ErrorType& error_type) { |
| 330 syncer::SyncProtocolError error; | 330 SyncProtocolError error; |
| 331 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type); | 331 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type); |
| 332 if (error_type == sync_pb::SyncEnums::CLEAR_PENDING || | 332 if (error_type == sync_pb::SyncEnums::CLEAR_PENDING || |
| 333 error_type == sync_pb::SyncEnums::NOT_MY_BIRTHDAY) { | 333 error_type == sync_pb::SyncEnums::NOT_MY_BIRTHDAY) { |
| 334 error.action = syncer::DISABLE_SYNC_ON_CLIENT; | 334 error.action = DISABLE_SYNC_ON_CLIENT; |
| 335 } // There is no other action we can compute for legacy server. | 335 } // There is no other action we can compute for legacy server. |
| 336 return error; | 336 return error; |
| 337 } | 337 } |
| 338 | 338 |
| 339 } // namespace | 339 } // namespace |
| 340 | 340 |
| 341 // static | 341 // static |
| 342 SyncerError SyncerProtoUtil::PostClientToServerMessage( | 342 SyncerError SyncerProtoUtil::PostClientToServerMessage( |
| 343 const ClientToServerMessage& msg, | 343 const ClientToServerMessage& msg, |
| 344 ClientToServerResponse* response, | 344 ClientToServerResponse* response, |
| 345 SyncSession* session) { | 345 SyncSession* session) { |
| 346 | 346 |
| 347 CHECK(response); | 347 CHECK(response); |
| 348 DCHECK(!msg.get_updates().has_from_timestamp()); // Deprecated. | 348 DCHECK(!msg.get_updates().has_from_timestamp()); // Deprecated. |
| 349 DCHECK(!msg.get_updates().has_requested_types()); // Deprecated. | 349 DCHECK(!msg.get_updates().has_requested_types()); // Deprecated. |
| 350 DCHECK(msg.has_store_birthday() || IsVeryFirstGetUpdates(msg)) | 350 DCHECK(msg.has_store_birthday() || IsVeryFirstGetUpdates(msg)) |
| 351 << "Must call AddRequestBirthday to set birthday."; | 351 << "Must call AddRequestBirthday to set birthday."; |
| 352 | 352 |
| 353 syncable::Directory* dir = session->context()->directory(); | 353 syncable::Directory* dir = session->context()->directory(); |
| 354 | 354 |
| 355 LogClientToServerMessage(msg); | 355 LogClientToServerMessage(msg); |
| 356 session->context()->traffic_recorder()->RecordClientToServerMessage(msg); | 356 session->context()->traffic_recorder()->RecordClientToServerMessage(msg); |
| 357 if (!PostAndProcessHeaders(session->context()->connection_manager(), session, | 357 if (!PostAndProcessHeaders(session->context()->connection_manager(), session, |
| 358 msg, response)) { | 358 msg, response)) { |
| 359 // There was an error establishing communication with the server. | 359 // There was an error establishing communication with the server. |
| 360 // We can not proceed beyond this point. | 360 // We can not proceed beyond this point. |
| 361 const syncer::HttpResponse::ServerConnectionCode server_status = | 361 const HttpResponse::ServerConnectionCode server_status = |
| 362 session->context()->connection_manager()->server_status(); | 362 session->context()->connection_manager()->server_status(); |
| 363 | 363 |
| 364 DCHECK_NE(server_status, syncer::HttpResponse::NONE); | 364 DCHECK_NE(server_status, HttpResponse::NONE); |
| 365 DCHECK_NE(server_status, syncer::HttpResponse::SERVER_CONNECTION_OK); | 365 DCHECK_NE(server_status, HttpResponse::SERVER_CONNECTION_OK); |
| 366 | 366 |
| 367 return ServerConnectionErrorAsSyncerError(server_status); | 367 return ServerConnectionErrorAsSyncerError(server_status); |
| 368 } | 368 } |
| 369 | 369 |
| 370 LogClientToServerResponse(*response); | 370 LogClientToServerResponse(*response); |
| 371 session->context()->traffic_recorder()->RecordClientToServerResponse( | 371 session->context()->traffic_recorder()->RecordClientToServerResponse( |
| 372 *response); | 372 *response); |
| 373 | 373 |
| 374 syncer::SyncProtocolError sync_protocol_error; | 374 SyncProtocolError sync_protocol_error; |
| 375 | 375 |
| 376 // Birthday mismatch overrides any error that is sent by the server. | 376 // Birthday mismatch overrides any error that is sent by the server. |
| 377 if (!VerifyResponseBirthday(dir, response)) { | 377 if (!VerifyResponseBirthday(dir, response)) { |
| 378 sync_protocol_error.error_type = syncer::NOT_MY_BIRTHDAY; | 378 sync_protocol_error.error_type = NOT_MY_BIRTHDAY; |
| 379 sync_protocol_error.action = | 379 sync_protocol_error.action = |
| 380 syncer::DISABLE_SYNC_ON_CLIENT; | 380 DISABLE_SYNC_ON_CLIENT; |
| 381 } else if (response->has_error()) { | 381 } else if (response->has_error()) { |
| 382 // This is a new server. Just get the error from the protocol. | 382 // This is a new server. Just get the error from the protocol. |
| 383 sync_protocol_error = ConvertErrorPBToLocalType(response->error()); | 383 sync_protocol_error = ConvertErrorPBToLocalType(response->error()); |
| 384 } else { | 384 } else { |
| 385 // Legacy server implementation. Compute the error based on |error_code|. | 385 // Legacy server implementation. Compute the error based on |error_code|. |
| 386 sync_protocol_error = ConvertLegacyErrorCodeToNewError( | 386 sync_protocol_error = ConvertLegacyErrorCodeToNewError( |
| 387 response->error_code()); | 387 response->error_code()); |
| 388 } | 388 } |
| 389 | 389 |
| 390 // Now set the error into the status so the layers above us could read it. | 390 // Now set the error into the status so the layers above us could read it. |
| 391 sessions::StatusController* status = session->mutable_status_controller(); | 391 sessions::StatusController* status = session->mutable_status_controller(); |
| 392 status->set_sync_protocol_error(sync_protocol_error); | 392 status->set_sync_protocol_error(sync_protocol_error); |
| 393 | 393 |
| 394 // Inform the delegate of the error we got. | 394 // Inform the delegate of the error we got. |
| 395 session->delegate()->OnSyncProtocolError(session->TakeSnapshot()); | 395 session->delegate()->OnSyncProtocolError(session->TakeSnapshot()); |
| 396 | 396 |
| 397 // Now do any special handling for the error type and decide on the return | 397 // Now do any special handling for the error type and decide on the return |
| 398 // value. | 398 // value. |
| 399 switch (sync_protocol_error.error_type) { | 399 switch (sync_protocol_error.error_type) { |
| 400 case syncer::UNKNOWN_ERROR: | 400 case UNKNOWN_ERROR: |
| 401 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " | 401 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " |
| 402 << "recent version."; | 402 << "recent version."; |
| 403 return SERVER_RETURN_UNKNOWN_ERROR; | 403 return SERVER_RETURN_UNKNOWN_ERROR; |
| 404 case syncer::SYNC_SUCCESS: | 404 case SYNC_SUCCESS: |
| 405 LogResponseProfilingData(*response); | 405 LogResponseProfilingData(*response); |
| 406 return SYNCER_OK; | 406 return SYNCER_OK; |
| 407 case syncer::THROTTLED: | 407 case THROTTLED: |
| 408 LOG(WARNING) << "Client silenced by server."; | 408 LOG(WARNING) << "Client silenced by server."; |
| 409 HandleThrottleError(sync_protocol_error, | 409 HandleThrottleError(sync_protocol_error, |
| 410 base::TimeTicks::Now() + GetThrottleDelay(*response), | 410 base::TimeTicks::Now() + GetThrottleDelay(*response), |
| 411 session->context()->throttled_data_type_tracker(), | 411 session->context()->throttled_data_type_tracker(), |
| 412 session->delegate()); | 412 session->delegate()); |
| 413 return SERVER_RETURN_THROTTLED; | 413 return SERVER_RETURN_THROTTLED; |
| 414 case syncer::TRANSIENT_ERROR: | 414 case TRANSIENT_ERROR: |
| 415 return SERVER_RETURN_TRANSIENT_ERROR; | 415 return SERVER_RETURN_TRANSIENT_ERROR; |
| 416 case syncer::MIGRATION_DONE: | 416 case MIGRATION_DONE: |
| 417 HandleMigrationDoneResponse(response, session); | 417 HandleMigrationDoneResponse(response, session); |
| 418 return SERVER_RETURN_MIGRATION_DONE; | 418 return SERVER_RETURN_MIGRATION_DONE; |
| 419 case syncer::CLEAR_PENDING: | 419 case CLEAR_PENDING: |
| 420 return SERVER_RETURN_CLEAR_PENDING; | 420 return SERVER_RETURN_CLEAR_PENDING; |
| 421 case syncer::NOT_MY_BIRTHDAY: | 421 case NOT_MY_BIRTHDAY: |
| 422 return SERVER_RETURN_NOT_MY_BIRTHDAY; | 422 return SERVER_RETURN_NOT_MY_BIRTHDAY; |
| 423 default: | 423 default: |
| 424 NOTREACHED(); | 424 NOTREACHED(); |
| 425 return UNSET; | 425 return UNSET; |
| 426 } | 426 } |
| 427 } | 427 } |
| 428 | 428 |
| 429 // static | 429 // static |
| 430 bool SyncerProtoUtil::Compare(const syncable::Entry& local_entry, | 430 bool SyncerProtoUtil::Compare(const syncable::Entry& local_entry, |
| 431 const sync_pb::SyncEntity& server_entry) { | 431 const sync_pb::SyncEntity& server_entry) { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 std::string SyncerProtoUtil::ClientToServerResponseDebugString( | 547 std::string SyncerProtoUtil::ClientToServerResponseDebugString( |
| 548 const ClientToServerResponse& response) { | 548 const ClientToServerResponse& response) { |
| 549 // Add more handlers as needed. | 549 // Add more handlers as needed. |
| 550 std::string output; | 550 std::string output; |
| 551 if (response.has_get_updates()) | 551 if (response.has_get_updates()) |
| 552 output.append(GetUpdatesResponseString(response.get_updates())); | 552 output.append(GetUpdatesResponseString(response.get_updates())); |
| 553 return output; | 553 return output; |
| 554 } | 554 } |
| 555 | 555 |
| 556 } // namespace syncer | 556 } // namespace syncer |
| OLD | NEW |