1/*
2 * Copyright 2009, 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#if ENABLE(DATABASE)
29
30#include "JavaSharedClient.h"
31#include "KURL.h"
32#include "PageGroup.h"
33#include "WebCoreJni.h"
34
35#include <JNIHelp.h>
36#include <JNIUtility.h>
37#include <WebCore/loader/appcache/ApplicationCacheStorage.h>
38#include <WebCore/page/SecurityOrigin.h>
39#include <WebCore/storage/DatabaseTracker.h>
40
41namespace android {
42
43static jobject GetOrigins(JNIEnv* env, jobject obj)
44{
45    Vector<RefPtr<WebCore::SecurityOrigin> > coreOrigins;
46    WebCore::DatabaseTracker::tracker().origins(coreOrigins);
47    Vector<WebCore::KURL> manifestUrls;
48    if (WebCore::cacheStorage().manifestURLs(&manifestUrls)) {
49        int size = manifestUrls.size();
50        for (int i = 0; i < size; ++i) {
51            RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]);
52            if (manifestOrigin.get() == 0)
53                continue;
54            coreOrigins.append(manifestOrigin);
55        }
56    }
57
58    jclass setClass = env->FindClass("java/util/HashSet");
59    jmethodID cid = env->GetMethodID(setClass, "<init>", "()V");
60    jmethodID mid = env->GetMethodID(setClass, "add", "(Ljava/lang/Object;)Z");
61    jobject set = env->NewObject(setClass, cid);
62
63    for (unsigned i = 0; i < coreOrigins.size(); ++i) {
64        WebCore::SecurityOrigin* origin = coreOrigins[i].get();
65        WebCore::String url = origin->toString();
66        jstring jUrl = env->NewString(url.characters(), url.length());
67        env->CallBooleanMethod(set, mid, jUrl);
68        env->DeleteLocalRef(jUrl);
69    }
70
71    return set;
72}
73
74static unsigned long long GetQuotaForOrigin(JNIEnv* env, jobject obj, jstring origin)
75{
76    WebCore::String originStr = to_string(env, origin);
77    RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr);
78    unsigned long long quota = WebCore::DatabaseTracker::tracker().quotaForOrigin(securityOrigin.get());
79    return quota;
80}
81
82static unsigned long long GetUsageForOrigin(JNIEnv* env, jobject obj, jstring origin)
83{
84    WebCore::String originStr = to_string(env, origin);
85    RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr);
86    unsigned long long usage = WebCore::DatabaseTracker::tracker().usageForOrigin(securityOrigin.get());
87    Vector<WebCore::KURL> manifestUrls;
88    if (!WebCore::cacheStorage().manifestURLs(&manifestUrls))
89        return usage;
90    int size = manifestUrls.size();
91    for (int i = 0; i < size; ++i) {
92        RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]);
93        if (manifestOrigin.get() == 0)
94            continue;
95        if (manifestOrigin->isSameSchemeHostPort(securityOrigin.get())) {
96            int64_t cacheSize = 0;
97            WebCore::cacheStorage().cacheGroupSize(manifestUrls[i].string(), &cacheSize);
98            usage += cacheSize;
99        }
100    }
101    return usage;
102}
103
104static void SetQuotaForOrigin(JNIEnv* env, jobject obj, jstring origin, unsigned long long quota)
105{
106    WebCore::String originStr = to_string(env, origin);
107    RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr);
108    WebCore::DatabaseTracker::tracker().setQuota(securityOrigin.get(), quota);
109}
110
111static void DeleteOrigin(JNIEnv* env, jobject obj, jstring origin)
112{
113    WebCore::String originStr = to_string(env, origin);
114    RefPtr<WebCore::SecurityOrigin> securityOrigin = WebCore::SecurityOrigin::createFromString(originStr);
115    WebCore::DatabaseTracker::tracker().deleteOrigin(securityOrigin.get());
116
117    Vector<WebCore::KURL> manifestUrls;
118    if (!WebCore::cacheStorage().manifestURLs(&manifestUrls))
119        return;
120    int size = manifestUrls.size();
121    for (int i = 0; i < size; ++i) {
122        RefPtr<WebCore::SecurityOrigin> manifestOrigin = WebCore::SecurityOrigin::create(manifestUrls[i]);
123        if (manifestOrigin.get() == 0)
124            continue;
125        if (manifestOrigin->isSameSchemeHostPort(securityOrigin.get()))
126            WebCore::cacheStorage().deleteCacheGroup(manifestUrls[i]);
127    }
128}
129
130static void DeleteAllData(JNIEnv* env, jobject obj)
131{
132    WebCore::DatabaseTracker::tracker().deleteAllDatabases();
133    WebCore::cacheStorage().empty();
134    // FIXME: this is a workaround for eliminating any DOM Storage data (both
135    // session and local storage) as there is no functionality inside WebKit at the
136    // moment to do it. That functionality is a WIP in https://bugs.webkit.org/show_bug.cgi?id=51878
137    // and when that patch lands and we merge it, we should move towards that approach instead.
138    WebCore::PageGroup::clearDomStorage();
139}
140
141static void SetAppCacheMaximumSize(JNIEnv* env, jobject obj, unsigned long long size)
142{
143    WebCore::cacheStorage().setMaximumSize(size);
144}
145
146/*
147 * JNI registration
148 */
149static JNINativeMethod gWebStorageMethods[] = {
150    { "nativeGetOrigins", "()Ljava/util/Set;",
151        (void*) GetOrigins },
152    { "nativeGetUsageForOrigin", "(Ljava/lang/String;)J",
153        (void*) GetUsageForOrigin },
154    { "nativeGetQuotaForOrigin", "(Ljava/lang/String;)J",
155        (void*) GetQuotaForOrigin },
156    { "nativeSetQuotaForOrigin", "(Ljava/lang/String;J)V",
157        (void*) SetQuotaForOrigin },
158    { "nativeDeleteOrigin", "(Ljava/lang/String;)V",
159        (void*) DeleteOrigin },
160    { "nativeDeleteAllData", "()V",
161        (void*) DeleteAllData },
162    { "nativeSetAppCacheMaximumSize", "(J)V",
163        (void*) SetAppCacheMaximumSize }
164};
165
166int register_webstorage(JNIEnv* env)
167{
168    jclass webStorage = env->FindClass("android/webkit/WebStorage");
169    LOG_ASSERT(webStorage, "Unable to find class android.webkit.WebStorage");
170
171    return jniRegisterNativeMethods(env, "android/webkit/WebStorage",
172            gWebStorageMethods, NELEM(gWebStorageMethods));
173}
174
175}
176
177#endif //ENABLE(DATABASE)
178