Home | History | Annotate | Download | only in jni
      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 
     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 
     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 
     60 static bool hasCookies(JNIEnv*, jobject, jboolean privateBrowsing)
     61 {
     62     return WebCookieJar::get(privateBrowsing)->getNumCookiesInDatabase() > 0;
     63 }
     64 
     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 
     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 
     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 
     97 static void removeSessionCookie(JNIEnv*, jobject)
     98 {
     99   removeSessionCookies(WebCookieJar::get(false));
    100   removeSessionCookies(WebCookieJar::get(true));
    101 }
    102 
    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 
    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 
    121 static void flushCookieStore(JNIEnv*, jobject)
    122 {
    123     WebCookieJar::flush();
    124 }
    125 
    126 static bool acceptFileSchemeCookies(JNIEnv*, jobject)
    127 {
    128     return WebCookieJar::acceptFileSchemeCookies();
    129 }
    130 
    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 
    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