Index: chrome/browser/signin/oauth2_token_service.cc |
diff --git a/chrome/browser/signin/oauth2_token_service.cc b/chrome/browser/signin/oauth2_token_service.cc |
index e787833cba2dfbfe0dc123ad33fec7704a4076a7..6bfc403d1fc0d7cd010441ed7b2d97d345bd4e6d 100644 |
--- a/chrome/browser/signin/oauth2_token_service.cc |
+++ b/chrome/browser/signin/oauth2_token_service.cc |
@@ -15,6 +15,8 @@ |
#include "base/timer.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/signin/oauth2_token_service_factory.h" |
+#include "chrome/browser/signin/signin_manager.h" |
+#include "chrome/browser/signin/signin_manager_factory.h" |
#include "chrome/browser/signin/token_service.h" |
#include "chrome/browser/signin/token_service_factory.h" |
#include "chrome/common/chrome_notification_types.h" |
@@ -129,6 +131,9 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
const OAuth2TokenService::ScopeSet& GetScopeSet() const; |
const std::string& GetRefreshToken() const; |
+ // The error result from this fetcher. |
+ const GoogleServiceAuthError& error() const { return error_; } |
+ |
protected: |
// OAuth2AccessTokenConsumer |
virtual void OnGetTokenSuccess(const std::string& access_token, |
@@ -316,7 +321,9 @@ OAuth2TokenService::Consumer::Consumer() { |
OAuth2TokenService::Consumer::~Consumer() { |
} |
-OAuth2TokenService::OAuth2TokenService() : profile_(NULL) { |
+OAuth2TokenService::OAuth2TokenService() |
+ : profile_(NULL), |
+ last_auth_error_(GoogleServiceAuthError::NONE) { |
} |
OAuth2TokenService::~OAuth2TokenService() { |
@@ -340,8 +347,18 @@ void OAuth2TokenService::Initialize(Profile* profile) { |
registrar_.Add(this, |
chrome::NOTIFICATION_TOKEN_AVAILABLE, |
token_service_source); |
+ SigninManagerFactory::GetForProfile(profile_)->signin_global_error()-> |
+ AddProvider(this); |
+} |
+ |
+void OAuth2TokenService::Shutdown() { |
+ if (profile_) { |
+ SigninManagerFactory::GetForProfile(profile_)->signin_global_error()-> |
+ RemoveProvider(this); |
+ } |
} |
+ |
// static |
void OAuth2TokenService::InformConsumer( |
base::WeakPtr<OAuth2TokenService::RequestImpl> request, |
@@ -413,6 +430,10 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { |
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
+ // Update the auth error state so auth errors are appropriately communicated |
+ // to the user. |
+ UpdateAuthError(fetcher->error()); |
+ |
// Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh |
// token and scope set. This is guaranteed as follows; here a Fetcher is said |
// to be uncompleted if it has not finished calling back |
@@ -499,4 +520,23 @@ void OAuth2TokenService::Observe(int type, |
// OAuth2 access tokens. If this token either changes or is cleared, any |
// available tokens must be invalidated. |
token_cache_.clear(); |
+ UpdateAuthError(GoogleServiceAuthError::None()); |
+} |
+ |
+void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { |
+ // Do not report connection errors as these are not actually auth errors. |
+ // We also want to avoid masking a "real" auth error just because we |
+ // subsequently get a transient network error. |
+ if (error.state() == GoogleServiceAuthError::CONNECTION_FAILED) |
+ return; |
+ |
+ if (error.state() != last_auth_error_.state()) { |
+ last_auth_error_ = error; |
+ SigninManagerFactory::GetForProfile(profile_)->signin_global_error()-> |
+ AuthStatusChanged(); |
+ } |
+} |
+ |
+GoogleServiceAuthError OAuth2TokenService::GetAuthStatus() const { |
+ return last_auth_error_; |
} |