Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(82)

Unified Diff: google_apis/gaia/oauth2_token_service_proxy.cc

Issue 299943003: Refactor ProfileOAuth2TokenServiceRequest into OAuth2TokenServiceRequest (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Allow ProfileOAuth2TokenServiceRequestTest to free UI thread resources. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: google_apis/gaia/oauth2_token_service_proxy.cc
diff --git a/google_apis/gaia/oauth2_token_service_proxy.cc b/google_apis/gaia/oauth2_token_service_proxy.cc
new file mode 100644
index 0000000000000000000000000000000000000000..39894167bff432f438d1e4d2b40017c0ad0083c7
--- /dev/null
+++ b/google_apis/gaia/oauth2_token_service_proxy.cc
@@ -0,0 +1,232 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "google_apis/gaia/oauth2_token_service_proxy.h"
+
+#include "base/bind.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/message_loop/message_loop.h"
+#include "base/threading/non_thread_safe.h"
+#include "google_apis/gaia/google_service_auth_error.h"
+
+namespace {
+
+// Retains an OAuth2TokenService::Request and proxies calls to
+// OAuth2TokenService::Consumer methods to |callback| on the
+// |callback_task_runner| thread.
+class RequestContext : public OAuth2TokenService::Consumer,
+ public base::NonThreadSafe {
+ public:
+ // |requester_id| is a string that describes the service requesting the token.
+ //
+ // |callback_task_runner| is the thread that |callback| lives on.
+ //
+ // |callback| will be invoked when the request has completed.
+ //
+ // |request_done_closure| is a closure used by RequestContext to signal that
+ // its job is all done and can be destroyed. This closure will be posted to
+ // the same thread on which RequestContext is constructed.
+ RequestContext(
+ const std::string& requester_id,
+ const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner,
+ const OAuth2TokenServiceProxy::RequestTokenCallback& callback,
+ const base::Closure& request_done_closure);
+
+ virtual ~RequestContext();
+
+ // OAuth2TokenService::Consumer implementation.
+ 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;
+
+ void SetRequest(scoped_ptr<OAuth2TokenService::Request> request);
+
+ private:
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner_;
+ OAuth2TokenServiceProxy::RequestTokenCallback callback_;
+ base::Closure request_done_closure_;
+ scoped_ptr<OAuth2TokenService::Request> request_;
+};
+
+RequestContext::RequestContext(
+ const std::string& requester_id,
+ const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner,
+ const OAuth2TokenServiceProxy::RequestTokenCallback& callback,
+ const base::Closure& request_done_closure)
+ : OAuth2TokenService::Consumer(requester_id),
+ callback_task_runner_(callback_task_runner),
+ callback_(callback),
+ request_done_closure_(request_done_closure) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(callback_task_runner_);
+}
+
+RequestContext::~RequestContext() {
+ DCHECK(CalledOnValidThread());
+}
+
+void RequestContext::OnGetTokenSuccess(
+ const OAuth2TokenService::Request* request,
+ const std::string& access_token,
+ const base::Time& expiration_time) {
+ DCHECK(CalledOnValidThread());
+ callback_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(callback_,
+ GoogleServiceAuthError::AuthErrorNone(),
+ access_token,
+ expiration_time));
+ base::MessageLoop::current()->PostTask(FROM_HERE, request_done_closure_);
+}
+
+void RequestContext::OnGetTokenFailure(
+ const OAuth2TokenService::Request* request,
+ const GoogleServiceAuthError& error) {
+ const std::string access_token;
+ const base::Time expiration_time;
+ DCHECK(CalledOnValidThread());
+ callback_task_runner_->PostTask(
+ FROM_HERE, base::Bind(callback_, error, access_token, expiration_time));
+ base::MessageLoop::current()->PostTask(FROM_HERE, request_done_closure_);
+}
+
+void RequestContext::SetRequest(
+ scoped_ptr<OAuth2TokenService::Request> request) {
+ DCHECK(CalledOnValidThread());
+ request_ = request.Pass();
+}
+
+} // namespace
+
+// Core lives on the same thread as the OAuth2TokenService and retains
+// OAuth2TokenService::Request objects returned by StartRequest.
+class OAuth2TokenServiceProxy::Core
+ : public base::RefCountedThreadSafe<OAuth2TokenServiceProxy::Core>,
+ public base::NonThreadSafe {
+ public:
+ Core(OAuth2TokenService* token_service);
+
+ virtual void RequestToken(
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner,
+ const RequestTokenCallback& callback,
+ const std::string& requester_id);
+
+ virtual void InvalidateToken(const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ const std::string& access_token);
+
+ private:
+ friend class base::RefCountedThreadSafe<OAuth2TokenServiceProxy::Core>;
+ virtual ~Core();
+ void RemoveRequest(int64 request_id);
+
+ OAuth2TokenService* token_service_;
+ // Used to identify RequestContexts in the request_context_map_. When
+ // completed, RequestContexts can be removed from the map by their id.
+ int64 next_id_;
+ base::ScopedPtrHashMap<int64, RequestContext> request_context_map_;
+};
+
+OAuth2TokenServiceProxy::Core::Core(OAuth2TokenService* token_service)
+ : token_service_(token_service), next_id_(0) {
+ DCHECK(token_service_);
+ DetachFromThread();
+}
+
+OAuth2TokenServiceProxy::Core::~Core() {
+ DCHECK(CalledOnValidThread());
+}
+
+void OAuth2TokenServiceProxy::Core::RemoveRequest(int64 request_id) {
+ request_context_map_.erase(request_id);
+}
+
+void OAuth2TokenServiceProxy::Core::RequestToken(
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner,
+ const RequestTokenCallback& callback,
+ const std::string& requester_id) {
+ DCHECK(CalledOnValidThread());
+
+ // Create a Closure that can be used to remove the RequestContext we are about
+ // to create.
+ int64 request_id = next_id_++;
+ base::Closure request_done_closure = base::Bind(
+ &OAuth2TokenServiceProxy::Core::RemoveRequest, this, request_id);
+
+ // Create a RequestContext that will retain a Request and adapt the Consumer
+ // interface to the user's callback.
+ scoped_ptr<RequestContext> request_context(new RequestContext(
+ requester_id, callback_task_runner, callback, request_done_closure));
+
+ // Start a Request.
+ scoped_ptr<OAuth2TokenService::Request> request =
+ token_service_->StartRequest(account_id, scopes, request_context.get());
+
+ // Then stash it.
+ request_context->SetRequest(request.Pass());
+ request_context_map_.set(request_id, request_context.Pass());
+}
+
+void OAuth2TokenServiceProxy::Core::InvalidateToken(
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ const std::string& access_token) {
+ DCHECK(CalledOnValidThread());
+ token_service_->InvalidateToken(account_id, scopes, access_token);
+}
+
+OAuth2TokenServiceProxy::OAuth2TokenServiceProxy(
+ const scoped_refptr<base::SequencedTaskRunner>& token_service_task_runner,
+ OAuth2TokenService* token_service)
+ : core_task_runner_(token_service_task_runner),
+ core_(new Core(token_service)) {
+ DCHECK(CalledOnValidThread());
+ DCHECK(core_task_runner_);
+}
+
+OAuth2TokenServiceProxy::~OAuth2TokenServiceProxy() {
+ DCHECK(CalledOnValidThread());
+ // core_ lives on the core_task_runner_ thread so we need to ensure it is
+ // destroyed there.
+ core_->AddRef();
+ core_task_runner_->ReleaseSoon(FROM_HERE, core_.get());
+ core_ = NULL;
+}
+
+void OAuth2TokenServiceProxy::RequestToken(
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ const RequestTokenCallback& callback,
+ const std::string& requester_id) {
+ DCHECK(CalledOnValidThread());
+ core_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&OAuth2TokenServiceProxy::Core::RequestToken,
+ core_,
+ account_id,
+ scopes,
+ base::MessageLoopProxy::current(),
+ callback,
+ requester_id));
+}
+
+void OAuth2TokenServiceProxy::InvalidateToken(
+ const std::string& account_id,
+ const OAuth2TokenService::ScopeSet& scopes,
+ const std::string& access_token) {
+ DCHECK(CalledOnValidThread());
+ core_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&OAuth2TokenServiceProxy::Core::InvalidateToken,
+ core_,
+ account_id,
+ scopes,
+ access_token));
+}

Powered by Google App Engine
This is Rietveld 408576698