Index: chrome/browser/sync/engine/syncer_proto_util.cc |
diff --git a/chrome/browser/sync/engine/syncer_proto_util.cc b/chrome/browser/sync/engine/syncer_proto_util.cc |
index 61f64fad5a9f6272793c20f521563d604aee6d78..835b88090fed5aec89c6d2aa0f77334d36a6d21a 100644 |
--- a/chrome/browser/sync/engine/syncer_proto_util.cc |
+++ b/chrome/browser/sync/engine/syncer_proto_util.cc |
@@ -100,6 +100,9 @@ bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir, |
std::string local_birthday = dir->store_birthday(); |
+ // TODO(lipalani) : Remove this check here. When the new implementation |
+ // becomes the default this check should go away. This is handled by the |
+ // switch case in the new implementation. |
if (response->error_code() == ClientToServerResponse::CLEAR_PENDING || |
response->error_code() == ClientToServerResponse::NOT_MY_BIRTHDAY) { |
// Birthday verification failures result in stopping sync and deleting |
@@ -211,6 +214,65 @@ bool IsVeryFirstGetUpdates(const ClientToServerMessage& message) { |
return true; |
} |
+browser_sync::sessions::SyncErrorType ConvertSyncErrorTypePBToLocalType( |
+ const sync_pb::ClientToServerResponse::ErrorType& error_type) { |
+ switch (error_type) { |
+ case ClientToServerResponse::SUCCESS: |
+ return browser_sync::sessions::SUCCESS; |
+ case ClientToServerResponse::NOT_MY_BIRTHDAY: |
+ return browser_sync::sessions::NOT_MY_BIRTHDAY; |
+ case ClientToServerResponse::THROTTLED: |
+ return browser_sync::sessions::THROTTLED; |
+ case ClientToServerResponse::CLEAR_PENDING: |
+ return browser_sync::sessions::CLEAR_PENDING; |
+ case ClientToServerResponse::TRANSIENT_ERROR: |
+ return browser_sync::sessions::TRANSIENT_ERROR; |
+ case ClientToServerResponse::MIGRATION_DONE: |
+ return browser_sync::sessions::MIGRATION_DONE; |
+ case ClientToServerResponse::UNKNOWN: |
+ return browser_sync::sessions::UNKNOWN_ERROR; |
+ case ClientToServerResponse::USER_NOT_ACTIVATED: |
+ case ClientToServerResponse::AUTH_INVALID: |
+ case ClientToServerResponse::ACCESS_DENIED: |
+ return browser_sync::sessions::INVALID_CREDENTIAL; |
+ default: |
+ NOTREACHED(); |
+ return browser_sync::sessions::UNKNOWN_ERROR; |
+ } |
+} |
+ |
+browser_sync::sessions::ClientAction ConvertClientActionPBToLocalClientAction( |
+ const sync_pb::ClientToServerResponse::Error::Action& action) { |
+ switch (action) { |
+ case ClientToServerResponse::Error::UPGRADE_CLIENT: |
+ return browser_sync::sessions::UPGRADE_CLIENT; |
+ case ClientToServerResponse::Error::CLEAR_USER_DATA_AND_RESYNC: |
+ return browser_sync::sessions::CLEAR_USER_DATA_AND_RESYNC; |
+ case ClientToServerResponse::Error::ENABLE_SYNC_ON_ACCOUNT: |
+ return browser_sync::sessions::ENABLE_SYNC_ON_ACCOUNT; |
+ case ClientToServerResponse::Error::STOP_AND_RESTART_SYNC: |
+ return browser_sync::sessions::STOP_AND_RESTART_SYNC; |
+ case ClientToServerResponse::Error::DISABLE_SYNC_ON_CLIENT: |
+ return browser_sync::sessions::DISABLE_SYNC_ON_CLIENT; |
+ case ClientToServerResponse::Error::UNKNOWN_ACTION: |
+ return browser_sync::sessions::UNKNOWN_ACTION; |
+ default: |
+ NOTREACHED(); |
+ return browser_sync::sessions::UNKNOWN_ACTION; |
+ } |
+} |
+ |
+browser_sync::sessions::SyncError ConvertErrorPBToLocalType( |
+ const sync_pb::ClientToServerResponse::Error& error) { |
+ browser_sync::sessions::SyncError sync_error; |
+ sync_error.error_type = ConvertSyncErrorTypePBToLocalType(error.error_type()); |
+ sync_error.error_description = error.error_description(); |
+ sync_error.url = error.url(); |
+ sync_error.action = ConvertClientActionPBToLocalClientAction(error.action()); |
+ |
+ return sync_error; |
+} |
+ |
} // namespace |
// static |
@@ -234,6 +296,54 @@ bool SyncerProtoUtil::PostClientToServerMessage( |
msg, response)) |
return false; |
+ if (response->has_error()) { |
+ // We are talking to a server that is capable of sending the |error| tag. |
+ browser_sync::sessions::SyncError sync_error = ConvertErrorPBToLocalType( |
+ response->error()); |
+ |
+ // Birthday mismatch overrides any error that is sent by the server. |
+ if (!VerifyResponseBirthday(dir, response)) { |
+ sync_error.error_type = browser_sync::sessions::NOT_MY_BIRTHDAY; |
+ sync_error.action = browser_sync::sessions::DISABLE_SYNC_ON_CLIENT; |
+ } |
+ |
+ // Now set the error into the status so the layers above us could read it. |
+ sessions::StatusController* status = session->status_controller(); |
+ status->set_sync_error(sync_error); |
+ |
+ // Inform the delegate of the error we got. |
+ session->delegate()->OnSyncError(session); |
+ |
+ // Now do any special handling for the error type and decide on the return |
+ // value. |
+ switch (sync_error.error_type) { |
+ case browser_sync::sessions::UNKNOWN_ERROR: |
+ LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " |
+ << "recent version."; |
+ return false; |
+ case browser_sync::sessions::SUCCESS: |
+ LogResponseProfilingData(*response); |
+ return true; |
+ case browser_sync::sessions::THROTTLED: |
+ LOG(WARNING) << "Client silenced by server."; |
+ session->delegate()->OnSilencedUntil(base::TimeTicks::Now() + |
+ GetThrottleDelay(*response)); |
+ return false; |
+ case browser_sync::sessions::TRANSIENT_ERROR: |
+ return false; |
+ case browser_sync::sessions::MIGRATION_DONE: |
+ HandleMigrationDoneResponse(response, session); |
+ return false; |
+ default: |
+ NOTREACHED(); |
+ return false; |
+ } |
+ } |
+ |
+ // TODO(lipalani): Plug this legacy implementation to the new error framework. |
+ // New implementation code would have returned before by now. This is waiting |
+ // on the frontend code being implemented. Otherwise ripping this would break |
+ // sync. |
if (!VerifyResponseBirthday(dir, response)) { |
session->status_controller()->set_syncer_stuck(true); |
session->delegate()->OnShouldStopSyncingPermanently(); |