From 7df1985e86635af006be3dfa65987d60e290b5de Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Wed, 22 Apr 2009 13:07:58 +0100 Subject: [PATCH] Merges p9 CLs 144856 and 145055 to GIT to enable the Database API in the browser. --- api/current.xml | 124 ++++++++++++++++++ core/java/android/webkit/CallbackProxy.java | 105 +++++++++++---- core/java/android/webkit/WebChromeClient.java | 17 +++ core/java/android/webkit/WebSettings.java | 44 +++++++ core/java/android/webkit/WebStorage.java | 35 +++++ core/java/android/webkit/WebViewCore.java | 29 ++++ 6 files changed, 327 insertions(+), 27 deletions(-) create mode 100644 core/java/android/webkit/WebStorage.java diff --git a/api/current.xml b/api/current.xml index 90e9fd6c03730..5bcd280f105b9 100644 --- a/api/current.xml +++ b/api/current.xml @@ -151989,6 +151989,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + map = + (HashMap) msg.obj; + String databaseIdentifier = + (String) map.get("databaseIdentifier"); + String url = (String) map.get("url"); + long currentQuota = + ((Long) map.get("currentQuota")).longValue(); + WebStorage.QuotaUpdater quotaUpdater = + (WebStorage.QuotaUpdater) map.get("quotaUpdater"); + + mWebChromeClient.onExceededDatabaseQuota(url, + databaseIdentifier, currentQuota, quotaUpdater); + } + break; + case JS_ALERT: if (mWebChromeClient != null) { final JsResult res = (JsResult) msg.obj; @@ -1022,4 +1040,37 @@ class CallbackProxy extends Handler { } return result.getResult(); } + + /** + * Called by WebViewCore to inform the Java side that the current origin + * has overflowed it's database quota. Called in the WebCore thread so + * posts a message to the UI thread that will prompt the WebChromeClient + * for what to do. On return back to C++ side, the WebCore thread will + * sleep pending a new quota value. + * @param url The URL that caused the quota overflow. + * @param databaseIdentifier The identifier of the database that the + * transaction that caused the overflow was running on. + * @param currentQuota The current quota the origin is allowed. + * @param quotaUpdater An instance of a class encapsulating a callback + * to WebViewCore to run when the decision to allow or deny more + * quota has been made. + */ + public void onExceededDatabaseQuota( + String url, String databaseIdentifier, long currentQuota, + WebStorage.QuotaUpdater quotaUpdater) { + if (mWebChromeClient == null) { + quotaUpdater.updateQuota(currentQuota); + return; + } + + Message exceededQuota = obtainMessage(EXCEEDED_DATABASE_QUOTA); + HashMap map = new HashMap(); + map.put("databaseIdentifier", databaseIdentifier); + map.put("url", url); + map.put("currentQuota", currentQuota); + map.put("quotaUpdater", quotaUpdater); + exceededQuota.obj = map; + sendMessage(exceededQuota); + } + } diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java index f9400061190b8..0b874fad5352e 100644 --- a/core/java/android/webkit/WebChromeClient.java +++ b/core/java/android/webkit/WebChromeClient.java @@ -157,4 +157,21 @@ public class WebChromeClient { JsResult result) { return false; } + + /** + * Tell the client that the database quota for the origin has been exceeded. + * @param url The URL that triggered the notification + * @param databaseIdentifier The identifier of the database that caused the + * quota overflow. + * @param currentQuota The current quota for the origin. + * @param quotaUpdater A callback to inform the WebCore thread that a new + * quota is available. This callback must always be executed at some + * point to ensure that the sleeping WebCore thread is woken up. + */ + public void onExceededDatabaseQuota(String url, String databaseIdentifier, + long currentQuota, WebStorage.QuotaUpdater quotaUpdater) { + // This default implementation passes the current quota back to WebCore. + // WebCore will interpret this that new quota was declined. + quotaUpdater.updateQuota(currentQuota); + } } diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 98e66b6f39d2d..5a2cd26d603ce 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -159,6 +159,8 @@ public class WebSettings { private boolean mSupportZoom = true; private boolean mBuiltInZoomControls = false; private boolean mAllowFileAccess = true; + private String mDatabasePath = ""; + private boolean mDatabaseEnabled = false; private String mAppCachePath = ""; private boolean mAppCacheEnabled = false; @@ -900,6 +902,19 @@ public class WebSettings { } } + /** + * Set the path to where database storage API databases should be saved. + * This will update WebCore when the Sync runs in the C++ side. + * @param databasePath String path to the directory where databases should + * be saved. May be the empty string but should never be null. + */ + public synchronized void setDatabasePath(String databasePath) { + if (databasePath != null && !databasePath.equals(mDatabasePath)) { + mDatabasePath = databasePath; + postSync(); + } + } + /** * Tell the WebView to enable Application Caches API. * @param flag True if the WebView should enable Application Caches. @@ -927,6 +942,35 @@ public class WebSettings { } } + /** + * Set whether the database storage API is enabled. + * @param flag boolean True if the WebView should use the database storage + * API. + */ + public synchronized void setDatabaseEnabled(boolean flag) { + if (mDatabaseEnabled != flag) { + mDatabaseEnabled = flag; + postSync(); + } + } + + /** + * Return the path to where database storage API databases are saved for + * the current WebView. + * @return the String path to the database storage API databases. + */ + public synchronized String getDatabasePath() { + return mDatabasePath; + } + + /** + * Returns true if database storage API is enabled. + * @return True if the database storage API is enabled. + */ + public synchronized boolean getDatabaseEnabled() { + return mDatabaseEnabled; + } + /** * Return true if javascript is enabled. Note: The default is false. * @return True if javascript is enabled. diff --git a/core/java/android/webkit/WebStorage.java b/core/java/android/webkit/WebStorage.java new file mode 100644 index 0000000000000..a0faf76d503f8 --- /dev/null +++ b/core/java/android/webkit/WebStorage.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.webkit; + +/** + * Functionality for manipulating the webstorage databases. + */ +public final class WebStorage { + + /** + * Encapsulates a callback function to be executed when a new quota is made + * available. We primarily want this to allow us to call back the sleeping + * WebCore thread from outside the WebViewCore class (as the native call + * is private). It is imperative that this the setDatabaseQuota method is + * executed once a decision to either allow or deny new quota is made, + * otherwise the WebCore thread will remain asleep. + */ + public interface QuotaUpdater { + public void updateQuota(long newQuota); + }; +} diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 1415597be09b2..b364952dea900 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -232,6 +232,27 @@ final class WebViewCore { mCallbackProxy.onJsAlert(url, message); } + /** + * Notify the user that the origin has exceeded it's database quota. + * @param url The URL that caused the overflow. + * @param databaseIdentifier The identifier of the database. + * @param currentQuota The current quota for the origin. + */ + protected void exceededDatabaseQuota(String url, + String databaseIdentifier, + long currentQuota) { + // Inform the callback proxy of the quota overflow. Send an object + // that encapsulates a call to the nativeSetDatabaseQuota method to + // awaken the sleeping webcore thread when a decision from the + // client to allow or deny quota is available. + mCallbackProxy.onExceededDatabaseQuota(url, databaseIdentifier, + currentQuota, new WebStorage.QuotaUpdater() { + public void updateQuota(long quota) { + nativeSetDatabaseQuota(quota); + } + }); + } + /** * Invoke a javascript confirm dialog. * @param message The message displayed in the dialog. @@ -396,6 +417,14 @@ final class WebViewCore { // local asset files for resources private native void nativeRegisterURLSchemeAsLocal(String scheme); + /* + * Inform webcore that the user has decided whether to allow or deny new + * quota for the current origin and that the main thread should wake up + * now. + * @param quota The new quota. + */ + private native void nativeSetDatabaseQuota(long quota); + // EventHub for processing messages private final EventHub mEventHub; // WebCore thread handler