| // 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 "chrome/browser/signin/signin_cookie_changed_subscription.h" |
| |
| #include "net/cookies/cookie_store.h" |
| #include "net/url_request/url_request_context.h" |
| #include "net/url_request/url_request_context_getter.h" |
| |
| SigninCookieChangedSubscription::SubscriptionHolder::SubscriptionHolder() { |
| } |
| |
| SigninCookieChangedSubscription::SubscriptionHolder::~SubscriptionHolder() { |
| } |
| |
| SigninCookieChangedSubscription::SigninCookieChangedSubscription( |
| scoped_refptr<net::URLRequestContextGetter> context_getter, |
| const GURL& url, |
| const std::string& name, |
| const net::CookieStore::CookieChangedCallback& callback) |
| : context_getter_(context_getter), |
| subscription_holder_io_(new SubscriptionHolder), |
| callback_(callback) { |
| RegisterForCookieChangedNotifications(url, name); |
| } |
| |
| SigninCookieChangedSubscription::~SigninCookieChangedSubscription() { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| scoped_refptr<base::SingleThreadTaskRunner> network_task_runner = |
| context_getter_->GetNetworkTaskRunner(); |
| if (network_task_runner->BelongsToCurrentThread()) { |
| subscription_holder_io_.reset(); |
| } else { |
| network_task_runner->DeleteSoon(FROM_HERE, |
| subscription_holder_io_.release()); |
| } |
| } |
| |
| void SigninCookieChangedSubscription::RegisterForCookieChangedNotifications( |
| const GURL& url, |
| const std::string& name) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| |
| // The cookie store can only be accessed from the context getter which lives |
| // on the network thread. As |AddCookieChangedCallback| is called from the |
| // main thread, a thread jump is needed to register for cookie changed |
| // notifications. |
| net::CookieStore::CookieChangedCallback run_on_current_thread_callback = |
| base::Bind(&SigninCookieChangedSubscription::RunAsyncOnCookieChanged, |
| base::MessageLoopProxy::current(), |
| this->AsWeakPtr()); |
| base::Closure register_closure = |
| base::Bind(&RegisterForCookieChangesOnIOThread, |
| context_getter_, |
| url, |
| name, |
| run_on_current_thread_callback, |
| base::Unretained(subscription_holder_io_.get())); |
| scoped_refptr<base::SingleThreadTaskRunner> network_task_runner = |
| context_getter_->GetNetworkTaskRunner(); |
| if (network_task_runner->BelongsToCurrentThread()) { |
| register_closure.Run(); |
| } else { |
| network_task_runner->PostTask(FROM_HERE, register_closure); |
| } |
| } |
| |
| // static |
| void SigninCookieChangedSubscription::RegisterForCookieChangesOnIOThread( |
| scoped_refptr<net::URLRequestContextGetter> context_getter, |
| const GURL url, |
| const std::string name, |
| const net::CookieStore::CookieChangedCallback callback, |
| SigninCookieChangedSubscription::SubscriptionHolder* |
| out_subscription_holder) { |
| DCHECK(out_subscription_holder); |
| net::CookieStore* cookie_store = |
| context_getter->GetURLRequestContext()->cookie_store(); |
| DCHECK(cookie_store); |
| out_subscription_holder->subscription = |
| cookie_store->AddCallbackForCookie(url, name, callback); |
| } |
| |
| // static |
| void SigninCookieChangedSubscription::RunAsyncOnCookieChanged( |
| scoped_refptr<base::TaskRunner> proxy, |
| base::WeakPtr<SigninCookieChangedSubscription> subscription, |
| const net::CanonicalCookie& cookie, |
| bool removed) { |
| proxy->PostTask(FROM_HERE, |
| base::Bind(&SigninCookieChangedSubscription::OnCookieChanged, |
| subscription, |
| cookie, |
| removed)); |
| } |
| |
| void SigninCookieChangedSubscription::OnCookieChanged( |
| const net::CanonicalCookie& cookie, |
| bool removed) { |
| DCHECK(thread_checker_.CalledOnValidThread()); |
| if (!callback_.is_null()) { |
| callback_.Run(cookie, removed); |
| } |
| } |