summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhaitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-07 19:53:06 +0000
committerhaitaol@chromium.org <haitaol@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-11-07 19:53:06 +0000
commit14a496ac45e7f3904a1ff1ff2f2cd605be72c6e8 (patch)
treea919a426696410daf5adb4bd65dc3d919682d7b4
parentd89670fe1ca11c633f82371002b18db044f1a03c (diff)
downloadchromium_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.cc51
-rw-r--r--chrome/browser/sync/profile_sync_service.cc33
-rw-r--r--chrome/browser/sync/profile_sync_service.h30
-rw-r--r--chrome/browser/sync/profile_sync_service_unittest.cc27
-rw-r--r--chrome/browser/sync/test_profile_sync_service.cc11
-rw-r--r--chrome/browser/sync/test_profile_sync_service.h3
-rw-r--r--sync/internal_api/public/sync_manager.h1
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