cookie_manager.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // Copyright 2019 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. #ifndef ANDROID_WEBVIEW_BROWSER_COOKIE_MANAGER_H_
  5. #define ANDROID_WEBVIEW_BROWSER_COOKIE_MANAGER_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "base/android/jni_array.h"
  9. #include "base/android/scoped_java_ref.h"
  10. #include "base/containers/circular_deque.h"
  11. #include "base/files/file_path.h"
  12. #include "base/no_destructor.h"
  13. #include "base/thread_annotations.h"
  14. #include "base/threading/thread.h"
  15. #include "mojo/public/cpp/bindings/pending_remote.h"
  16. #include "mojo/public/cpp/bindings/remote.h"
  17. #include "services/network/public/mojom/cookie_manager.mojom-forward.h"
  18. #include "services/network/public/mojom/cookie_manager.mojom.h"
  19. class GURL;
  20. namespace base {
  21. class SingleThreadTaskRunner;
  22. }
  23. namespace net {
  24. class CookieStore;
  25. class CanonicalCookie;
  26. }
  27. namespace android_webview {
  28. // CookieManager creates and owns WebView's CookieStore, in addition to handling
  29. // calls into the CookieStore from Java.
  30. //
  31. // Since Java calls can be made on the IO Thread, and must synchronously return
  32. // a result, and the CookieStore API allows it to asynchronously return results,
  33. // the CookieStore must be run on its own thread, to prevent deadlock.
  34. //
  35. // Initialization:
  36. //
  37. // There are two possible scenarios: 1) The CookieManager is used before the
  38. // Network Service is initialized. 2) The CookieManager is not used until after
  39. // the Network Service is initialized (during content initialization).
  40. //
  41. // Case 2) is straightforward: When the
  42. // ContentBrowserClient::ConfigureNetworkContextParams was called
  43. // AwContentBrowserClient will finally call
  44. // CookieManager::SwapMojoCookieManagerAsync by calling
  45. // CookieManager::SetMojoCookieManager, setting the |mojo_cookie_manager_|
  46. // member of CookieManager (the AW one; it's an unfortunately overloaded term).
  47. //
  48. // In case 1), the CookieManager creates a provisional CookieStore
  49. // |cookie_store_|, which it uses for all operations (because the
  50. // network::mojom::CookieManager doesn't exist yet): For every cookie task
  51. // it receives, the CookieManager first checks for the presence of a
  52. // |mojo_cookie_manager_|, and if it doesn't exist, the CookieManager checks for
  53. // the presence of a provisionally-created CookieStore, creating one if it
  54. // doesn't exist (in GetCookieStore). Then whichever one it found will handle
  55. // the cookie task.
  56. //
  57. // When it comes time to create the NetworkContext, which comes with a
  58. // network::mojom::CookieManager, the provisionally-created CookieStore needs to
  59. // transfer its contents (with the results of the pre-content-initialization
  60. // cookie tasks) to the newly created network::mojom::CookieManager. It does
  61. // this by flushing its contents to disk and then calling the same method,
  62. // CookieManager::SwapMojoCookieManagerAsync, which binds the newly created
  63. // network::mojom::CookieManager to |mojo_cookie_manager_|. Thereafter, any
  64. // cookie tasks will be handled by |mojo_cookie_manager_| because it now exists.
  65. //
  66. // This works because the newly created network::mojom::CookieManager reads from
  67. // the same on-disk backing store that the provisionally-created CookieStore
  68. // just flushed its contents to.
  69. //
  70. // Why is this not a race condition? This was addressed in crbug.com/933461.
  71. // If the CookieManager receives cookie tasks while the flush is in progress,
  72. // those tasks are added to a task queue, which is not executed until after the
  73. // new |mojo_cookie_manager_| has finished being set. The new
  74. // |mojo_cookie_manager_| only loads from disk upon receiving a task (*not* upon
  75. // creation, importantly; see CookieMonster::FetchAllCookiesIfNecessary, which
  76. // is only called if cookie tasks are received), so it will not try to load from
  77. // disk until the flush is complete.
  78. class CookieManager {
  79. public:
  80. static CookieManager* GetInstance();
  81. CookieManager(const CookieManager&) = delete;
  82. CookieManager& operator=(const CookieManager&) = delete;
  83. // Passes a |cookie_manager_remote|, which this will use for CookieManager
  84. // APIs going forward. Only called in the Network Service path, with the
  85. // intention this is called once during content initialization (when we create
  86. // the only NetworkContext). Note: no other cookie tasks will be processed
  87. // while this operation is running.
  88. void SetMojoCookieManager(
  89. mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote);
  90. // Configure whether or not this CookieManager should workaround cookies
  91. // specified for insecure URLs with the 'Secure' directive. See
  92. // |workaround_http_secure_cookies_| for the default behavior. This should not
  93. // be needed in production, as the default is the desirable behavior.
  94. void SetWorkaroundHttpSecureCookiesForTesting(
  95. JNIEnv* env,
  96. const base::android::JavaParamRef<jobject>& obj,
  97. jboolean allow);
  98. void SetShouldAcceptCookies(JNIEnv* env,
  99. const base::android::JavaParamRef<jobject>& obj,
  100. jboolean accept);
  101. jboolean GetShouldAcceptCookies(
  102. JNIEnv* env,
  103. const base::android::JavaParamRef<jobject>& obj);
  104. void SetCookie(JNIEnv* env,
  105. const base::android::JavaParamRef<jobject>& obj,
  106. const base::android::JavaParamRef<jstring>& url,
  107. const base::android::JavaParamRef<jstring>& value,
  108. const base::android::JavaParamRef<jobject>& java_callback);
  109. void SetCookieSync(JNIEnv* env,
  110. const base::android::JavaParamRef<jobject>& obj,
  111. const base::android::JavaParamRef<jstring>& url,
  112. const base::android::JavaParamRef<jstring>& value);
  113. base::android::ScopedJavaLocalRef<jstring> GetCookie(
  114. JNIEnv* env,
  115. const base::android::JavaParamRef<jobject>& obj,
  116. const base::android::JavaParamRef<jstring>& url);
  117. base::android::ScopedJavaLocalRef<jobjectArray> GetCookieInfo(
  118. JNIEnv* env,
  119. const base::android::JavaParamRef<jobject>& obj,
  120. const base::android::JavaParamRef<jstring>& url);
  121. void RemoveAllCookies(
  122. JNIEnv* env,
  123. const base::android::JavaParamRef<jobject>& obj,
  124. const base::android::JavaParamRef<jobject>& java_callback);
  125. void RemoveSessionCookies(
  126. JNIEnv* env,
  127. const base::android::JavaParamRef<jobject>& obj,
  128. const base::android::JavaParamRef<jobject>& java_callback);
  129. void RemoveAllCookiesSync(JNIEnv* env,
  130. const base::android::JavaParamRef<jobject>& obj);
  131. void RemoveSessionCookiesSync(
  132. JNIEnv* env,
  133. const base::android::JavaParamRef<jobject>& obj);
  134. void RemoveExpiredCookies(JNIEnv* env,
  135. const base::android::JavaParamRef<jobject>& obj);
  136. void FlushCookieStore(JNIEnv* env,
  137. const base::android::JavaParamRef<jobject>& obj);
  138. jboolean HasCookies(JNIEnv* env,
  139. const base::android::JavaParamRef<jobject>& obj);
  140. bool GetAllowFileSchemeCookies();
  141. jboolean GetAllowFileSchemeCookies(
  142. JNIEnv* env,
  143. const base::android::JavaParamRef<jobject>& obj);
  144. // Configures whether CookieManager and WebView instances will honor requests
  145. // to set cookies for file:// scheme URLs. This method must be called (and
  146. // must finish execution) before calling any other WebView APIs which modify
  147. // the cookie store (otherwise, this is not guaranteed to succeed).
  148. //
  149. // This blocks the calling thread until its work is done to achieve this
  150. // guarantee (otherwise other mojo::Remote<network::mojom::CookieManager>
  151. // instances might be able to modify the underlying net::CookieStore before
  152. // this call finishes.
  153. void SetAllowFileSchemeCookies(
  154. JNIEnv* env,
  155. const base::android::JavaParamRef<jobject>& obj,
  156. jboolean allow);
  157. base::FilePath GetCookieStorePath();
  158. private:
  159. friend class base::NoDestructor<CookieManager>;
  160. CookieManager();
  161. ~CookieManager();
  162. // Returns the CookieStore, creating it if necessary. This must only be called
  163. // on the CookieStore TaskRunner.
  164. net::CookieStore* GetCookieStore();
  165. // Gets the Network Service CookieManager if it's been passed via
  166. // |SetMojoCookieManager|. Otherwise (if Network Service is disabled or
  167. // content layer has not yet initialized the NetworkContext), this returns
  168. // nullptr (and |GetCookieStore| should be used installed). This must only be
  169. // called on the CookieStore TaskRunner.
  170. network::mojom::CookieManager* GetMojoCookieManager();
  171. void ExecCookieTaskSync(
  172. base::OnceCallback<void(base::OnceCallback<void(bool)>)> task);
  173. void ExecCookieTaskSync(
  174. base::OnceCallback<void(base::OnceCallback<void(int)>)> task);
  175. void ExecCookieTaskSync(base::OnceCallback<void(base::OnceClosure)> task);
  176. void ExecCookieTask(base::OnceClosure task);
  177. // Runs all queued-up cookie tasks in |tasks_|.
  178. void RunPendingCookieTasks();
  179. void SetCookieHelper(const GURL& host,
  180. const std::string& value,
  181. base::OnceCallback<void(bool)> callback);
  182. void SetWorkaroundHttpSecureCookiesAsyncHelper(bool allow,
  183. base::OnceClosure complete);
  184. void GotCookies(const std::vector<net::CanonicalCookie>& cookies);
  185. void GetCookieListAsyncHelper(const GURL& host,
  186. net::CookieList* result,
  187. base::OnceClosure complete);
  188. void GetCookieListCompleted(
  189. base::OnceClosure complete,
  190. net::CookieList* result,
  191. const net::CookieAccessResultList& value,
  192. const net::CookieAccessResultList& excluded_cookies);
  193. void RemoveSessionCookiesHelper(base::OnceCallback<void(bool)> callback);
  194. void RemoveAllCookiesHelper(base::OnceCallback<void(bool)> callback);
  195. void RemoveCookiesCompleted(base::OnceCallback<void(bool)> callback,
  196. uint32_t num_deleted);
  197. void FlushCookieStoreAsyncHelper(base::OnceClosure complete);
  198. void SetMojoCookieManagerAsync(
  199. mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote,
  200. base::OnceClosure complete);
  201. void SwapMojoCookieManagerAsync(
  202. mojo::PendingRemote<network::mojom::CookieManager> cookie_manager_remote,
  203. base::OnceClosure complete);
  204. void HasCookiesAsyncHelper(bool* result, base::OnceClosure complete);
  205. void HasCookiesCompleted(base::OnceClosure complete,
  206. bool* result,
  207. const net::CookieList& cookies);
  208. void SetAllowFileSchemeCookiesAsyncHelper(bool allow,
  209. base::OnceClosure complete);
  210. // |can_change_schemes| indicates whether or not this call was successful,
  211. // indicating whether we may update |allow_file_scheme_cookies_|.
  212. void SetAllowFileSchemeCookiesCompleted(base::OnceClosure complete,
  213. bool allow,
  214. bool can_change_schemes);
  215. void MigrateCookieStorePath();
  216. base::FilePath cookie_store_path_;
  217. // This protects the following bool, as it's used on multiple threads.
  218. base::Lock allow_file_scheme_cookies_lock_;
  219. // True if cookies should be allowed for file URLs. Can only be changed prior
  220. // to creating the CookieStore.
  221. bool allow_file_scheme_cookies_ GUARDED_BY(allow_file_scheme_cookies_lock_);
  222. // True once the cookie store has been created. Just used to track when
  223. // |allow_file_scheme_cookies_| can no longer be modified. Only accessed on
  224. // |cookie_store_task_runner_|.
  225. bool cookie_store_created_;
  226. // Whether or not to workaround 'Secure' cookies set on insecure URLs. See
  227. // MaybeFixUpSchemeForSecureCookieAndGetSameSite. Only accessed on
  228. // |cookie_store_task_runner_|. Defaults to false starting for apps targeting
  229. // >= R.
  230. bool workaround_http_secure_cookies_;
  231. base::Thread cookie_store_client_thread_;
  232. base::Thread cookie_store_backend_thread_;
  233. scoped_refptr<base::SingleThreadTaskRunner> cookie_store_task_runner_;
  234. std::unique_ptr<net::CookieStore> cookie_store_;
  235. // Tracks if we're in the middle of a call to SetMojoCookieManager(). See the
  236. // note in SetMojoCookieManager(). Must only be accessed on
  237. // |cookie_store_task_runner_|.
  238. bool setting_new_mojo_cookie_manager_;
  239. // |tasks_| is a queue we manage, to allow us to delay tasks until after
  240. // SetMojoCookieManager()'s work is done. This is modified on different
  241. // threads, so accesses must be guarded by |task_queue_lock_|.
  242. base::Lock task_queue_lock_;
  243. base::circular_deque<base::OnceClosure> tasks_ GUARDED_BY(task_queue_lock_);
  244. // The CookieManager shared with the NetworkContext.
  245. mojo::Remote<network::mojom::CookieManager> mojo_cookie_manager_;
  246. };
  247. } // namespace android_webview
  248. #endif // ANDROID_WEBVIEW_BROWSER_COOKIE_MANAGER_H_