Chromium Code Reviews| Index: blimp/client/core/session/identity_source.cc |
| diff --git a/blimp/client/core/session/identity_source.cc b/blimp/client/core/session/identity_source.cc |
| index 48b96f4154863c698a969c928957f3fbc16b9537..e2d8eab3c52017fdf1f9c6085b922858c07aef68 100644 |
| --- a/blimp/client/core/session/identity_source.cc |
| +++ b/blimp/client/core/session/identity_source.cc |
| @@ -4,7 +4,9 @@ |
| #include "blimp/client/core/session/identity_source.h" |
| +#include "base/command_line.h" |
| #include "base/memory/ptr_util.h" |
| +#include "blimp/client/core/blimp_client_switches.h" |
| namespace blimp { |
| namespace client { |
| @@ -13,6 +15,9 @@ namespace { |
| // OAuth2 token scope. |
| const char kOAuth2TokenScope[] = |
| "https://www.googleapis.com/auth/userinfo.email"; |
| + |
| +// Max retry times when OAuth2 token request is canceled. |
| +const int kTokenRequestCancelMaxRetry = 3; |
| } // namespace |
| IdentitySource::IdentitySource(BlimpClientContextDelegate* delegate, |
| @@ -20,6 +25,7 @@ IdentitySource::IdentitySource(BlimpClientContextDelegate* delegate, |
| : OAuth2TokenService::Consumer("blimp_client"), |
| token_callback_(callback), |
| is_fetching_token_(false), |
| + retry_times_(0), |
| delegate_(delegate) { |
| DCHECK(delegate_); |
| @@ -39,9 +45,16 @@ void IdentitySource::Connect() { |
| return; |
| } |
| - const std::string& account_id = identity_provider_->GetActiveAccountId(); |
| + // Pass empty token to assignment source if we have command line switches. |
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEngineIP)) { |
| + if (token_callback_) { |
| + token_callback_.Run(std::string()); |
| + } |
| + return; |
| + } |
| - // User must sign in first. |
| + // User must sign in first to get an OAuth2 token. |
| + const std::string& account_id = identity_provider_->GetActiveAccountId(); |
| if (account_id.empty()) { |
| delegate_->OnAuthenticationError( |
| BlimpClientContextDelegate::AuthError::NOT_SIGNED_IN); |
| @@ -53,12 +66,25 @@ void IdentitySource::Connect() { |
| FetchAuthToken(); |
| } |
| +// Add sign in state observer. |
| +void IdentitySource::AddObserver(IdentityProvider::Observer* observer) { |
| + DCHECK(identity_provider_); |
| + identity_provider_->AddObserver(observer); |
| +} |
| + |
| +// Remove sign in state observer. |
| +void IdentitySource::RemoveObserver(IdentityProvider::Observer* observer) { |
| + DCHECK(identity_provider_); |
| + identity_provider_->RemoveObserver(observer); |
| +} |
| + |
| void IdentitySource::OnGetTokenSuccess( |
| const OAuth2TokenService::Request* request, |
| const std::string& access_token, |
| const base::Time& expiration_time) { |
| token_request_.reset(); |
| is_fetching_token_ = false; |
| + retry_times_ = 0; |
| if (token_callback_) { |
| token_callback_.Run(access_token); |
| @@ -70,8 +96,26 @@ void IdentitySource::OnGetTokenFailure( |
| const OAuth2TokenService::Request* request, |
| const GoogleServiceAuthError& error) { |
| token_request_.reset(); |
| - is_fetching_token_ = false; |
| + // The embedder can invalidate the refresh token at any time, this happens |
| + // during application start up or when user switches account. |
| + // OnGetTokenFailure will be called and the error code is REQUEST_CANCELED. |
| + // Retry the request to avoid this to happen. |
|
David Trainor- moved to gerrit
2016/08/30 20:46:29
remove "to happen"
xingliu
2016/08/30 22:27:36
Done.
|
| + if (error.state() == GoogleServiceAuthError::State::REQUEST_CANCELED && |
| + retry_times_ < kTokenRequestCancelMaxRetry) { |
| + retry_times_++; |
| + VLOG(1) << "Retrying to get OAuth2 token due to request cancellation. " |
| + "retry time = " |
| + << retry_times_; |
| + FetchAuthToken(); |
| + return; |
| + } |
| + |
| + // If request failure was not caused by cancellation, or reached max retry |
| + // times on request cancellation, propagate the error to embedder. |
| + is_fetching_token_ = false; |
| + retry_times_ = 0; |
| + VLOG(1) << "OAuth2 token error: " << error.state(); |
| DCHECK(delegate_); |
| delegate_->OnAuthenticationError( |
| BlimpClientContextDelegate::AuthError::OAUTH_TOKEN_FAIL); |