| OLD | NEW |
| (Empty) |
| 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 | |
| 5 #include "android_webview/native/cookie_manager.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 #include <utility> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "android_webview/browser/aw_browser_context.h" | |
| 12 #include "android_webview/browser/aw_cookie_access_policy.h" | |
| 13 #include "android_webview/browser/net/init_native_callback.h" | |
| 14 #include "base/android/jni_string.h" | |
| 15 #include "base/android/path_utils.h" | |
| 16 #include "base/bind.h" | |
| 17 #include "base/bind_helpers.h" | |
| 18 #include "base/files/file_path.h" | |
| 19 #include "base/files/file_util.h" | |
| 20 #include "base/lazy_instance.h" | |
| 21 #include "base/location.h" | |
| 22 #include "base/logging.h" | |
| 23 #include "base/memory/ref_counted.h" | |
| 24 #include "base/path_service.h" | |
| 25 #include "base/single_thread_task_runner.h" | |
| 26 #include "base/synchronization/lock.h" | |
| 27 #include "base/synchronization/waitable_event.h" | |
| 28 #include "base/threading/sequenced_worker_pool.h" | |
| 29 #include "base/threading/thread.h" | |
| 30 #include "base/threading/thread_restrictions.h" | |
| 31 #include "content/public/browser/browser_context.h" | |
| 32 #include "content/public/browser/browser_thread.h" | |
| 33 #include "content/public/browser/cookie_store_factory.h" | |
| 34 #include "jni/AwCookieManager_jni.h" | |
| 35 #include "net/cookies/cookie_monster.h" | |
| 36 #include "net/cookies/cookie_options.h" | |
| 37 #include "net/cookies/cookie_store.h" | |
| 38 #include "net/cookies/parsed_cookie.h" | |
| 39 #include "net/extras/sqlite/cookie_crypto_delegate.h" | |
| 40 #include "net/url_request/url_request_context.h" | |
| 41 #include "url/url_constants.h" | |
| 42 | |
| 43 using base::FilePath; | |
| 44 using base::WaitableEvent; | |
| 45 using base::android::ConvertJavaStringToUTF8; | |
| 46 using base::android::ConvertJavaStringToUTF16; | |
| 47 using base::android::JavaParamRef; | |
| 48 using base::android::ScopedJavaGlobalRef; | |
| 49 using base::android::ScopedJavaLocalRef; | |
| 50 using content::BrowserThread; | |
| 51 using net::CookieList; | |
| 52 | |
| 53 // In the future, we may instead want to inject an explicit CookieStore | |
| 54 // dependency into this object during process initialization to avoid | |
| 55 // depending on the URLRequestContext. | |
| 56 // See issue http://crbug.com/157683 | |
| 57 | |
| 58 // On the CookieManager methods without a callback and methods with a callback | |
| 59 // when that callback is null can be called from any thread, including threads | |
| 60 // without a message loop. Methods with a non-null callback must be called on | |
| 61 // a thread with a running message loop. | |
| 62 | |
| 63 namespace android_webview { | |
| 64 | |
| 65 namespace { | |
| 66 | |
| 67 typedef base::Callback<void(bool)> BoolCallback; | |
| 68 typedef base::Callback<void(int)> IntCallback; | |
| 69 | |
| 70 // Holds a Java BooleanCookieCallback, knows how to invoke it and turn it | |
| 71 // into a base callback. | |
| 72 class BoolCookieCallbackHolder { | |
| 73 public: | |
| 74 BoolCookieCallbackHolder(JNIEnv* env, jobject callback) { | |
| 75 callback_.Reset(env, callback); | |
| 76 } | |
| 77 | |
| 78 void Invoke(bool result) { | |
| 79 if (!callback_.is_null()) { | |
| 80 JNIEnv* env = base::android::AttachCurrentThread(); | |
| 81 Java_AwCookieManager_invokeBooleanCookieCallback(env, callback_, result); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 static BoolCallback ConvertToCallback( | |
| 86 std::unique_ptr<BoolCookieCallbackHolder> me) { | |
| 87 return base::Bind(&BoolCookieCallbackHolder::Invoke, | |
| 88 base::Owned(me.release())); | |
| 89 } | |
| 90 | |
| 91 private: | |
| 92 ScopedJavaGlobalRef<jobject> callback_; | |
| 93 DISALLOW_COPY_AND_ASSIGN(BoolCookieCallbackHolder); | |
| 94 }; | |
| 95 | |
| 96 // Construct a closure which signals a waitable event if and when the closure | |
| 97 // is called the waitable event must still exist. | |
| 98 static base::Closure SignalEventClosure(WaitableEvent* completion) { | |
| 99 return base::Bind(&WaitableEvent::Signal, base::Unretained(completion)); | |
| 100 } | |
| 101 | |
| 102 static void DiscardBool(const base::Closure& f, bool b) { | |
| 103 f.Run(); | |
| 104 } | |
| 105 | |
| 106 static BoolCallback BoolCallbackAdapter(const base::Closure& f) { | |
| 107 return base::Bind(&DiscardBool, f); | |
| 108 } | |
| 109 | |
| 110 static void DiscardInt(const base::Closure& f, int i) { | |
| 111 f.Run(); | |
| 112 } | |
| 113 | |
| 114 static IntCallback IntCallbackAdapter(const base::Closure& f) { | |
| 115 return base::Bind(&DiscardInt, f); | |
| 116 } | |
| 117 | |
| 118 // Are cookies allowed for file:// URLs by default? | |
| 119 const bool kDefaultFileSchemeAllowed = false; | |
| 120 | |
| 121 void ImportLegacyCookieStore(const FilePath& cookie_store_path) { | |
| 122 // We use the old cookie store to create the new cookie store only if the | |
| 123 // new cookie store does not exist. | |
| 124 if (base::PathExists(cookie_store_path)) | |
| 125 return; | |
| 126 | |
| 127 // WebViewClassic gets the database path from Context and appends a | |
| 128 // hardcoded name. See: | |
| 129 // https://android.googlesource.com/platform/frameworks/base/+/bf6f6f9d/core/j
ava/android/webkit/JniUtil.java | |
| 130 // https://android.googlesource.com/platform/external/webkit/+/7151e/ | |
| 131 // Source/WebKit/android/WebCoreSupport/WebCookieJar.cpp | |
| 132 FilePath old_cookie_store_path; | |
| 133 base::android::GetDatabaseDirectory(&old_cookie_store_path); | |
| 134 old_cookie_store_path = old_cookie_store_path.Append( | |
| 135 FILE_PATH_LITERAL("webviewCookiesChromium.db")); | |
| 136 if (base::PathExists(old_cookie_store_path) && | |
| 137 !base::Move(old_cookie_store_path, cookie_store_path)) { | |
| 138 LOG(WARNING) << "Failed to move old cookie store path from " | |
| 139 << old_cookie_store_path.AsUTF8Unsafe() << " to " | |
| 140 << cookie_store_path.AsUTF8Unsafe(); | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 void GetUserDataDir(FilePath* user_data_dir) { | |
| 145 if (!PathService::Get(base::DIR_ANDROID_APP_DATA, user_data_dir)) { | |
| 146 NOTREACHED() << "Failed to get app data directory for Android WebView"; | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 } // namespace | |
| 151 | |
| 152 // CookieManager creates and owns Webview's CookieStore, in addition to handling | |
| 153 // calls into the CookieStore from Java. | |
| 154 // | |
| 155 // Since Java calls can be made on the IO Thread, and must synchronously return | |
| 156 // a result, and the CookieStore API allows it to asynchronously return results, | |
| 157 // the CookieStore must be run on its own thread, to prevent deadlock. | |
| 158 class CookieManager { | |
| 159 public: | |
| 160 static CookieManager* GetInstance(); | |
| 161 | |
| 162 // Returns the TaskRunner on which the CookieStore lives. | |
| 163 base::SingleThreadTaskRunner* GetCookieStoreTaskRunner(); | |
| 164 // Returns the CookieStore, creating it if necessary. This must only be called | |
| 165 // on the CookieStore TaskRunner. | |
| 166 net::CookieStore* GetCookieStore(); | |
| 167 | |
| 168 void SetShouldAcceptCookies(bool accept); | |
| 169 bool GetShouldAcceptCookies(); | |
| 170 void SetCookie(const GURL& host, | |
| 171 const std::string& cookie_value, | |
| 172 std::unique_ptr<BoolCookieCallbackHolder> callback); | |
| 173 void SetCookieSync(const GURL& host, const std::string& cookie_value); | |
| 174 std::string GetCookie(const GURL& host); | |
| 175 void RemoveSessionCookies(std::unique_ptr<BoolCookieCallbackHolder> callback); | |
| 176 void RemoveAllCookies(std::unique_ptr<BoolCookieCallbackHolder> callback); | |
| 177 void RemoveAllCookiesSync(); | |
| 178 void RemoveSessionCookiesSync(); | |
| 179 void RemoveExpiredCookies(); | |
| 180 void FlushCookieStore(); | |
| 181 bool HasCookies(); | |
| 182 bool AllowFileSchemeCookies(); | |
| 183 void SetAcceptFileSchemeCookies(bool accept); | |
| 184 | |
| 185 private: | |
| 186 friend struct base::LazyInstanceTraitsBase<CookieManager>; | |
| 187 | |
| 188 CookieManager(); | |
| 189 ~CookieManager(); | |
| 190 | |
| 191 void ExecCookieTaskSync(const base::Callback<void(BoolCallback)>& task); | |
| 192 void ExecCookieTaskSync(const base::Callback<void(IntCallback)>& task); | |
| 193 void ExecCookieTaskSync(const base::Callback<void(base::Closure)>& task); | |
| 194 void ExecCookieTask(const base::Closure& task); | |
| 195 | |
| 196 void SetCookieHelper(const GURL& host, | |
| 197 const std::string& value, | |
| 198 BoolCallback callback); | |
| 199 | |
| 200 void GetCookieValueAsyncHelper(const GURL& host, | |
| 201 std::string* result, | |
| 202 base::Closure complete); | |
| 203 void GetCookieValueCompleted(base::Closure complete, | |
| 204 std::string* result, | |
| 205 const std::string& value); | |
| 206 | |
| 207 void RemoveSessionCookiesHelper(BoolCallback callback); | |
| 208 void RemoveAllCookiesHelper(BoolCallback callback); | |
| 209 void RemoveCookiesCompleted(BoolCallback callback, int num_deleted); | |
| 210 | |
| 211 void FlushCookieStoreAsyncHelper(base::Closure complete); | |
| 212 | |
| 213 void HasCookiesAsyncHelper(bool* result, base::Closure complete); | |
| 214 void HasCookiesCompleted(base::Closure complete, | |
| 215 bool* result, | |
| 216 const net::CookieList& cookies); | |
| 217 | |
| 218 // This protects the following two bools, as they're used on multiple threads. | |
| 219 base::Lock accept_file_scheme_cookies_lock_; | |
| 220 // True if cookies should be allowed for file URLs. Can only be changed prior | |
| 221 // to creating the CookieStore. | |
| 222 bool accept_file_scheme_cookies_; | |
| 223 // True once the cookie store has been created. Just used to track when | |
| 224 // |accept_file_scheme_cookies_| can no longer be modified. | |
| 225 bool cookie_store_created_; | |
| 226 | |
| 227 base::Thread cookie_store_client_thread_; | |
| 228 base::Thread cookie_store_backend_thread_; | |
| 229 | |
| 230 scoped_refptr<base::SingleThreadTaskRunner> cookie_store_task_runner_; | |
| 231 std::unique_ptr<net::CookieStore> cookie_store_; | |
| 232 | |
| 233 DISALLOW_COPY_AND_ASSIGN(CookieManager); | |
| 234 }; | |
| 235 | |
| 236 namespace { | |
| 237 base::LazyInstance<CookieManager>::Leaky g_lazy_instance; | |
| 238 } | |
| 239 | |
| 240 // static | |
| 241 CookieManager* CookieManager::GetInstance() { | |
| 242 return g_lazy_instance.Pointer(); | |
| 243 } | |
| 244 | |
| 245 CookieManager::CookieManager() | |
| 246 : accept_file_scheme_cookies_(kDefaultFileSchemeAllowed), | |
| 247 cookie_store_created_(false), | |
| 248 cookie_store_client_thread_("CookieMonsterClient"), | |
| 249 cookie_store_backend_thread_("CookieMonsterBackend") { | |
| 250 cookie_store_client_thread_.Start(); | |
| 251 cookie_store_backend_thread_.Start(); | |
| 252 cookie_store_task_runner_ = cookie_store_client_thread_.task_runner(); | |
| 253 } | |
| 254 | |
| 255 CookieManager::~CookieManager() { | |
| 256 } | |
| 257 | |
| 258 // Executes the |task| on |cookie_store_task_runner_| and waits for it to | |
| 259 // complete before returning. | |
| 260 // | |
| 261 // To execute a CookieTask synchronously you must arrange for Signal to be | |
| 262 // called on the waitable event at some point. You can call the bool or int | |
| 263 // versions of ExecCookieTaskSync, these will supply the caller with a dummy | |
| 264 // callback which takes an int/bool, throws it away and calls Signal. | |
| 265 // Alternatively you can call the version which supplies a Closure in which | |
| 266 // case you must call Run on it when you want the unblock the calling code. | |
| 267 // | |
| 268 // Ignore a bool callback. | |
| 269 void CookieManager::ExecCookieTaskSync( | |
| 270 const base::Callback<void(BoolCallback)>& task) { | |
| 271 WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 272 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 273 ExecCookieTask( | |
| 274 base::Bind(task, BoolCallbackAdapter(SignalEventClosure(&completion)))); | |
| 275 base::ThreadRestrictions::ScopedAllowWait wait; | |
| 276 completion.Wait(); | |
| 277 } | |
| 278 | |
| 279 // Ignore an int callback. | |
| 280 void CookieManager::ExecCookieTaskSync( | |
| 281 const base::Callback<void(IntCallback)>& task) { | |
| 282 WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 283 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 284 ExecCookieTask( | |
| 285 base::Bind(task, IntCallbackAdapter(SignalEventClosure(&completion)))); | |
| 286 base::ThreadRestrictions::ScopedAllowWait wait; | |
| 287 completion.Wait(); | |
| 288 } | |
| 289 | |
| 290 // Call the supplied closure when you want to signal that the blocked code can | |
| 291 // continue. | |
| 292 void CookieManager::ExecCookieTaskSync( | |
| 293 const base::Callback<void(base::Closure)>& task) { | |
| 294 WaitableEvent completion(base::WaitableEvent::ResetPolicy::AUTOMATIC, | |
| 295 base::WaitableEvent::InitialState::NOT_SIGNALED); | |
| 296 ExecCookieTask(base::Bind(task, SignalEventClosure(&completion))); | |
| 297 base::ThreadRestrictions::ScopedAllowWait wait; | |
| 298 completion.Wait(); | |
| 299 } | |
| 300 | |
| 301 // Executes the |task| using |cookie_store_task_runner_|. | |
| 302 void CookieManager::ExecCookieTask(const base::Closure& task) { | |
| 303 cookie_store_task_runner_->PostTask(FROM_HERE, task); | |
| 304 } | |
| 305 | |
| 306 base::SingleThreadTaskRunner* CookieManager::GetCookieStoreTaskRunner() { | |
| 307 return cookie_store_task_runner_.get(); | |
| 308 } | |
| 309 | |
| 310 net::CookieStore* CookieManager::GetCookieStore() { | |
| 311 DCHECK(cookie_store_task_runner_->RunsTasksOnCurrentThread()); | |
| 312 | |
| 313 if (!cookie_store_) { | |
| 314 FilePath user_data_dir; | |
| 315 GetUserDataDir(&user_data_dir); | |
| 316 FilePath cookie_store_path = | |
| 317 user_data_dir.Append(FILE_PATH_LITERAL("Cookies")); | |
| 318 | |
| 319 cookie_store_backend_thread_.task_runner()->PostTask( | |
| 320 FROM_HERE, base::Bind(ImportLegacyCookieStore, cookie_store_path)); | |
| 321 | |
| 322 content::CookieStoreConfig cookie_config( | |
| 323 cookie_store_path, content::CookieStoreConfig::RESTORED_SESSION_COOKIES, | |
| 324 nullptr, nullptr); | |
| 325 cookie_config.client_task_runner = cookie_store_task_runner_; | |
| 326 cookie_config.background_task_runner = | |
| 327 cookie_store_backend_thread_.task_runner(); | |
| 328 | |
| 329 { | |
| 330 base::AutoLock lock(accept_file_scheme_cookies_lock_); | |
| 331 | |
| 332 // There are some unknowns about how to correctly handle file:// cookies, | |
| 333 // and our implementation for this is not robust. http://crbug.com/582985 | |
| 334 // | |
| 335 // TODO(mmenke): This call should be removed once we can deprecate and | |
| 336 // remove the Android WebView 'CookieManager::setAcceptFileSchemeCookies' | |
| 337 // method. Until then, note that this is just not a great idea. | |
| 338 cookie_config.cookieable_schemes.insert( | |
| 339 cookie_config.cookieable_schemes.begin(), | |
| 340 net::CookieMonster::kDefaultCookieableSchemes, | |
| 341 net::CookieMonster::kDefaultCookieableSchemes + | |
| 342 net::CookieMonster::kDefaultCookieableSchemesCount); | |
| 343 if (accept_file_scheme_cookies_) | |
| 344 cookie_config.cookieable_schemes.push_back(url::kFileScheme); | |
| 345 cookie_store_created_ = true; | |
| 346 } | |
| 347 | |
| 348 cookie_store_ = content::CreateCookieStore(cookie_config); | |
| 349 } | |
| 350 | |
| 351 return cookie_store_.get(); | |
| 352 } | |
| 353 | |
| 354 void CookieManager::SetShouldAcceptCookies(bool accept) { | |
| 355 AwCookieAccessPolicy::GetInstance()->SetShouldAcceptCookies(accept); | |
| 356 } | |
| 357 | |
| 358 bool CookieManager::GetShouldAcceptCookies() { | |
| 359 return AwCookieAccessPolicy::GetInstance()->GetShouldAcceptCookies(); | |
| 360 } | |
| 361 | |
| 362 void CookieManager::SetCookie( | |
| 363 const GURL& host, | |
| 364 const std::string& cookie_value, | |
| 365 std::unique_ptr<BoolCookieCallbackHolder> callback_holder) { | |
| 366 BoolCallback callback = | |
| 367 BoolCookieCallbackHolder::ConvertToCallback(std::move(callback_holder)); | |
| 368 ExecCookieTask(base::Bind(&CookieManager::SetCookieHelper, | |
| 369 base::Unretained(this), | |
| 370 host, | |
| 371 cookie_value, | |
| 372 callback)); | |
| 373 } | |
| 374 | |
| 375 void CookieManager::SetCookieSync(const GURL& host, | |
| 376 const std::string& cookie_value) { | |
| 377 ExecCookieTaskSync(base::Bind(&CookieManager::SetCookieHelper, | |
| 378 base::Unretained(this), | |
| 379 host, | |
| 380 cookie_value)); | |
| 381 } | |
| 382 | |
| 383 void CookieManager::SetCookieHelper( | |
| 384 const GURL& host, | |
| 385 const std::string& value, | |
| 386 const BoolCallback callback) { | |
| 387 net::CookieOptions options; | |
| 388 options.set_include_httponly(); | |
| 389 | |
| 390 // Log message for catching strict secure cookies related bugs. | |
| 391 // TODO(sgurun) temporary. Add UMA stats to monitor, and remove afterwards. | |
| 392 if (host.is_valid() && | |
| 393 (!host.has_scheme() || host.SchemeIs(url::kHttpScheme))) { | |
| 394 net::ParsedCookie parsed_cookie(value); | |
| 395 if (parsed_cookie.IsValid() && parsed_cookie.IsSecure()) { | |
| 396 LOG(WARNING) << "Strict Secure Cookie policy does not allow setting a " | |
| 397 "secure cookie for " | |
| 398 << host.spec(); | |
| 399 GURL::Replacements replace_host; | |
| 400 replace_host.SetSchemeStr("https"); | |
| 401 GURL new_host = host.ReplaceComponents(replace_host); | |
| 402 GetCookieStore()->SetCookieWithOptionsAsync(new_host, value, options, | |
| 403 callback); | |
| 404 return; | |
| 405 } | |
| 406 } | |
| 407 | |
| 408 GetCookieStore()->SetCookieWithOptionsAsync(host, value, options, callback); | |
| 409 } | |
| 410 | |
| 411 std::string CookieManager::GetCookie(const GURL& host) { | |
| 412 std::string cookie_value; | |
| 413 ExecCookieTaskSync(base::Bind(&CookieManager::GetCookieValueAsyncHelper, | |
| 414 base::Unretained(this), | |
| 415 host, | |
| 416 &cookie_value)); | |
| 417 return cookie_value; | |
| 418 } | |
| 419 | |
| 420 void CookieManager::GetCookieValueAsyncHelper( | |
| 421 const GURL& host, | |
| 422 std::string* result, | |
| 423 base::Closure complete) { | |
| 424 net::CookieOptions options; | |
| 425 options.set_include_httponly(); | |
| 426 | |
| 427 GetCookieStore()->GetCookiesWithOptionsAsync( | |
| 428 host, options, base::Bind(&CookieManager::GetCookieValueCompleted, | |
| 429 base::Unretained(this), complete, result)); | |
| 430 } | |
| 431 | |
| 432 void CookieManager::GetCookieValueCompleted(base::Closure complete, | |
| 433 std::string* result, | |
| 434 const std::string& value) { | |
| 435 *result = value; | |
| 436 complete.Run(); | |
| 437 } | |
| 438 | |
| 439 void CookieManager::RemoveSessionCookies( | |
| 440 std::unique_ptr<BoolCookieCallbackHolder> callback_holder) { | |
| 441 BoolCallback callback = | |
| 442 BoolCookieCallbackHolder::ConvertToCallback(std::move(callback_holder)); | |
| 443 ExecCookieTask(base::Bind(&CookieManager::RemoveSessionCookiesHelper, | |
| 444 base::Unretained(this), | |
| 445 callback)); | |
| 446 } | |
| 447 | |
| 448 void CookieManager::RemoveSessionCookiesSync() { | |
| 449 ExecCookieTaskSync(base::Bind(&CookieManager::RemoveSessionCookiesHelper, | |
| 450 base::Unretained(this))); | |
| 451 } | |
| 452 | |
| 453 void CookieManager::RemoveSessionCookiesHelper( | |
| 454 BoolCallback callback) { | |
| 455 GetCookieStore()->DeleteSessionCookiesAsync( | |
| 456 base::Bind(&CookieManager::RemoveCookiesCompleted, base::Unretained(this), | |
| 457 callback)); | |
| 458 } | |
| 459 | |
| 460 void CookieManager::RemoveCookiesCompleted( | |
| 461 BoolCallback callback, | |
| 462 int num_deleted) { | |
| 463 callback.Run(num_deleted > 0); | |
| 464 } | |
| 465 | |
| 466 void CookieManager::RemoveAllCookies( | |
| 467 std::unique_ptr<BoolCookieCallbackHolder> callback_holder) { | |
| 468 BoolCallback callback = | |
| 469 BoolCookieCallbackHolder::ConvertToCallback(std::move(callback_holder)); | |
| 470 ExecCookieTask(base::Bind(&CookieManager::RemoveAllCookiesHelper, | |
| 471 base::Unretained(this), | |
| 472 callback)); | |
| 473 } | |
| 474 | |
| 475 void CookieManager::RemoveAllCookiesSync() { | |
| 476 ExecCookieTaskSync(base::Bind(&CookieManager::RemoveAllCookiesHelper, | |
| 477 base::Unretained(this))); | |
| 478 } | |
| 479 | |
| 480 void CookieManager::RemoveAllCookiesHelper( | |
| 481 const BoolCallback callback) { | |
| 482 GetCookieStore()->DeleteAllAsync( | |
| 483 base::Bind(&CookieManager::RemoveCookiesCompleted, base::Unretained(this), | |
| 484 callback)); | |
| 485 } | |
| 486 | |
| 487 void CookieManager::RemoveExpiredCookies() { | |
| 488 // HasCookies will call GetAllCookiesAsync, which in turn will force a GC. | |
| 489 HasCookies(); | |
| 490 } | |
| 491 | |
| 492 void CookieManager::FlushCookieStore() { | |
| 493 ExecCookieTaskSync(base::Bind(&CookieManager::FlushCookieStoreAsyncHelper, | |
| 494 base::Unretained(this))); | |
| 495 } | |
| 496 | |
| 497 void CookieManager::FlushCookieStoreAsyncHelper( | |
| 498 base::Closure complete) { | |
| 499 GetCookieStore()->FlushStore(complete); | |
| 500 } | |
| 501 | |
| 502 bool CookieManager::HasCookies() { | |
| 503 bool has_cookies; | |
| 504 ExecCookieTaskSync(base::Bind(&CookieManager::HasCookiesAsyncHelper, | |
| 505 base::Unretained(this), | |
| 506 &has_cookies)); | |
| 507 return has_cookies; | |
| 508 } | |
| 509 | |
| 510 // TODO(kristianm): Simplify this, copying the entire list around | |
| 511 // should not be needed. | |
| 512 void CookieManager::HasCookiesAsyncHelper(bool* result, | |
| 513 base::Closure complete) { | |
| 514 GetCookieStore()->GetAllCookiesAsync( | |
| 515 base::Bind(&CookieManager::HasCookiesCompleted, base::Unretained(this), | |
| 516 complete, result)); | |
| 517 } | |
| 518 | |
| 519 void CookieManager::HasCookiesCompleted(base::Closure complete, | |
| 520 bool* result, | |
| 521 const CookieList& cookies) { | |
| 522 *result = cookies.size() != 0; | |
| 523 complete.Run(); | |
| 524 } | |
| 525 | |
| 526 bool CookieManager::AllowFileSchemeCookies() { | |
| 527 base::AutoLock lock(accept_file_scheme_cookies_lock_); | |
| 528 return accept_file_scheme_cookies_; | |
| 529 } | |
| 530 | |
| 531 void CookieManager::SetAcceptFileSchemeCookies(bool accept) { | |
| 532 base::AutoLock lock(accept_file_scheme_cookies_lock_); | |
| 533 // Can only modify this before the cookie store is created. | |
| 534 if (!cookie_store_created_) | |
| 535 accept_file_scheme_cookies_ = accept; | |
| 536 } | |
| 537 | |
| 538 static void SetShouldAcceptCookies(JNIEnv* env, | |
| 539 const JavaParamRef<jobject>& obj, | |
| 540 jboolean accept) { | |
| 541 CookieManager::GetInstance()->SetShouldAcceptCookies(accept); | |
| 542 } | |
| 543 | |
| 544 static jboolean GetShouldAcceptCookies(JNIEnv* env, | |
| 545 const JavaParamRef<jobject>& obj) { | |
| 546 return CookieManager::GetInstance()->GetShouldAcceptCookies(); | |
| 547 } | |
| 548 | |
| 549 static void SetCookie(JNIEnv* env, | |
| 550 const JavaParamRef<jobject>& obj, | |
| 551 const JavaParamRef<jstring>& url, | |
| 552 const JavaParamRef<jstring>& value, | |
| 553 const JavaParamRef<jobject>& java_callback) { | |
| 554 GURL host(ConvertJavaStringToUTF16(env, url)); | |
| 555 std::string cookie_value(ConvertJavaStringToUTF8(env, value)); | |
| 556 std::unique_ptr<BoolCookieCallbackHolder> callback( | |
| 557 new BoolCookieCallbackHolder(env, java_callback)); | |
| 558 CookieManager::GetInstance()->SetCookie(host, cookie_value, | |
| 559 std::move(callback)); | |
| 560 } | |
| 561 | |
| 562 static void SetCookieSync(JNIEnv* env, | |
| 563 const JavaParamRef<jobject>& obj, | |
| 564 const JavaParamRef<jstring>& url, | |
| 565 const JavaParamRef<jstring>& value) { | |
| 566 GURL host(ConvertJavaStringToUTF16(env, url)); | |
| 567 std::string cookie_value(ConvertJavaStringToUTF8(env, value)); | |
| 568 | |
| 569 CookieManager::GetInstance()->SetCookieSync(host, cookie_value); | |
| 570 } | |
| 571 | |
| 572 static ScopedJavaLocalRef<jstring> GetCookie(JNIEnv* env, | |
| 573 const JavaParamRef<jobject>& obj, | |
| 574 const JavaParamRef<jstring>& url) { | |
| 575 GURL host(ConvertJavaStringToUTF16(env, url)); | |
| 576 | |
| 577 return base::android::ConvertUTF8ToJavaString( | |
| 578 env, CookieManager::GetInstance()->GetCookie(host)); | |
| 579 } | |
| 580 | |
| 581 static void RemoveSessionCookies(JNIEnv* env, | |
| 582 const JavaParamRef<jobject>& obj, | |
| 583 const JavaParamRef<jobject>& java_callback) { | |
| 584 std::unique_ptr<BoolCookieCallbackHolder> callback( | |
| 585 new BoolCookieCallbackHolder(env, java_callback)); | |
| 586 CookieManager::GetInstance()->RemoveSessionCookies(std::move(callback)); | |
| 587 } | |
| 588 | |
| 589 static void RemoveSessionCookiesSync(JNIEnv* env, | |
| 590 const JavaParamRef<jobject>& obj) { | |
| 591 CookieManager::GetInstance()->RemoveSessionCookiesSync(); | |
| 592 } | |
| 593 | |
| 594 static void RemoveAllCookies(JNIEnv* env, | |
| 595 const JavaParamRef<jobject>& obj, | |
| 596 const JavaParamRef<jobject>& java_callback) { | |
| 597 std::unique_ptr<BoolCookieCallbackHolder> callback( | |
| 598 new BoolCookieCallbackHolder(env, java_callback)); | |
| 599 CookieManager::GetInstance()->RemoveAllCookies(std::move(callback)); | |
| 600 } | |
| 601 | |
| 602 static void RemoveAllCookiesSync(JNIEnv* env, | |
| 603 const JavaParamRef<jobject>& obj) { | |
| 604 CookieManager::GetInstance()->RemoveAllCookiesSync(); | |
| 605 } | |
| 606 | |
| 607 static void RemoveExpiredCookies(JNIEnv* env, | |
| 608 const JavaParamRef<jobject>& obj) { | |
| 609 CookieManager::GetInstance()->RemoveExpiredCookies(); | |
| 610 } | |
| 611 | |
| 612 static void FlushCookieStore(JNIEnv* env, const JavaParamRef<jobject>& obj) { | |
| 613 CookieManager::GetInstance()->FlushCookieStore(); | |
| 614 } | |
| 615 | |
| 616 static jboolean HasCookies(JNIEnv* env, const JavaParamRef<jobject>& obj) { | |
| 617 return CookieManager::GetInstance()->HasCookies(); | |
| 618 } | |
| 619 | |
| 620 static jboolean AllowFileSchemeCookies(JNIEnv* env, | |
| 621 const JavaParamRef<jobject>& obj) { | |
| 622 return CookieManager::GetInstance()->AllowFileSchemeCookies(); | |
| 623 } | |
| 624 | |
| 625 static void SetAcceptFileSchemeCookies(JNIEnv* env, | |
| 626 const JavaParamRef<jobject>& obj, | |
| 627 jboolean accept) { | |
| 628 return CookieManager::GetInstance()->SetAcceptFileSchemeCookies(accept); | |
| 629 } | |
| 630 | |
| 631 // The following two methods are used to avoid a circular project dependency. | |
| 632 // TODO(mmenke): This is weird. Maybe there should be a leaky Singleton in | |
| 633 // browser/net that creates and owns there? | |
| 634 | |
| 635 scoped_refptr<base::SingleThreadTaskRunner> GetCookieStoreTaskRunner() { | |
| 636 return CookieManager::GetInstance()->GetCookieStoreTaskRunner(); | |
| 637 } | |
| 638 | |
| 639 net::CookieStore* GetCookieStore() { | |
| 640 return CookieManager::GetInstance()->GetCookieStore(); | |
| 641 } | |
| 642 | |
| 643 bool RegisterCookieManager(JNIEnv* env) { | |
| 644 return RegisterNativesImpl(env); | |
| 645 } | |
| 646 | |
| 647 } // android_webview namespace | |
| OLD | NEW |