cookie_manager.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "android_webview/browser/cookie_manager.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include <utility>
  8. #include <vector>
  9. #include "android_webview/browser/aw_browser_context.h"
  10. #include "android_webview/browser/aw_cookie_access_policy.h"
  11. #include "android_webview/browser_jni_headers/AwCookieManager_jni.h"
  12. #include "android_webview/common/aw_switches.h"
  13. #include "base/android/build_info.h"
  14. #include "base/android/callback_android.h"
  15. #include "base/android/jni_string.h"
  16. #include "base/android/path_utils.h"
  17. #include "base/bind.h"
  18. #include "base/callback_helpers.h"
  19. #include "base/command_line.h"
  20. #include "base/containers/circular_deque.h"
  21. #include "base/files/file_util.h"
  22. #include "base/location.h"
  23. #include "base/logging.h"
  24. #include "base/memory/ref_counted.h"
  25. #include "base/metrics/histogram_functions.h"
  26. #include "base/no_destructor.h"
  27. #include "base/path_service.h"
  28. #include "base/synchronization/lock.h"
  29. #include "base/synchronization/waitable_event.h"
  30. #include "base/task/single_thread_task_runner.h"
  31. #include "base/threading/thread.h"
  32. #include "base/threading/thread_restrictions.h"
  33. #include "base/time/time.h"
  34. #include "content/public/browser/browser_thread.h"
  35. #include "content/public/browser/cookie_store_factory.h"
  36. #include "net/cookies/canonical_cookie.h"
  37. #include "net/cookies/cookie_constants.h"
  38. #include "net/cookies/cookie_monster.h"
  39. #include "net/cookies/cookie_options.h"
  40. #include "net/cookies/cookie_store.h"
  41. #include "net/cookies/cookie_util.h"
  42. #include "net/cookies/parsed_cookie.h"
  43. #include "net/url_request/url_request_context.h"
  44. #include "services/network/cookie_access_delegate_impl.h"
  45. #include "services/network/network_service.h"
  46. #include "services/network/public/mojom/cookie_manager.mojom.h"
  47. #include "third_party/abseil-cpp/absl/types/optional.h"
  48. #include "url/url_constants.h"
  49. using base::WaitableEvent;
  50. using base::android::ConvertJavaStringToUTF16;
  51. using base::android::ConvertJavaStringToUTF8;
  52. using base::android::JavaParamRef;
  53. using base::android::ScopedJavaGlobalRef;
  54. using base::android::ScopedJavaLocalRef;
  55. using content::BrowserThread;
  56. using net::CookieList;
  57. // In the future, we may instead want to inject an explicit CookieStore
  58. // dependency into this object during process initialization to avoid
  59. // depending on the URLRequestContext.
  60. // See issue http://crbug.com/157683
  61. // On the CookieManager methods without a callback and methods with a callback
  62. // when that callback is null can be called from any thread, including threads
  63. // without a message loop. Methods with a non-null callback must be called on
  64. // a thread with a running message loop.
  65. namespace android_webview {
  66. namespace {
  67. void MaybeRunCookieCallback(base::OnceCallback<void(bool)> callback,
  68. const bool& result) {
  69. if (callback)
  70. std::move(callback).Run(result);
  71. }
  72. const char kSecureCookieHistogramName[] = "Android.WebView.SecureCookieAction";
  73. // These values are persisted to logs. Entries should not be renumbered and
  74. // numeric values should never be reused.
  75. enum class SecureCookieAction {
  76. kInvalidUrl = 0,
  77. kAlreadySecureScheme = 1,
  78. kInvalidCookie = 2,
  79. kNotASecureCookie = 3,
  80. kFixedUp = 4,
  81. kDisallowedAndroidR = 5,
  82. kMaxValue = kDisallowedAndroidR,
  83. };
  84. GURL MaybeFixUpSchemeForSecureCookie(const GURL& host,
  85. const std::string& value,
  86. bool workaround_http_secure_cookies,
  87. bool* should_allow_cookie) {
  88. net::ParsedCookie parsed_cookie(value);
  89. *should_allow_cookie = true;
  90. // Log message for catching strict secure cookies related bugs.
  91. // TODO(ntfschr): try to remove this, based on UMA stats
  92. // (https://crbug.com/933981)
  93. if (!host.is_valid()) {
  94. base::UmaHistogramEnumeration(kSecureCookieHistogramName,
  95. SecureCookieAction::kInvalidUrl);
  96. return host;
  97. }
  98. if (host.has_scheme() && !host.SchemeIs(url::kHttpScheme)) {
  99. base::UmaHistogramEnumeration(kSecureCookieHistogramName,
  100. SecureCookieAction::kAlreadySecureScheme);
  101. return host;
  102. }
  103. if (!parsed_cookie.IsValid()) {
  104. base::UmaHistogramEnumeration(kSecureCookieHistogramName,
  105. SecureCookieAction::kInvalidCookie);
  106. return host;
  107. }
  108. if (!parsed_cookie.IsSecure()) {
  109. base::UmaHistogramEnumeration(kSecureCookieHistogramName,
  110. SecureCookieAction::kNotASecureCookie);
  111. return host;
  112. }
  113. LOG(ERROR) << "Strict Secure Cookie policy does not allow setting a "
  114. "secure cookie for "
  115. << host.spec()
  116. << " for apps targeting >= R. Please either use the 'https:' "
  117. "scheme for this URL or omit the 'Secure' directive in the "
  118. "cookie value.";
  119. if (!workaround_http_secure_cookies) {
  120. // Don't allow setting this cookie if we target >= R.
  121. *should_allow_cookie = false;
  122. base::UmaHistogramEnumeration(kSecureCookieHistogramName,
  123. SecureCookieAction::kDisallowedAndroidR);
  124. return host;
  125. }
  126. base::UmaHistogramEnumeration(kSecureCookieHistogramName,
  127. SecureCookieAction::kFixedUp);
  128. GURL::Replacements replace_host;
  129. replace_host.SetSchemeStr(url::kHttpsScheme);
  130. return host.ReplaceComponents(replace_host);
  131. }
  132. // Construct a closure which signals a waitable event if and when the closure
  133. // is called the waitable event must still exist.
  134. static base::OnceClosure SignalEventClosure(WaitableEvent* completion) {
  135. return base::BindOnce(&WaitableEvent::Signal, base::Unretained(completion));
  136. }
  137. static void DiscardBool(base::OnceClosure f, bool b) {
  138. std::move(f).Run();
  139. }
  140. static base::OnceCallback<void(bool)> BoolCallbackAdapter(base::OnceClosure f) {
  141. return base::BindOnce(&DiscardBool, std::move(f));
  142. }
  143. static void DiscardInt(base::OnceClosure f, int i) {
  144. std::move(f).Run();
  145. }
  146. static base::OnceCallback<void(int)> IntCallbackAdapter(base::OnceClosure f) {
  147. return base::BindOnce(&DiscardInt, std::move(f));
  148. }
  149. // Are cookies allowed for file:// URLs by default?
  150. const bool kDefaultFileSchemeAllowed = false;
  151. } // namespace
  152. // static
  153. CookieManager* CookieManager::GetInstance() {
  154. static base::NoDestructor<CookieManager> instance;
  155. return instance.get();
  156. }
  157. namespace {
  158. base::FilePath GetPathInAppDirectory(std::string path) {
  159. base::FilePath result;
  160. if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &result)) {
  161. NOTREACHED() << "Failed to get app data directory for Android WebView";
  162. }
  163. result = result.Append(FILE_PATH_LITERAL(path));
  164. return result;
  165. }
  166. } // namespace
  167. CookieManager::CookieManager()
  168. : allow_file_scheme_cookies_(kDefaultFileSchemeAllowed),
  169. cookie_store_created_(false),
  170. workaround_http_secure_cookies_(
  171. base::android::BuildInfo::GetInstance()->target_sdk_version() <
  172. base::android::SDK_VERSION_R),
  173. cookie_store_client_thread_("CookieMonsterClient"),
  174. cookie_store_backend_thread_("CookieMonsterBackend"),
  175. setting_new_mojo_cookie_manager_(false) {
  176. cookie_store_client_thread_.Start();
  177. cookie_store_backend_thread_.Start();
  178. cookie_store_task_runner_ = cookie_store_client_thread_.task_runner();
  179. // TODO(amalova): initialize cookie_store_path_ for non-default profile
  180. // Do not migrate cookies for non-default profile.
  181. cookie_store_path_ = GetPathInAppDirectory("Default/Cookies");
  182. MigrateCookieStorePath();
  183. }
  184. CookieManager::~CookieManager() = default;
  185. void CookieManager::MigrateCookieStorePath() {
  186. base::FilePath old_cookie_store_path = GetPathInAppDirectory("Cookies");
  187. base::FilePath old_cookie_journal_path =
  188. GetPathInAppDirectory("Cookies-journal");
  189. base::FilePath new_cookie_journal_path =
  190. GetPathInAppDirectory("Default/Cookies-journal");
  191. if (base::PathExists(old_cookie_store_path)) {
  192. base::CreateDirectory(cookie_store_path_.DirName());
  193. base::Move(old_cookie_store_path, cookie_store_path_);
  194. base::Move(old_cookie_journal_path, new_cookie_journal_path);
  195. }
  196. }
  197. // Executes the |task| on |cookie_store_task_runner_| and waits for it to
  198. // complete before returning.
  199. //
  200. // To execute a CookieTask synchronously you must arrange for Signal to be
  201. // called on the waitable event at some point. You can call the bool or int
  202. // versions of ExecCookieTaskSync, these will supply the caller with a dummy
  203. // callback which takes an int/bool, throws it away and calls Signal.
  204. // Alternatively you can call the version which supplies a Closure in which
  205. // case you must call Run on it when you want the unblock the calling code.
  206. //
  207. // Ignore a bool callback.
  208. void CookieManager::ExecCookieTaskSync(
  209. base::OnceCallback<void(base::OnceCallback<void(bool)>)> task) {
  210. WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC,
  211. base::WaitableEvent::InitialState::NOT_SIGNALED);
  212. ExecCookieTask(base::BindOnce(
  213. std::move(task), BoolCallbackAdapter(SignalEventClosure(&completion))));
  214. // Waiting is necessary when implementing synchronous APIs for the WebView
  215. // embedder.
  216. base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope wait;
  217. completion.Wait();
  218. }
  219. // Ignore an int callback.
  220. void CookieManager::ExecCookieTaskSync(
  221. base::OnceCallback<void(base::OnceCallback<void(int)>)> task) {
  222. WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC,
  223. base::WaitableEvent::InitialState::NOT_SIGNALED);
  224. ExecCookieTask(base::BindOnce(
  225. std::move(task), IntCallbackAdapter(SignalEventClosure(&completion))));
  226. base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope wait;
  227. completion.Wait();
  228. }
  229. // Call the supplied closure when you want to signal that the blocked code can
  230. // continue.
  231. void CookieManager::ExecCookieTaskSync(
  232. base::OnceCallback<void(base::OnceClosure)> task) {
  233. WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC,
  234. base::WaitableEvent::InitialState::NOT_SIGNALED);
  235. ExecCookieTask(
  236. base::BindOnce(std::move(task), SignalEventClosure(&completion)));
  237. base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope wait;
  238. completion.Wait();
  239. }
  240. // Executes the |task| using |cookie_store_task_runner_|.
  241. void CookieManager::ExecCookieTask(base::OnceClosure task) {
  242. base::AutoLock lock(task_queue_lock_);
  243. tasks_.push_back(std::move(task));
  244. // Unretained is safe, since android_webview::CookieManager is a singleton we
  245. // never destroy (we don't need PostTask to do any memory management).
  246. cookie_store_task_runner_->PostTask(
  247. FROM_HERE, base::BindOnce(&CookieManager::RunPendingCookieTasks,
  248. base::Unretained(this)));
  249. }
  250. void CookieManager::RunPendingCookieTasks() {
  251. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  252. // Don't do any cookie tasks if in the middle of setting a mojo CookieManager,
  253. // we'll call this method when that operation is finished.
  254. if (setting_new_mojo_cookie_manager_)
  255. return;
  256. // Copy tasks into temp_queue to minimize the amount of time in the critical
  257. // section, and to mitigate live-lock issues if these tasks append to the task
  258. // queue themselves.
  259. base::circular_deque<base::OnceClosure> temp_queue;
  260. {
  261. base::AutoLock lock(task_queue_lock_);
  262. temp_queue.swap(tasks_);
  263. }
  264. while (!temp_queue.empty()) {
  265. std::move(temp_queue.front()).Run();
  266. temp_queue.pop_front();
  267. }
  268. }
  269. base::FilePath CookieManager::GetCookieStorePath() {
  270. return cookie_store_path_;
  271. }
  272. net::CookieStore* CookieManager::GetCookieStore() {
  273. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  274. if (!cookie_store_) {
  275. // TODO(https://crbug.com/1286070): Provide a non-hardcoded value for
  276. // the 'first_party_sets_enabled' argument below.
  277. content::CookieStoreConfig cookie_config(
  278. cookie_store_path_, /* restore_old_session_cookies= */ true,
  279. /* persist_session_cookies= */ true,
  280. /* first_party_sets_enabled= */ false);
  281. cookie_config.client_task_runner = cookie_store_task_runner_;
  282. cookie_config.background_task_runner =
  283. cookie_store_backend_thread_.task_runner();
  284. {
  285. base::AutoLock lock(allow_file_scheme_cookies_lock_);
  286. // There are some unknowns about how to correctly handle file:// cookies,
  287. // and our implementation for this is not robust. http://crbug.com/582985
  288. //
  289. // TODO(mmenke): This call should be removed once we can deprecate and
  290. // remove the Android WebView 'CookieManager::SetAllowFileSchemeCookies'
  291. // method. Until then, note that this is just not a great idea.
  292. cookie_config.cookieable_schemes.insert(
  293. cookie_config.cookieable_schemes.begin(),
  294. net::CookieMonster::kDefaultCookieableSchemes,
  295. net::CookieMonster::kDefaultCookieableSchemes +
  296. net::CookieMonster::kDefaultCookieableSchemesCount);
  297. if (allow_file_scheme_cookies_)
  298. cookie_config.cookieable_schemes.push_back(url::kFileScheme);
  299. cookie_store_created_ = true;
  300. }
  301. cookie_store_ = content::CreateCookieStore(cookie_config, nullptr);
  302. auto cookie_access_delegate_type =
  303. base::CommandLine::ForCurrentProcess()->HasSwitch(
  304. switches::kWebViewEnableModernCookieSameSite)
  305. ? network::mojom::CookieAccessDelegateType::ALWAYS_NONLEGACY
  306. : network::mojom::CookieAccessDelegateType::ALWAYS_LEGACY;
  307. cookie_store_->SetCookieAccessDelegate(
  308. std::make_unique<network::CookieAccessDelegateImpl>(
  309. cookie_access_delegate_type, nullptr /* first_party_sets */));
  310. }
  311. return cookie_store_.get();
  312. }
  313. network::mojom::CookieManager* CookieManager::GetMojoCookieManager() {
  314. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  315. if (!mojo_cookie_manager_.is_bound())
  316. return nullptr;
  317. return mojo_cookie_manager_.get();
  318. }
  319. void CookieManager::SetMojoCookieManager(
  320. mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote) {
  321. DCHECK_CURRENTLY_ON(BrowserThread::UI);
  322. ExecCookieTaskSync(base::BindOnce(&CookieManager::SetMojoCookieManagerAsync,
  323. base::Unretained(this),
  324. std::move(cookie_manager_remote)));
  325. }
  326. void CookieManager::SetMojoCookieManagerAsync(
  327. mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote,
  328. base::OnceClosure complete) {
  329. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  330. setting_new_mojo_cookie_manager_ = true;
  331. // For simplicity, only permit this method to be called once (otherwise, we
  332. // must sometimes flush the mojo_cookie_manager_ instead of cookie_store_).
  333. DCHECK(!mojo_cookie_manager_.is_bound());
  334. if (!cookie_store_created_) {
  335. SwapMojoCookieManagerAsync(std::move(cookie_manager_remote),
  336. std::move(complete));
  337. return;
  338. }
  339. GetCookieStore()->FlushStore(base::BindOnce(
  340. &CookieManager::SwapMojoCookieManagerAsync, base::Unretained(this),
  341. std::move(cookie_manager_remote), std::move(complete)));
  342. }
  343. void CookieManager::SwapMojoCookieManagerAsync(
  344. mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote,
  345. base::OnceClosure complete) {
  346. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  347. mojo_cookie_manager_.Bind(std::move(cookie_manager_remote));
  348. setting_new_mojo_cookie_manager_ = false;
  349. std::move(complete).Run(); // unblock content initialization
  350. RunPendingCookieTasks();
  351. }
  352. void CookieManager::SetWorkaroundHttpSecureCookiesForTesting(
  353. JNIEnv* env,
  354. const JavaParamRef<jobject>& obj,
  355. jboolean allow) {
  356. ExecCookieTaskSync(
  357. base::BindOnce(&CookieManager::SetWorkaroundHttpSecureCookiesAsyncHelper,
  358. base::Unretained(this), allow));
  359. }
  360. void CookieManager::SetWorkaroundHttpSecureCookiesAsyncHelper(
  361. bool allow,
  362. base::OnceClosure complete) {
  363. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  364. workaround_http_secure_cookies_ = allow;
  365. std::move(complete).Run();
  366. }
  367. void CookieManager::SetShouldAcceptCookies(JNIEnv* env,
  368. const JavaParamRef<jobject>& obj,
  369. jboolean accept) {
  370. AwCookieAccessPolicy::GetInstance()->SetShouldAcceptCookies(accept);
  371. }
  372. jboolean CookieManager::GetShouldAcceptCookies(
  373. JNIEnv* env,
  374. const JavaParamRef<jobject>& obj) {
  375. return AwCookieAccessPolicy::GetInstance()->GetShouldAcceptCookies();
  376. }
  377. void CookieManager::SetCookie(JNIEnv* env,
  378. const JavaParamRef<jobject>& obj,
  379. const JavaParamRef<jstring>& url,
  380. const JavaParamRef<jstring>& value,
  381. const JavaParamRef<jobject>& java_callback) {
  382. DCHECK(java_callback) << "Unexpected null Java callback";
  383. GURL host(ConvertJavaStringToUTF16(env, url));
  384. std::string cookie_value(ConvertJavaStringToUTF8(env, value));
  385. base::OnceCallback<void(bool)> callback =
  386. base::BindOnce(&base::android::RunBooleanCallbackAndroid,
  387. ScopedJavaGlobalRef<jobject>(java_callback));
  388. ExecCookieTask(base::BindOnce(&CookieManager::SetCookieHelper,
  389. base::Unretained(this), host, cookie_value,
  390. std::move(callback)));
  391. }
  392. void CookieManager::SetCookieSync(JNIEnv* env,
  393. const JavaParamRef<jobject>& obj,
  394. const JavaParamRef<jstring>& url,
  395. const JavaParamRef<jstring>& value) {
  396. GURL host(ConvertJavaStringToUTF16(env, url));
  397. std::string cookie_value(ConvertJavaStringToUTF8(env, value));
  398. ExecCookieTaskSync(base::BindOnce(&CookieManager::SetCookieHelper,
  399. base::Unretained(this), host,
  400. cookie_value));
  401. }
  402. void CookieManager::SetCookieHelper(const GURL& host,
  403. const std::string& value,
  404. base::OnceCallback<void(bool)> callback) {
  405. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  406. bool should_allow_cookie = true;
  407. const GURL& new_host = MaybeFixUpSchemeForSecureCookie(
  408. host, value, workaround_http_secure_cookies_, &should_allow_cookie);
  409. std::unique_ptr<net::CanonicalCookie> cc(net::CanonicalCookie::Create(
  410. new_host, value, base::Time::Now(), absl::nullopt /* server_time */,
  411. absl::nullopt /* cookie_partition_key */));
  412. if (!cc || !should_allow_cookie) {
  413. MaybeRunCookieCallback(std::move(callback), false);
  414. return;
  415. }
  416. // Note: CookieStore and network::CookieManager both accept a
  417. // CookieAccessResult callback. WebView only cares about boolean success,
  418. // which is why we use |AdaptCookieAccessResultToBool|. This is temporary
  419. // technical debt until we fully launch the Network Service code path.
  420. if (GetMojoCookieManager()) {
  421. // *cc.get() is safe, because network::CookieManager::SetCanonicalCookie
  422. // will make a copy before our smart pointer goes out of scope.
  423. GetMojoCookieManager()->SetCanonicalCookie(
  424. *cc.get(), new_host, net::CookieOptions::MakeAllInclusive(),
  425. net::cookie_util::AdaptCookieAccessResultToBool(std::move(callback)));
  426. } else {
  427. GetCookieStore()->SetCanonicalCookieAsync(
  428. std::move(cc), new_host, net::CookieOptions::MakeAllInclusive(),
  429. net::cookie_util::AdaptCookieAccessResultToBool(std::move(callback)));
  430. }
  431. }
  432. ScopedJavaLocalRef<jstring> CookieManager::GetCookie(
  433. JNIEnv* env,
  434. const JavaParamRef<jobject>& obj,
  435. const JavaParamRef<jstring>& url) {
  436. GURL host(ConvertJavaStringToUTF16(env, url));
  437. net::CookieList cookie_list;
  438. ExecCookieTaskSync(base::BindOnce(&CookieManager::GetCookieListAsyncHelper,
  439. base::Unretained(this), host,
  440. &cookie_list));
  441. return base::android::ConvertUTF8ToJavaString(
  442. env, net::CanonicalCookie::BuildCookieLine(cookie_list));
  443. }
  444. ScopedJavaLocalRef<jobjectArray> CookieManager::GetCookieInfo(
  445. JNIEnv* env,
  446. const JavaParamRef<jobject>& obj,
  447. const JavaParamRef<jstring>& url) {
  448. GURL host(ConvertJavaStringToUTF16(env, url));
  449. net::CookieList cookie_list;
  450. ExecCookieTaskSync(base::BindOnce(&CookieManager::GetCookieListAsyncHelper,
  451. base::Unretained(this), host,
  452. &cookie_list));
  453. std::vector<std::string> cookie_attributes;
  454. for (net::CanonicalCookie cookie : cookie_list) {
  455. cookie_attributes.push_back(
  456. net::CanonicalCookie::BuildCookieAttributesLine(cookie));
  457. }
  458. return base::android::ToJavaArrayOfStrings(
  459. env, base::span<const std::string>(cookie_attributes));
  460. }
  461. void CookieManager::GetCookieListAsyncHelper(const GURL& host,
  462. net::CookieList* result,
  463. base::OnceClosure complete) {
  464. net::CookieOptions options = net::CookieOptions::MakeAllInclusive();
  465. if (GetMojoCookieManager()) {
  466. GetMojoCookieManager()->GetCookieList(
  467. host, options, net::CookiePartitionKeyCollection::Todo(),
  468. base::BindOnce(&CookieManager::GetCookieListCompleted,
  469. base::Unretained(this), std::move(complete), result));
  470. } else {
  471. GetCookieStore()->GetCookieListWithOptionsAsync(
  472. host, options, net::CookiePartitionKeyCollection::Todo(),
  473. base::BindOnce(&CookieManager::GetCookieListCompleted,
  474. base::Unretained(this), std::move(complete), result));
  475. }
  476. }
  477. void CookieManager::GetCookieListCompleted(
  478. base::OnceClosure complete,
  479. net::CookieList* result,
  480. const net::CookieAccessResultList& value,
  481. const net::CookieAccessResultList& excluded_cookies) {
  482. *result = net::cookie_util::StripAccessResults(value);
  483. std::move(complete).Run();
  484. }
  485. void CookieManager::RemoveSessionCookies(
  486. JNIEnv* env,
  487. const JavaParamRef<jobject>& obj,
  488. const JavaParamRef<jobject>& java_callback) {
  489. DCHECK(java_callback) << "Unexpected null Java callback";
  490. base::OnceCallback<void(bool)> callback =
  491. base::BindOnce(&base::android::RunBooleanCallbackAndroid,
  492. ScopedJavaGlobalRef<jobject>(java_callback));
  493. ExecCookieTask(base::BindOnce(&CookieManager::RemoveSessionCookiesHelper,
  494. base::Unretained(this), std::move(callback)));
  495. }
  496. void CookieManager::RemoveSessionCookiesSync(JNIEnv* env,
  497. const JavaParamRef<jobject>& obj) {
  498. ExecCookieTaskSync(base::BindOnce(&CookieManager::RemoveSessionCookiesHelper,
  499. base::Unretained(this)));
  500. }
  501. void CookieManager::RemoveSessionCookiesHelper(
  502. base::OnceCallback<void(bool)> callback) {
  503. if (GetMojoCookieManager()) {
  504. auto match_session_cookies = network::mojom::CookieDeletionFilter::New();
  505. match_session_cookies->session_control =
  506. network::mojom::CookieDeletionSessionControl::SESSION_COOKIES;
  507. GetMojoCookieManager()->DeleteCookies(
  508. std::move(match_session_cookies),
  509. base::BindOnce(&CookieManager::RemoveCookiesCompleted,
  510. base::Unretained(this), std::move(callback)));
  511. } else {
  512. GetCookieStore()->DeleteSessionCookiesAsync(
  513. base::BindOnce(&CookieManager::RemoveCookiesCompleted,
  514. base::Unretained(this), std::move(callback)));
  515. }
  516. }
  517. void CookieManager::RemoveCookiesCompleted(
  518. base::OnceCallback<void(bool)> callback,
  519. uint32_t num_deleted) {
  520. std::move(callback).Run(num_deleted > 0u);
  521. }
  522. void CookieManager::RemoveAllCookies(
  523. JNIEnv* env,
  524. const JavaParamRef<jobject>& obj,
  525. const JavaParamRef<jobject>& java_callback) {
  526. DCHECK(java_callback) << "Unexpected null Java callback";
  527. base::OnceCallback<void(bool)> callback =
  528. base::BindOnce(&base::android::RunBooleanCallbackAndroid,
  529. ScopedJavaGlobalRef<jobject>(java_callback));
  530. ExecCookieTask(base::BindOnce(&CookieManager::RemoveAllCookiesHelper,
  531. base::Unretained(this), std::move(callback)));
  532. }
  533. void CookieManager::RemoveAllCookiesSync(JNIEnv* env,
  534. const JavaParamRef<jobject>& obj) {
  535. ExecCookieTaskSync(base::BindOnce(&CookieManager::RemoveAllCookiesHelper,
  536. base::Unretained(this)));
  537. }
  538. void CookieManager::RemoveAllCookiesHelper(
  539. base::OnceCallback<void(bool)> callback) {
  540. if (GetMojoCookieManager()) {
  541. // An empty filter matches all cookies.
  542. auto match_all_cookies = network::mojom::CookieDeletionFilter::New();
  543. GetMojoCookieManager()->DeleteCookies(
  544. std::move(match_all_cookies),
  545. base::BindOnce(&CookieManager::RemoveCookiesCompleted,
  546. base::Unretained(this), std::move(callback)));
  547. } else {
  548. GetCookieStore()->DeleteAllAsync(
  549. base::BindOnce(&CookieManager::RemoveCookiesCompleted,
  550. base::Unretained(this), std::move(callback)));
  551. }
  552. }
  553. void CookieManager::RemoveExpiredCookies(JNIEnv* env,
  554. const JavaParamRef<jobject>& obj) {
  555. // HasCookies will call GetAllCookiesAsync, which in turn will force a GC.
  556. HasCookies(env, obj);
  557. }
  558. void CookieManager::FlushCookieStore(JNIEnv* env,
  559. const JavaParamRef<jobject>& obj) {
  560. ExecCookieTaskSync(base::BindOnce(&CookieManager::FlushCookieStoreAsyncHelper,
  561. base::Unretained(this)));
  562. }
  563. void CookieManager::FlushCookieStoreAsyncHelper(base::OnceClosure complete) {
  564. if (GetMojoCookieManager()) {
  565. GetMojoCookieManager()->FlushCookieStore(std::move(complete));
  566. } else {
  567. GetCookieStore()->FlushStore(std::move(complete));
  568. }
  569. }
  570. jboolean CookieManager::HasCookies(JNIEnv* env,
  571. const JavaParamRef<jobject>& obj) {
  572. bool has_cookies;
  573. ExecCookieTaskSync(base::BindOnce(&CookieManager::HasCookiesAsyncHelper,
  574. base::Unretained(this), &has_cookies));
  575. return has_cookies;
  576. }
  577. // TODO(kristianm): Simplify this, copying the entire list around
  578. // should not be needed.
  579. void CookieManager::HasCookiesAsyncHelper(bool* result,
  580. base::OnceClosure complete) {
  581. if (GetMojoCookieManager()) {
  582. GetMojoCookieManager()->GetAllCookies(
  583. base::BindOnce(&CookieManager::HasCookiesCompleted,
  584. base::Unretained(this), std::move(complete), result));
  585. } else {
  586. GetCookieStore()->GetAllCookiesAsync(
  587. base::BindOnce(&CookieManager::HasCookiesCompleted,
  588. base::Unretained(this), std::move(complete), result));
  589. }
  590. }
  591. void CookieManager::HasCookiesCompleted(base::OnceClosure complete,
  592. bool* result,
  593. const CookieList& cookies) {
  594. *result = cookies.size() != 0;
  595. std::move(complete).Run();
  596. }
  597. bool CookieManager::GetAllowFileSchemeCookies() {
  598. base::AutoLock lock(allow_file_scheme_cookies_lock_);
  599. return allow_file_scheme_cookies_;
  600. }
  601. jboolean CookieManager::GetAllowFileSchemeCookies(
  602. JNIEnv* env,
  603. const JavaParamRef<jobject>& obj) {
  604. return GetAllowFileSchemeCookies();
  605. }
  606. void CookieManager::SetAllowFileSchemeCookies(JNIEnv* env,
  607. const JavaParamRef<jobject>& obj,
  608. jboolean allow) {
  609. ExecCookieTaskSync(
  610. base::BindOnce(&CookieManager::SetAllowFileSchemeCookiesAsyncHelper,
  611. base::Unretained(this), allow));
  612. }
  613. void CookieManager::SetAllowFileSchemeCookiesAsyncHelper(
  614. bool allow,
  615. base::OnceClosure complete) {
  616. DCHECK(cookie_store_task_runner_->RunsTasksInCurrentSequence());
  617. if (GetMojoCookieManager()) {
  618. GetMojoCookieManager()->AllowFileSchemeCookies(
  619. allow,
  620. base::BindOnce(&CookieManager::SetAllowFileSchemeCookiesCompleted,
  621. base::Unretained(this), std::move(complete), allow));
  622. } else {
  623. // If we have neither a Network Service CookieManager nor have created the
  624. // CookieStore, we may modify |allow_file_scheme_cookies_|.
  625. bool can_change_schemes = !cookie_store_created_;
  626. SetAllowFileSchemeCookiesCompleted(std::move(complete), allow,
  627. can_change_schemes);
  628. }
  629. }
  630. void CookieManager::SetAllowFileSchemeCookiesCompleted(
  631. base::OnceClosure complete,
  632. bool allow,
  633. bool can_change_schemes) {
  634. // Should only update |allow_file_scheme_cookies_| if
  635. // SetAllowFileSchemeCookiesAsyncHelper said this is OK.
  636. if (can_change_schemes) {
  637. base::AutoLock lock(allow_file_scheme_cookies_lock_);
  638. allow_file_scheme_cookies_ = allow;
  639. }
  640. std::move(complete).Run();
  641. }
  642. static jlong JNI_AwCookieManager_GetDefaultCookieManager(JNIEnv* env) {
  643. return reinterpret_cast<intptr_t>(CookieManager::GetInstance());
  644. }
  645. } // namespace android_webview