| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "google_apis/gaia/oauth2_token_service_request.h" | 5 #include "google_apis/gaia/oauth2_token_service_request.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/location.h" | 10 #include "base/location.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // 2. Start() is called on owner thread, which calls StartOnTokenServiceThread() | 31 // 2. Start() is called on owner thread, which calls StartOnTokenServiceThread() |
| 32 // on token service thread. | 32 // on token service thread. |
| 33 // | 33 // |
| 34 // 3. Request is executed. | 34 // 3. Request is executed. |
| 35 // | 35 // |
| 36 // 4. Stop() is called on owner thread, which calls StopOnTokenServiceThread() | 36 // 4. Stop() is called on owner thread, which calls StopOnTokenServiceThread() |
| 37 // on token service thread. | 37 // on token service thread. |
| 38 // | 38 // |
| 39 // 5. Core is destroyed on owner thread. | 39 // 5. Core is destroyed on owner thread. |
| 40 class OAuth2TokenServiceRequest::Core | 40 class OAuth2TokenServiceRequest::Core |
| 41 : public base::NonThreadSafe, | 41 : public base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core> { |
| 42 public base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core> { | |
| 43 public: | 42 public: |
| 44 // Note the thread where an instance of Core is constructed is referred to as | 43 // Note the thread where an instance of Core is constructed is referred to as |
| 45 // the "owner thread" here. | 44 // the "owner thread" here. |
| 46 Core(OAuth2TokenServiceRequest* owner, | 45 Core(OAuth2TokenServiceRequest* owner, |
| 47 const scoped_refptr<TokenServiceProvider>& provider); | 46 const scoped_refptr<TokenServiceProvider>& provider); |
| 48 | 47 |
| 49 // Starts the core. Must be called on the owner thread. | 48 // Starts the core. Must be called on the owner thread. |
| 50 void Start(); | 49 void Start(); |
| 51 | 50 |
| 52 // Stops the core. Must be called on the owner thread. | 51 // Stops the core. Must be called on the owner thread. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 65 // Called on the token service thread. | 64 // Called on the token service thread. |
| 66 virtual void StartOnTokenServiceThread() = 0; | 65 virtual void StartOnTokenServiceThread() = 0; |
| 67 | 66 |
| 68 // Called on the token service thread. | 67 // Called on the token service thread. |
| 69 virtual void StopOnTokenServiceThread() = 0; | 68 virtual void StopOnTokenServiceThread() = 0; |
| 70 | 69 |
| 71 base::SingleThreadTaskRunner* token_service_task_runner(); | 70 base::SingleThreadTaskRunner* token_service_task_runner(); |
| 72 OAuth2TokenService* token_service(); | 71 OAuth2TokenService* token_service(); |
| 73 OAuth2TokenServiceRequest* owner(); | 72 OAuth2TokenServiceRequest* owner(); |
| 74 | 73 |
| 74 SEQUENCE_CHECKER(sequence_checker_); |
| 75 |
| 75 private: | 76 private: |
| 76 friend class base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core>; | 77 friend class base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core>; |
| 77 | 78 |
| 78 void DoNothing(); | 79 void DoNothing(); |
| 79 | 80 |
| 80 scoped_refptr<base::SingleThreadTaskRunner> token_service_task_runner_; | 81 scoped_refptr<base::SingleThreadTaskRunner> token_service_task_runner_; |
| 81 OAuth2TokenServiceRequest* owner_; | 82 OAuth2TokenServiceRequest* owner_; |
| 82 | 83 |
| 83 // Clear on owner thread. OAuth2TokenServiceRequest promises to clear its | 84 // Clear on owner thread. OAuth2TokenServiceRequest promises to clear its |
| 84 // last reference to TokenServiceProvider on the owner thread so the caller | 85 // last reference to TokenServiceProvider on the owner thread so the caller |
| (...skipping 10 matching lines...) Expand all Loading... |
| 95 DCHECK(owner_); | 96 DCHECK(owner_); |
| 96 DCHECK(provider_.get()); | 97 DCHECK(provider_.get()); |
| 97 token_service_task_runner_ = provider_->GetTokenServiceTaskRunner(); | 98 token_service_task_runner_ = provider_->GetTokenServiceTaskRunner(); |
| 98 DCHECK(token_service_task_runner_.get()); | 99 DCHECK(token_service_task_runner_.get()); |
| 99 } | 100 } |
| 100 | 101 |
| 101 OAuth2TokenServiceRequest::Core::~Core() { | 102 OAuth2TokenServiceRequest::Core::~Core() { |
| 102 } | 103 } |
| 103 | 104 |
| 104 void OAuth2TokenServiceRequest::Core::Start() { | 105 void OAuth2TokenServiceRequest::Core::Start() { |
| 105 DCHECK(CalledOnValidThread()); | 106 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 106 token_service_task_runner_->PostTask( | 107 token_service_task_runner_->PostTask( |
| 107 FROM_HERE, | 108 FROM_HERE, |
| 108 base::Bind(&OAuth2TokenServiceRequest::Core::StartOnTokenServiceThread, | 109 base::Bind(&OAuth2TokenServiceRequest::Core::StartOnTokenServiceThread, |
| 109 this)); | 110 this)); |
| 110 } | 111 } |
| 111 | 112 |
| 112 void OAuth2TokenServiceRequest::Core::Stop() { | 113 void OAuth2TokenServiceRequest::Core::Stop() { |
| 113 DCHECK(CalledOnValidThread()); | 114 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 114 DCHECK(!IsStopped()); | 115 DCHECK(!IsStopped()); |
| 115 | 116 |
| 116 // Detaches |owner_| from this instance so |owner_| will be called back only | 117 // Detaches |owner_| from this instance so |owner_| will be called back only |
| 117 // if |Stop()| has never been called. | 118 // if |Stop()| has never been called. |
| 118 owner_ = NULL; | 119 owner_ = NULL; |
| 119 | 120 |
| 120 // We are stopping and will likely be destroyed soon. Use a reply closure | 121 // We are stopping and will likely be destroyed soon. Use a reply closure |
| 121 // (DoNothing) to retain "this" and ensure we are destroyed in the owner | 122 // (DoNothing) to retain "this" and ensure we are destroyed in the owner |
| 122 // thread, not the task runner thread. PostTaskAndReply guarantees that the | 123 // thread, not the task runner thread. PostTaskAndReply guarantees that the |
| 123 // reply closure will execute after StopOnTokenServiceThread has completed. | 124 // reply closure will execute after StopOnTokenServiceThread has completed. |
| 124 token_service_task_runner_->PostTaskAndReply( | 125 token_service_task_runner_->PostTaskAndReply( |
| 125 FROM_HERE, | 126 FROM_HERE, |
| 126 base::Bind(&OAuth2TokenServiceRequest::Core::StopOnTokenServiceThread, | 127 base::Bind(&OAuth2TokenServiceRequest::Core::StopOnTokenServiceThread, |
| 127 this), | 128 this), |
| 128 base::Bind(&OAuth2TokenServiceRequest::Core::DoNothing, this)); | 129 base::Bind(&OAuth2TokenServiceRequest::Core::DoNothing, this)); |
| 129 } | 130 } |
| 130 | 131 |
| 131 bool OAuth2TokenServiceRequest::Core::IsStopped() const { | 132 bool OAuth2TokenServiceRequest::Core::IsStopped() const { |
| 132 DCHECK(CalledOnValidThread()); | 133 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 133 return owner_ == NULL; | 134 return owner_ == NULL; |
| 134 } | 135 } |
| 135 | 136 |
| 136 base::SingleThreadTaskRunner* | 137 base::SingleThreadTaskRunner* |
| 137 OAuth2TokenServiceRequest::Core::token_service_task_runner() { | 138 OAuth2TokenServiceRequest::Core::token_service_task_runner() { |
| 138 return token_service_task_runner_.get(); | 139 return token_service_task_runner_.get(); |
| 139 } | 140 } |
| 140 | 141 |
| 141 OAuth2TokenService* OAuth2TokenServiceRequest::Core::token_service() { | 142 OAuth2TokenService* OAuth2TokenServiceRequest::Core::token_service() { |
| 142 DCHECK(token_service_task_runner_->BelongsToCurrentThread()); | 143 DCHECK(token_service_task_runner_->BelongsToCurrentThread()); |
| 143 return provider_->GetTokenService(); | 144 return provider_->GetTokenService(); |
| 144 } | 145 } |
| 145 | 146 |
| 146 OAuth2TokenServiceRequest* OAuth2TokenServiceRequest::Core::owner() { | 147 OAuth2TokenServiceRequest* OAuth2TokenServiceRequest::Core::owner() { |
| 147 DCHECK(CalledOnValidThread()); | 148 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 148 return owner_; | 149 return owner_; |
| 149 } | 150 } |
| 150 | 151 |
| 151 void OAuth2TokenServiceRequest::Core::DoNothing() { | 152 void OAuth2TokenServiceRequest::Core::DoNothing() { |
| 152 DCHECK(CalledOnValidThread()); | 153 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 153 } | 154 } |
| 154 | 155 |
| 155 namespace { | 156 namespace { |
| 156 | 157 |
| 157 // An implementation of Core for getting an access token. | 158 // An implementation of Core for getting an access token. |
| 158 class RequestCore : public OAuth2TokenServiceRequest::Core, | 159 class RequestCore : public OAuth2TokenServiceRequest::Core, |
| 159 public OAuth2TokenService::Consumer { | 160 public OAuth2TokenService::Consumer { |
| 160 public: | 161 public: |
| 161 RequestCore(OAuth2TokenServiceRequest* owner, | 162 RequestCore(OAuth2TokenServiceRequest* owner, |
| 162 const scoped_refptr< | 163 const scoped_refptr< |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 DCHECK(token_service_task_runner()->BelongsToCurrentThread()); | 249 DCHECK(token_service_task_runner()->BelongsToCurrentThread()); |
| 249 DCHECK_EQ(request_.get(), request); | 250 DCHECK_EQ(request_.get(), request); |
| 250 owner_task_runner_->PostTask( | 251 owner_task_runner_->PostTask( |
| 251 FROM_HERE, | 252 FROM_HERE, |
| 252 base::Bind(&RequestCore::InformOwnerOnGetTokenFailure, this, error)); | 253 base::Bind(&RequestCore::InformOwnerOnGetTokenFailure, this, error)); |
| 253 request_.reset(); | 254 request_.reset(); |
| 254 } | 255 } |
| 255 | 256 |
| 256 void RequestCore::InformOwnerOnGetTokenSuccess(std::string access_token, | 257 void RequestCore::InformOwnerOnGetTokenSuccess(std::string access_token, |
| 257 base::Time expiration_time) { | 258 base::Time expiration_time) { |
| 258 DCHECK(CalledOnValidThread()); | 259 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 259 if (!IsStopped()) { | 260 if (!IsStopped()) { |
| 260 consumer_->OnGetTokenSuccess(owner(), access_token, expiration_time); | 261 consumer_->OnGetTokenSuccess(owner(), access_token, expiration_time); |
| 261 } | 262 } |
| 262 } | 263 } |
| 263 | 264 |
| 264 void RequestCore::InformOwnerOnGetTokenFailure(GoogleServiceAuthError error) { | 265 void RequestCore::InformOwnerOnGetTokenFailure(GoogleServiceAuthError error) { |
| 265 DCHECK(CalledOnValidThread()); | 266 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 266 if (!IsStopped()) { | 267 if (!IsStopped()) { |
| 267 consumer_->OnGetTokenFailure(owner(), error); | 268 consumer_->OnGetTokenFailure(owner(), error); |
| 268 } | 269 } |
| 269 } | 270 } |
| 270 | 271 |
| 271 // An implementation of Core for invalidating an access token. | 272 // An implementation of Core for invalidating an access token. |
| 272 class InvalidateCore : public OAuth2TokenServiceRequest::Core { | 273 class InvalidateCore : public OAuth2TokenServiceRequest::Core { |
| 273 public: | 274 public: |
| 274 InvalidateCore(OAuth2TokenServiceRequest* owner, | 275 InvalidateCore(OAuth2TokenServiceRequest* owner, |
| 275 const scoped_refptr< | 276 const scoped_refptr< |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 const OAuth2TokenService::ScopeSet& scopes, | 349 const OAuth2TokenService::ScopeSet& scopes, |
| 349 const std::string& access_token) { | 350 const std::string& access_token) { |
| 350 std::unique_ptr<OAuth2TokenServiceRequest> request( | 351 std::unique_ptr<OAuth2TokenServiceRequest> request( |
| 351 new OAuth2TokenServiceRequest(account_id)); | 352 new OAuth2TokenServiceRequest(account_id)); |
| 352 scoped_refptr<Core> core(new InvalidateCore( | 353 scoped_refptr<Core> core(new InvalidateCore( |
| 353 request.get(), provider, access_token, account_id, scopes)); | 354 request.get(), provider, access_token, account_id, scopes)); |
| 354 request->StartWithCore(core); | 355 request->StartWithCore(core); |
| 355 } | 356 } |
| 356 | 357 |
| 357 OAuth2TokenServiceRequest::~OAuth2TokenServiceRequest() { | 358 OAuth2TokenServiceRequest::~OAuth2TokenServiceRequest() { |
| 359 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 358 core_->Stop(); | 360 core_->Stop(); |
| 359 } | 361 } |
| 360 | 362 |
| 361 std::string OAuth2TokenServiceRequest::GetAccountId() const { | 363 std::string OAuth2TokenServiceRequest::GetAccountId() const { |
| 362 return account_id_; | 364 return account_id_; |
| 363 } | 365 } |
| 364 | 366 |
| 365 OAuth2TokenServiceRequest::OAuth2TokenServiceRequest( | 367 OAuth2TokenServiceRequest::OAuth2TokenServiceRequest( |
| 366 const std::string& account_id) | 368 const std::string& account_id) |
| 367 : account_id_(account_id) { | 369 : account_id_(account_id) { |
| 368 DCHECK(!account_id_.empty()); | 370 DCHECK(!account_id_.empty()); |
| 369 } | 371 } |
| 370 | 372 |
| 371 void OAuth2TokenServiceRequest::StartWithCore(const scoped_refptr<Core>& core) { | 373 void OAuth2TokenServiceRequest::StartWithCore(const scoped_refptr<Core>& core) { |
| 372 DCHECK(core.get()); | 374 DCHECK(core.get()); |
| 373 core_ = core; | 375 core_ = core; |
| 374 core_->Start(); | 376 core_->Start(); |
| 375 } | 377 } |
| OLD | NEW |