summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/WebCoreSupport/WebCookieJar.cpp60
-rw-r--r--WebKit/android/WebCoreSupport/WebCookieJar.h3
-rw-r--r--WebKit/android/jni/CookieManager.cpp3
3 files changed, 64 insertions, 2 deletions
diff --git a/WebKit/android/WebCoreSupport/WebCookieJar.cpp b/WebKit/android/WebCoreSupport/WebCookieJar.cpp
index 6cef74b..6a81ff1 100644
--- a/WebKit/android/WebCoreSupport/WebCookieJar.cpp
+++ b/WebKit/android/WebCoreSupport/WebCookieJar.cpp
@@ -29,6 +29,7 @@
#include "JNIUtility.h"
#include "WebCoreJni.h"
#include "WebRequestContext.h"
+#include "WebUrlLoaderClient.h"
namespace android {
@@ -124,4 +125,63 @@ int WebCookieJar::CanSetCookie(const GURL&, const GURL&, const std::string&, net
return m_allowCookies ? net::OK : net::ERR_ACCESS_DENIED;
}
+class FlushSemaphore : public base::RefCounted<FlushSemaphore>
+{
+public:
+ FlushSemaphore()
+ : m_condition(&m_lock)
+ , m_count(0)
+ {}
+
+ void SendFlushRequest(net::CookieMonster* monster) {
+ // FlushStore() needs to run on a Chrome thread (because it will need
+ // to post the callback, and it may want to do so on its own thread.)
+ // We use the IO thread for this purpose.
+ //
+ // TODO(husky): Our threads are hidden away in various files. Clean this
+ // up and consider integrating with Chrome's browser_thread.h. Might be
+ // a better idea to use the DB thread here rather than the IO thread.
+
+ base::Thread* ioThread = WebUrlLoaderClient::ioThread();
+ if (ioThread) {
+ Task* callback = NewRunnableMethod(this, &FlushSemaphore::Callback);
+ ioThread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ monster, &net::CookieMonster::FlushStore, callback));
+ }
+ }
+
+ // Block until the given number of callbacks has been made.
+ void Wait(int numCallbacks) {
+ AutoLock al(m_lock);
+ while (m_count < numCallbacks) {
+ // TODO(husky): Maybe use TimedWait() here? But it's not obvious what
+ // to do if the flush fails. Might be okay just to let the OS kill us.
+ m_condition.Wait();
+ }
+ m_count -= numCallbacks;
+ }
+
+private:
+ friend class base::RefCounted<FlushSemaphore>;
+
+ void Callback() {
+ AutoLock al(m_lock);
+ m_count++;
+ m_condition.Broadcast();
+ }
+
+ Lock m_lock;
+ ConditionVariable m_condition;
+ volatile int m_count;
+};
+
+void WebCookieJar::flush()
+{
+ // Flush both cookie stores (private and non-private), wait for 2 callbacks.
+ static scoped_refptr<FlushSemaphore> semaphore(new FlushSemaphore());
+ semaphore->SendFlushRequest(get(false)->cookieStore()->GetCookieMonster());
+ semaphore->SendFlushRequest(get(true)->cookieStore()->GetCookieMonster());
+ semaphore->Wait(2);
+}
+
}
diff --git a/WebKit/android/WebCoreSupport/WebCookieJar.h b/WebKit/android/WebCoreSupport/WebCookieJar.h
index ecaa228..1372064 100644
--- a/WebKit/android/WebCoreSupport/WebCookieJar.h
+++ b/WebKit/android/WebCoreSupport/WebCookieJar.h
@@ -39,6 +39,9 @@ public:
static WebCookieJar* get(bool isPrivateBrowsing);
static void cleanup(bool isPrivateBrowsing);
+ // Flush all cookies to disk. Synchronous.
+ static void flush();
+
// CookiePolicy implementation from external/chromium
virtual int CanGetCookies(const GURL& url, const GURL& first_party_for_cookies, net::CompletionCallback*);
virtual int CanSetCookie(const GURL& url, const GURL& first_party_for_cookies, const std::string& cookie_line, net::CompletionCallback*);
diff --git a/WebKit/android/jni/CookieManager.cpp b/WebKit/android/jni/CookieManager.cpp
index 0053e4f..5532f6a 100644
--- a/WebKit/android/jni/CookieManager.cpp
+++ b/WebKit/android/jni/CookieManager.cpp
@@ -158,8 +158,7 @@ static void setCookie(JNIEnv* env, jobject, jstring url, jstring value)
static void flushCookieStore(JNIEnv*, jobject)
{
#if USE(CHROME_NETWORK_STACK)
- WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->FlushStore();
- WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->FlushStore();
+ WebCookieJar::flush();
#endif
}