1bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block/*
2bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * Copyright 2010, The Android Open Source Project
3bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block *
4bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * Redistribution and use in source and binary forms, with or without
5bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * modification, are permitted provided that the following conditions
6bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * are met:
7bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block *  * Redistributions of source code must retain the above copyright
8bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block *    notice, this list of conditions and the following disclaimer.
9bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block *  * Redistributions in binary form must reproduce the above copyright
10bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block *    notice, this list of conditions and the following disclaimer in the
11bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block *    documentation and/or other materials provided with the distribution.
12bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block *
13bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block */
25bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
26bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block#include "config.h"
27bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
28bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block#include "ChromiumIncludes.h"
298a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen#include "WebCookieJar.h"
301dddc338abb68784365d3608c5372d1b6a203706Steve Block#include "WebCoreJni.h"
31bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block#include <JNIHelp.h>
32bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
33bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Blockusing namespace base;
341dddc338abb68784365d3608c5372d1b6a203706Steve Blockusing namespace net;
35bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
36bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Blocknamespace android {
37bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
38492bcfac9fc25b61f44811050fb0cfe827eb6a08Jonathan Dixon// JNI for android.webkit.CookieManagerClassic
39492bcfac9fc25b61f44811050fb0cfe827eb6a08Jonathan Dixonstatic const char* javaCookieManagerClass = "android/webkit/CookieManagerClassic";
40bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
411dddc338abb68784365d3608c5372d1b6a203706Steve Blockstatic bool acceptCookie(JNIEnv*, jobject)
421dddc338abb68784365d3608c5372d1b6a203706Steve Block{
43965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    // This is a static method which gets the cookie policy for all WebViews. We
44965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    // always apply the same configuration to the contexts for both regular and
45965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    // private browsing, so expect the same result here.
468a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen    bool regularAcceptCookies = WebCookieJar::get(false)->allowCookies();
478a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen    ASSERT(regularAcceptCookies == WebCookieJar::get(true)->allowCookies());
48965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    return regularAcceptCookies;
49965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block}
50965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block
5194deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsenstatic jstring getCookie(JNIEnv* env, jobject, jstring url, jboolean privateBrowsing)
521dddc338abb68784365d3608c5372d1b6a203706Steve Block{
531dddc338abb68784365d3608c5372d1b6a203706Steve Block    GURL gurl(jstringToStdString(env, url));
54e7a75b7848b8ad8fa825770872bbc4c2c0726b65Steve Block    CookieOptions options;
55e7a75b7848b8ad8fa825770872bbc4c2c0726b65Steve Block    options.set_include_httponly();
5694deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsen    std::string cookies = WebCookieJar::get(privateBrowsing)->cookieStore()->GetCookieMonster()->GetCookiesWithOptions(gurl, options);
575e8fa1efdccd0072c3e6e80e265a77568179577eSteve Block    return stdStringToJstring(env, cookies);
581dddc338abb68784365d3608c5372d1b6a203706Steve Block}
591dddc338abb68784365d3608c5372d1b6a203706Steve Block
6094deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsenstatic bool hasCookies(JNIEnv*, jobject, jboolean privateBrowsing)
61126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block{
6294deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsen    return WebCookieJar::get(privateBrowsing)->getNumCookiesInDatabase() > 0;
63126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block}
64126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block
651dddc338abb68784365d3608c5372d1b6a203706Steve Blockstatic void removeAllCookie(JNIEnv*, jobject)
661dddc338abb68784365d3608c5372d1b6a203706Steve Block{
67e7b25f70239e5490aba9d2c65ffb67176eb76c0eKristian Monsen    WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->DeleteAll(true);
68bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    // This will lazily create a new private browsing context. However, if the
69bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    // context doesn't already exist, there's no need to create it, as cookies
70bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    // for such contexts are cleared up when we're done with them.
71bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    // TODO: Consider adding an optimisation to not create the context if it
72bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    // doesn't already exist.
73e7b25f70239e5490aba9d2c65ffb67176eb76c0eKristian Monsen    WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->DeleteAll(true);
74c65c296d5bbf1608aedeceac90179a261deb0368Iain Merrick
75c65c296d5bbf1608aedeceac90179a261deb0368Iain Merrick    // The Java code removes cookies directly from the backing database, so we do the same,
76c65c296d5bbf1608aedeceac90179a261deb0368Iain Merrick    // but with a NULL callback so it's asynchronous.
77c65c296d5bbf1608aedeceac90179a261deb0368Iain Merrick    WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->FlushStore(NULL);
78bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block}
79bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
80126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Blockstatic void removeExpiredCookie(JNIEnv*, jobject)
81126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block{
82126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block    // This simply forces a GC. The getters delete expired cookies so won't return expired cookies anyway.
838a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen    WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->GetAllCookies();
848a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen    WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->GetAllCookies();
85126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block}
86126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block
878a5f8b64a112f92833cd718f9b401c996918081bKristian Monsenstatic void removeSessionCookies(WebCookieJar* cookieJar)
88126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block{
898a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen  CookieMonster* cookieMonster = cookieJar->cookieStore()->GetCookieMonster();
90e3ea42dbe72fb01590e098d40bef2c41463ced81Kristian Monsen  CookieList cookies = cookieMonster->GetAllCookies();
91e3ea42dbe72fb01590e098d40bef2c41463ced81Kristian Monsen  for (CookieList::const_iterator iter = cookies.begin(); iter != cookies.end(); ++iter) {
924d251b254389274b619593335842516460c63ecfIain Merrick    if (iter->IsSessionCookie())
93126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block      cookieMonster->DeleteCanonicalCookie(*iter);
94126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block  }
95126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block}
96126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block
97126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Blockstatic void removeSessionCookie(JNIEnv*, jobject)
98126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block{
998a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen  removeSessionCookies(WebCookieJar::get(false));
1008a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen  removeSessionCookies(WebCookieJar::get(true));
101126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block}
102126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block
1031dddc338abb68784365d3608c5372d1b6a203706Steve Blockstatic void setAcceptCookie(JNIEnv*, jobject, jboolean accept)
1041dddc338abb68784365d3608c5372d1b6a203706Steve Block{
105965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    // This is a static method which configures the cookie policy for all
106965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    // WebViews, so we configure the contexts for both regular and private
107965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    // browsing.
1088a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen    WebCookieJar::get(false)->setAllowCookies(accept);
1098a5f8b64a112f92833cd718f9b401c996918081bKristian Monsen    WebCookieJar::get(true)->setAllowCookies(accept);
110965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block}
111965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block
11294deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsenstatic void setCookie(JNIEnv* env, jobject, jstring url, jstring value, jboolean privateBrowsing)
113126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block{
114126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block    GURL gurl(jstringToStdString(env, url));
115126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block    std::string line(jstringToStdString(env, value));
116126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block    CookieOptions options;
117126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block    options.set_include_httponly();
11894deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsen    WebCookieJar::get(privateBrowsing)->cookieStore()->GetCookieMonster()->SetCookieWithOptions(gurl, line, options);
119126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block}
120126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block
12126f434aca230193a44d0ccc1abe25f54d59df2fdIain Merrickstatic void flushCookieStore(JNIEnv*, jobject)
12226f434aca230193a44d0ccc1abe25f54d59df2fdIain Merrick{
123e4aa630adb18846d4420dc328cdfcfef6b47caa5Iain Merrick    WebCookieJar::flush();
12426f434aca230193a44d0ccc1abe25f54d59df2fdIain Merrick}
12526f434aca230193a44d0ccc1abe25f54d59df2fdIain Merrick
126571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsenstatic bool acceptFileSchemeCookies(JNIEnv*, jobject)
127571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen{
128571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen    return WebCookieJar::acceptFileSchemeCookies();
129571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen}
130571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen
131571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsenstatic void setAcceptFileSchemeCookies(JNIEnv*, jobject, jboolean accept)
132571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen{
133571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen    WebCookieJar::setAcceptFileSchemeCookies(accept);
134571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen}
135571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen
136bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Blockstatic JNINativeMethod gCookieManagerMethods[] = {
137965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    { "nativeAcceptCookie", "()Z", (void*) acceptCookie },
13894deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsen    { "nativeGetCookie", "(Ljava/lang/String;Z)Ljava/lang/String;", (void*) getCookie },
13994deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsen    { "nativeHasCookies", "(Z)Z", (void*) hasCookies },
140bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    { "nativeRemoveAllCookie", "()V", (void*) removeAllCookie },
141126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block    { "nativeRemoveExpiredCookie", "()V", (void*) removeExpiredCookie },
142126a2dcc3b8ba5809023675c7ec4dfd97e9e9bb1Steve Block    { "nativeRemoveSessionCookie", "()V", (void*) removeSessionCookie },
143965d128a2f803da81a8a6d04c3d79382ff827bb9Steve Block    { "nativeSetAcceptCookie", "(Z)V", (void*) setAcceptCookie },
14494deb9d1218be3c13781a684ef0ddb205efa6c98Kristian Monsen    { "nativeSetCookie", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*) setCookie },
14526f434aca230193a44d0ccc1abe25f54d59df2fdIain Merrick    { "nativeFlushCookieStore", "()V", (void*) flushCookieStore },
146571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen    { "nativeAcceptFileSchemeCookies", "()Z", (void*) acceptFileSchemeCookies },
147571670f6c01cdf0e24a55c840bee7e8f6e7e9b36Kristian Monsen    { "nativeSetAcceptFileSchemeCookies", "(Z)V", (void*) setAcceptFileSchemeCookies },
148bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block};
149bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
150bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Blockint registerCookieManager(JNIEnv* env)
151bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block{
152bf3f67c4fcfd68df256e5c001c67969997a63e28Steve Block#ifndef NDEBUG
153bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    jclass cookieManager = env->FindClass(javaCookieManagerClass);
1546dd76b804786ec760bb04b137a6bf017064226dcSteve Block    ALOG_ASSERT(cookieManager, "Unable to find class");
155bf3f67c4fcfd68df256e5c001c67969997a63e28Steve Block    env->DeleteLocalRef(cookieManager);
156bf3f67c4fcfd68df256e5c001c67969997a63e28Steve Block#endif
157bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block    return jniRegisterNativeMethods(env, javaCookieManagerClass, gCookieManagerMethods, NELEM(gCookieManagerMethods));
158bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block}
159bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block
160bba097db0bb40a3a24c4d54c869d4b0f273f2779Steve Block} // namespace android
161