blob: 975e1377752ea9269f77df0fa7c0839a1d75f74f [file] [log] [blame]
Ben Murdoch7df19852009-04-22 13:07:58 +01001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.webkit;
18
Nicolas Roard11e8fe52009-05-11 15:04:16 +010019import android.os.Handler;
20import android.os.Message;
Nicolas Roard11e8fe52009-05-11 15:04:16 +010021
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010022import java.util.Collection;
Nicolas Roard11e8fe52009-05-11 15:04:16 +010023import java.util.HashMap;
Jonathan Dixon36196b62012-03-28 16:40:37 +010024import java.util.Map;
Andrei Popescuaf9c77e2009-07-21 17:02:35 +010025import java.util.Set;
Nicolas Roard11e8fe52009-05-11 15:04:16 +010026
Ben Murdoch7df19852009-04-22 13:07:58 +010027/**
Steve Block285ddfc2012-03-28 12:46:02 +010028 * This class is used to manage the JavaScript storage APIs provided by the
29 * {@link WebView}. It manages the Application Cache API, the Web SQL Database
30 * API and the HTML5 Web Storage API.
31 *
32 * The Web SQL Database API provides storage which is private to a given
33 * origin, where an origin comprises the host, scheme and port of a URI.
34 * Similarly, use of the Application Cache API can be attributed to an origin.
35 * This class provides access to the storage use and quotas for these APIs for
36 * a given origin. Origins are represented using {@link WebStorage.Origin}.
Ben Murdoch7df19852009-04-22 13:07:58 +010037 */
38public final class WebStorage {
39
40 /**
Steve Block285ddfc2012-03-28 12:46:02 +010041 * Encapsulates a callback function which is used to provide a new quota
42 * for a JavaScript storage API. See
43 * {@link WebChromeClient#onExceededDatabaseQuota} and
44 * {@link WebChromeClient#onReachedMaxAppCacheSize}.
Ben Murdoch7df19852009-04-22 13:07:58 +010045 */
Steve Block285ddfc2012-03-28 12:46:02 +010046 // We primarily want this to allow us to call back the sleeping WebCore
47 // thread from outside the WebViewCore class (as the native call is
48 // private). It is imperative that the setDatabaseQuota method is
49 // executed after a decision to either allow or deny new quota is made,
50 // otherwise the WebCore thread will remain asleep.
Ben Murdoch7df19852009-04-22 13:07:58 +010051 public interface QuotaUpdater {
Steve Block285ddfc2012-03-28 12:46:02 +010052 /**
53 * Provide a new quota, specified in bytes.
54 * @param newQuota The new quota, in bytes
55 */
Ben Murdoch7df19852009-04-22 13:07:58 +010056 public void updateQuota(long newQuota);
57 };
Nicolas Roard11e8fe52009-05-11 15:04:16 +010058
Nicolas Roard11e8fe52009-05-11 15:04:16 +010059 // Global instance of a WebStorage
60 private static WebStorage sWebStorage;
61
Nicolas Roard11e8fe52009-05-11 15:04:16 +010062 // Message ids
63 static final int UPDATE = 0;
64 static final int SET_QUOTA_ORIGIN = 1;
65 static final int DELETE_ORIGIN = 2;
66 static final int DELETE_ALL = 3;
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010067 static final int GET_ORIGINS = 4;
68 static final int GET_USAGE_ORIGIN = 5;
69 static final int GET_QUOTA_ORIGIN = 6;
Nicolas Roard11e8fe52009-05-11 15:04:16 +010070
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010071 // Message ids on the UI thread
72 static final int RETURN_ORIGINS = 0;
73 static final int RETURN_USAGE_ORIGIN = 1;
74 static final int RETURN_QUOTA_ORIGIN = 2;
75
76 private static final String ORIGINS = "origins";
77 private static final String ORIGIN = "origin";
78 private static final String CALLBACK = "callback";
79 private static final String USAGE = "usage";
80 private static final String QUOTA = "quota";
81
82 private Map <String, Origin> mOrigins;
Nicolas Roard11e8fe52009-05-11 15:04:16 +010083
84 private Handler mHandler = null;
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010085 private Handler mUIHandler = null;
Nicolas Roard11e8fe52009-05-11 15:04:16 +010086
John Reck9b2a59b2011-01-24 17:31:39 -080087 /**
Steve Block285ddfc2012-03-28 12:46:02 +010088 * This class encapsulates information about the amount of storage
89 * currently used by an origin for the JavaScript storage APIs.
90 * See {@link WebStorage} for details.
John Reck9b2a59b2011-01-24 17:31:39 -080091 */
John Reck87745ce2010-11-30 14:00:54 -080092 public static class Origin {
93 private String mOrigin = null;
94 private long mQuota = 0;
95 private long mUsage = 0;
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010096
John Reck87745ce2010-11-30 14:00:54 -080097 private Origin(String origin, long quota, long usage) {
Nicolas Roard6c24b4d2009-09-22 18:44:52 +010098 mOrigin = origin;
99 mQuota = quota;
100 mUsage = usage;
101 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100102
John Reck87745ce2010-11-30 14:00:54 -0800103 private Origin(String origin, long quota) {
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100104 mOrigin = origin;
105 mQuota = quota;
106 }
107
John Reck87745ce2010-11-30 14:00:54 -0800108 private Origin(String origin) {
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100109 mOrigin = origin;
110 }
111
John Reck9b2a59b2011-01-24 17:31:39 -0800112 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100113 * Get the string representation of this origin.
114 * @return The string representation of this origin
John Reck9b2a59b2011-01-24 17:31:39 -0800115 */
Steve Block285ddfc2012-03-28 12:46:02 +0100116 // An origin string is created using WebCore::SecurityOrigin::toString().
117 // Note that WebCore::SecurityOrigin uses 0 (which is not printed) for
118 // the port if the port is the default for the protocol. Eg
119 // http://www.google.com and http://www.google.com:80 both record a port
120 // of 0 and hence toString() == 'http://www.google.com' for both.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100121 public String getOrigin() {
122 return mOrigin;
123 }
124
John Reck9b2a59b2011-01-24 17:31:39 -0800125 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100126 * Get the quota for this origin, for the Web SQL Database API, in
127 * bytes. If this origin does not use the Web SQL Database API, this
128 * quota will be set to zero.
129 * @return The quota, in bytes.
John Reck9b2a59b2011-01-24 17:31:39 -0800130 */
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100131 public long getQuota() {
132 return mQuota;
133 }
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100134
John Reck9b2a59b2011-01-24 17:31:39 -0800135 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100136 * Get the total amount of storage currently being used by this origin,
137 * for all JavaScript storage APIs, in bytes.
138 * @return The total amount of storage, in bytes.
John Reck9b2a59b2011-01-24 17:31:39 -0800139 */
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100140 public long getUsage() {
141 return mUsage;
142 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100143 }
144
145 /**
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100146 * Message handler, UI side
Steve Block285ddfc2012-03-28 12:46:02 +0100147 * @hide
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100148 */
149 public void createUIHandler() {
150 if (mUIHandler == null) {
151 mUIHandler = new Handler() {
152 @Override
153 public void handleMessage(Message msg) {
154 switch (msg.what) {
155 case RETURN_ORIGINS: {
156 Map values = (Map) msg.obj;
157 Map origins = (Map) values.get(ORIGINS);
158 ValueCallback<Map> callback = (ValueCallback<Map>) values.get(CALLBACK);
159 callback.onReceiveValue(origins);
160 } break;
161
162 case RETURN_USAGE_ORIGIN: {
163 Map values = (Map) msg.obj;
164 ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
165 callback.onReceiveValue((Long)values.get(USAGE));
166 } break;
167
168 case RETURN_QUOTA_ORIGIN: {
169 Map values = (Map) msg.obj;
170 ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK);
171 callback.onReceiveValue((Long)values.get(QUOTA));
172 } break;
173 }
174 }
175 };
176 }
177 }
178
179 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100180 * Message handler, WebCore side
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100181 * @hide
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100182 */
Steve Blocke4b2d4d2010-02-19 12:21:35 +0000183 public synchronized void createHandler() {
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100184 if (mHandler == null) {
185 mHandler = new Handler() {
186 @Override
187 public void handleMessage(Message msg) {
188 switch (msg.what) {
189 case SET_QUOTA_ORIGIN: {
190 Origin website = (Origin) msg.obj;
191 nativeSetQuotaForOrigin(website.getOrigin(),
192 website.getQuota());
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100193 } break;
194
195 case DELETE_ORIGIN: {
196 Origin website = (Origin) msg.obj;
197 nativeDeleteOrigin(website.getOrigin());
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100198 } break;
199
200 case DELETE_ALL:
Andrei Popescuaf9c77e2009-07-21 17:02:35 +0100201 nativeDeleteAllData();
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100202 break;
203
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100204 case GET_ORIGINS: {
205 syncValues();
206 ValueCallback callback = (ValueCallback) msg.obj;
207 Map origins = new HashMap(mOrigins);
208 Map values = new HashMap<String, Object>();
209 values.put(CALLBACK, callback);
210 values.put(ORIGINS, origins);
211 postUIMessage(Message.obtain(null, RETURN_ORIGINS, values));
212 } break;
213
214 case GET_USAGE_ORIGIN: {
215 syncValues();
216 Map values = (Map) msg.obj;
217 String origin = (String) values.get(ORIGIN);
218 ValueCallback callback = (ValueCallback) values.get(CALLBACK);
219 Origin website = mOrigins.get(origin);
220 Map retValues = new HashMap<String, Object>();
221 retValues.put(CALLBACK, callback);
222 if (website != null) {
223 long usage = website.getUsage();
224 retValues.put(USAGE, new Long(usage));
225 }
226 postUIMessage(Message.obtain(null, RETURN_USAGE_ORIGIN, retValues));
227 } break;
228
229 case GET_QUOTA_ORIGIN: {
230 syncValues();
231 Map values = (Map) msg.obj;
232 String origin = (String) values.get(ORIGIN);
233 ValueCallback callback = (ValueCallback) values.get(CALLBACK);
234 Origin website = mOrigins.get(origin);
235 Map retValues = new HashMap<String, Object>();
236 retValues.put(CALLBACK, callback);
237 if (website != null) {
238 long quota = website.getQuota();
239 retValues.put(QUOTA, new Long(quota));
240 }
241 postUIMessage(Message.obtain(null, RETURN_QUOTA_ORIGIN, retValues));
242 } break;
243
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100244 case UPDATE:
245 syncValues();
246 break;
247 }
248 }
249 };
250 }
251 }
252
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100253 /*
254 * When calling getOrigins(), getUsageForOrigin() and getQuotaForOrigin(),
Steve Block285ddfc2012-03-28 12:46:02 +0100255 * we need to get the values from WebCore, but we cannot block while doing so
256 * as we used to do, as this could result in a full deadlock (other WebCore
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100257 * messages received while we are still blocked here, see http://b/2127737).
258 *
259 * We have to do everything asynchronously, by providing a callback function.
Steve Block285ddfc2012-03-28 12:46:02 +0100260 * We post a message on the WebCore thread (mHandler) that will get the result
261 * from WebCore, and we post it back on the UI thread (using mUIHandler).
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100262 * We can then use the callback function to return the value.
263 */
264
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100265 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100266 * Get the origins currently using either the Application Cache or Web SQL
267 * Database APIs. This method operates asynchronously, with the result
268 * being provided via a {@link ValueCallback}. The origins are provided as
269 * a map, of type {@code Map<String, WebStorage.Origin>}, from the string
270 * representation of the origin to a {@link WebStorage.Origin} object.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100271 */
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100272 public void getOrigins(ValueCallback<Map> callback) {
273 if (callback != null) {
274 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
275 syncValues();
276 callback.onReceiveValue(mOrigins);
277 } else {
278 postMessage(Message.obtain(null, GET_ORIGINS, callback));
Andrei Popescu59e2ad92009-07-28 13:38:06 +0100279 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100280 }
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100281 }
282
283 /**
284 * Returns a list of origins having a database
285 * should only be called from WebViewCore.
286 */
287 Collection<Origin> getOriginsSync() {
288 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
289 update();
290 return mOrigins.values();
291 }
292 return null;
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100293 }
294
295 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100296 * Get the amount of storage currently being used by both the Application
297 * Cache and Web SQL Database APIs by the given origin. The amount is given
298 * in bytes and the origin is specified using its string representation.
299 * This method operates asynchronously, with the result being provided via
300 * a {@link ValueCallback}.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100301 */
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100302 public void getUsageForOrigin(String origin, ValueCallback<Long> callback) {
303 if (callback == null) {
304 return;
305 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100306 if (origin == null) {
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100307 callback.onReceiveValue(null);
308 return;
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100309 }
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100310 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
311 syncValues();
312 Origin website = mOrigins.get(origin);
313 callback.onReceiveValue(new Long(website.getUsage()));
314 } else {
315 HashMap values = new HashMap<String, Object>();
316 values.put(ORIGIN, origin);
317 values.put(CALLBACK, callback);
318 postMessage(Message.obtain(null, GET_USAGE_ORIGIN, values));
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100319 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100320 }
321
322 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100323 * Get the storage quota for the Web SQL Database API for the given origin.
324 * The quota is given in bytes and the origin is specified using its string
325 * representation. This method operates asynchronously, with the result
326 * being provided via a {@link ValueCallback}. Note that a quota is not
327 * enforced on a per-origin basis for the Application Cache API.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100328 */
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100329 public void getQuotaForOrigin(String origin, ValueCallback<Long> callback) {
330 if (callback == null) {
331 return;
332 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100333 if (origin == null) {
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100334 callback.onReceiveValue(null);
335 return;
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100336 }
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100337 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
338 syncValues();
339 Origin website = mOrigins.get(origin);
340 callback.onReceiveValue(new Long(website.getUsage()));
341 } else {
342 HashMap values = new HashMap<String, Object>();
343 values.put(ORIGIN, origin);
344 values.put(CALLBACK, callback);
345 postMessage(Message.obtain(null, GET_QUOTA_ORIGIN, values));
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100346 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100347 }
348
349 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100350 * Set the storage quota for the Web SQL Database API for the given origin.
351 * The quota is specified in bytes and the origin is specified using its string
352 * representation. Note that a quota is not enforced on a per-origin basis
353 * for the Application Cache API.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100354 */
355 public void setQuotaForOrigin(String origin, long quota) {
356 if (origin != null) {
Ben Murdoch5647bb32009-06-18 17:48:34 +0100357 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
358 nativeSetQuotaForOrigin(origin, quota);
Ben Murdoch5647bb32009-06-18 17:48:34 +0100359 } else {
360 postMessage(Message.obtain(null, SET_QUOTA_ORIGIN,
361 new Origin(origin, quota)));
362 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100363 }
364 }
365
366 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100367 * Clear the storage currently being used by both the Application Cache and
368 * Web SQL Database APIs by the given origin. The origin is specified using
369 * its string representation.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100370 */
371 public void deleteOrigin(String origin) {
372 if (origin != null) {
Ben Murdoch5647bb32009-06-18 17:48:34 +0100373 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
374 nativeDeleteOrigin(origin);
Ben Murdoch5647bb32009-06-18 17:48:34 +0100375 } else {
376 postMessage(Message.obtain(null, DELETE_ORIGIN,
377 new Origin(origin)));
378 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100379 }
380 }
381
382 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100383 * Clear all storage currently being used by the JavaScript storage APIs.
384 * This includes the Application Cache, Web SQL Database and the HTML5 Web
385 * Storage APIs.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100386 */
Andrei Popescuaf9c77e2009-07-21 17:02:35 +0100387 public void deleteAllData() {
Ben Murdoch5647bb32009-06-18 17:48:34 +0100388 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
Andrei Popescuaf9c77e2009-07-21 17:02:35 +0100389 nativeDeleteAllData();
Ben Murdoch5647bb32009-06-18 17:48:34 +0100390 } else {
391 postMessage(Message.obtain(null, DELETE_ALL));
392 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100393 }
394
395 /**
Steve Block427efcc2010-03-19 15:26:42 +0000396 * Sets the maximum size of the ApplicationCache.
397 * This should only ever be called on the WebKit thread.
Jonathan Dixon4cde13a2011-12-16 18:36:20 +0000398 * @hide
Steve Block427efcc2010-03-19 15:26:42 +0000399 */
400 public void setAppCacheMaximumSize(long size) {
401 nativeSetAppCacheMaximumSize(size);
402 }
403
404 /**
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100405 * Utility function to send a message to our handler
406 */
Steve Blocke4b2d4d2010-02-19 12:21:35 +0000407 private synchronized void postMessage(Message msg) {
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100408 if (mHandler != null) {
409 mHandler.sendMessage(msg);
410 }
411 }
412
413 /**
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100414 * Utility function to send a message to the handler on the UI thread
415 */
416 private void postUIMessage(Message msg) {
417 if (mUIHandler != null) {
418 mUIHandler.sendMessage(msg);
419 }
420 }
421
422 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100423 * Get the singleton instance of this class.
424 * @return The singleton {@link WebStorage} instance.
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100425 */
426 public static WebStorage getInstance() {
427 if (sWebStorage == null) {
428 sWebStorage = new WebStorage();
429 }
430 return sWebStorage;
431 }
432
433 /**
434 * @hide
435 * Post a Sync request
436 */
437 public void update() {
Ben Murdoch5647bb32009-06-18 17:48:34 +0100438 if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) {
439 syncValues();
440 } else {
441 postMessage(Message.obtain(null, UPDATE));
442 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100443 }
444
445 /**
Steve Block285ddfc2012-03-28 12:46:02 +0100446 * Run on the WebCore thread
Andrei Popescu9a56bb82009-07-22 19:21:48 +0100447 * set the local values with the current ones
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100448 */
449 private void syncValues() {
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100450 Set<String> tmp = nativeGetOrigins();
451 mOrigins = new HashMap<String, Origin>();
452 for (String origin : tmp) {
453 Origin website = new Origin(origin,
Andrei Popescu98409702010-01-08 16:41:23 +0000454 nativeGetQuotaForOrigin(origin),
455 nativeGetUsageForOrigin(origin));
Nicolas Roard6c24b4d2009-09-22 18:44:52 +0100456 mOrigins.put(origin, website);
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100457 }
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100458 }
459
460 // Native functions
Andrei Popescuaf9c77e2009-07-21 17:02:35 +0100461 private static native Set nativeGetOrigins();
Nicolas Roard11e8fe52009-05-11 15:04:16 +0100462 private static native long nativeGetUsageForOrigin(String origin);
463 private static native long nativeGetQuotaForOrigin(String origin);
464 private static native void nativeSetQuotaForOrigin(String origin, long quota);
465 private static native void nativeDeleteOrigin(String origin);
Andrei Popescuaf9c77e2009-07-21 17:02:35 +0100466 private static native void nativeDeleteAllData();
Steve Block427efcc2010-03-19 15:26:42 +0000467 private static native void nativeSetAppCacheMaximumSize(long size);
Ben Murdoch7df19852009-04-22 13:07:58 +0100468}