| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/sync/engine/syncer_proto_util.h" | 5 #include "chrome/browser/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 "chrome/browser/sync/engine/net/server_connection_manager.h" | 9 #include "chrome/browser/sync/engine/net/server_connection_manager.h" |
| 10 #include "chrome/browser/sync/engine/syncer.h" | 10 #include "chrome/browser/sync/engine/syncer.h" |
| 11 #include "chrome/browser/sync/engine/syncer_types.h" | 11 #include "chrome/browser/sync/engine/syncer_types.h" |
| 12 #include "chrome/browser/sync/protocol/service_constants.h" | 12 #include "chrome/browser/sync/protocol/service_constants.h" |
| 13 #include "chrome/browser/sync/protocol/sync.pb.h" | 13 #include "chrome/browser/sync/protocol/sync.pb.h" |
| 14 #include "chrome/browser/sync/protocol/sync_protocol_error.h" | 14 #include "chrome/browser/sync/protocol/sync_protocol_error.h" |
| 15 #include "chrome/browser/sync/sessions/sync_session.h" | 15 #include "chrome/browser/sync/sessions/sync_session.h" |
| 16 #include "chrome/browser/sync/syncable/directory_manager.h" | 16 #include "chrome/browser/sync/syncable/directory_manager.h" |
| 17 #include "chrome/browser/sync/syncable/model_type.h" | 17 #include "chrome/browser/sync/syncable/model_type.h" |
| 18 #include "chrome/browser/sync/syncable/syncable-inl.h" | 18 #include "chrome/browser/sync/syncable/syncable-inl.h" |
| 19 #include "chrome/browser/sync/syncable/syncable.h" | 19 #include "chrome/browser/sync/syncable/syncable.h" |
| 20 #include "chrome/browser/sync/util/time.h" | 20 #include "chrome/browser/sync/util/time.h" |
| 21 | 21 |
| 22 using browser_sync::SyncProtocolErrorType; | 22 using browser_sync::SyncOperationResultType; |
| 23 using std::string; | 23 using std::string; |
| 24 using std::stringstream; | 24 using std::stringstream; |
| 25 using syncable::BASE_VERSION; | 25 using syncable::BASE_VERSION; |
| 26 using syncable::CTIME; | 26 using syncable::CTIME; |
| 27 using syncable::ID; | 27 using syncable::ID; |
| 28 using syncable::IS_DEL; | 28 using syncable::IS_DEL; |
| 29 using syncable::IS_DIR; | 29 using syncable::IS_DIR; |
| 30 using syncable::IS_UNSYNCED; | 30 using syncable::IS_UNSYNCED; |
| 31 using syncable::MTIME; | 31 using syncable::MTIME; |
| 32 using syncable::PARENT_ID; | 32 using syncable::PARENT_ID; |
| 33 using syncable::ScopedDirLookup; | 33 using syncable::ScopedDirLookup; |
| 34 using syncable::SyncName; | 34 using syncable::SyncName; |
| 35 | 35 |
| 36 namespace browser_sync { | 36 namespace browser_sync { |
| 37 using sessions::SyncSession; | 37 using sessions::SyncSession; |
| 38 | 38 |
| 39 namespace { | 39 namespace { |
| 40 | 40 |
| 41 SyncOperationResult ServerConnectionErrorToSyncOperationResult( |
| 42 const browser_sync::HttpResponse::ServerConnectionCode server_status) |
| 43 { |
| 44 SyncOperationResult result; |
| 45 |
| 46 switch (server_status) { |
| 47 case browser_sync::HttpResponse::CONNECTION_UNAVAILABLE: |
| 48 result.error_type = NETWORK_CONNECTION_UNAVAILABLE; |
| 49 break; |
| 50 case browser_sync::HttpResponse::IO_ERROR: |
| 51 result.error_type = NETWORK_IO_ERROR; |
| 52 break; |
| 53 case browser_sync::HttpResponse::SYNC_SERVER_ERROR: |
| 54 // FIXME: how does this happen? Can we map this to TRANSIENT_ERROR or |
| 55 // NON_RETRIABLE_ERROR? |
| 56 result.error_type = SYNC_SERVER_ERROR; |
| 57 break; |
| 58 case browser_sync::HttpResponse::SYNC_AUTH_ERROR: |
| 59 // FIXME: how does this compare to invalid credential? |
| 60 result.error_type = SYNC_AUTH_ERROR; |
| 61 break; |
| 62 case browser_sync::HttpResponse::RETRY: |
| 63 result.error_type = TRANSIENT_ERROR; |
| 64 break; |
| 65 |
| 66 // If we succeeded in contacting the server, then the server will provide us |
| 67 // with all the data we need to compute a SyncOperationResult. We don't |
| 68 // handle that here. |
| 69 case browser_sync::HttpResponse::SERVER_CONNECTION_OK: |
| 70 case browser_sync::HttpResponse::NONE: |
| 71 default: |
| 72 NOTREACHED(); |
| 73 result.error_type = INVALID; |
| 74 } |
| 75 |
| 76 return result; |
| 77 } |
| 78 |
| 41 // Time to backoff syncing after receiving a throttled response. | 79 // Time to backoff syncing after receiving a throttled response. |
| 42 static const int kSyncDelayAfterThrottled = 2 * 60 * 60; // 2 hours | 80 static const int kSyncDelayAfterThrottled = 2 * 60 * 60; // 2 hours |
| 43 void LogResponseProfilingData(const ClientToServerResponse& response) { | 81 void LogResponseProfilingData(const ClientToServerResponse& response) { |
| 44 if (response.has_profiling_data()) { | 82 if (response.has_profiling_data()) { |
| 45 stringstream response_trace; | 83 stringstream response_trace; |
| 46 response_trace << "Server response trace:"; | 84 response_trace << "Server response trace:"; |
| 47 | 85 |
| 48 if (response.profiling_data().has_user_lookup_time()) { | 86 if (response.profiling_data().has_user_lookup_time()) { |
| 49 response_trace << " user lookup: " | 87 response_trace << " user lookup: " |
| 50 << response.profiling_data().user_lookup_time() << "ms"; | 88 << response.profiling_data().user_lookup_time() << "ms"; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 if (!message.has_get_updates()) | 234 if (!message.has_get_updates()) |
| 197 return false; | 235 return false; |
| 198 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); | 236 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); |
| 199 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { | 237 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { |
| 200 if (!message.get_updates().from_progress_marker(i).token().empty()) | 238 if (!message.get_updates().from_progress_marker(i).token().empty()) |
| 201 return false; | 239 return false; |
| 202 } | 240 } |
| 203 return true; | 241 return true; |
| 204 } | 242 } |
| 205 | 243 |
| 206 SyncProtocolErrorType ConvertSyncProtocolErrorTypePBToLocalType( | 244 SyncOperationResultType ConvertSyncProtocolErrorTypePBToLocalType( |
| 207 const sync_pb::ClientToServerResponse::ErrorType& error_type) { | 245 const sync_pb::ClientToServerResponse::ErrorType& error_type) { |
| 208 switch (error_type) { | 246 switch (error_type) { |
| 209 case ClientToServerResponse::SUCCESS: | 247 case ClientToServerResponse::SUCCESS: |
| 210 return browser_sync::SYNC_SUCCESS; | 248 return browser_sync::OPERATION_SUCCESS; |
| 211 case ClientToServerResponse::NOT_MY_BIRTHDAY: | 249 case ClientToServerResponse::NOT_MY_BIRTHDAY: |
| 212 return browser_sync::NOT_MY_BIRTHDAY; | 250 return browser_sync::NOT_MY_BIRTHDAY; |
| 213 case ClientToServerResponse::THROTTLED: | 251 case ClientToServerResponse::THROTTLED: |
| 214 return browser_sync::THROTTLED; | 252 return browser_sync::THROTTLED; |
| 215 case ClientToServerResponse::CLEAR_PENDING: | 253 case ClientToServerResponse::CLEAR_PENDING: |
| 216 return browser_sync::CLEAR_PENDING; | 254 return browser_sync::CLEAR_PENDING; |
| 217 case ClientToServerResponse::TRANSIENT_ERROR: | 255 case ClientToServerResponse::TRANSIENT_ERROR: |
| 218 return browser_sync::TRANSIENT_ERROR; | 256 return browser_sync::TRANSIENT_ERROR; |
| 219 case ClientToServerResponse::MIGRATION_DONE: | 257 case ClientToServerResponse::MIGRATION_DONE: |
| 220 return browser_sync::MIGRATION_DONE; | 258 return browser_sync::MIGRATION_DONE; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 244 case ClientToServerResponse::Error::DISABLE_SYNC_ON_CLIENT: | 282 case ClientToServerResponse::Error::DISABLE_SYNC_ON_CLIENT: |
| 245 return browser_sync::DISABLE_SYNC_ON_CLIENT; | 283 return browser_sync::DISABLE_SYNC_ON_CLIENT; |
| 246 case ClientToServerResponse::Error::UNKNOWN_ACTION: | 284 case ClientToServerResponse::Error::UNKNOWN_ACTION: |
| 247 return browser_sync::UNKNOWN_ACTION; | 285 return browser_sync::UNKNOWN_ACTION; |
| 248 default: | 286 default: |
| 249 NOTREACHED(); | 287 NOTREACHED(); |
| 250 return browser_sync::UNKNOWN_ACTION; | 288 return browser_sync::UNKNOWN_ACTION; |
| 251 } | 289 } |
| 252 } | 290 } |
| 253 | 291 |
| 254 browser_sync::SyncProtocolError ConvertErrorPBToLocalType( | 292 browser_sync::SyncOperationResult ConvertErrorPBToLocalType( |
| 255 const sync_pb::ClientToServerResponse::Error& error) { | 293 const sync_pb::ClientToServerResponse::Error& error) { |
| 256 browser_sync::SyncProtocolError sync_protocol_error; | 294 browser_sync::SyncOperationResult sync_protocol_error; |
| 257 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType( | 295 sync_protocol_error.error_type = ConvertSyncProtocolErrorTypePBToLocalType( |
| 258 error.error_type()); | 296 error.error_type()); |
| 259 sync_protocol_error.error_description = error.error_description(); | 297 sync_protocol_error.error_description = error.error_description(); |
| 260 sync_protocol_error.url = error.url(); | 298 sync_protocol_error.url = error.url(); |
| 261 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction( | 299 sync_protocol_error.action = ConvertClientActionPBToLocalClientAction( |
| 262 error.action()); | 300 error.action()); |
| 263 return sync_protocol_error; | 301 return sync_protocol_error; |
| 264 } | 302 } |
| 265 | 303 |
| 266 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067. | 304 // TODO(lipalani) : Rename these function names as per the CR for issue 7740067. |
| 267 browser_sync::SyncProtocolError ConvertLegacyErrorCodeToNewError( | 305 browser_sync::SyncOperationResult ConvertLegacyErrorCodeToNewError( |
| 268 const sync_pb::ClientToServerResponse::ErrorType& error_type) { | 306 const sync_pb::ClientToServerResponse::ErrorType& error_type) { |
| 269 browser_sync::SyncProtocolError error; | 307 browser_sync::SyncOperationResult error; |
| 270 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type); | 308 error.error_type = ConvertSyncProtocolErrorTypePBToLocalType(error_type); |
| 271 if (error_type == ClientToServerResponse::CLEAR_PENDING || | 309 if (error_type == ClientToServerResponse::CLEAR_PENDING || |
| 272 error_type == ClientToServerResponse::NOT_MY_BIRTHDAY) { | 310 error_type == ClientToServerResponse::NOT_MY_BIRTHDAY) { |
| 273 error.action = browser_sync::DISABLE_SYNC_ON_CLIENT; | 311 error.action = browser_sync::DISABLE_SYNC_ON_CLIENT; |
| 274 } // There is no other action we can compute for legacy server. | 312 } // There is no other action we can compute for legacy server. |
| 275 return error; | 313 return error; |
| 276 } | 314 } |
| 277 | 315 |
| 278 } // namespace | 316 } // namespace |
| 279 | 317 |
| 280 // static | 318 // static |
| 281 bool SyncerProtoUtil::PostClientToServerMessage( | 319 SyncOperationResult SyncerProtoUtil::PostClientToServerMessage( |
| 282 const ClientToServerMessage& msg, | 320 const ClientToServerMessage& msg, |
| 283 ClientToServerResponse* response, | 321 ClientToServerResponse* response, |
| 284 SyncSession* session) { | 322 SyncSession* session) { |
| 285 | 323 |
| 286 CHECK(response); | 324 CHECK(response); |
| 287 DCHECK(!msg.get_updates().has_from_timestamp()); // Deprecated. | 325 DCHECK(!msg.get_updates().has_from_timestamp()); // Deprecated. |
| 288 DCHECK(!msg.get_updates().has_requested_types()); // Deprecated. | 326 DCHECK(!msg.get_updates().has_requested_types()); // Deprecated. |
| 289 DCHECK(msg.has_store_birthday() || IsVeryFirstGetUpdates(msg)) | 327 DCHECK(msg.has_store_birthday() || IsVeryFirstGetUpdates(msg)) |
| 290 << "Must call AddRequestBirthday to set birthday."; | 328 << "Must call AddRequestBirthday to set birthday."; |
| 291 | 329 |
| 292 ScopedDirLookup dir(session->context()->directory_manager(), | 330 ScopedDirLookup dir(session->context()->directory_manager(), |
| 293 session->context()->account_name()); | 331 session->context()->account_name()); |
| 294 if (!dir.good()) | 332 if (!dir.good()) { |
| 295 return false; | 333 SyncOperationResult result; |
| 334 result.error_type = DIRECTORY_LOOKUP_FAILED; |
| 335 return result; |
| 336 } |
| 296 | 337 |
| 297 if (!PostAndProcessHeaders(session->context()->connection_manager(), session, | 338 if (!PostAndProcessHeaders(session->context()->connection_manager(), session, |
| 298 msg, response)) | 339 msg, response)) { |
| 299 return false; | 340 // There was an error establishing communication with the server. |
| 341 // We can not proceed beyond this point. |
| 342 const browser_sync::HttpResponse::ServerConnectionCode server_status = |
| 343 session->context()->connection_manager()->server_status(); |
| 300 | 344 |
| 301 browser_sync::SyncProtocolError sync_protocol_error; | 345 DCHECK(server_status != browser_sync::HttpResponse::NONE); |
| 346 DCHECK(server_status != browser_sync::HttpResponse::SERVER_CONNECTION_OK); |
| 347 |
| 348 return ServerConnectionErrorToSyncOperationResult(server_status); |
| 349 } |
| 350 |
| 351 browser_sync::SyncOperationResult sync_protocol_error; |
| 302 | 352 |
| 303 // Birthday mismatch overrides any error that is sent by the server. | 353 // Birthday mismatch overrides any error that is sent by the server. |
| 304 if (!VerifyResponseBirthday(dir, response)) { | 354 if (!VerifyResponseBirthday(dir, response)) { |
| 305 sync_protocol_error.error_type = browser_sync::NOT_MY_BIRTHDAY; | 355 sync_protocol_error.error_type = browser_sync::NOT_MY_BIRTHDAY; |
| 306 sync_protocol_error.action = | 356 sync_protocol_error.action = |
| 307 browser_sync::DISABLE_SYNC_ON_CLIENT; | 357 browser_sync::DISABLE_SYNC_ON_CLIENT; |
| 308 } else if (response->has_error()) { | 358 } else if (response->has_error()) { |
| 309 // This is a new server. Just get the error from the protocol. | 359 // This is a new server. Just get the error from the protocol. |
| 310 sync_protocol_error = ConvertErrorPBToLocalType(response->error()); | 360 sync_protocol_error = ConvertErrorPBToLocalType(response->error()); |
| 311 } else { | 361 } else { |
| 312 // Legacy server implementation. Compute the error based on |error_code|. | 362 // Legacy server implementation. Compute the error based on |error_code|. |
| 313 sync_protocol_error = ConvertLegacyErrorCodeToNewError( | 363 sync_protocol_error = ConvertLegacyErrorCodeToNewError( |
| 314 response->error_code()); | 364 response->error_code()); |
| 315 } | 365 } |
| 316 | 366 |
| 317 // Now set the error into the status so the layers above us could read it. | 367 // Now set the error into the status so the layers above us could read it. |
| 318 sessions::StatusController* status = session->status_controller(); | 368 sessions::StatusController* status = session->status_controller(); |
| 319 status->set_sync_protocol_error(sync_protocol_error); | 369 status->set_sync_protocol_error(sync_protocol_error); |
| 320 | 370 |
| 321 // Inform the delegate of the error we got. | 371 // Inform the delegate of the error we got. |
| 322 session->delegate()->OnSyncProtocolError(session->TakeSnapshot()); | 372 session->delegate()->OnSyncProtocolError(session->TakeSnapshot()); |
| 323 | 373 |
| 324 // Now do any special handling for the error type and decide on the return | 374 // Now do any special handling for the error type and decide on the return |
| 325 // value. | 375 // value. |
| 326 switch (sync_protocol_error.error_type) { | 376 switch (sync_protocol_error.error_type) { |
| 327 case browser_sync::UNKNOWN_ERROR: | 377 case browser_sync::UNKNOWN_ERROR: |
| 328 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " | 378 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " |
| 329 << "recent version."; | 379 << "recent version."; |
| 330 return false; | 380 break; |
| 331 case browser_sync::SYNC_SUCCESS: | 381 case browser_sync::OPERATION_SUCCESS: |
| 332 LogResponseProfilingData(*response); | 382 LogResponseProfilingData(*response); |
| 333 return true; | 383 break; |
| 334 case browser_sync::THROTTLED: | 384 case browser_sync::THROTTLED: |
| 335 LOG(WARNING) << "Client silenced by server."; | 385 LOG(WARNING) << "Client silenced by server."; |
| 336 session->delegate()->OnSilencedUntil(base::TimeTicks::Now() + | 386 session->delegate()->OnSilencedUntil(base::TimeTicks::Now() + |
| 337 GetThrottleDelay(*response)); | 387 GetThrottleDelay(*response)); |
| 338 return false; | 388 break; |
| 339 case browser_sync::TRANSIENT_ERROR: | |
| 340 return false; | |
| 341 case browser_sync::MIGRATION_DONE: | 389 case browser_sync::MIGRATION_DONE: |
| 342 HandleMigrationDoneResponse(response, session); | 390 HandleMigrationDoneResponse(response, session); |
| 343 return false; | 391 break; |
| 344 case browser_sync::CLEAR_PENDING: | 392 case INVALID: |
| 345 case browser_sync::NOT_MY_BIRTHDAY: | 393 NOTREACHED(); |
| 346 return false; | |
| 347 default: | 394 default: |
| 348 NOTREACHED(); | 395 break; |
| 349 return false; | |
| 350 } | 396 } |
| 397 |
| 398 return sync_protocol_error; |
| 351 } | 399 } |
| 352 | 400 |
| 353 // static | 401 // static |
| 354 bool SyncerProtoUtil::Compare(const syncable::Entry& local_entry, | 402 bool SyncerProtoUtil::Compare(const syncable::Entry& local_entry, |
| 355 const SyncEntity& server_entry) { | 403 const SyncEntity& server_entry) { |
| 356 const std::string name = NameFromSyncEntity(server_entry); | 404 const std::string name = NameFromSyncEntity(server_entry); |
| 357 | 405 |
| 358 CHECK(local_entry.Get(ID) == server_entry.id()) << | 406 CHECK(local_entry.Get(ID) == server_entry.id()) << |
| 359 " SyncerProtoUtil::Compare precondition not met."; | 407 " SyncerProtoUtil::Compare precondition not met."; |
| 360 CHECK(server_entry.version() == local_entry.Get(BASE_VERSION)) << | 408 CHECK(server_entry.version() == local_entry.Get(BASE_VERSION)) << |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 std::string SyncerProtoUtil::ClientToServerResponseDebugString( | 521 std::string SyncerProtoUtil::ClientToServerResponseDebugString( |
| 474 const sync_pb::ClientToServerResponse& response) { | 522 const sync_pb::ClientToServerResponse& response) { |
| 475 // Add more handlers as needed. | 523 // Add more handlers as needed. |
| 476 std::string output; | 524 std::string output; |
| 477 if (response.has_get_updates()) | 525 if (response.has_get_updates()) |
| 478 output.append(GetUpdatesResponseString(response.get_updates())); | 526 output.append(GetUpdatesResponseString(response.get_updates())); |
| 479 return output; | 527 return output; |
| 480 } | 528 } |
| 481 | 529 |
| 482 } // namespace browser_sync | 530 } // namespace browser_sync |
| OLD | NEW |