cookie_manager_impl.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Copyright 2020 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 "weblayer/browser/cookie_manager_impl.h"
  5. #include "build/build_config.h"
  6. #include "content/public/browser/browser_context.h"
  7. #include "content/public/browser/storage_partition.h"
  8. #include "net/cookies/cookie_constants.h"
  9. #include "net/cookies/cookie_util.h"
  10. #include "net/cookies/parsed_cookie.h"
  11. #if BUILDFLAG(IS_ANDROID)
  12. #include "base/android/callback_android.h"
  13. #include "base/android/jni_array.h"
  14. #include "base/android/jni_string.h"
  15. #include "base/android/scoped_java_ref.h"
  16. #include "weblayer/browser/java/jni/CookieManagerImpl_jni.h"
  17. #endif
  18. namespace weblayer {
  19. namespace {
  20. constexpr base::TimeDelta kCookieFlushDelay = base::Seconds(1);
  21. void GetCookieComplete(CookieManager::GetCookieCallback callback,
  22. const net::CookieAccessResultList& cookies,
  23. const net::CookieAccessResultList& excluded_cookies) {
  24. net::CookieList cookie_list = net::cookie_util::StripAccessResults(cookies);
  25. std::move(callback).Run(net::CanonicalCookie::BuildCookieLine(cookie_list));
  26. }
  27. void GetResponseCookiesComplete(
  28. CookieManager::GetResponseCookiesCallback callback,
  29. const net::CookieAccessResultList& cookies,
  30. const net::CookieAccessResultList& excluded_cookies) {
  31. net::CookieList cookie_list = net::cookie_util::StripAccessResults(cookies);
  32. std::vector<std::string> response_cookies;
  33. for (const net::CanonicalCookie& cookie : cookie_list) {
  34. net::ParsedCookie parsed("");
  35. parsed.SetName(cookie.Name());
  36. parsed.SetValue(cookie.Value());
  37. parsed.SetPath(cookie.Path());
  38. parsed.SetDomain(cookie.Domain());
  39. if (!cookie.ExpiryDate().is_null())
  40. parsed.SetExpires(base::TimeFormatHTTP(cookie.ExpiryDate()));
  41. parsed.SetIsSecure(cookie.IsSecure());
  42. parsed.SetIsHttpOnly(cookie.IsHttpOnly());
  43. if (cookie.SameSite() != net::CookieSameSite::UNSPECIFIED)
  44. parsed.SetSameSite(net::CookieSameSiteToString(cookie.SameSite()));
  45. parsed.SetPriority(net::CookiePriorityToString(cookie.Priority()));
  46. parsed.SetIsSameParty(cookie.IsSameParty());
  47. parsed.SetIsPartitioned(cookie.IsPartitioned());
  48. response_cookies.push_back(parsed.ToCookieLine());
  49. }
  50. std::move(callback).Run(response_cookies);
  51. }
  52. #if BUILDFLAG(IS_ANDROID)
  53. void OnCookieChangedAndroid(
  54. base::android::ScopedJavaGlobalRef<jobject> callback,
  55. const net::CookieChangeInfo& change) {
  56. JNIEnv* env = base::android::AttachCurrentThread();
  57. Java_CookieManagerImpl_onCookieChange(
  58. env, callback,
  59. base::android::ConvertUTF8ToJavaString(
  60. env, net::CanonicalCookie::BuildCookieLine({change.cookie})),
  61. static_cast<int>(change.cause));
  62. }
  63. void RunGetResponseCookiesCallback(
  64. const base::android::JavaRef<jobject>& callback,
  65. const std::vector<std::string>& cookies) {
  66. JNIEnv* env = base::android::AttachCurrentThread();
  67. base::android::RunObjectCallbackAndroid(
  68. callback, base::android::ToJavaArrayOfStrings(env, cookies));
  69. }
  70. #endif
  71. void OnCookieChanged(CookieManager::CookieChangedCallbackList* callback_list,
  72. const net::CookieChangeInfo& change) {
  73. callback_list->Notify(change);
  74. }
  75. class CookieChangeListenerImpl : public network::mojom::CookieChangeListener {
  76. public:
  77. explicit CookieChangeListenerImpl(
  78. CookieManager::CookieChangedCallback callback)
  79. : callback_(std::move(callback)) {}
  80. // mojom::CookieChangeListener
  81. void OnCookieChange(const net::CookieChangeInfo& change) override {
  82. callback_.Run(change);
  83. }
  84. private:
  85. CookieManager::CookieChangedCallback callback_;
  86. };
  87. } // namespace
  88. CookieManagerImpl::CookieManagerImpl(content::BrowserContext* browser_context)
  89. : browser_context_(browser_context) {}
  90. CookieManagerImpl::~CookieManagerImpl() = default;
  91. void CookieManagerImpl::SetCookie(const GURL& url,
  92. const std::string& value,
  93. SetCookieCallback callback) {
  94. CHECK(SetCookieInternal(url, value, std::move(callback)));
  95. }
  96. void CookieManagerImpl::GetCookie(const GURL& url, GetCookieCallback callback) {
  97. browser_context_->GetDefaultStoragePartition()
  98. ->GetCookieManagerForBrowserProcess()
  99. ->GetCookieList(url, net::CookieOptions::MakeAllInclusive(),
  100. net::CookiePartitionKeyCollection::Todo(),
  101. base::BindOnce(&GetCookieComplete, std::move(callback)));
  102. }
  103. void CookieManagerImpl::GetResponseCookies(
  104. const GURL& url,
  105. GetResponseCookiesCallback callback) {
  106. browser_context_->GetDefaultStoragePartition()
  107. ->GetCookieManagerForBrowserProcess()
  108. ->GetCookieList(
  109. url, net::CookieOptions::MakeAllInclusive(),
  110. net::CookiePartitionKeyCollection::Todo(),
  111. base::BindOnce(&GetResponseCookiesComplete, std::move(callback)));
  112. }
  113. base::CallbackListSubscription CookieManagerImpl::AddCookieChangedCallback(
  114. const GURL& url,
  115. const std::string* name,
  116. CookieChangedCallback callback) {
  117. auto callback_list = std::make_unique<CookieChangedCallbackList>();
  118. auto* callback_list_ptr = callback_list.get();
  119. int id = AddCookieChangedCallbackInternal(
  120. url, name,
  121. base::BindRepeating(&OnCookieChanged,
  122. base::Owned(std::move(callback_list))));
  123. callback_list_ptr->set_removal_callback(base::BindRepeating(
  124. &CookieManagerImpl::RemoveCookieChangedCallbackInternal,
  125. weak_factory_.GetWeakPtr(), id));
  126. return callback_list_ptr->Add(std::move(callback));
  127. }
  128. #if BUILDFLAG(IS_ANDROID)
  129. bool CookieManagerImpl::SetCookie(
  130. JNIEnv* env,
  131. const base::android::JavaParamRef<jstring>& url,
  132. const base::android::JavaParamRef<jstring>& value,
  133. const base::android::JavaParamRef<jobject>& callback) {
  134. return SetCookieInternal(
  135. GURL(ConvertJavaStringToUTF8(url)), ConvertJavaStringToUTF8(value),
  136. base::BindOnce(&base::android::RunBooleanCallbackAndroid,
  137. base::android::ScopedJavaGlobalRef<jobject>(callback)));
  138. }
  139. void CookieManagerImpl::GetCookie(
  140. JNIEnv* env,
  141. const base::android::JavaParamRef<jstring>& url,
  142. const base::android::JavaParamRef<jobject>& callback) {
  143. GetCookie(
  144. GURL(ConvertJavaStringToUTF8(url)),
  145. base::BindOnce(&base::android::RunStringCallbackAndroid,
  146. base::android::ScopedJavaGlobalRef<jobject>(callback)));
  147. }
  148. void CookieManagerImpl::GetResponseCookies(
  149. JNIEnv* env,
  150. const base::android::JavaParamRef<jstring>& url,
  151. const base::android::JavaParamRef<jobject>& callback) {
  152. GetResponseCookies(
  153. GURL(ConvertJavaStringToUTF8(url)),
  154. base::BindOnce(&RunGetResponseCookiesCallback,
  155. base::android::ScopedJavaGlobalRef<jobject>(callback)));
  156. }
  157. int CookieManagerImpl::AddCookieChangedCallback(
  158. JNIEnv* env,
  159. const base::android::JavaParamRef<jstring>& url,
  160. const base::android::JavaParamRef<jstring>& name,
  161. const base::android::JavaParamRef<jobject>& callback) {
  162. std::string name_str;
  163. if (name)
  164. name_str = ConvertJavaStringToUTF8(name);
  165. return AddCookieChangedCallbackInternal(
  166. GURL(ConvertJavaStringToUTF8(url)), name ? &name_str : nullptr,
  167. base::BindRepeating(
  168. &OnCookieChangedAndroid,
  169. base::android::ScopedJavaGlobalRef<jobject>(callback)));
  170. }
  171. void CookieManagerImpl::RemoveCookieChangedCallback(JNIEnv* env, int id) {
  172. RemoveCookieChangedCallbackInternal(id);
  173. }
  174. #endif
  175. bool CookieManagerImpl::FireFlushTimerForTesting() {
  176. if (!flush_timer_)
  177. return false;
  178. flush_run_loop_for_testing_ = std::make_unique<base::RunLoop>();
  179. flush_timer_->FireNow();
  180. flush_run_loop_for_testing_->Run();
  181. flush_run_loop_for_testing_ = nullptr;
  182. return true;
  183. }
  184. bool CookieManagerImpl::SetCookieInternal(const GURL& url,
  185. const std::string& value,
  186. SetCookieCallback callback) {
  187. auto cc = net::CanonicalCookie::Create(url, value, base::Time::Now(),
  188. absl::nullopt, absl::nullopt);
  189. if (!cc) {
  190. return false;
  191. }
  192. browser_context_->GetDefaultStoragePartition()
  193. ->GetCookieManagerForBrowserProcess()
  194. ->SetCanonicalCookie(
  195. *cc, url, net::CookieOptions::MakeAllInclusive(),
  196. net::cookie_util::AdaptCookieAccessResultToBool(
  197. base::BindOnce(&CookieManagerImpl::OnCookieSet,
  198. weak_factory_.GetWeakPtr(), std::move(callback))));
  199. return true;
  200. }
  201. int CookieManagerImpl::AddCookieChangedCallbackInternal(
  202. const GURL& url,
  203. const std::string* name,
  204. CookieChangedCallback callback) {
  205. mojo::PendingRemote<network::mojom::CookieChangeListener> listener_remote;
  206. auto receiver = listener_remote.InitWithNewPipeAndPassReceiver();
  207. browser_context_->GetDefaultStoragePartition()
  208. ->GetCookieManagerForBrowserProcess()
  209. ->AddCookieChangeListener(
  210. url, name ? absl::make_optional(*name) : absl::nullopt,
  211. std::move(listener_remote));
  212. auto listener =
  213. std::make_unique<CookieChangeListenerImpl>(std::move(callback));
  214. auto* listener_ptr = listener.get();
  215. return cookie_change_receivers_.Add(listener_ptr, std::move(receiver),
  216. std::move(listener));
  217. }
  218. void CookieManagerImpl::RemoveCookieChangedCallbackInternal(int id) {
  219. cookie_change_receivers_.Remove(id);
  220. }
  221. void CookieManagerImpl::OnCookieSet(SetCookieCallback callback, bool success) {
  222. std::move(callback).Run(success);
  223. if (!flush_timer_) {
  224. flush_timer_ = std::make_unique<base::OneShotTimer>();
  225. flush_timer_->Start(FROM_HERE, kCookieFlushDelay,
  226. base::BindOnce(&CookieManagerImpl::OnFlushTimerFired,
  227. weak_factory_.GetWeakPtr()));
  228. }
  229. }
  230. void CookieManagerImpl::OnFlushTimerFired() {
  231. browser_context_->GetDefaultStoragePartition()
  232. ->GetCookieManagerForBrowserProcess()
  233. ->FlushCookieStore(flush_run_loop_for_testing_
  234. ? flush_run_loop_for_testing_->QuitClosure()
  235. : base::DoNothing());
  236. flush_timer_ = nullptr;
  237. }
  238. } // namespace weblayer