diff options
author | haitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-07 19:53:06 +0000 |
---|---|---|
committer | haitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-07 19:53:06 +0000 |
commit | 14a496ac45e7f3904a1ff1ff2f2cd605be72c6e8 (patch) | |
tree | a919a426696410daf5adb4bd65dc3d919682d7b4 | |
parent | d89670fe1ca11c633f82371002b18db044f1a03c (diff) | |
download | chromium_src-14a496ac45e7f3904a1ff1ff2f2cd605be72c6e8.zip chromium_src-14a496ac45e7f3904a1ff1ff2f2cd605be72c6e8.tar.gz chromium_src-14a496ac45e7f3904a1ff1ff2f2cd605be72c6e8.tar.bz2 |
Reveal information about sync server connection and token on about tab.
The information includes server connection status, token
request/response time, error message and next scheduled request time
if in exponential backoff state.
BUG=309103,311414
NOTRY=true
Review URL: https://codereview.chromium.org/60703002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233665 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/sync/about_sync_util.cc | 51 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 33 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.h | 30 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service_unittest.cc | 27 | ||||
-rw-r--r-- | chrome/browser/sync/test_profile_sync_service.cc | 11 | ||||
-rw-r--r-- | chrome/browser/sync/test_profile_sync_service.h | 3 | ||||
-rw-r--r-- | sync/internal_api/public/sync_manager.h | 1 |
7 files changed, 153 insertions, 3 deletions
diff --git a/chrome/browser/sync/about_sync_util.cc b/chrome/browser/sync/about_sync_util.cc index c4a75ab..7e3205a 100644 --- a/chrome/browser/sync/about_sync_util.cc +++ b/chrome/browser/sync/about_sync_util.cc @@ -7,6 +7,7 @@ #include <string> #include "base/strings/string16.h" +#include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/sync/profile_sync_service.h" @@ -155,6 +156,34 @@ std::string GetTimeStr(base::Time time, const std::string& default_msg) { return time_str; } +std::string GetConnectionStatus( + const ProfileSyncService::SyncTokenStatus& status) { + std::string message; + switch (status.connection_status) { + case syncer::CONNECTION_NOT_ATTEMPTED: + base::StringAppendF(&message, "not attempted"); + break; + case syncer::CONNECTION_OK: + base::StringAppendF( + &message, "OK since %s", + GetTimeStr(status.connection_status_update_time, "n/a").c_str()); + break; + case syncer::CONNECTION_AUTH_ERROR: + base::StringAppendF( + &message, "auth error since %s", + GetTimeStr(status.connection_status_update_time, "n/a").c_str()); + break; + case syncer::CONNECTION_SERVER_ERROR: + base::StringAppendF( + &message, "server error since %s", + GetTimeStr(status.connection_status_update_time, "n/a").c_str()); + break; + default: + NOTREACHED(); + } + return message; +} + } // namespace namespace sync_ui_util { @@ -182,9 +211,16 @@ scoped_ptr<DictionaryValue> ConstructAboutInformation( StringSyncStat sync_id(section_credentials, "Sync Client ID"); StringSyncStat invalidator_id(section_credentials, "Invalidator Client ID"); StringSyncStat username(section_credentials, "Username"); - BoolSyncStat is_token_available(section_credentials, "Sync Token Available"); + StringSyncStat request_token_time(section_credentials, "Requested Token"); + StringSyncStat receive_token_time(section_credentials, "Received Token"); + StringSyncStat token_request_status(section_credentials, + "Token Request Status"); + StringSyncStat next_token_request(section_credentials, + "Next Token Request"); ListValue* section_local = AddSection(stats_list, "Local State"); + StringSyncStat server_connection(section_local, + "Server Connection"); StringSyncStat last_synced(section_local, "Last Synced"); BoolSyncStat is_setup_complete(section_local, "Sync First-Time Setup Complete"); @@ -296,7 +332,18 @@ scoped_ptr<DictionaryValue> ConstructAboutInformation( invalidator_id.SetValue(full_status.invalidator_client_id); if (service->signin()) username.SetValue(service->signin()->GetAuthenticatedUsername()); - is_token_available.SetValue(service->IsOAuthRefreshTokenAvailable()); + + const ProfileSyncService::SyncTokenStatus& token_status = + service->GetSyncTokenStatus(); + server_connection.SetValue(GetConnectionStatus(token_status)); + request_token_time.SetValue(GetTimeStr(token_status.token_request_time, + "n/a")); + receive_token_time.SetValue(GetTimeStr(token_status.token_receive_time, + "n/a")); + std::string err = token_status.last_get_token_error.error_message(); + token_request_status.SetValue(err.empty() ? "OK" : err); + next_token_request.SetValue( + GetTimeStr(token_status.next_token_request_time, "not scheduled")); last_synced.SetValue(service->GetLastSyncedTimeString()); is_setup_complete.SetValue(service->HasSyncSetupCompleted()); diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index bc576b9..d156ee7 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -178,7 +178,9 @@ ProfileSyncService::ProfileSyncService( setup_in_progress_(false), oauth2_token_service_(oauth2_token_service), request_access_token_backoff_(&kRequestAccessTokenBackoffPolicy), - weak_factory_(this) { + weak_factory_(this), + connection_status_(syncer::CONNECTION_NOT_ATTEMPTED), + last_get_token_error_(GoogleServiceAuthError::AuthErrorNone()) { // By default, dev, canary, and unbranded Chromium users will go to the // development servers. Development servers have more features than standard // sync servers. Users with officially-branded Chrome stable and beta builds @@ -649,6 +651,8 @@ void ProfileSyncService::OnGetTokenSuccess( // Reset backoff time after successful response. request_access_token_backoff_.Reset(); access_token_ = access_token; + token_receive_time_ = base::Time::Now(); + last_get_token_error_ = GoogleServiceAuthError::AuthErrorNone(); if (sync_prefs_.SyncHasAuthError()) { sync_prefs_.SetSyncAuthError(false); @@ -669,11 +673,14 @@ void ProfileSyncService::OnGetTokenFailure( DCHECK_EQ(access_token_request_, request); DCHECK_NE(error.state(), GoogleServiceAuthError::NONE); access_token_request_.reset(); + last_get_token_error_ = error; switch (error.state()) { case GoogleServiceAuthError::CONNECTION_FAILED: case GoogleServiceAuthError::SERVICE_UNAVAILABLE: { // Transient error. Retry after some time. request_access_token_backoff_.InformOfRequest(false); + next_token_request_time_ = base::Time::Now() + + request_access_token_backoff_.GetTimeUntilRelease(); request_access_token_retry_timer_.Start( FROM_HERE, request_access_token_backoff_.GetTimeUntilRelease(), @@ -1126,6 +1133,8 @@ AuthError ConnectionStatusToAuthError( void ProfileSyncService::OnConnectionStatusChange( syncer::ConnectionStatus status) { + connection_status_update_time_ = base::Time::Now(); + connection_status_ = status; if (status == syncer::CONNECTION_AUTH_ERROR) { // Sync server returned error indicating that access token is invalid. It // could be either expired or access is revoked. Let's request another @@ -1913,6 +1922,10 @@ void ProfileSyncService::RequestAccessToken() { } access_token_.clear(); + + token_request_time_ = base::Time::Now(); + token_receive_time_ = base::Time(); + next_token_request_time_ = base::Time(); access_token_request_ = oauth2_token_service_->StartRequest(account_id, oauth2_scopes, this); } @@ -2177,3 +2190,21 @@ std::string ProfileSyncService::GetAccountIdToUse() { WeakHandle<syncer::JsEventHandler> ProfileSyncService::GetJsEventHandler() { return MakeWeakHandle(sync_js_controller_.AsWeakPtr()); } + +ProfileSyncService::SyncTokenStatus::SyncTokenStatus() + : connection_status(syncer::CONNECTION_NOT_ATTEMPTED), + last_get_token_error(GoogleServiceAuthError::AuthErrorNone()) {} +ProfileSyncService::SyncTokenStatus::~SyncTokenStatus() {} + +ProfileSyncService::SyncTokenStatus +ProfileSyncService::GetSyncTokenStatus() const { + SyncTokenStatus status; + status.connection_status_update_time = connection_status_update_time_; + status.connection_status = connection_status_; + status.token_request_time = token_request_time_; + status.token_receive_time = token_receive_time_; + status.last_get_token_error = last_get_token_error_; + if (request_access_token_retry_timer_.IsRunning()) + status.next_token_request_time = next_token_request_time_; + return status; +} diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h index f64f8ea..c590769 100644 --- a/chrome/browser/sync/profile_sync_service.h +++ b/chrome/browser/sync/profile_sync_service.h @@ -174,6 +174,25 @@ class ProfileSyncService : public ProfileSyncServiceBase, public: typedef browser_sync::SyncBackendHost::Status Status; + // Status of sync server connection, sync token and token request. + struct SyncTokenStatus { + SyncTokenStatus(); + ~SyncTokenStatus(); + + // Sync server connection status reported by sync backend. + base::Time connection_status_update_time; + syncer::ConnectionStatus connection_status; + + // Times when OAuth2 access token is requested and received. + base::Time token_request_time; + base::Time token_receive_time; + + // Error returned by OAuth2TokenService for token request and time when + // next request is scheduled. + GoogleServiceAuthError last_get_token_error; + base::Time next_token_request_time; + }; + enum SyncEventCodes { MIN_SYNC_EVENT_CODE = 0, @@ -656,6 +675,9 @@ class ProfileSyncService : public ProfileSyncServiceBase, // told to MergeDataAndStartSyncing yet. void OnDataTypeRequestsSyncStartup(syncer::ModelType type); + // Return sync token status. + SyncTokenStatus GetSyncTokenStatus() const; + protected: // Used by test classes that derive from ProfileSyncService. virtual browser_sync::SyncBackendHost* GetBackendForTest(); @@ -987,6 +1009,14 @@ class ProfileSyncService : public ProfileSyncServiceBase, base::WeakPtrFactory<ProfileSyncService> weak_factory_; + // States related to sync token and connection. + base::Time connection_status_update_time_; + syncer::ConnectionStatus connection_status_; + base::Time token_request_time_; + base::Time token_receive_time_; + GoogleServiceAuthError last_get_token_error_; + base::Time next_token_request_time_; + DISALLOW_COPY_AND_ASSIGN(ProfileSyncService); }; diff --git a/chrome/browser/sync/profile_sync_service_unittest.cc b/chrome/browser/sync/profile_sync_service_unittest.cc index 18deb39..6ae260c 100644 --- a/chrome/browser/sync/profile_sync_service_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_unittest.cc @@ -491,5 +491,32 @@ TEST_F(ProfileSyncServiceTest, FailToDownloadControlTypes) { EXPECT_FALSE(service_->sync_initialized()); } +TEST_F(ProfileSyncServiceTest, GetSyncTokenStatus) { + StartSyncService(); + ProfileSyncService::SyncTokenStatus token_status = + service_->GetSyncTokenStatus(); + EXPECT_EQ(syncer::CONNECTION_NOT_ATTEMPTED, token_status.connection_status); + EXPECT_TRUE(token_status.connection_status_update_time.is_null()); + EXPECT_TRUE(token_status.token_request_time.is_null()); + EXPECT_TRUE(token_status.token_receive_time.is_null()); + + // Sync engine is given invalid token at initialization and will report + // auth error when trying to connect. + service_->OnConnectionStatusChange(syncer::CONNECTION_AUTH_ERROR); + token_status = service_->GetSyncTokenStatus(); + EXPECT_EQ(syncer::CONNECTION_AUTH_ERROR, token_status.connection_status); + EXPECT_FALSE(token_status.connection_status_update_time.is_null()); + EXPECT_FALSE(token_status.token_request_time.is_null()); + EXPECT_FALSE(token_status.token_receive_time.is_null()); + EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), + token_status.last_get_token_error); + EXPECT_TRUE(token_status.next_token_request_time.is_null()); + + // Simulate successful connection. + service_->OnConnectionStatusChange(syncer::CONNECTION_OK); + token_status = service_->GetSyncTokenStatus(); + EXPECT_EQ(syncer::CONNECTION_OK, token_status.connection_status); +} + } // namespace } // namespace browser_sync diff --git a/chrome/browser/sync/test_profile_sync_service.cc b/chrome/browser/sync/test_profile_sync_service.cc index 70ca26f..ad4f5ee 100644 --- a/chrome/browser/sync/test_profile_sync_service.cc +++ b/chrome/browser/sync/test_profile_sync_service.cc @@ -209,6 +209,17 @@ void TestProfileSyncService::RequestAccessToken() { } } +void TestProfileSyncService::OnGetTokenSuccess( + const OAuth2TokenService::Request* request, + const std::string& access_token, + const base::Time& expiration_time) { + ProfileSyncService::OnGetTokenSuccess(request, access_token, + expiration_time); + if (synchronous_backend_initialization_) { + base::MessageLoop::current()->Quit(); + } +} + void TestProfileSyncService::OnGetTokenFailure( const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) { diff --git a/chrome/browser/sync/test_profile_sync_service.h b/chrome/browser/sync/test_profile_sync_service.h index 4c0c3ce..18e468f3 100644 --- a/chrome/browser/sync/test_profile_sync_service.h +++ b/chrome/browser/sync/test_profile_sync_service.h @@ -117,6 +117,9 @@ class TestProfileSyncService : public ProfileSyncService { virtual ~TestProfileSyncService(); virtual void RequestAccessToken() OVERRIDE; + virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, + const std::string& access_token, + const base::Time& expiration_time) OVERRIDE; virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) OVERRIDE; diff --git a/sync/internal_api/public/sync_manager.h b/sync/internal_api/public/sync_manager.h index 1cd3319..a5e6926 100644 --- a/sync/internal_api/public/sync_manager.h +++ b/sync/internal_api/public/sync_manager.h @@ -53,6 +53,7 @@ class SyncSessionSnapshot; // Used by SyncManager::OnConnectionStatusChange(). enum ConnectionStatus { + CONNECTION_NOT_ATTEMPTED, CONNECTION_OK, CONNECTION_AUTH_ERROR, CONNECTION_SERVER_ERROR |