1 /*
2 * Copyright 2010, The Android Open Source Project
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27
28 #include "ChromiumIncludes.h"
29 #include "WebCookieJar.h"
30 #include "WebCoreJni.h"
31 #include <JNIHelp.h>
32
33 using namespace base;
34 using namespace net;
35
36 namespace android {
37
38 // JNI for android.webkit.CookieManagerClassic
39 static const char* javaCookieManagerClass = "android/webkit/CookieManagerClassic";
40
acceptCookie(JNIEnv *,jobject)41 static bool acceptCookie(JNIEnv*, jobject)
42 {
43 // This is a static method which gets the cookie policy for all WebViews. We
44 // always apply the same configuration to the contexts for both regular and
45 // private browsing, so expect the same result here.
46 bool regularAcceptCookies = WebCookieJar::get(false)->allowCookies();
47 ASSERT(regularAcceptCookies == WebCookieJar::get(true)->allowCookies());
48 return regularAcceptCookies;
49 }
50
getCookie(JNIEnv * env,jobject,jstring url,jboolean privateBrowsing)51 static jstring getCookie(JNIEnv* env, jobject, jstring url, jboolean privateBrowsing)
52 {
53 GURL gurl(jstringToStdString(env, url));
54 CookieOptions options;
55 options.set_include_httponly();
56 std::string cookies = WebCookieJar::get(privateBrowsing)->cookieStore()->GetCookieMonster()->GetCookiesWithOptions(gurl, options);
57 return stdStringToJstring(env, cookies);
58 }
59
hasCookies(JNIEnv *,jobject,jboolean privateBrowsing)60 static bool hasCookies(JNIEnv*, jobject, jboolean privateBrowsing)
61 {
62 return WebCookieJar::get(privateBrowsing)->getNumCookiesInDatabase() > 0;
63 }
64
removeAllCookie(JNIEnv *,jobject)65 static void removeAllCookie(JNIEnv*, jobject)
66 {
67 WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->DeleteAll(true);
68 // This will lazily create a new private browsing context. However, if the
69 // context doesn't already exist, there's no need to create it, as cookies
70 // for such contexts are cleared up when we're done with them.
71 // TODO: Consider adding an optimisation to not create the context if it
72 // doesn't already exist.
73 WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->DeleteAll(true);
74
75 // The Java code removes cookies directly from the backing database, so we do the same,
76 // but with a NULL callback so it's asynchronous.
77 WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->FlushStore(NULL);
78 }
79
removeExpiredCookie(JNIEnv *,jobject)80 static void removeExpiredCookie(JNIEnv*, jobject)
81 {
82 // This simply forces a GC. The getters delete expired cookies so won't return expired cookies anyway.
83 WebCookieJar::get(false)->cookieStore()->GetCookieMonster()->GetAllCookies();
84 WebCookieJar::get(true)->cookieStore()->GetCookieMonster()->GetAllCookies();
85 }
86
removeSessionCookies(WebCookieJar * cookieJar)87 static void removeSessionCookies(WebCookieJar* cookieJar)
88 {
89 CookieMonster* cookieMonster = cookieJar->cookieStore()->GetCookieMonster();
90 CookieList cookies = cookieMonster->GetAllCookies();
91 for (CookieList::const_iterator iter = cookies.begin(); iter != cookies.end(); ++iter) {
92 if (iter->IsSessionCookie())
93 cookieMonster->DeleteCanonicalCookie(*iter);
94 }
95 }
96
removeSessionCookie(JNIEnv *,jobject)97 static void removeSessionCookie(JNIEnv*, jobject)
98 {
99 removeSessionCookies(WebCookieJar::get(false));
100 removeSessionCookies(WebCookieJar::get(true));
101 }
102
setAcceptCookie(JNIEnv *,jobject,jboolean accept)103 static void setAcceptCookie(JNIEnv*, jobject, jboolean accept)
104 {
105 // This is a static method which configures the cookie policy for all
106 // WebViews, so we configure the contexts for both regular and private
107 // browsing.
108 WebCookieJar::get(false)->setAllowCookies(accept);
109 WebCookieJar::get(true)->setAllowCookies(accept);
110 }
111
setCookie(JNIEnv * env,jobject,jstring url,jstring value,jboolean privateBrowsing)112 static void setCookie(JNIEnv* env, jobject, jstring url, jstring value, jboolean privateBrowsing)
113 {
114 GURL gurl(jstringToStdString(env, url));
115 std::string line(jstringToStdString(env, value));
116 CookieOptions options;
117 options.set_include_httponly();
118 WebCookieJar::get(privateBrowsing)->cookieStore()->GetCookieMonster()->SetCookieWithOptions(gurl, line, options);
119 }
120
flushCookieStore(JNIEnv *,jobject)121 static void flushCookieStore(JNIEnv*, jobject)
122 {
123 WebCookieJar::flush();
124 }
125
acceptFileSchemeCookies(JNIEnv *,jobject)126 static bool acceptFileSchemeCookies(JNIEnv*, jobject)
127 {
128 return WebCookieJar::acceptFileSchemeCookies();
129 }
130
setAcceptFileSchemeCookies(JNIEnv *,jobject,jboolean accept)131 static void setAcceptFileSchemeCookies(JNIEnv*, jobject, jboolean accept)
132 {
133 WebCookieJar::setAcceptFileSchemeCookies(accept);
134 }
135
136 static JNINativeMethod gCookieManagerMethods[] = {
137 { "nativeAcceptCookie", "()Z", (void*) acceptCookie },
138 { "nativeGetCookie", "(Ljava/lang/String;Z)Ljava/lang/String;", (void*) getCookie },
139 { "nativeHasCookies", "(Z)Z", (void*) hasCookies },
140 { "nativeRemoveAllCookie", "()V", (void*) removeAllCookie },
141 { "nativeRemoveExpiredCookie", "()V", (void*) removeExpiredCookie },
142 { "nativeRemoveSessionCookie", "()V", (void*) removeSessionCookie },
143 { "nativeSetAcceptCookie", "(Z)V", (void*) setAcceptCookie },
144 { "nativeSetCookie", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*) setCookie },
145 { "nativeFlushCookieStore", "()V", (void*) flushCookieStore },
146 { "nativeAcceptFileSchemeCookies", "()Z", (void*) acceptFileSchemeCookies },
147 { "nativeSetAcceptFileSchemeCookies", "(Z)V", (void*) setAcceptFileSchemeCookies },
148 };
149
registerCookieManager(JNIEnv * env)150 int registerCookieManager(JNIEnv* env)
151 {
152 #ifndef NDEBUG
153 jclass cookieManager = env->FindClass(javaCookieManagerClass);
154 ALOG_ASSERT(cookieManager, "Unable to find class");
155 env->DeleteLocalRef(cookieManager);
156 #endif
157 return jniRegisterNativeMethods(env, javaCookieManagerClass, gCookieManagerMethods, NELEM(gCookieManagerMethods));
158 }
159
160 } // namespace android
161