WebStorage.java revision 87745ce21fe3f65b8cf7a92372c24227821318d3
17df1985e86635af006be3dfa65987d60e290b5deBen Murdoch/* 27df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * Copyright (C) 2009 The Android Open Source Project 37df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * 47df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * Licensed under the Apache License, Version 2.0 (the "License"); 57df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * you may not use this file except in compliance with the License. 67df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * You may obtain a copy of the License at 77df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * 87df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * http://www.apache.org/licenses/LICENSE-2.0 97df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * 107df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * Unless required by applicable law or agreed to in writing, software 117df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * distributed under the License is distributed on an "AS IS" BASIS, 127df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * See the License for the specific language governing permissions and 147df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * limitations under the License. 157df1985e86635af006be3dfa65987d60e290b5deBen Murdoch */ 167df1985e86635af006be3dfa65987d60e290b5deBen Murdoch 177df1985e86635af006be3dfa65987d60e290b5deBen Murdochpackage android.webkit; 187df1985e86635af006be3dfa65987d60e290b5deBen Murdoch 1911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roardimport android.os.Handler; 2011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roardimport android.os.Message; 2111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roardimport android.util.Log; 2211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 236c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roardimport java.util.Collection; 246c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roardimport java.util.Map; 2511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roardimport java.util.HashMap; 26af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescuimport java.util.HashSet; 27af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescuimport java.util.Iterator; 28af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescuimport java.util.Set; 2911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 307df1985e86635af006be3dfa65987d60e290b5deBen Murdoch/** 317df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * Functionality for manipulating the webstorage databases. 327df1985e86635af006be3dfa65987d60e290b5deBen Murdoch */ 337df1985e86635af006be3dfa65987d60e290b5deBen Murdochpublic final class WebStorage { 347df1985e86635af006be3dfa65987d60e290b5deBen Murdoch 357df1985e86635af006be3dfa65987d60e290b5deBen Murdoch /** 367df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * Encapsulates a callback function to be executed when a new quota is made 377df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * available. We primarily want this to allow us to call back the sleeping 387df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * WebCore thread from outside the WebViewCore class (as the native call 397df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * is private). It is imperative that this the setDatabaseQuota method is 407df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * executed once a decision to either allow or deny new quota is made, 417df1985e86635af006be3dfa65987d60e290b5deBen Murdoch * otherwise the WebCore thread will remain asleep. 427df1985e86635af006be3dfa65987d60e290b5deBen Murdoch */ 437df1985e86635af006be3dfa65987d60e290b5deBen Murdoch public interface QuotaUpdater { 447df1985e86635af006be3dfa65987d60e290b5deBen Murdoch public void updateQuota(long newQuota); 457df1985e86635af006be3dfa65987d60e290b5deBen Murdoch }; 4611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 4711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard // Log tag 4811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static final String TAG = "webstorage"; 4911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 5011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard // Global instance of a WebStorage 5111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static WebStorage sWebStorage; 5211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 5311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard // Message ids 5411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard static final int UPDATE = 0; 5511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard static final int SET_QUOTA_ORIGIN = 1; 5611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard static final int DELETE_ORIGIN = 2; 5711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard static final int DELETE_ALL = 3; 586c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard static final int GET_ORIGINS = 4; 596c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard static final int GET_USAGE_ORIGIN = 5; 606c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard static final int GET_QUOTA_ORIGIN = 6; 616c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 626c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard // Message ids on the UI thread 636c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard static final int RETURN_ORIGINS = 0; 646c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard static final int RETURN_USAGE_ORIGIN = 1; 656c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard static final int RETURN_QUOTA_ORIGIN = 2; 666c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 676c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private static final String ORIGINS = "origins"; 686c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private static final String ORIGIN = "origin"; 696c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private static final String CALLBACK = "callback"; 706c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private static final String USAGE = "usage"; 716c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private static final String QUOTA = "quota"; 7211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 736c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private Map <String, Origin> mOrigins; 7411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 7511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private Handler mHandler = null; 766c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private Handler mUIHandler = null; 7711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 7887745ce21fe3f65b8cf7a92372c24227821318d3John Reck public static class Origin { 7987745ce21fe3f65b8cf7a92372c24227821318d3John Reck private String mOrigin = null; 8087745ce21fe3f65b8cf7a92372c24227821318d3John Reck private long mQuota = 0; 8187745ce21fe3f65b8cf7a92372c24227821318d3John Reck private long mUsage = 0; 826c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 8387745ce21fe3f65b8cf7a92372c24227821318d3John Reck private Origin(String origin, long quota, long usage) { 846c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mOrigin = origin; 856c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mQuota = quota; 866c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mUsage = usage; 876c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 8811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 8987745ce21fe3f65b8cf7a92372c24227821318d3John Reck private Origin(String origin, long quota) { 9011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mOrigin = origin; 9111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mQuota = quota; 9211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 9311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 9487745ce21fe3f65b8cf7a92372c24227821318d3John Reck private Origin(String origin) { 9511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mOrigin = origin; 9611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 9711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 9811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public String getOrigin() { 9911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard return mOrigin; 10011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 10111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 10211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public long getQuota() { 10311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard return mQuota; 10411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 1056c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1066c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public long getUsage() { 1076c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return mUsage; 1086c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1096c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1106c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1116c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /** 1126c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * @hide 1136c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Message handler, UI side 1146c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 1156c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void createUIHandler() { 1166c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (mUIHandler == null) { 1176c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mUIHandler = new Handler() { 1186c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard @Override 1196c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void handleMessage(Message msg) { 1206c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard switch (msg.what) { 1216c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case RETURN_ORIGINS: { 1226c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1236c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map origins = (Map) values.get(ORIGINS); 1246c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback<Map> callback = (ValueCallback<Map>) values.get(CALLBACK); 1256c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(origins); 1266c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1276c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1286c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case RETURN_USAGE_ORIGIN: { 1296c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1306c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK); 1316c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue((Long)values.get(USAGE)); 1326c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1336c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1346c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case RETURN_QUOTA_ORIGIN: { 1356c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1366c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK); 1376c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue((Long)values.get(QUOTA)); 1386c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1396c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1406c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1416c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard }; 1426c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 14311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 14411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 14511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 14611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * @hide 1476c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Message handler, webcore side 14811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 149e4b2d4dc7db426052d1dfebc40f6b64a001b6d73Steve Block public synchronized void createHandler() { 15011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (mHandler == null) { 15111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mHandler = new Handler() { 15211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard @Override 15311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void handleMessage(Message msg) { 15411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard switch (msg.what) { 15511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case SET_QUOTA_ORIGIN: { 15611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard Origin website = (Origin) msg.obj; 15711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard nativeSetQuotaForOrigin(website.getOrigin(), 15811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard website.getQuota()); 15911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } break; 16011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 16111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case DELETE_ORIGIN: { 16211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard Origin website = (Origin) msg.obj; 16311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard nativeDeleteOrigin(website.getOrigin()); 16411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } break; 16511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 16611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case DELETE_ALL: 167af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu nativeDeleteAllData(); 16811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard break; 16911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 1706c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case GET_ORIGINS: { 1716c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 1726c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback callback = (ValueCallback) msg.obj; 1736c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map origins = new HashMap(mOrigins); 1746c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = new HashMap<String, Object>(); 1756c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(CALLBACK, callback); 1766c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(ORIGINS, origins); 1776c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postUIMessage(Message.obtain(null, RETURN_ORIGINS, values)); 1786c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1796c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1806c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case GET_USAGE_ORIGIN: { 1816c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 1826c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1836c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard String origin = (String) values.get(ORIGIN); 1846c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback callback = (ValueCallback) values.get(CALLBACK); 1856c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 1866c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map retValues = new HashMap<String, Object>(); 1876c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(CALLBACK, callback); 1886c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (website != null) { 1896c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard long usage = website.getUsage(); 1906c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(USAGE, new Long(usage)); 1916c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1926c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postUIMessage(Message.obtain(null, RETURN_USAGE_ORIGIN, retValues)); 1936c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1946c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1956c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case GET_QUOTA_ORIGIN: { 1966c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 1976c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1986c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard String origin = (String) values.get(ORIGIN); 1996c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback callback = (ValueCallback) values.get(CALLBACK); 2006c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 2016c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map retValues = new HashMap<String, Object>(); 2026c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(CALLBACK, callback); 2036c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (website != null) { 2046c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard long quota = website.getQuota(); 2056c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(QUOTA, new Long(quota)); 2066c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 2076c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postUIMessage(Message.obtain(null, RETURN_QUOTA_ORIGIN, retValues)); 2086c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 2096c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 21011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case UPDATE: 21111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard syncValues(); 21211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard break; 21311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 21411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 21511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard }; 21611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 21711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 21811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 2196c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /* 2206c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * When calling getOrigins(), getUsageForOrigin() and getQuotaForOrigin(), 2216c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * we need to get the values from webcore, but we cannot block while doing so 2226c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * as we used to do, as this could result in a full deadlock (other webcore 2236c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * messages received while we are still blocked here, see http://b/2127737). 2246c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * 2256c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * We have to do everything asynchronously, by providing a callback function. 2266c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * We post a message on the webcore thread (mHandler) that will get the result 2276c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * from webcore, and we post it back on the UI thread (using mUIHandler). 2286c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * We can then use the callback function to return the value. 2296c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 2306c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 23111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 23211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Returns a list of origins having a database 23311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 2346c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void getOrigins(ValueCallback<Map> callback) { 2356c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (callback != null) { 2366c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 2376c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 2386c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(mOrigins); 2396c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } else { 2406c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postMessage(Message.obtain(null, GET_ORIGINS, callback)); 24159e2ad93bf37c7ded44c033d38fe7c972e2f4118Andrei Popescu } 24211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 2436c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 2446c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 2456c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /** 2466c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Returns a list of origins having a database 2476c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * should only be called from WebViewCore. 2486c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 2496c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Collection<Origin> getOriginsSync() { 2506c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 2516c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard update(); 2526c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return mOrigins.values(); 2536c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 2546c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return null; 25511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 25611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 25711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 25811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Returns the use for a given origin 25911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 2606c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void getUsageForOrigin(String origin, ValueCallback<Long> callback) { 2616c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (callback == null) { 2626c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 2636c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 26411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin == null) { 2656c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(null); 2666c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 26711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 2686c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 2696c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 2706c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 2716c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(new Long(website.getUsage())); 2726c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } else { 2736c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard HashMap values = new HashMap<String, Object>(); 2746c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(ORIGIN, origin); 2756c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(CALLBACK, callback); 2766c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postMessage(Message.obtain(null, GET_USAGE_ORIGIN, values)); 27711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 27811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 27911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 28011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 28111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Returns the quota for a given origin 28211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 2836c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void getQuotaForOrigin(String origin, ValueCallback<Long> callback) { 2846c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (callback == null) { 2856c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 2866c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 28711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin == null) { 2886c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(null); 2896c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 29011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 2916c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 2926c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 2936c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 2946c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(new Long(website.getUsage())); 2956c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } else { 2966c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard HashMap values = new HashMap<String, Object>(); 2976c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(ORIGIN, origin); 2986c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(CALLBACK, callback); 2996c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postMessage(Message.obtain(null, GET_QUOTA_ORIGIN, values)); 30011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 30111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 30211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 30311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 30411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Set the quota for a given origin 30511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 30611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void setQuotaForOrigin(String origin, long quota) { 30711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin != null) { 3085647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 3095647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch nativeSetQuotaForOrigin(origin, quota); 3105647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 3115647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, SET_QUOTA_ORIGIN, 3125647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch new Origin(origin, quota))); 3135647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 31411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 31511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 31611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 31711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 31811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Delete a given origin 31911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 32011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void deleteOrigin(String origin) { 32111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin != null) { 3225647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 3235647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch nativeDeleteOrigin(origin); 3245647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 3255647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, DELETE_ORIGIN, 3265647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch new Origin(origin))); 3275647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 32811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 32911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 33011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 33111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 33211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Delete all databases 33311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 334af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu public void deleteAllData() { 3355647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 336af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu nativeDeleteAllData(); 3375647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 3385647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, DELETE_ALL)); 3395647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 34011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 34111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 34211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 343427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block * Sets the maximum size of the ApplicationCache. 344427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block * This should only ever be called on the WebKit thread. 345427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block * @hide Pending API council approval 346427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block */ 347427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block public void setAppCacheMaximumSize(long size) { 348427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block nativeSetAppCacheMaximumSize(size); 349427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block } 350427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block 351427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block /** 35211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Utility function to send a message to our handler 35311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 354e4b2d4dc7db426052d1dfebc40f6b64a001b6d73Steve Block private synchronized void postMessage(Message msg) { 35511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (mHandler != null) { 35611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mHandler.sendMessage(msg); 35711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 35811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 35911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 36011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 3616c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Utility function to send a message to the handler on the UI thread 3626c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 3636c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private void postUIMessage(Message msg) { 3646c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (mUIHandler != null) { 3656c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mUIHandler.sendMessage(msg); 3666c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 3676c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 3686c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 3696c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /** 37011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Get the global instance of WebStorage. 37111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * @return A single instance of WebStorage. 37211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 37311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public static WebStorage getInstance() { 37411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (sWebStorage == null) { 37511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard sWebStorage = new WebStorage(); 37611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 37711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard return sWebStorage; 37811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 37911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 38011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 38111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * @hide 38211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Post a Sync request 38311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 38411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void update() { 3855647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 3865647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch syncValues(); 3875647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 3885647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, UPDATE)); 3895647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 39011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 39111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 39211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 39311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Run on the webcore thread 3949a56bb838c099a318d4f961f290d324ed5f1949dAndrei Popescu * set the local values with the current ones 39511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 39611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private void syncValues() { 3976c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Set<String> tmp = nativeGetOrigins(); 3986c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mOrigins = new HashMap<String, Origin>(); 3996c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard for (String origin : tmp) { 4006c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = new Origin(origin, 40198409704134c262fdaab47055f60b7e01a4bc0b2Andrei Popescu nativeGetQuotaForOrigin(origin), 40298409704134c262fdaab47055f60b7e01a4bc0b2Andrei Popescu nativeGetUsageForOrigin(origin)); 4036c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mOrigins.put(origin, website); 40411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 40511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 40611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 40711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard // Native functions 408af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu private static native Set nativeGetOrigins(); 40911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native long nativeGetUsageForOrigin(String origin); 41011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native long nativeGetQuotaForOrigin(String origin); 41111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native void nativeSetQuotaForOrigin(String origin, long quota); 41211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native void nativeDeleteOrigin(String origin); 413af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu private static native void nativeDeleteAllData(); 414427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block private static native void nativeSetAppCacheMaximumSize(long size); 4157df1985e86635af006be3dfa65987d60e290b5deBen Murdoch} 416