123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739 |
- // Copyright (c) 2011 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 "android_webview/browser/cookie_manager.h"
- #include <stdint.h>
- #include <memory>
- #include <utility>
- #include <vector>
- #include "android_webview/browser/aw_browser_context.h"
- #include "android_webview/browser/aw_cookie_access_policy.h"
- #include "android_webview/browser_jni_headers/AwCookieManager_jni.h"
- #include "android_webview/common/aw_switches.h"
- #include "base/android/build_info.h"
- #include "base/android/callback_android.h"
- #include "base/android/jni_string.h"
- #include "base/android/path_utils.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/command_line.h"
- #include "base/containers/circular_deque.h"
- #include "base/files/file_util.h"
- #include "base/location.h"
- #include "base/logging.h"
- #include "base/memory/ref_counted.h"
- #include "base/metrics/histogram_functions.h"
- #include "base/no_destructor.h"
- #include "base/path_service.h"
- #include "base/synchronization/lock.h"
- #include "base/synchronization/waitable_event.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/threading/thread.h"
- #include "base/threading/thread_restrictions.h"
- #include "base/time/time.h"
- #include "content/public/browser/browser_thread.h"
- #include "content/public/browser/cookie_store_factory.h"
- #include "net/cookies/canonical_cookie.h"
- #include "net/cookies/cookie_constants.h"
- #include "net/cookies/cookie_monster.h"
- #include "net/cookies/cookie_options.h"
- #include "net/cookies/cookie_store.h"
- #include "net/cookies/cookie_util.h"
- #include "net/cookies/parsed_cookie.h"
- #include "net/url_request/url_request_context.h"
- #include "services/network/cookie_access_delegate_impl.h"
- #include "services/network/network_service.h"
- #include "services/network/public/mojom/cookie_manager.mojom.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "url/url_constants.h"
- using base::WaitableEvent;
- using base::android::ConvertJavaStringToUTF16;
- using base::android::ConvertJavaStringToUTF8;
- using base::android::JavaParamRef;
- using base::android::ScopedJavaGlobalRef;
- using base::android::ScopedJavaLocalRef;
- using content::BrowserThread;
- using net::CookieList;
- // In the future, we may instead want to inject an explicit CookieStore
- // dependency into this object during process initialization to avoid
- // depending on the URLRequestContext.
- // See issue http://crbug.com/157683
- // On the CookieManager methods without a callback and methods with a callback
- // when that callback is null can be called from any thread, including threads
- // without a message loop. Methods with a non-null callback must be called on
- // a thread with a running message loop.
- namespace android_webview {
- namespace {
- void MaybeRunCookieCallback(base::OnceCallback<void(bool)> callback,
- const bool& result) {
- if (callback)
- std::move(callback).Run(result);
- }
- const char kSecureCookieHistogramName[] = "Android.WebView.SecureCookieAction";
- // These values are persisted to logs. Entries should not be renumbered and
- // numeric values should never be reused.
- enum class SecureCookieAction {
- kInvalidUrl = 0,
- kAlreadySecureScheme = 1,
- kInvalidCookie = 2,
- kNotASecureCookie = 3,
- kFixedUp = 4,
- kDisallowedAndroidR = 5,
- kMaxValue = kDisallowedAndroidR,
- };
- GURL MaybeFixUpSchemeForSecureCookie(const GURL& host,
- const std::string& value,
- bool workaround_http_secure_cookies,
- bool* should_allow_cookie) {
- net::ParsedCookie parsed_cookie(value);
- *should_allow_cookie = true;
- // Log message for catching strict secure cookies related bugs.
- // TODO(ntfschr): try to remove this, based on UMA stats
- // (https://crbug.com/933981)
- if (!host.is_valid()) {
- base::UmaHistogramEnumeration(kSecureCookieHistogramName,
- SecureCookieAction::kInvalidUrl);
- return host;
- }
- if (host.has_scheme() && !host.SchemeIs(url::kHttpScheme)) {
- base::UmaHistogramEnumeration(kSecureCookieHistogramName,
- SecureCookieAction::kAlreadySecureScheme);
- return host;
- }
- if (!parsed_cookie.IsValid()) {
- base::UmaHistogramEnumeration(kSecureCookieHistogramName,
- SecureCookieAction::kInvalidCookie);
- return host;
- }
- if (!parsed_cookie.IsSecure()) {
- base::UmaHistogramEnumeration(kSecureCookieHistogramName,
- SecureCookieAction::kNotASecureCookie);
- return host;
- }
- LOG(ERROR) << "Strict Secure Cookie policy does not allow setting a "
- "secure cookie for "
- << host.spec()
- << " for apps targeting >= R. Please either use the 'https:' "
- "scheme for this URL or omit the 'Secure' directive in the "
- "cookie value.";
- if (!workaround_http_secure_cookies) {
- // Don't allow setting this cookie if we target >= R.
- *should_allow_cookie = false;
- base::UmaHistogramEnumeration(kSecureCookieHistogramName,
- SecureCookieAction::kDisallowedAndroidR);
- return host;
- }
- base::UmaHistogramEnumeration(kSecureCookieHistogramName,
- SecureCookieAction::kFixedUp);
- GURL::Replacements replace_host;
- replace_host.SetSchemeStr(url::kHttpsScheme);
- return host.ReplaceComponents(replace_host);
- }
- // Construct a closure which signals a waitable event if and when the closure
- // is called the waitable event must still exist.
- static base::OnceClosure SignalEventClosure(WaitableEvent* completion) {
- return base::BindOnce(&WaitableEvent::Signal, base::Unretained(completion));
- }
- static void DiscardBool(base::OnceClosure f, bool b) {
- std::move(f).Run();
- }
- static base::OnceCallback<void(bool)> BoolCallbackAdapter(base::OnceClosure f) {
- return base::BindOnce(&DiscardBool, std::move(f));
- }
- static void DiscardInt(base::OnceClosure f, int i) {
- std::move(f).Run();
- }
- static base::OnceCallback<void(int)> IntCallbackAdapter(base::OnceClosure f) {
- return base::BindOnce(&DiscardInt, std::move(f));
- }
- // Are cookies allowed for file:// URLs by default?
- const bool kDefaultFileSchemeAllowed = false;
- } // namespace
- // static
- CookieManager* CookieManager::GetInstance() {
- static base::NoDestructor<CookieManager> instance;
- return instance.get();
- }
- namespace {
- base::FilePath GetPathInAppDirectory(std::string path) {
- base::FilePath result;
- if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &result)) {
- NOTREACHED() << "Failed to get app data directory for Android WebView";
- }
- result = result.Append(FILE_PATH_LITERAL(path));
- return result;
- }
- } // namespace
- CookieManager::CookieManager()
- : allow_file_scheme_cookies_(kDefaultFileSchemeAllowed),
- cookie_store_created_(false),
- workaround_http_secure_cookies_(
- base::android::BuildInfo::GetInstance()->target_sdk_version() <
- base::android::SDK_VERSION_R),
- cookie_store_client_thread_("CookieMonsterClient"),
- cookie_store_backend_thread_("CookieMonsterBackend"),
- setting_new_mojo_cookie_manager_(false) {
- cookie_store_client_thread_.Start();
- cookie_store_backend_thread_.Start();
- cookie_store_task_runner_ = cookie_store_client_thread_.task_runner();
- // TODO(amalova): initialize cookie_store_path_ for non-default profile
- // Do not migrate cookies for non-default profile.
- cookie_store_path_ = GetPathInAppDirectory("Default/Cookies");
- MigrateCookieStorePath();
- }
- CookieManager::~CookieManager() = default;
- void CookieManager::MigrateCookieStorePath() {
- base::FilePath old_cookie_store_path = GetPathInAppDirectory("Cookies");
- base::FilePath old_cookie_journal_path =
- GetPathInAppDirectory("Cookies-journal");
- base::FilePath new_cookie_journal_path =
- GetPathInAppDirectory("Default/Cookies-journal");
- if (base::PathExists(old_cookie_store_path)) {
- base::CreateDirectory(cookie_store_path_.DirName());
- base::Move(old_cookie_store_path, cookie_store_path_);
- base::Move(old_cookie_journal_path, new_cookie_journal_path);
- }
- }
- // Executes the |task| on |cookie_store_task_runner_| and waits for it to
- // complete before returning.
- //
- // To execute a CookieTask synchronously you must arrange for Signal to be
- // called on the waitable event at some point. You can call the bool or int
- // versions of ExecCookieTaskSync, these will supply the caller with a dummy
- // callback which takes an int/bool, throws it away and calls Signal.
- // Alternatively you can call the version which supplies a Closure in which
- // case you must call Run on it when you want the unblock the calling code.
- //
- // Ignore a bool callback.
- void CookieManager::ExecCookieTaskSync(
- base::OnceCallback<void(base::OnceCallback<void(bool)>)> task) {
- WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- ExecCookieTask(base::BindOnce(
- std::move(task), BoolCallbackAdapter(SignalEventClosure(&completion))));
- // Waiting is necessary when implementing synchronous APIs for the WebView
- // embedder.
- base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope wait;
- completion.Wait();
- }
- // Ignore an int callback.
- void CookieManager::ExecCookieTaskSync(
- base::OnceCallback<void(base::OnceCallback<void(int)>)> task) {
- WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- ExecCookieTask(base::BindOnce(
- std::move(task), IntCallbackAdapter(SignalEventClosure(&completion))));
- base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope wait;
- completion.Wait();
- }
- // Call the supplied closure when you want to signal that the blocked code can
- // continue.
- void CookieManager::ExecCookieTaskSync(
- base::OnceCallback<void(base::OnceClosure)> task) {
- WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- ExecCookieTask(
- base::BindOnce(std::move(task), SignalEventClosure(&completion)));
- base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope wait;
- completion.Wait();
- }
- // Executes the |task| using |cookie_store_task_runner_|.
- void CookieManager::ExecCookieTask(base::OnceClosure task) {
- base::AutoLock lock(task_queue_lock_);
- tasks_.push_back(std::move(task));
- // Unretained is safe, since android_webview::CookieManager is a singleton we
- // never destroy (we don't need PostTask to do any memory management).
- cookie_store_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&CookieManager::RunPendingCookieTasks,
- base::Unretained(this)));
- }
- void CookieManager::RunPendingCookieTasks() {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- // Don't do any cookie tasks if in the middle of setting a mojo CookieManager,
- // we'll call this method when that operation is finished.
- if (setting_new_mojo_cookie_manager_)
- return;
- // Copy tasks into temp_queue to minimize the amount of time in the critical
- // section, and to mitigate live-lock issues if these tasks append to the task
- // queue themselves.
- base::circular_deque<base::OnceClosure> temp_queue;
- {
- base::AutoLock lock(task_queue_lock_);
- temp_queue.swap(tasks_);
- }
- while (!temp_queue.empty()) {
- std::move(temp_queue.front()).Run();
- temp_queue.pop_front();
- }
- }
- base::FilePath CookieManager::GetCookieStorePath() {
- return cookie_store_path_;
- }
- net::CookieStore* CookieManager::GetCookieStore() {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- if (!cookie_store_) {
- // TODO(https://crbug.com/1286070): Provide a non-hardcoded value for
- // the 'first_party_sets_enabled' argument below.
- content::CookieStoreConfig cookie_config(
- cookie_store_path_, /* restore_old_session_cookies= */ true,
- /* persist_session_cookies= */ true,
- /* first_party_sets_enabled= */ false);
- cookie_config.client_task_runner = cookie_store_task_runner_;
- cookie_config.background_task_runner =
- cookie_store_backend_thread_.task_runner();
- {
- base::AutoLock lock(allow_file_scheme_cookies_lock_);
- // There are some unknowns about how to correctly handle file:// cookies,
- // and our implementation for this is not robust. http://crbug.com/582985
- //
- // TODO(mmenke): This call should be removed once we can deprecate and
- // remove the Android WebView 'CookieManager::SetAllowFileSchemeCookies'
- // method. Until then, note that this is just not a great idea.
- cookie_config.cookieable_schemes.insert(
- cookie_config.cookieable_schemes.begin(),
- net::CookieMonster::kDefaultCookieableSchemes,
- net::CookieMonster::kDefaultCookieableSchemes +
- net::CookieMonster::kDefaultCookieableSchemesCount);
- if (allow_file_scheme_cookies_)
- cookie_config.cookieable_schemes.push_back(url::kFileScheme);
- cookie_store_created_ = true;
- }
- cookie_store_ = content::CreateCookieStore(cookie_config, nullptr);
- auto cookie_access_delegate_type =
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kWebViewEnableModernCookieSameSite)
- ? network::mojom::CookieAccessDelegateType::ALWAYS_NONLEGACY
- : network::mojom::CookieAccessDelegateType::ALWAYS_LEGACY;
- cookie_store_->SetCookieAccessDelegate(
- std::make_unique<network::CookieAccessDelegateImpl>(
- cookie_access_delegate_type, nullptr /* first_party_sets */));
- }
- return cookie_store_.get();
- }
- network::mojom::CookieManager* CookieManager::GetMojoCookieManager() {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- if (!mojo_cookie_manager_.is_bound())
- return nullptr;
- return mojo_cookie_manager_.get();
- }
- void CookieManager::SetMojoCookieManager(
- mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote) {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ExecCookieTaskSync(base::BindOnce(&CookieManager::SetMojoCookieManagerAsync,
- base::Unretained(this),
- std::move(cookie_manager_remote)));
- }
- void CookieManager::SetMojoCookieManagerAsync(
- mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote,
- base::OnceClosure complete) {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- setting_new_mojo_cookie_manager_ = true;
- // For simplicity, only permit this method to be called once (otherwise, we
- // must sometimes flush the mojo_cookie_manager_ instead of cookie_store_).
- DCHECK(!mojo_cookie_manager_.is_bound());
- if (!cookie_store_created_) {
- SwapMojoCookieManagerAsync(std::move(cookie_manager_remote),
- std::move(complete));
- return;
- }
- GetCookieStore()->FlushStore(base::BindOnce(
- &CookieManager::SwapMojoCookieManagerAsync, base::Unretained(this),
- std::move(cookie_manager_remote), std::move(complete)));
- }
- void CookieManager::SwapMojoCookieManagerAsync(
- mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote,
- base::OnceClosure complete) {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- mojo_cookie_manager_.Bind(std::move(cookie_manager_remote));
- setting_new_mojo_cookie_manager_ = false;
- std::move(complete).Run(); // unblock content initialization
- RunPendingCookieTasks();
- }
- void CookieManager::SetWorkaroundHttpSecureCookiesForTesting(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jboolean allow) {
- ExecCookieTaskSync(
- base::BindOnce(&CookieManager::SetWorkaroundHttpSecureCookiesAsyncHelper,
- base::Unretained(this), allow));
- }
- void CookieManager::SetWorkaroundHttpSecureCookiesAsyncHelper(
- bool allow,
- base::OnceClosure complete) {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- workaround_http_secure_cookies_ = allow;
- std::move(complete).Run();
- }
- void CookieManager::SetShouldAcceptCookies(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jboolean accept) {
- AwCookieAccessPolicy::GetInstance()->SetShouldAcceptCookies(accept);
- }
- jboolean CookieManager::GetShouldAcceptCookies(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- return AwCookieAccessPolicy::GetInstance()->GetShouldAcceptCookies();
- }
- void CookieManager::SetCookie(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jstring>& url,
- const JavaParamRef<jstring>& value,
- const JavaParamRef<jobject>& java_callback) {
- DCHECK(java_callback) << "Unexpected null Java callback";
- GURL host(ConvertJavaStringToUTF16(env, url));
- std::string cookie_value(ConvertJavaStringToUTF8(env, value));
- base::OnceCallback<void(bool)> callback =
- base::BindOnce(&base::android::RunBooleanCallbackAndroid,
- ScopedJavaGlobalRef<jobject>(java_callback));
- ExecCookieTask(base::BindOnce(&CookieManager::SetCookieHelper,
- base::Unretained(this), host, cookie_value,
- std::move(callback)));
- }
- void CookieManager::SetCookieSync(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jstring>& url,
- const JavaParamRef<jstring>& value) {
- GURL host(ConvertJavaStringToUTF16(env, url));
- std::string cookie_value(ConvertJavaStringToUTF8(env, value));
- ExecCookieTaskSync(base::BindOnce(&CookieManager::SetCookieHelper,
- base::Unretained(this), host,
- cookie_value));
- }
- void CookieManager::SetCookieHelper(const GURL& host,
- const std::string& value,
- base::OnceCallback<void(bool)> callback) {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- bool should_allow_cookie = true;
- const GURL& new_host = MaybeFixUpSchemeForSecureCookie(
- host, value, workaround_http_secure_cookies_, &should_allow_cookie);
- std::unique_ptr<net::CanonicalCookie> cc(net::CanonicalCookie::Create(
- new_host, value, base::Time::Now(), absl::nullopt /* server_time */,
- absl::nullopt /* cookie_partition_key */));
- if (!cc || !should_allow_cookie) {
- MaybeRunCookieCallback(std::move(callback), false);
- return;
- }
- // Note: CookieStore and network::CookieManager both accept a
- // CookieAccessResult callback. WebView only cares about boolean success,
- // which is why we use |AdaptCookieAccessResultToBool|. This is temporary
- // technical debt until we fully launch the Network Service code path.
- if (GetMojoCookieManager()) {
- // *cc.get() is safe, because network::CookieManager::SetCanonicalCookie
- // will make a copy before our smart pointer goes out of scope.
- GetMojoCookieManager()->SetCanonicalCookie(
- *cc.get(), new_host, net::CookieOptions::MakeAllInclusive(),
- net::cookie_util::AdaptCookieAccessResultToBool(std::move(callback)));
- } else {
- GetCookieStore()->SetCanonicalCookieAsync(
- std::move(cc), new_host, net::CookieOptions::MakeAllInclusive(),
- net::cookie_util::AdaptCookieAccessResultToBool(std::move(callback)));
- }
- }
- ScopedJavaLocalRef<jstring> CookieManager::GetCookie(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jstring>& url) {
- GURL host(ConvertJavaStringToUTF16(env, url));
- net::CookieList cookie_list;
- ExecCookieTaskSync(base::BindOnce(&CookieManager::GetCookieListAsyncHelper,
- base::Unretained(this), host,
- &cookie_list));
- return base::android::ConvertUTF8ToJavaString(
- env, net::CanonicalCookie::BuildCookieLine(cookie_list));
- }
- ScopedJavaLocalRef<jobjectArray> CookieManager::GetCookieInfo(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jstring>& url) {
- GURL host(ConvertJavaStringToUTF16(env, url));
- net::CookieList cookie_list;
- ExecCookieTaskSync(base::BindOnce(&CookieManager::GetCookieListAsyncHelper,
- base::Unretained(this), host,
- &cookie_list));
- std::vector<std::string> cookie_attributes;
- for (net::CanonicalCookie cookie : cookie_list) {
- cookie_attributes.push_back(
- net::CanonicalCookie::BuildCookieAttributesLine(cookie));
- }
- return base::android::ToJavaArrayOfStrings(
- env, base::span<const std::string>(cookie_attributes));
- }
- void CookieManager::GetCookieListAsyncHelper(const GURL& host,
- net::CookieList* result,
- base::OnceClosure complete) {
- net::CookieOptions options = net::CookieOptions::MakeAllInclusive();
- if (GetMojoCookieManager()) {
- GetMojoCookieManager()->GetCookieList(
- host, options, net::CookiePartitionKeyCollection::Todo(),
- base::BindOnce(&CookieManager::GetCookieListCompleted,
- base::Unretained(this), std::move(complete), result));
- } else {
- GetCookieStore()->GetCookieListWithOptionsAsync(
- host, options, net::CookiePartitionKeyCollection::Todo(),
- base::BindOnce(&CookieManager::GetCookieListCompleted,
- base::Unretained(this), std::move(complete), result));
- }
- }
- void CookieManager::GetCookieListCompleted(
- base::OnceClosure complete,
- net::CookieList* result,
- const net::CookieAccessResultList& value,
- const net::CookieAccessResultList& excluded_cookies) {
- *result = net::cookie_util::StripAccessResults(value);
- std::move(complete).Run();
- }
- void CookieManager::RemoveSessionCookies(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& java_callback) {
- DCHECK(java_callback) << "Unexpected null Java callback";
- base::OnceCallback<void(bool)> callback =
- base::BindOnce(&base::android::RunBooleanCallbackAndroid,
- ScopedJavaGlobalRef<jobject>(java_callback));
- ExecCookieTask(base::BindOnce(&CookieManager::RemoveSessionCookiesHelper,
- base::Unretained(this), std::move(callback)));
- }
- void CookieManager::RemoveSessionCookiesSync(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- ExecCookieTaskSync(base::BindOnce(&CookieManager::RemoveSessionCookiesHelper,
- base::Unretained(this)));
- }
- void CookieManager::RemoveSessionCookiesHelper(
- base::OnceCallback<void(bool)> callback) {
- if (GetMojoCookieManager()) {
- auto match_session_cookies = network::mojom::CookieDeletionFilter::New();
- match_session_cookies->session_control =
- network::mojom::CookieDeletionSessionControl::SESSION_COOKIES;
- GetMojoCookieManager()->DeleteCookies(
- std::move(match_session_cookies),
- base::BindOnce(&CookieManager::RemoveCookiesCompleted,
- base::Unretained(this), std::move(callback)));
- } else {
- GetCookieStore()->DeleteSessionCookiesAsync(
- base::BindOnce(&CookieManager::RemoveCookiesCompleted,
- base::Unretained(this), std::move(callback)));
- }
- }
- void CookieManager::RemoveCookiesCompleted(
- base::OnceCallback<void(bool)> callback,
- uint32_t num_deleted) {
- std::move(callback).Run(num_deleted > 0u);
- }
- void CookieManager::RemoveAllCookies(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- const JavaParamRef<jobject>& java_callback) {
- DCHECK(java_callback) << "Unexpected null Java callback";
- base::OnceCallback<void(bool)> callback =
- base::BindOnce(&base::android::RunBooleanCallbackAndroid,
- ScopedJavaGlobalRef<jobject>(java_callback));
- ExecCookieTask(base::BindOnce(&CookieManager::RemoveAllCookiesHelper,
- base::Unretained(this), std::move(callback)));
- }
- void CookieManager::RemoveAllCookiesSync(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- ExecCookieTaskSync(base::BindOnce(&CookieManager::RemoveAllCookiesHelper,
- base::Unretained(this)));
- }
- void CookieManager::RemoveAllCookiesHelper(
- base::OnceCallback<void(bool)> callback) {
- if (GetMojoCookieManager()) {
- // An empty filter matches all cookies.
- auto match_all_cookies = network::mojom::CookieDeletionFilter::New();
- GetMojoCookieManager()->DeleteCookies(
- std::move(match_all_cookies),
- base::BindOnce(&CookieManager::RemoveCookiesCompleted,
- base::Unretained(this), std::move(callback)));
- } else {
- GetCookieStore()->DeleteAllAsync(
- base::BindOnce(&CookieManager::RemoveCookiesCompleted,
- base::Unretained(this), std::move(callback)));
- }
- }
- void CookieManager::RemoveExpiredCookies(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- // HasCookies will call GetAllCookiesAsync, which in turn will force a GC.
- HasCookies(env, obj);
- }
- void CookieManager::FlushCookieStore(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- ExecCookieTaskSync(base::BindOnce(&CookieManager::FlushCookieStoreAsyncHelper,
- base::Unretained(this)));
- }
- void CookieManager::FlushCookieStoreAsyncHelper(base::OnceClosure complete) {
- if (GetMojoCookieManager()) {
- GetMojoCookieManager()->FlushCookieStore(std::move(complete));
- } else {
- GetCookieStore()->FlushStore(std::move(complete));
- }
- }
- jboolean CookieManager::HasCookies(JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- bool has_cookies;
- ExecCookieTaskSync(base::BindOnce(&CookieManager::HasCookiesAsyncHelper,
- base::Unretained(this), &has_cookies));
- return has_cookies;
- }
- // TODO(kristianm): Simplify this, copying the entire list around
- // should not be needed.
- void CookieManager::HasCookiesAsyncHelper(bool* result,
- base::OnceClosure complete) {
- if (GetMojoCookieManager()) {
- GetMojoCookieManager()->GetAllCookies(
- base::BindOnce(&CookieManager::HasCookiesCompleted,
- base::Unretained(this), std::move(complete), result));
- } else {
- GetCookieStore()->GetAllCookiesAsync(
- base::BindOnce(&CookieManager::HasCookiesCompleted,
- base::Unretained(this), std::move(complete), result));
- }
- }
- void CookieManager::HasCookiesCompleted(base::OnceClosure complete,
- bool* result,
- const CookieList& cookies) {
- *result = cookies.size() != 0;
- std::move(complete).Run();
- }
- bool CookieManager::GetAllowFileSchemeCookies() {
- base::AutoLock lock(allow_file_scheme_cookies_lock_);
- return allow_file_scheme_cookies_;
- }
- jboolean CookieManager::GetAllowFileSchemeCookies(
- JNIEnv* env,
- const JavaParamRef<jobject>& obj) {
- return GetAllowFileSchemeCookies();
- }
- void CookieManager::SetAllowFileSchemeCookies(JNIEnv* env,
- const JavaParamRef<jobject>& obj,
- jboolean allow) {
- ExecCookieTaskSync(
- base::BindOnce(&CookieManager::SetAllowFileSchemeCookiesAsyncHelper,
- base::Unretained(this), allow));
- }
- void CookieManager::SetAllowFileSchemeCookiesAsyncHelper(
- bool allow,
- base::OnceClosure complete) {
- DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
- if (GetMojoCookieManager()) {
- GetMojoCookieManager()->AllowFileSchemeCookies(
- allow,
- base::BindOnce(&CookieManager::SetAllowFileSchemeCookiesCompleted,
- base::Unretained(this), std::move(complete), allow));
- } else {
- // If we have neither a Network Service CookieManager nor have created the
- // CookieStore, we may modify |allow_file_scheme_cookies_|.
- bool can_change_schemes = !cookie_store_created_;
- SetAllowFileSchemeCookiesCompleted(std::move(complete), allow,
- can_change_schemes);
- }
- }
- void CookieManager::SetAllowFileSchemeCookiesCompleted(
- base::OnceClosure complete,
- bool allow,
- bool can_change_schemes) {
- // Should only update |allow_file_scheme_cookies_| if
- // SetAllowFileSchemeCookiesAsyncHelper said this is OK.
- if (can_change_schemes) {
- base::AutoLock lock(allow_file_scheme_cookies_lock_);
- allow_file_scheme_cookies_ = allow;
- }
- std::move(complete).Run();
- }
- static jlong JNI_AwCookieManager_GetDefaultCookieManager(JNIEnv* env) {
- return reinterpret_cast<intptr_t>(CookieManager::GetInstance());
- }
- } // namespace android_webview
|