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 789b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck /** 799b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * Class containing the HTML5 database quota and usage for an origin. 809b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck */ 8187745ce21fe3f65b8cf7a92372c24227821318d3John Reck public static class Origin { 8287745ce21fe3f65b8cf7a92372c24227821318d3John Reck private String mOrigin = null; 8387745ce21fe3f65b8cf7a92372c24227821318d3John Reck private long mQuota = 0; 8487745ce21fe3f65b8cf7a92372c24227821318d3John Reck private long mUsage = 0; 856c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 8687745ce21fe3f65b8cf7a92372c24227821318d3John Reck private Origin(String origin, long quota, long usage) { 876c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mOrigin = origin; 886c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mQuota = quota; 896c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mUsage = usage; 906c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 9111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 9287745ce21fe3f65b8cf7a92372c24227821318d3John Reck private Origin(String origin, long quota) { 9311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mOrigin = origin; 9411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mQuota = quota; 9511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 9611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 9787745ce21fe3f65b8cf7a92372c24227821318d3John Reck private Origin(String origin) { 9811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mOrigin = origin; 9911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 10011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 1019b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck /** 1029b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * An origin string is created using WebCore::SecurityOrigin::toString(). 1039b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * Note that WebCore::SecurityOrigin uses 0 (which is not printed) for 1049b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * the port if the port is the default for the protocol. Eg 1059b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * http://www.google.com and http://www.google.com:80 both record a port 1069b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * of 0 and hence toString() == 'http://www.google.com' for both. 1079b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * @return The origin string. 1089b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck */ 10911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public String getOrigin() { 11011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard return mOrigin; 11111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 11211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 1139b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck /** 1149b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * Returns the quota for this origin's HTML5 database. 1159b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * @return The quota in bytes. 1169b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck */ 11711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public long getQuota() { 11811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard return mQuota; 11911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 1206c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1219b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck /** 1229b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * Returns the usage for this origin's HTML5 database. 1239b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * @return The usage in bytes. 1249b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck */ 1256c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public long getUsage() { 1266c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return mUsage; 1276c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1286c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1296c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1306c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /** 1316c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * @hide 1326c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Message handler, UI side 1336c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 1346c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void createUIHandler() { 1356c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (mUIHandler == null) { 1366c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mUIHandler = new Handler() { 1376c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard @Override 1386c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void handleMessage(Message msg) { 1396c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard switch (msg.what) { 1406c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case RETURN_ORIGINS: { 1416c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1426c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map origins = (Map) values.get(ORIGINS); 1436c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback<Map> callback = (ValueCallback<Map>) values.get(CALLBACK); 1446c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(origins); 1456c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1466c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1476c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case RETURN_USAGE_ORIGIN: { 1486c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1496c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK); 1506c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue((Long)values.get(USAGE)); 1516c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1526c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1536c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case RETURN_QUOTA_ORIGIN: { 1546c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 1556c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback<Long> callback = (ValueCallback<Long>) values.get(CALLBACK); 1566c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue((Long)values.get(QUOTA)); 1576c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1586c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1596c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 1606c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard }; 1616c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 16211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 16311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 16411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 16511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * @hide 1666c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Message handler, webcore side 16711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 168e4b2d4dc7db426052d1dfebc40f6b64a001b6d73Steve Block public synchronized void createHandler() { 16911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (mHandler == null) { 17011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mHandler = new Handler() { 17111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard @Override 17211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void handleMessage(Message msg) { 17311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard switch (msg.what) { 17411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case SET_QUOTA_ORIGIN: { 17511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard Origin website = (Origin) msg.obj; 17611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard nativeSetQuotaForOrigin(website.getOrigin(), 17711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard website.getQuota()); 17811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } break; 17911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 18011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case DELETE_ORIGIN: { 18111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard Origin website = (Origin) msg.obj; 18211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard nativeDeleteOrigin(website.getOrigin()); 18311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } break; 18411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 18511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case DELETE_ALL: 186af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu nativeDeleteAllData(); 18711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard break; 18811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 1896c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case GET_ORIGINS: { 1906c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 1916c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback callback = (ValueCallback) msg.obj; 1926c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map origins = new HashMap(mOrigins); 1936c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = new HashMap<String, Object>(); 1946c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(CALLBACK, callback); 1956c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(ORIGINS, origins); 1966c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postUIMessage(Message.obtain(null, RETURN_ORIGINS, values)); 1976c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 1986c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 1996c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case GET_USAGE_ORIGIN: { 2006c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 2016c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 2026c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard String origin = (String) values.get(ORIGIN); 2036c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback callback = (ValueCallback) values.get(CALLBACK); 2046c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 2056c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map retValues = new HashMap<String, Object>(); 2066c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(CALLBACK, callback); 2076c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (website != null) { 2086c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard long usage = website.getUsage(); 2096c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(USAGE, new Long(usage)); 2106c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 2116c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postUIMessage(Message.obtain(null, RETURN_USAGE_ORIGIN, retValues)); 2126c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 2136c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 2146c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard case GET_QUOTA_ORIGIN: { 2156c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 2166c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map values = (Map) msg.obj; 2176c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard String origin = (String) values.get(ORIGIN); 2186c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard ValueCallback callback = (ValueCallback) values.get(CALLBACK); 2196c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 2206c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Map retValues = new HashMap<String, Object>(); 2216c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(CALLBACK, callback); 2226c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (website != null) { 2236c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard long quota = website.getQuota(); 2246c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard retValues.put(QUOTA, new Long(quota)); 2256c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 2266c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postUIMessage(Message.obtain(null, RETURN_QUOTA_ORIGIN, retValues)); 2276c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } break; 2286c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 22911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard case UPDATE: 23011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard syncValues(); 23111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard break; 23211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 23311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 23411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard }; 23511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 23611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 23711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 2386c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /* 2396c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * When calling getOrigins(), getUsageForOrigin() and getQuotaForOrigin(), 2406c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * we need to get the values from webcore, but we cannot block while doing so 2416c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * as we used to do, as this could result in a full deadlock (other webcore 2426c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * messages received while we are still blocked here, see http://b/2127737). 2436c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * 2446c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * We have to do everything asynchronously, by providing a callback function. 2456c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * We post a message on the webcore thread (mHandler) that will get the result 2466c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * from webcore, and we post it back on the UI thread (using mUIHandler). 2476c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * We can then use the callback function to return the value. 2486c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 2496c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 25011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 2519b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * Returns a list of origins having a database. The Map is of type 2529b2a59bdd27cfa45c7bb3b58eb705b35589b7050John Reck * Map<String, Origin>. 25311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 2546c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void getOrigins(ValueCallback<Map> callback) { 2556c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (callback != null) { 2566c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 2576c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 2586c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(mOrigins); 2596c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } else { 2606c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postMessage(Message.obtain(null, GET_ORIGINS, callback)); 26159e2ad93bf37c7ded44c033d38fe7c972e2f4118Andrei Popescu } 26211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 2636c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 2646c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 2656c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /** 2666c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Returns a list of origins having a database 2676c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * should only be called from WebViewCore. 2686c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 2696c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Collection<Origin> getOriginsSync() { 2706c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 2716c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard update(); 2726c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return mOrigins.values(); 2736c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 2746c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return null; 27511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 27611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 27711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 27811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Returns the use for a given origin 27911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 2806c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void getUsageForOrigin(String origin, ValueCallback<Long> callback) { 2816c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (callback == null) { 2826c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 2836c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 28411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin == null) { 2856c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(null); 2866c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 28711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 2886c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 2896c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 2906c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 2916c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(new Long(website.getUsage())); 2926c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } else { 2936c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard HashMap values = new HashMap<String, Object>(); 2946c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(ORIGIN, origin); 2956c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(CALLBACK, callback); 2966c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postMessage(Message.obtain(null, GET_USAGE_ORIGIN, values)); 29711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 29811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 29911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 30011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 30111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Returns the quota for a given origin 30211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 3036c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard public void getQuotaForOrigin(String origin, ValueCallback<Long> callback) { 3046c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (callback == null) { 3056c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 3066c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 30711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin == null) { 3086c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(null); 3096c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard return; 31011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 3116c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 3126c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard syncValues(); 3136c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = mOrigins.get(origin); 3146c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard callback.onReceiveValue(new Long(website.getUsage())); 3156c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } else { 3166c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard HashMap values = new HashMap<String, Object>(); 3176c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(ORIGIN, origin); 3186c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard values.put(CALLBACK, callback); 3196c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard postMessage(Message.obtain(null, GET_QUOTA_ORIGIN, values)); 32011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 32111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 32211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 32311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 32411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Set the quota for a given origin 32511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 32611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void setQuotaForOrigin(String origin, long quota) { 32711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin != null) { 3285647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 3295647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch nativeSetQuotaForOrigin(origin, quota); 3305647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 3315647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, SET_QUOTA_ORIGIN, 3325647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch new Origin(origin, quota))); 3335647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 33411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 33511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 33611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 33711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 33811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Delete a given origin 33911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 34011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void deleteOrigin(String origin) { 34111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (origin != null) { 3425647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 3435647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch nativeDeleteOrigin(origin); 3445647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 3455647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, DELETE_ORIGIN, 3465647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch new Origin(origin))); 3475647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 34811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 34911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 35011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 35111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 35211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Delete all databases 35311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 354af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu public void deleteAllData() { 3555647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 356af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu nativeDeleteAllData(); 3575647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 3585647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, DELETE_ALL)); 3595647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 36011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 36111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 36211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 363427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block * Sets the maximum size of the ApplicationCache. 364427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block * This should only ever be called on the WebKit thread. 365427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block * @hide Pending API council approval 366427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block */ 367427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block public void setAppCacheMaximumSize(long size) { 368427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block nativeSetAppCacheMaximumSize(size); 369427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block } 370427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block 371427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block /** 37211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Utility function to send a message to our handler 37311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 374e4b2d4dc7db426052d1dfebc40f6b64a001b6d73Steve Block private synchronized void postMessage(Message msg) { 37511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (mHandler != null) { 37611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard mHandler.sendMessage(msg); 37711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 37811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 37911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 38011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 3816c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard * Utility function to send a message to the handler on the UI thread 3826c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard */ 3836c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard private void postUIMessage(Message msg) { 3846c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard if (mUIHandler != null) { 3856c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mUIHandler.sendMessage(msg); 3866c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 3876c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard } 3886c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard 3896c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard /** 39011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Get the global instance of WebStorage. 39111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * @return A single instance of WebStorage. 39211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 39311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public static WebStorage getInstance() { 39411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard if (sWebStorage == null) { 39511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard sWebStorage = new WebStorage(); 39611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 39711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard return sWebStorage; 39811e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 39911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 40011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 40111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * @hide 40211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Post a Sync request 40311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 40411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard public void update() { 4055647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch if (WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName())) { 4065647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch syncValues(); 4075647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } else { 4085647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch postMessage(Message.obtain(null, UPDATE)); 4095647bb3cc21428dd5242255323dff13c71a3343dBen Murdoch } 41011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 41111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 41211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard /** 41311e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard * Run on the webcore thread 4149a56bb838c099a318d4f961f290d324ed5f1949dAndrei Popescu * set the local values with the current ones 41511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard */ 41611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private void syncValues() { 4176c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Set<String> tmp = nativeGetOrigins(); 4186c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mOrigins = new HashMap<String, Origin>(); 4196c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard for (String origin : tmp) { 4206c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard Origin website = new Origin(origin, 42198409704134c262fdaab47055f60b7e01a4bc0b2Andrei Popescu nativeGetQuotaForOrigin(origin), 42298409704134c262fdaab47055f60b7e01a4bc0b2Andrei Popescu nativeGetUsageForOrigin(origin)); 4236c24b4d10223cb522e6bdbf0e334f61e672f4366Nicolas Roard mOrigins.put(origin, website); 42411e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 42511e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard } 42611e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard 42711e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard // Native functions 428af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu private static native Set nativeGetOrigins(); 42911e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native long nativeGetUsageForOrigin(String origin); 43011e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native long nativeGetQuotaForOrigin(String origin); 43111e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native void nativeSetQuotaForOrigin(String origin, long quota); 43211e8fe5a7208c9cd6afc2a0373761ae506d7707fNicolas Roard private static native void nativeDeleteOrigin(String origin); 433af9c77edbddfcf87a4dc17b95db84bf741674a9aAndrei Popescu private static native void nativeDeleteAllData(); 434427efcca1988e3f424e363808e8fd0978f4e78d1Steve Block private static native void nativeSetAppCacheMaximumSize(long size); 4357df1985e86635af006be3dfa65987d60e290b5deBen Murdoch} 436