blob: a5bbf1a13c2efb7068d58f30f36e0328a8a3f001 [file] [log] [blame]
// Copyright 2016 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 <string>
#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner.h"
#include "base/time/time.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_store.h"
namespace android_webview {
// A cross-threaded cookie store implementation that wraps the CookieManager's
// CookieStore. It posts tasks to the CookieStore's thread, and invokes
// callbacks on the originating thread. Deleting it cancels pending callbacks.
// This is needed to allow Webview to run the CookieStore on its own thread, to
// enable synchronous calls into the store on the IO Thread from Java.
//
// AwCookieStoreWrapper will only grab the CookieStore pointer from the
// CookieManager when it's needed, allowing for lazy creation of the
// CookieStore.
//
// AwCookieStoreWrapper may only be called from the thread on which it's
// created.
//
// The CookieManager must outlive the AwCookieStoreWrapper.
class AwCookieStoreWrapper : public net::CookieStore {
public:
AwCookieStoreWrapper();
~AwCookieStoreWrapper() override;
// CookieStore implementation:
void SetCookieWithOptionsAsync(const GURL& url,
const std::string& cookie_line,
const net::CookieOptions& options,
const SetCookiesCallback& callback) override;
void SetCookieWithDetailsAsync(const GURL& url,
const std::string& name,
const std::string& value,
const std::string& domain,
const std::string& path,
base::Time creation_time,
base::Time expiration_time,
base::Time last_access_time,
bool secure,
bool http_only,
net::CookieSameSite same_site,
bool enforce_strict_secure,
net::CookiePriority priority,
const SetCookiesCallback& callback) override;
void GetCookiesWithOptionsAsync(const GURL& url,
const net::CookieOptions& options,
const GetCookiesCallback& callback) override;
void GetCookieListWithOptionsAsync(
const GURL& url,
const net::CookieOptions& options,
const GetCookieListCallback& callback) override;
void GetAllCookiesAsync(const GetCookieListCallback& callback) override;
void DeleteCookieAsync(const GURL& url,
const std::string& cookie_name,
const base::Closure& callback) override;
void DeleteCanonicalCookieAsync(const net::CanonicalCookie& cookie,
const DeleteCallback& callback) override;
void DeleteAllCreatedBetweenAsync(const base::Time& delete_begin,
const base::Time& delete_end,
const DeleteCallback& callback) override;
void DeleteAllCreatedBetweenForHostAsync(
const base::Time delete_begin,
const base::Time delete_end,
const GURL& url,
const DeleteCallback& callback) override;
void DeleteSessionCookiesAsync(const DeleteCallback& callback) override;
void FlushStore(const base::Closure& callback) override;
void SetForceKeepSessionState() override;
scoped_ptr<CookieChangedSubscription> AddCallbackForCookie(
const GURL& url,
const std::string& name,
const CookieChangedCallback& callback) override;
bool IsEphemeral() override;
private:
// Used by CreateWrappedCallback below. Takes an arugment of Type and posts
// a task to |task_runner| to invoke |callback| with that argument. If
// |weak_cookie_store| is deleted before the task is run, the task will not
// be run.
template <class Type>
static void RunCallbackOnClientThread(
base::TaskRunner* task_runner,
base::WeakPtr<AwCookieStoreWrapper> weak_cookie_store,
base::Callback<void(Type)> callback,
Type argument) {
task_runner->PostTask(
FROM_HERE,
base::Bind(&AwCookieStoreWrapper::RunClosureCallback, weak_cookie_store,
base::Bind(callback, argument)));
}
// Returns a base::Callback that takes an argument of Type and posts a task to
// the |client_task_runner_| to invoke |callback| with that argument.
template <class Type>
base::Callback<void(Type)> CreateWrappedCallback(
base::Callback<void(Type)> callback) {
if (callback.is_null())
return callback;
return base::Bind(&AwCookieStoreWrapper::RunCallbackOnClientThread<Type>,
client_task_runner_, weak_factory_.GetWeakPtr(),
callback);
}
// Returns a base::Closure that posts a task to the |client_task_runner_| to
// invoke |callback|.
base::Closure CreateWrappedClosureCallback(const base::Closure& callback);
// Runs |callback|. Used to prevent callbacks from being invoked after the
// AwCookieStoreWrapper has been destroyed.
void RunClosureCallback(const base::Closure& callback);
scoped_refptr<base::SingleThreadTaskRunner> client_task_runner_;
base::WeakPtrFactory<AwCookieStoreWrapper> weak_factory_;
};
} // namesspace android_webview