summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authorhjd@chromium.org <hjd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-19 17:21:27 +0000
committerhjd@chromium.org <hjd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-19 17:21:27 +0000
commit976e410c08958691e4c2d887fcf83cb5993f636f (patch)
tree44c748a76ede1b35fbe7a76137b11c404b3b7d45 /android_webview
parent9a024901aec2050f12f81e4f2c6dddf1e946f4a4 (diff)
downloadchromium_src-976e410c08958691e4c2d887fcf83cb5993f636f.zip
chromium_src-976e410c08958691e4c2d887fcf83cb5993f636f.tar.gz
chromium_src-976e410c08958691e4c2d887fcf83cb5993f636f.tar.bz2
Adds Asynchronous APIs to CookieManager
Creates asynchronous versions of SetCookie, removeAllCookie and removeSessionCookie which take callbacks. BUG= TEST=AndroidWebviewTest Review URL: https://codereview.chromium.org/273873003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271411 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwCookieManager.java144
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java26
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java350
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/util/CookieUtils.java84
-rw-r--r--android_webview/native/cookie_manager.cc320
5 files changed, 728 insertions, 196 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java b/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java
index ab91e5d..c7f04aa 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwCookieManager.java
@@ -4,6 +4,11 @@
package org.chromium.android_webview;
+import android.os.Handler;
+import android.os.Looper;
+import android.webkit.ValueCallback;
+
+import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
/**
@@ -13,6 +18,22 @@ import org.chromium.base.JNINamespace;
*/
@JNINamespace("android_webview")
public final class AwCookieManager {
+
+ // TODO(hjd): remove after landing android update to use new calls.
+ public void removeExpiredCookie() {
+ removeExpiredCookies();
+ }
+
+ // TODO(hjd): remove after landing android update to use new calls.
+ public void removeAllCookie() {
+ removeAllCookies();
+ }
+
+ // TODO(hjd): remove after landing android update to use new calls.
+ public void removeSessionCookie() {
+ removeSessionCookies();
+ }
+
/**
* Control whether cookie is enabled or disabled
* @param accept TRUE if accept cookie
@@ -46,14 +67,42 @@ public final class AwCookieManager {
}
/**
+ * Synchronous version of setCookie.
+ */
+ public void setCookie(String url, String value) {
+ nativeSetCookieSync(url, value);
+ }
+
+ /**
+ * Deprecated synchronous version of removeSessionCookies.
+ */
+ public void removeSessionCookies() {
+ nativeRemoveSessionCookiesSync();
+ }
+
+ /**
+ * Deprecated synchronous version of removeAllCookies.
+ */
+ public void removeAllCookies() {
+ nativeRemoveAllCookiesSync();
+ }
+
+ /**
* Set cookie for a given url. The old cookie with same host/path/name will
* be removed. The new cookie will be added if it is not expired or it does
* not have expiration which implies it is session cookie.
- * @param url The url which cookie is set for
- * @param value The value for set-cookie: in http response header
+ * @param url The url which cookie is set for.
+ * @param value The value for set-cookie: in http response header.
+ * @param callback A callback called with the success status after the cookie is set.
*/
- public void setCookie(final String url, final String value) {
- nativeSetCookie(url, value);
+ public void setCookie(final String url, final String value,
+ final ValueCallback<Boolean> callback) {
+ try {
+ nativeSetCookie(url, value, CookieCallback.convert(callback));
+ } catch (IllegalStateException e) {
+ throw new IllegalStateException(
+ "SetCookie must be called on a thread with a running Looper.");
+ }
}
/**
@@ -69,17 +118,31 @@ public final class AwCookieManager {
}
/**
- * Remove all session cookies, which are cookies without expiration date
+ * Remove all session cookies, the cookies without an expiration date.
+ * The value of the callback is true iff at least one cookie was removed.
+ * @param callback A callback called after the cookies (if any) are removed.
*/
- public void removeSessionCookie() {
- nativeRemoveSessionCookie();
+ public void removeSessionCookies(ValueCallback<Boolean> callback) {
+ try {
+ nativeRemoveSessionCookies(CookieCallback.convert(callback));
+ } catch (IllegalStateException e) {
+ throw new IllegalStateException(
+ "removeSessionCookies must be called on a thread with a running Looper.");
+ }
}
/**
- * Remove all cookies
+ * Remove all cookies.
+ * The value of the callback is true iff at least one cookie was removed.
+ * @param callback A callback called after the cookies (if any) are removed.
*/
- public void removeAllCookie() {
- nativeRemoveAllCookie();
+ public void removeAllCookies(ValueCallback<Boolean> callback) {
+ try {
+ nativeRemoveAllCookies(CookieCallback.convert(callback));
+ } catch (IllegalStateException e) {
+ throw new IllegalStateException(
+ "removeAllCookies must be called on a thread with a running Looper.");
+ }
}
/**
@@ -92,8 +155,8 @@ public final class AwCookieManager {
/**
* Remove all expired cookies
*/
- public void removeExpiredCookie() {
- nativeRemoveExpiredCookie();
+ public void removeExpiredCookies() {
+ nativeRemoveExpiredCookies();
}
public void flushCookieStore() {
@@ -120,18 +183,67 @@ public final class AwCookieManager {
nativeSetAcceptFileSchemeCookies(accept);
}
+ @CalledByNative
+ public static void invokeBooleanCookieCallback(CookieCallback<Boolean> callback,
+ boolean result) {
+ callback.onReceiveValue(result);
+ }
+
+ /**
+ * CookieCallback is a bridge that knows how to call a ValueCallback on its original thread.
+ * We need to arrange for the users ValueCallback#onReceiveValue to be called on the original
+ * thread after the work is done. When the API is called we construct a CookieCallback which
+ * remembers the handler of the current thread. Later the native code uses
+ * invokeBooleanCookieCallback to call CookieCallback#onReceiveValue which posts a Runnable
+ * on the handler of the original thread which in turn calls ValueCallback#onReceiveValue.
+ */
+ private static class CookieCallback<T> {
+ ValueCallback<T> mCallback;
+ Handler mHandler;
+
+ public CookieCallback(ValueCallback<T> callback, Handler handler) {
+ mCallback = callback;
+ mHandler = handler;
+ }
+
+ public static<T> CookieCallback<T> convert(ValueCallback<T> callback) throws
+ IllegalStateException {
+ if (callback == null) {
+ return null;
+ }
+ if (Looper.myLooper() == null) {
+ throw new IllegalStateException(
+ "CookieCallback.convert should be called on a thread with a running Looper.");
+ }
+ return new CookieCallback<T>(callback, new Handler());
+ }
+
+ public void onReceiveValue(final T t) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onReceiveValue(t);
+ }
+ });
+ }
+ }
+
private native void nativeSetAcceptCookie(boolean accept);
private native boolean nativeAcceptCookie();
private native void nativeSetAcceptThirdPartyCookie(boolean accept);
private native boolean nativeAcceptThirdPartyCookie();
- private native void nativeSetCookie(String url, String value);
+ private native void nativeSetCookie(String url, String value,
+ CookieCallback<Boolean> callback);
+ private native void nativeSetCookieSync(String url, String value);
private native String nativeGetCookie(String url);
- private native void nativeRemoveSessionCookie();
- private native void nativeRemoveAllCookie();
- private native void nativeRemoveExpiredCookie();
+ private native void nativeRemoveSessionCookies(CookieCallback<Boolean> callback);
+ private native void nativeRemoveSessionCookiesSync();
+ private native void nativeRemoveAllCookies(CookieCallback<Boolean> callback);
+ private native void nativeRemoveAllCookiesSync();
+ private native void nativeRemoveExpiredCookies();
private native void nativeFlushCookieStore();
private native boolean nativeHasCookies();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
index 3a26d37..8cad692 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerStartupTest.java
@@ -6,11 +6,13 @@ package org.chromium.android_webview.test;
import android.content.Context;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.android_webview.AwBrowserProcess;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwCookieManager;
import org.chromium.android_webview.test.util.CommonResources;
+import org.chromium.android_webview.test.util.CookieUtils;
import org.chromium.base.test.util.Feature;
import org.chromium.content.app.ContentMain;
import org.chromium.net.test.util.TestWebServer;
@@ -64,10 +66,11 @@ public class CookieManagerStartupTest extends AwTestBase {
String path = "/cookie_test.html";
String url = webServer.setResponse(path, CommonResources.ABOUT_HTML, null);
+ CookieUtils.clearCookies(this, mCookieManager);
+
mCookieManager.setAcceptCookie(true);
- mCookieManager.removeAllCookie();
assertTrue(mCookieManager.acceptCookie());
- assertFalse(mCookieManager.hasCookies());
+
mCookieManager.setCookie(url, "count=41");
startChromium();
@@ -83,4 +86,23 @@ public class CookieManagerStartupTest extends AwTestBase {
}
}
+ @SmallTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testAllowFileSchemeCookies() throws Throwable {
+ assertFalse(mCookieManager.allowFileSchemeCookies());
+ mCookieManager.setAcceptFileSchemeCookies(true);
+ assertTrue(mCookieManager.allowFileSchemeCookies());
+ mCookieManager.setAcceptFileSchemeCookies(false);
+ assertFalse(mCookieManager.allowFileSchemeCookies());
+ }
+
+ @SmallTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testAllowCookies() throws Throwable {
+ assertTrue(mCookieManager.acceptCookie());
+ mCookieManager.setAcceptCookie(false);
+ assertFalse(mCookieManager.acceptCookie());
+ mCookieManager.setAcceptCookie(true);
+ assertTrue(mCookieManager.acceptCookie());
+ }
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
index d105966..f9687ee 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/CookieManagerTest.java
@@ -6,11 +6,14 @@ package org.chromium.android_webview.test;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
+import android.webkit.ValueCallback;
+
+import static org.chromium.android_webview.test.util.CookieUtils.TestValueCallback;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwCookieManager;
+import org.chromium.android_webview.test.util.CookieUtils;
import org.chromium.android_webview.test.util.JSUtils;
import org.chromium.base.test.util.Feature;
import org.chromium.net.test.util.TestWebServer;
@@ -43,16 +46,17 @@ public class CookieManagerTest extends AwTestBase {
mAwContents = testContainerView.getAwContents();
mAwContents.getSettings().setJavaScriptEnabled(true);
assertNotNull(mCookieManager);
- }
- @SmallTest
- @Feature({"AndroidWebView", "Privacy"})
- public void testAllowFileSchemeCookies() throws Throwable {
- assertFalse(mCookieManager.allowFileSchemeCookies());
- mCookieManager.setAcceptFileSchemeCookies(true);
- assertTrue(mCookieManager.allowFileSchemeCookies());
- mCookieManager.setAcceptFileSchemeCookies(false);
- assertFalse(mCookieManager.allowFileSchemeCookies());
+ // All tests start with no cookies.
+ try {
+ clearCookies();
+ } catch (Throwable e) {
+ throw new RuntimeException("Could not clear cookies.");
+ }
+
+ // But setting cookies enabled.
+ mCookieManager.setAcceptCookie(true);
+ assertTrue(mCookieManager.acceptCookie());
}
@MediumTest
@@ -67,12 +71,10 @@ public class CookieManagerTest extends AwTestBase {
String url = webServer.setResponse(path, responseStr, null);
mCookieManager.setAcceptCookie(false);
- mCookieManager.removeAllCookie();
assertFalse(mCookieManager.acceptCookie());
- assertFalse(mCookieManager.hasCookies());
loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
- setCookie("test1", "value1");
+ setCookieWithJavaScript("test1", "value1");
assertNull(mCookieManager.getCookie(url));
List<Pair<String, String>> responseHeaders = new ArrayList<Pair<String, String>>();
@@ -87,7 +89,7 @@ public class CookieManagerTest extends AwTestBase {
url = webServer.setResponse(path, responseStr, null);
loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), url);
- setCookie("test2", "value2");
+ setCookieWithJavaScript("test2", "value2");
waitForCookie(url);
String cookie = mCookieManager.getCookie(url);
assertNotNull(cookie);
@@ -102,15 +104,12 @@ public class CookieManagerTest extends AwTestBase {
cookie = mCookieManager.getCookie(url);
assertNotNull(cookie);
validateCookies(cookie, "test2", "header-test2");
-
- // clean up all cookies
- mCookieManager.removeAllCookie();
} finally {
if (webServer != null) webServer.shutdown();
}
}
- private void setCookie(final String name, final String value)
+ private void setCookieWithJavaScript(final String name, final String value)
throws Throwable {
JSUtils.executeJavaScriptAndWaitForResult(
this, mAwContents,
@@ -121,41 +120,82 @@ public class CookieManagerTest extends AwTestBase {
"; expires=' + expirationDate.toUTCString();");
}
- private void waitForCookie(final String url) throws Exception {
- poll(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- return mCookieManager.getCookie(url) != null;
- }
- });
- }
-
- private void validateCookies(String responseCookie, String... expectedCookieNames) {
- String[] cookies = responseCookie.split(";");
- Set<String> foundCookieNames = new HashSet<String>();
- for (String cookie : cookies) {
- foundCookieNames.add(cookie.substring(0, cookie.indexOf("=")).trim());
- }
- MoreAsserts.assertEquals(
- foundCookieNames, new HashSet<String>(Arrays.asList(expectedCookieNames)));
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testRemoveAllCookies() throws Exception {
+ mCookieManager.setCookie("http://www.example.com", "name=test");
+ assertTrue(mCookieManager.hasCookies());
+ mCookieManager.removeAllCookies();
+ assertFalse(mCookieManager.hasCookies());
}
@MediumTest
@Feature({"AndroidWebView", "Privacy"})
- public void testRemoveAllCookie() throws Exception {
- // enable cookie
- mCookieManager.setAcceptCookie(true);
- assertTrue(mCookieManager.acceptCookie());
+ public void testRemoveSessionCookies() throws Exception {
+ final String url = "http://www.example.com";
+ final String sessionCookie = "cookie1=peter";
+ final String normalCookie = "cookie2=sue";
- // first there should be no cookie stored
- mCookieManager.removeAllCookie();
- mCookieManager.flushCookieStore();
- assertFalse(mCookieManager.hasCookies());
+ mCookieManager.setCookie(url, sessionCookie);
+ mCookieManager.setCookie(url, makeExpiringCookie(normalCookie, 600));
+ mCookieManager.removeSessionCookies();
+
+ String allCookies = mCookieManager.getCookie(url);
+ assertFalse(allCookies.contains(sessionCookie));
+ assertTrue(allCookies.contains(normalCookie));
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testSetCookie() throws Throwable {
String url = "http://www.example.com";
String cookie = "name=test";
mCookieManager.setCookie(url, cookie);
assertEquals(cookie, mCookieManager.getCookie(url));
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testHasCookie() throws Throwable {
+ assertFalse(mCookieManager.hasCookies());
+ mCookieManager.setCookie("http://www.example.com", "name=test");
+ assertTrue(mCookieManager.hasCookies());
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testSetCookieCallback() throws Throwable {
+ final String url = "http://www.example.com";
+ final String cookie = "name=test";
+ final String brokenUrl = "foo";
+
+ final TestValueCallback<Boolean> callback = new TestValueCallback<Boolean>();
+ int callCount = callback.getOnReceiveValueHelper().getCallCount();
+
+ setCookieOnUiThread(url, cookie, callback);
+ callback.getOnReceiveValueHelper().waitForCallback(callCount);
+ assertTrue(callback.getValue());
+ assertEquals(cookie, mCookieManager.getCookie(url));
+
+ callCount = callback.getOnReceiveValueHelper().getCallCount();
+
+ setCookieOnUiThread(brokenUrl, cookie, callback);
+ callback.getOnReceiveValueHelper().waitForCallback(callCount);
+ assertFalse(callback.getValue());
+ assertEquals(null, mCookieManager.getCookie(brokenUrl));
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testSetCookieNullCallback() throws Throwable {
+ mCookieManager.setAcceptCookie(true);
+ assertTrue(mCookieManager.acceptCookie());
+
+ final String url = "http://www.example.com";
+ final String cookie = "name=test";
+
+ mCookieManager.setCookie(url, cookie, null);
poll(new Callable<Boolean>() {
@Override
@@ -163,9 +203,38 @@ public class CookieManagerTest extends AwTestBase {
return mCookieManager.hasCookies();
}
});
+ }
- // clean up all cookies
- mCookieManager.removeAllCookie();
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testRemoveAllCookiesCallback() throws Throwable {
+ TestValueCallback<Boolean> callback = new TestValueCallback<Boolean>();
+ int callCount = callback.getOnReceiveValueHelper().getCallCount();
+
+ mCookieManager.setCookie("http://www.example.com", "name=test");
+
+ // When we remove all cookies the first time some cookies are removed.
+ removeAllCookiesOnUiThread(callback);
+ callback.getOnReceiveValueHelper().waitForCallback(callCount);
+ assertTrue(callback.getValue());
+ assertFalse(mCookieManager.hasCookies());
+
+ callCount = callback.getOnReceiveValueHelper().getCallCount();
+
+ // The second time none are removed.
+ removeAllCookiesOnUiThread(callback);
+ callback.getOnReceiveValueHelper().waitForCallback(callCount);
+ assertFalse(callback.getValue());
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testRemoveAllCookiesNullCallback() throws Throwable {
+ mCookieManager.setCookie("http://www.example.com", "name=test");
+
+ mCookieManager.removeAllCookies(null);
+
+ // Eventually the cookies are removed.
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
@@ -176,67 +245,113 @@ public class CookieManagerTest extends AwTestBase {
@MediumTest
@Feature({"AndroidWebView", "Privacy"})
- @SuppressWarnings("deprecation")
- public void testCookieExpiration() throws Exception {
- // enable cookie
- mCookieManager.setAcceptCookie(true);
- assertTrue(mCookieManager.acceptCookie());
- mCookieManager.removeAllCookie();
- assertFalse(mCookieManager.hasCookies());
-
+ public void testRemoveSessionCookiesCallback() throws Throwable {
final String url = "http://www.example.com";
- final String cookie1 = "cookie1=peter";
- final String cookie2 = "cookie2=sue";
- final String cookie3 = "cookie3=marc";
+ final String sessionCookie = "cookie1=peter";
+ final String normalCookie = "cookie2=sue";
- mCookieManager.setCookie(url, cookie1); // session cookie
+ TestValueCallback<Boolean> callback = new TestValueCallback<Boolean>();
+ int callCount = callback.getOnReceiveValueHelper().getCallCount();
- Date date = new Date();
- date.setTime(date.getTime() + 1000 * 600);
- String value2 = cookie2 + "; expires=" + date.toGMTString();
- mCookieManager.setCookie(url, value2); // expires in 10min
+ mCookieManager.setCookie(url, sessionCookie);
+ mCookieManager.setCookie(url, makeExpiringCookie(normalCookie, 600));
- long expiration = 3000;
- date = new Date();
- date.setTime(date.getTime() + expiration);
- String value3 = cookie3 + "; expires=" + date.toGMTString();
- mCookieManager.setCookie(url, value3); // expires in 3s
+ // When there is a session cookie then it is removed.
+ removeSessionCookiesOnUiThread(callback);
+ callback.getOnReceiveValueHelper().waitForCallback(callCount);
+ assertTrue(callback.getValue());
+ String allCookies = mCookieManager.getCookie(url);
+ assertTrue(!allCookies.contains(sessionCookie));
+ assertTrue(allCookies.contains(normalCookie));
+ callCount = callback.getOnReceiveValueHelper().getCallCount();
+
+ // If there are no session cookies then none are removed.
+ removeSessionCookiesOnUiThread(callback);
+ callback.getOnReceiveValueHelper().waitForCallback(callCount);
+ assertFalse(callback.getValue());
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testRemoveSessionCookiesNullCallback() throws Throwable {
+ final String url = "http://www.example.com";
+ final String sessionCookie = "cookie1=peter";
+ final String normalCookie = "cookie2=sue";
+
+ mCookieManager.setCookie(url, sessionCookie);
+ mCookieManager.setCookie(url, makeExpiringCookie(normalCookie, 600));
String allCookies = mCookieManager.getCookie(url);
- assertTrue(allCookies.contains(cookie1));
- assertTrue(allCookies.contains(cookie2));
- assertTrue(allCookies.contains(cookie3));
+ assertTrue(allCookies.contains(sessionCookie));
+ assertTrue(allCookies.contains(normalCookie));
- mCookieManager.removeSessionCookie();
- poll(new Callable<Boolean>() {
- @Override
- public Boolean call() throws Exception {
- String c = mCookieManager.getCookie(url);
- return !c.contains(cookie1) && c.contains(cookie2) && c.contains(cookie3);
- }
- });
+ mCookieManager.removeSessionCookies(null);
- Thread.sleep(expiration + 1000); // wait for cookie to expire
- mCookieManager.removeExpiredCookie();
+ // Eventually the session cookie is removed.
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
String c = mCookieManager.getCookie(url);
- return !c.contains(cookie1) && c.contains(cookie2) && !c.contains(cookie3);
+ return !c.contains(sessionCookie) && c.contains(normalCookie);
}
});
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testExpiredCookiesAreNotSet() throws Exception {
+ final String url = "http://www.example.com";
+ final String cookie = "cookie1=peter";
+
+ mCookieManager.setCookie(url, makeExpiringCookie(cookie, -1));
+ assertNull(mCookieManager.getCookie(url));
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
+ public void testCookiesExpire() throws Exception {
+ final String url = "http://www.example.com";
+ final String cookie = "cookie1=peter";
- mCookieManager.removeAllCookie();
+ mCookieManager.setCookie(url, makeExpiringCookieMs(cookie, 1200));
+
+ // The cookie exists:
+ assertTrue(mCookieManager.hasCookies());
+
+ // But eventually expires:
poll(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
- return mCookieManager.getCookie(url) == null;
+ return !mCookieManager.hasCookies();
}
});
}
@MediumTest
@Feature({"AndroidWebView", "Privacy"})
+ public void testCookieExpiration() throws Exception {
+ final String url = "http://www.example.com";
+ final String sessionCookie = "cookie1=peter";
+ final String longCookie = "cookie2=marc";
+
+ mCookieManager.setCookie(url, sessionCookie);
+ mCookieManager.setCookie(url, makeExpiringCookie(longCookie, 600));
+
+ String allCookies = mCookieManager.getCookie(url);
+ assertTrue(allCookies.contains(sessionCookie));
+ assertTrue(allCookies.contains(longCookie));
+
+ // Removing expired cookies doesn't have an observable effect but since people will still
+ // be calling it for a while it shouldn't break anything either.
+ mCookieManager.removeExpiredCookies();
+
+ allCookies = mCookieManager.getCookie(url);
+ assertTrue(allCookies.contains(sessionCookie));
+ assertTrue(allCookies.contains(longCookie));
+ }
+
+ @MediumTest
+ @Feature({"AndroidWebView", "Privacy"})
public void testThirdPartyCookie() throws Throwable {
TestWebServer webServer = null;
try {
@@ -254,9 +369,7 @@ public class CookieManagerTest extends AwTestBase {
// Turn global allow on.
mCookieManager.setAcceptCookie(true);
- mCookieManager.removeAllCookie();
assertTrue(mCookieManager.acceptCookie());
- assertFalse(mCookieManager.hasCookies());
// When third party cookies are disabled...
mCookieManager.setAcceptThirdPartyCookie(false);
@@ -327,9 +440,7 @@ public class CookieManagerTest extends AwTestBase {
webServer = new TestWebServer(false);
mCookieManager.setAcceptCookie(true);
- mCookieManager.removeAllCookie();
assertTrue(mCookieManager.acceptCookie());
- assertFalse(mCookieManager.hasCookies());
// When third party cookies are disabled...
mCookieManager.setAcceptThirdPartyCookie(false);
@@ -397,4 +508,71 @@ public class CookieManagerTest extends AwTestBase {
private String toThirdPartyUrl(String url) {
return url.replace("localhost", "127.0.0.1");
}
+
+ private void setCookieOnUiThread(final String url, final String cookie,
+ final ValueCallback<Boolean> callback) throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mCookieManager.setCookie(url, cookie, callback);
+ }
+ });
+ }
+
+ private void removeSessionCookiesOnUiThread(final ValueCallback<Boolean> callback)
+ throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mCookieManager.removeSessionCookies(callback);
+ }
+ });
+ }
+
+ private void removeAllCookiesOnUiThread(final ValueCallback<Boolean> callback)
+ throws Throwable {
+ runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mCookieManager.removeAllCookies(callback);
+ }
+ });
+ }
+
+ /**
+ * Clears all cookies synchronously.
+ */
+ private void clearCookies() throws Throwable {
+ CookieUtils.clearCookies(this, mCookieManager);
+ }
+
+ private void waitForCookie(final String url) throws Exception {
+ poll(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return mCookieManager.getCookie(url) != null;
+ }
+ });
+ }
+
+ private void validateCookies(String responseCookie, String... expectedCookieNames) {
+ String[] cookies = responseCookie.split(";");
+ Set<String> foundCookieNames = new HashSet<String>();
+ for (String cookie : cookies) {
+ foundCookieNames.add(cookie.substring(0, cookie.indexOf("=")).trim());
+ }
+ MoreAsserts.assertEquals(
+ foundCookieNames, new HashSet<String>(Arrays.asList(expectedCookieNames)));
+ }
+
+ private String makeExpiringCookie(String cookie, int secondsTillExpiry) {
+ return makeExpiringCookieMs(cookie, secondsTillExpiry * 1000);
+ }
+
+ @SuppressWarnings("deprecation")
+ private String makeExpiringCookieMs(String cookie, int millisecondsTillExpiry) {
+ Date date = new Date();
+ date.setTime(date.getTime() + millisecondsTillExpiry);
+ return cookie + "; expires=" + date.toGMTString();
+ }
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/util/CookieUtils.java b/android_webview/javatests/src/org/chromium/android_webview/test/util/CookieUtils.java
new file mode 100644
index 0000000..15484f7
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/util/CookieUtils.java
@@ -0,0 +1,84 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview.test.util;
+
+import android.webkit.ValueCallback;
+
+import junit.framework.Assert;
+
+import org.chromium.android_webview.AwCookieManager;
+import org.chromium.android_webview.test.AwTestBase;
+import org.chromium.content.browser.test.util.CallbackHelper;
+
+/**
+ * Useful functions for testing the CookieManager.
+ */
+public class CookieUtils {
+ private CookieUtils() {
+ }
+
+
+ /**
+ * A CallbackHelper for use with setCookie/removeXXXCookie.
+ */
+ public static class TestValueCallback<T> implements ValueCallback<T> {
+ /**
+ * We only have one intresting method on ValueCallback: onReceiveValue.
+ */
+ public static class OnReceiveValueHelper<T> extends CallbackHelper {
+ private T mValue;
+
+ public T getValue() {
+ assert getCallCount() > 0;
+ return mValue;
+ }
+
+ public void notifyCalled(T value) {
+ mValue = value;
+ notifyCalled();
+ }
+ }
+
+ private OnReceiveValueHelper<T> mOnReceiveValueHelper;
+
+ public TestValueCallback() {
+ mOnReceiveValueHelper = new OnReceiveValueHelper<T>();
+ }
+
+ public OnReceiveValueHelper getOnReceiveValueHelper() {
+ return mOnReceiveValueHelper;
+ }
+
+ @Override
+ public void onReceiveValue(T value) {
+ mOnReceiveValueHelper.notifyCalled(value);
+ }
+
+ public T getValue() {
+ return mOnReceiveValueHelper.getValue();
+ }
+ }
+
+ /**
+ * Clear all cookies from the CookieManager synchronously then assert they are gone.
+ * @param cookieManager the CookieManager on which to remove cookies.
+ * @param timeoutMs the timeout in milliseconds for waiting for the callback to complete.
+ */
+ public static void clearCookies(AwTestBase awTestBase, final AwCookieManager cookieManager)
+ throws Throwable {
+
+ final TestValueCallback<Boolean> callback = new TestValueCallback<Boolean>();
+ int callCount = callback.getOnReceiveValueHelper().getCallCount();
+
+ awTestBase.runTestOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ cookieManager.removeAllCookies(callback);
+ }
+ });
+ callback.getOnReceiveValueHelper().waitForCallback(callCount);
+ Assert.assertFalse(cookieManager.hasCookies());
+ }
+}
diff --git a/android_webview/native/cookie_manager.cc b/android_webview/native/cookie_manager.cc
index adb0ec8..90fa23f 100644
--- a/android_webview/native/cookie_manager.cc
+++ b/android_webview/native/cookie_manager.cc
@@ -35,8 +35,10 @@
#include "net/url_request/url_request_context.h"
using base::FilePath;
+using base::WaitableEvent;
using base::android::ConvertJavaStringToUTF8;
using base::android::ConvertJavaStringToUTF16;
+using base::android::ScopedJavaGlobalRef;
using content::BrowserThread;
using net::CookieList;
using net::CookieMonster;
@@ -46,15 +48,67 @@ using net::CookieMonster;
// depending on the URLRequestContext.
// See issue http://crbug.com/157683
-// All functions on the CookieManager can be called from any thread, including
-// threads without a message loop. BrowserThread::IO is used to call methods
-// on CookieMonster that needs to be called, and called back, on a chrome
-// thread.
+// On the CookieManager methods without a callback and methods with a callback
+// when that callback is null can be called from any thread, including threads
+// without a message loop. Methods with a non-null callback must be called on
+// a thread with a running message loop.
namespace android_webview {
namespace {
+typedef base::Callback<void(bool)> BoolCallback;
+typedef base::Callback<void(int)> IntCallback;
+
+// Holds a Java BooleanCookieCallback, knows how to invoke it and turn it
+// into a base callback.
+class BoolCookieCallbackHolder {
+ public:
+ BoolCookieCallbackHolder(JNIEnv* env, jobject callback) {
+ callback_.Reset(env, callback);
+ }
+
+ void Invoke(bool result) {
+ if (!callback_.is_null()) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_AwCookieManager_invokeBooleanCookieCallback(
+ env, callback_.obj(), result);
+ }
+ }
+
+ static BoolCallback ConvertToCallback(
+ scoped_ptr<BoolCookieCallbackHolder> me) {
+ return base::Bind(&BoolCookieCallbackHolder::Invoke,
+ base::Owned(me.release()));
+ }
+
+ private:
+ ScopedJavaGlobalRef<jobject> callback_;
+ DISALLOW_COPY_AND_ASSIGN(BoolCookieCallbackHolder);
+};
+
+// Construct a closure which signals a waitable event if and when the closure
+// is called the waitable event must still exist.
+static base::Closure SignalEventClosure(WaitableEvent* completion) {
+ return base::Bind(&WaitableEvent::Signal, base::Unretained(completion));
+}
+
+static void DiscardBool(const base::Closure& f, bool b) {
+ f.Run();
+}
+
+static BoolCallback BoolCallbackAdapter(const base::Closure& f) {
+ return base::Bind(&DiscardBool, f);
+}
+
+static void DiscardInt(const base::Closure& f, int i) {
+ f.Run();
+}
+
+static IntCallback IntCallbackAdapter(const base::Closure& f) {
+ return base::Bind(&DiscardInt, f);
+}
+
// Are cookies allowed for file:// URLs by default?
const bool kDefaultFileSchemeAllowed = false;
@@ -98,11 +152,17 @@ class CookieManager {
bool AcceptCookie();
void SetAcceptThirdPartyCookie(bool accept);
bool AcceptThirdPartyCookie();
- void SetCookie(const GURL& host, const std::string& cookie_value);
+ void SetCookie(const GURL& host,
+ const std::string& cookie_value,
+ scoped_ptr<BoolCookieCallbackHolder> callback);
+ void SetCookieSync(const GURL& host,
+ const std::string& cookie_value);
std::string GetCookie(const GURL& host);
- void RemoveSessionCookie();
- void RemoveAllCookie();
- void RemoveExpiredCookie();
+ void RemoveSessionCookies(scoped_ptr<BoolCookieCallbackHolder> callback);
+ void RemoveAllCookies(scoped_ptr<BoolCookieCallbackHolder> callback);
+ void RemoveAllCookiesSync();
+ void RemoveSessionCookiesSync();
+ void RemoveExpiredCookies();
void FlushCookieStore();
bool HasCookies();
bool AllowFileSchemeCookies();
@@ -114,32 +174,31 @@ class CookieManager {
CookieManager();
~CookieManager();
- typedef base::Callback<void(base::WaitableEvent*)> CookieTask;
- void ExecCookieTask(const CookieTask& task);
+ void ExecCookieTaskSync(const base::Callback<void(BoolCallback)>& task);
+ void ExecCookieTaskSync(const base::Callback<void(IntCallback)>& task);
+ void ExecCookieTaskSync(const base::Callback<void(base::Closure)>& task);
+ void ExecCookieTask(const base::Closure& task);
- void SetCookieAsyncHelper(
+ void SetCookieHelper(
const GURL& host,
const std::string& value,
- base::WaitableEvent* completion);
- void SetCookieCompleted(base::WaitableEvent* completion, bool success);
+ BoolCallback callback);
- void GetCookieValueAsyncHelper(
- const GURL& host,
- std::string* result,
- base::WaitableEvent* completion);
- void GetCookieValueCompleted(base::WaitableEvent* completion,
+ void GetCookieValueAsyncHelper(const GURL& host,
+ std::string* result,
+ base::Closure complete);
+ void GetCookieValueCompleted(base::Closure complete,
std::string* result,
const std::string& value);
- void RemoveSessionCookieAsyncHelper(base::WaitableEvent* completion);
- void RemoveAllCookieAsyncHelper(base::WaitableEvent* completion);
- void RemoveCookiesCompleted(base::WaitableEvent* completion, int num_deleted);
+ void RemoveSessionCookiesHelper(BoolCallback callback);
+ void RemoveAllCookiesHelper(BoolCallback callback);
+ void RemoveCookiesCompleted(BoolCallback callback, int num_deleted);
- void FlushCookieStoreAsyncHelper(base::WaitableEvent* completion);
+ void FlushCookieStoreAsyncHelper(base::Closure complete);
- void HasCookiesAsyncHelper(bool* result,
- base::WaitableEvent* completion);
- void HasCookiesCompleted(base::WaitableEvent* completion,
+ void HasCookiesAsyncHelper(bool* result, base::Closure complete);
+ void HasCookiesCompleted(base::Closure complete,
bool* result,
const CookieList& cookies);
@@ -221,22 +280,53 @@ void CookieManager::EnsureCookieMonsterExistsLocked() {
cookie_monster_backend_thread_->message_loop_proxy());
}
-// Executes the |task| on the |cookie_monster_proxy_| message loop.
-void CookieManager::ExecCookieTask(const CookieTask& task) {
- base::WaitableEvent completion(false, false);
- base::AutoLock lock(cookie_monster_lock_);
+// Executes the |task| on the |cookie_monster_proxy_| message loop and
+// waits for it to complete before returning.
- EnsureCookieMonsterExistsLocked();
+// To execute a CookieTask synchronously you must arrange for Signal to be
+// called on the waitable event at some point. You can call the bool or int
+// versions of ExecCookieTaskSync, these will supply the caller with a dummy
+// callback which takes an int/bool, throws it away and calls Signal.
+// Alternatively you can call the version which supplies a Closure in which
+// case you must call Run on it when you want the unblock the calling code.
- cookie_monster_proxy_->PostTask(FROM_HERE, base::Bind(task, &completion));
+// Ignore a bool callback.
+void CookieManager::ExecCookieTaskSync(
+ const base::Callback<void(BoolCallback)>& task) {
+ WaitableEvent completion(false, false);
+ ExecCookieTask(
+ base::Bind(task, BoolCallbackAdapter(SignalEventClosure(&completion))));
+ ScopedAllowWaitForLegacyWebViewApi wait;
+ completion.Wait();
+}
+
+// Ignore an int callback.
+void CookieManager::ExecCookieTaskSync(
+ const base::Callback<void(IntCallback)>& task) {
+ WaitableEvent completion(false, false);
+ ExecCookieTask(
+ base::Bind(task, IntCallbackAdapter(SignalEventClosure(&completion))));
+ ScopedAllowWaitForLegacyWebViewApi wait;
+ completion.Wait();
+}
- // We always wait for the posted task to complete, even when it doesn't return
- // a value, because previous versions of the CookieManager API were
- // synchronous in most/all cases and the caller may be relying on this.
+// Call the supplied closure when you want to signal that the blocked code can
+// continue.
+void CookieManager::ExecCookieTaskSync(
+ const base::Callback<void(base::Closure)>& task) {
+ WaitableEvent completion(false, false);
+ ExecCookieTask(base::Bind(task, SignalEventClosure(&completion)));
ScopedAllowWaitForLegacyWebViewApi wait;
completion.Wait();
}
+// Executes the |task| on the |cookie_monster_proxy_| message loop.
+void CookieManager::ExecCookieTask(const base::Closure& task) {
+ base::AutoLock lock(cookie_monster_lock_);
+ EnsureCookieMonsterExistsLocked();
+ cookie_monster_proxy_->PostTask(FROM_HERE, task);
+}
+
scoped_refptr<net::CookieStore> CookieManager::CreateBrowserThreadCookieStore(
AwBrowserContext* browser_context) {
base::AutoLock lock(cookie_monster_lock_);
@@ -283,49 +373,51 @@ bool CookieManager::AcceptThirdPartyCookie() {
return AwCookieAccessPolicy::GetInstance()->GetThirdPartyAllowAccess();
}
-void CookieManager::SetCookie(const GURL& host,
+void CookieManager::SetCookie(
+ const GURL& host,
+ const std::string& cookie_value,
+ scoped_ptr<BoolCookieCallbackHolder> callback_holder) {
+ BoolCallback callback =
+ BoolCookieCallbackHolder::ConvertToCallback(callback_holder.Pass());
+ ExecCookieTask(base::Bind(&CookieManager::SetCookieHelper,
+ base::Unretained(this),
+ host,
+ cookie_value,
+ callback));
+}
+
+void CookieManager::SetCookieSync(const GURL& host,
const std::string& cookie_value) {
- ExecCookieTask(base::Bind(&CookieManager::SetCookieAsyncHelper,
+ ExecCookieTaskSync(base::Bind(&CookieManager::SetCookieHelper,
base::Unretained(this),
host,
cookie_value));
}
-void CookieManager::SetCookieAsyncHelper(
+void CookieManager::SetCookieHelper(
const GURL& host,
const std::string& value,
- base::WaitableEvent* completion) {
+ const BoolCallback callback) {
net::CookieOptions options;
options.set_include_httponly();
cookie_monster_->SetCookieWithOptionsAsync(
- host, value, options,
- base::Bind(&CookieManager::SetCookieCompleted,
- base::Unretained(this),
- completion));
-}
-
-void CookieManager::SetCookieCompleted(base::WaitableEvent* completion,
- bool success) {
- // The CookieManager API does not return a value for SetCookie,
- // so we don't need to propagate the |success| value back to the caller.
- completion->Signal();
+ host, value, options, callback);
}
std::string CookieManager::GetCookie(const GURL& host) {
std::string cookie_value;
- ExecCookieTask(base::Bind(&CookieManager::GetCookieValueAsyncHelper,
+ ExecCookieTaskSync(base::Bind(&CookieManager::GetCookieValueAsyncHelper,
base::Unretained(this),
host,
&cookie_value));
-
return cookie_value;
}
void CookieManager::GetCookieValueAsyncHelper(
const GURL& host,
std::string* result,
- base::WaitableEvent* completion) {
+ base::Closure complete) {
net::CookieOptions options;
options.set_include_httponly();
@@ -334,70 +426,85 @@ void CookieManager::GetCookieValueAsyncHelper(
options,
base::Bind(&CookieManager::GetCookieValueCompleted,
base::Unretained(this),
- completion,
+ complete,
result));
}
-void CookieManager::GetCookieValueCompleted(base::WaitableEvent* completion,
+void CookieManager::GetCookieValueCompleted(base::Closure complete,
std::string* result,
const std::string& value) {
*result = value;
- completion->Signal();
+ complete.Run();
}
-void CookieManager::RemoveSessionCookie() {
- ExecCookieTask(base::Bind(&CookieManager::RemoveSessionCookieAsyncHelper,
+void CookieManager::RemoveSessionCookies(
+ scoped_ptr<BoolCookieCallbackHolder> callback_holder) {
+ BoolCallback callback =
+ BoolCookieCallbackHolder::ConvertToCallback(callback_holder.Pass());
+ ExecCookieTask(base::Bind(&CookieManager::RemoveSessionCookiesHelper,
+ base::Unretained(this),
+ callback));
+}
+
+void CookieManager::RemoveSessionCookiesSync() {
+ ExecCookieTaskSync(base::Bind(&CookieManager::RemoveSessionCookiesHelper,
base::Unretained(this)));
}
-void CookieManager::RemoveSessionCookieAsyncHelper(
- base::WaitableEvent* completion) {
+void CookieManager::RemoveSessionCookiesHelper(
+ BoolCallback callback) {
cookie_monster_->DeleteSessionCookiesAsync(
base::Bind(&CookieManager::RemoveCookiesCompleted,
base::Unretained(this),
- completion));
+ callback));
}
-void CookieManager::RemoveCookiesCompleted(base::WaitableEvent* completion,
- int num_deleted) {
- // The CookieManager API does not return a value for removeSessionCookie or
- // removeAllCookie, so we don't need to propagate the |num_deleted| value back
- // to the caller.
- completion->Signal();
+void CookieManager::RemoveCookiesCompleted(
+ BoolCallback callback,
+ int num_deleted) {
+ callback.Run(num_deleted > 0);
}
-void CookieManager::RemoveAllCookie() {
- ExecCookieTask(base::Bind(&CookieManager::RemoveAllCookieAsyncHelper,
+void CookieManager::RemoveAllCookies(
+ scoped_ptr<BoolCookieCallbackHolder> callback_holder) {
+ BoolCallback callback =
+ BoolCookieCallbackHolder::ConvertToCallback(callback_holder.Pass());
+ ExecCookieTask(base::Bind(&CookieManager::RemoveAllCookiesHelper,
+ base::Unretained(this),
+ callback));
+}
+
+void CookieManager::RemoveAllCookiesSync() {
+ ExecCookieTaskSync(base::Bind(&CookieManager::RemoveAllCookiesHelper,
base::Unretained(this)));
}
-void CookieManager::RemoveAllCookieAsyncHelper(
- base::WaitableEvent* completion) {
+void CookieManager::RemoveAllCookiesHelper(
+ const BoolCallback callback) {
cookie_monster_->DeleteAllAsync(
base::Bind(&CookieManager::RemoveCookiesCompleted,
base::Unretained(this),
- completion));
+ callback));
}
-void CookieManager::RemoveExpiredCookie() {
+void CookieManager::RemoveExpiredCookies() {
// HasCookies will call GetAllCookiesAsync, which in turn will force a GC.
HasCookies();
}
-void CookieManager::FlushCookieStoreAsyncHelper(
- base::WaitableEvent* completion) {
- cookie_monster_->FlushStore(base::Bind(&base::WaitableEvent::Signal,
- base::Unretained(completion)));
-}
-
void CookieManager::FlushCookieStore() {
- ExecCookieTask(base::Bind(&CookieManager::FlushCookieStoreAsyncHelper,
+ ExecCookieTaskSync(base::Bind(&CookieManager::FlushCookieStoreAsyncHelper,
base::Unretained(this)));
}
+void CookieManager::FlushCookieStoreAsyncHelper(
+ base::Closure complete) {
+ cookie_monster_->FlushStore(complete);
+}
+
bool CookieManager::HasCookies() {
bool has_cookies;
- ExecCookieTask(base::Bind(&CookieManager::HasCookiesAsyncHelper,
+ ExecCookieTaskSync(base::Bind(&CookieManager::HasCookiesAsyncHelper,
base::Unretained(this),
&has_cookies));
return has_cookies;
@@ -406,19 +513,19 @@ bool CookieManager::HasCookies() {
// TODO(kristianm): Simplify this, copying the entire list around
// should not be needed.
void CookieManager::HasCookiesAsyncHelper(bool* result,
- base::WaitableEvent* completion) {
+ base::Closure complete) {
cookie_monster_->GetAllCookiesAsync(
base::Bind(&CookieManager::HasCookiesCompleted,
base::Unretained(this),
- completion,
+ complete,
result));
}
-void CookieManager::HasCookiesCompleted(base::WaitableEvent* completion,
+void CookieManager::HasCookiesCompleted(base::Closure complete,
bool* result,
const CookieList& cookies) {
*result = cookies.size() != 0;
- completion->Signal();
+ complete.Run();
}
bool CookieManager::AllowFileSchemeCookies() {
@@ -467,11 +574,26 @@ static jboolean AcceptThirdPartyCookie(JNIEnv* env, jobject obj) {
return CookieManager::GetInstance()->AcceptThirdPartyCookie();
}
-static void SetCookie(JNIEnv* env, jobject obj, jstring url, jstring value) {
+static void SetCookie(JNIEnv* env,
+ jobject obj,
+ jstring url,
+ jstring value,
+ jobject java_callback) {
+ GURL host(ConvertJavaStringToUTF16(env, url));
+ std::string cookie_value(ConvertJavaStringToUTF8(env, value));
+ scoped_ptr<BoolCookieCallbackHolder> callback(
+ new BoolCookieCallbackHolder(env, java_callback));
+ CookieManager::GetInstance()->SetCookie(host, cookie_value, callback.Pass());
+}
+
+static void SetCookieSync(JNIEnv* env,
+ jobject obj,
+ jstring url,
+ jstring value) {
GURL host(ConvertJavaStringToUTF16(env, url));
std::string cookie_value(ConvertJavaStringToUTF8(env, value));
- CookieManager::GetInstance()->SetCookie(host, cookie_value);
+ CookieManager::GetInstance()->SetCookieSync(host, cookie_value);
}
static jstring GetCookie(JNIEnv* env, jobject obj, jstring url) {
@@ -482,16 +604,30 @@ static jstring GetCookie(JNIEnv* env, jobject obj, jstring url) {
CookieManager::GetInstance()->GetCookie(host)).Release();
}
-static void RemoveSessionCookie(JNIEnv* env, jobject obj) {
- CookieManager::GetInstance()->RemoveSessionCookie();
+static void RemoveSessionCookies(JNIEnv* env,
+ jobject obj,
+ jobject java_callback) {
+ scoped_ptr<BoolCookieCallbackHolder> callback(
+ new BoolCookieCallbackHolder(env, java_callback));
+ CookieManager::GetInstance()->RemoveSessionCookies(callback.Pass());
+}
+
+static void RemoveSessionCookiesSync(JNIEnv* env, jobject obj) {
+ CookieManager::GetInstance()->RemoveSessionCookiesSync();
+}
+
+static void RemoveAllCookies(JNIEnv* env, jobject obj, jobject java_callback) {
+ scoped_ptr<BoolCookieCallbackHolder> callback(
+ new BoolCookieCallbackHolder(env, java_callback));
+ CookieManager::GetInstance()->RemoveAllCookies(callback.Pass());
}
-static void RemoveAllCookie(JNIEnv* env, jobject obj) {
- CookieManager::GetInstance()->RemoveAllCookie();
+static void RemoveAllCookiesSync(JNIEnv* env, jobject obj) {
+ CookieManager::GetInstance()->RemoveAllCookiesSync();
}
-static void RemoveExpiredCookie(JNIEnv* env, jobject obj) {
- CookieManager::GetInstance()->RemoveExpiredCookie();
+static void RemoveExpiredCookies(JNIEnv* env, jobject obj) {
+ CookieManager::GetInstance()->RemoveExpiredCookies();
}
static void FlushCookieStore(JNIEnv* env, jobject obj) {