Merges p9 CLs 144856 and 145055 to GIT to enable the Database API in the browser.
diff --git a/api/current.xml b/api/current.xml
index 90e9fd6..5bcd280 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -151989,6 +151989,25 @@
 <parameter name="contentLength" type="long">
 </parameter>
 </method>
+<method name="onExceededDatabaseQuota"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="url" type="java.lang.String">
+</parameter>
+<parameter name="databaseIdentifier" type="java.lang.String">
+</parameter>
+<parameter name="currentQuota" type="long">
+</parameter>
+<parameter name="quotaUpdater" type="android.webkit.WebStorage.QuotaUpdater">
+</parameter>
+</method>
 <method name="onFormResubmission"
  return="void"
  abstract="false"
@@ -153630,6 +153649,25 @@
 <parameter name="resultMsg" type="android.os.Message">
 </parameter>
 </method>
+<method name="onExceededDatabaseQuota"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="url" type="java.lang.String">
+</parameter>
+<parameter name="databaseIdentifier" type="java.lang.String">
+</parameter>
+<parameter name="currentQuota" type="long">
+</parameter>
+<parameter name="quotaUpdater" type="android.webkit.WebStorage.QuotaUpdater">
+</parameter>
+</method>
 <method name="onJsAlert"
  return="boolean"
  abstract="false"
@@ -154015,6 +154053,28 @@
  visibility="public"
 >
 </method>
+<method name="getDatabaseEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getDatabasePath"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getDefaultFixedFontSize"
  return="int"
  abstract="false"
@@ -154355,6 +154415,32 @@
 <parameter name="font" type="java.lang.String">
 </parameter>
 </method>
+<method name="setDatabaseEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="flag" type="boolean">
+</parameter>
+</method>
+<method name="setDatabasePath"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="databasePath" type="java.lang.String">
+</parameter>
+</method>
 <method name="setDefaultFixedFontSize"
  return="void"
  abstract="false"
@@ -154909,6 +154995,44 @@
 >
 </method>
 </class>
+<class name="WebStorage"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="WebStorage"
+ type="android.webkit.WebStorage"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+</class>
+<interface name="WebStorage.QuotaUpdater"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="updateQuota"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="newQuota" type="long">
+</parameter>
+</method>
+</interface>
 <class name="WebSyncManager"
  extends="java.lang.Object"
  abstract="true"
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 5f8acc8..be15ef8 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -72,35 +72,36 @@
     private final Context mContext;
 
     // Message Ids
-    private static final int PAGE_STARTED         = 100;
-    private static final int RECEIVED_ICON        = 101;
-    private static final int RECEIVED_TITLE       = 102;
-    private static final int OVERRIDE_URL         = 103;
-    private static final int AUTH_REQUEST         = 104;
-    private static final int SSL_ERROR            = 105;
-    private static final int PROGRESS             = 106;
-    private static final int UPDATE_VISITED       = 107;
-    private static final int LOAD_RESOURCE        = 108;
-    private static final int CREATE_WINDOW        = 109;
-    private static final int CLOSE_WINDOW         = 110;
-    private static final int SAVE_PASSWORD        = 111;
-    private static final int JS_ALERT             = 112;
-    private static final int JS_CONFIRM           = 113;
-    private static final int JS_PROMPT            = 114;
-    private static final int JS_UNLOAD            = 115;
-    private static final int ASYNC_KEYEVENTS      = 116;
-    private static final int TOO_MANY_REDIRECTS   = 117;
-    private static final int DOWNLOAD_FILE        = 118;
-    private static final int REPORT_ERROR         = 119;
-    private static final int RESEND_POST_DATA     = 120;
-    private static final int PAGE_FINISHED        = 121;
-    private static final int REQUEST_FOCUS        = 122;
-    private static final int SCALE_CHANGED        = 123;
-    private static final int RECEIVED_CERTIFICATE = 124;
-    private static final int SWITCH_OUT_HISTORY   = 125;
+    private static final int PAGE_STARTED              = 100;
+    private static final int RECEIVED_ICON             = 101;
+    private static final int RECEIVED_TITLE            = 102;
+    private static final int OVERRIDE_URL              = 103;
+    private static final int AUTH_REQUEST              = 104;
+    private static final int SSL_ERROR                 = 105;
+    private static final int PROGRESS                  = 106;
+    private static final int UPDATE_VISITED            = 107;
+    private static final int LOAD_RESOURCE             = 108;
+    private static final int CREATE_WINDOW             = 109;
+    private static final int CLOSE_WINDOW              = 110;
+    private static final int SAVE_PASSWORD             = 111;
+    private static final int JS_ALERT                  = 112;
+    private static final int JS_CONFIRM                = 113;
+    private static final int JS_PROMPT                 = 114;
+    private static final int JS_UNLOAD                 = 115;
+    private static final int ASYNC_KEYEVENTS           = 116;
+    private static final int TOO_MANY_REDIRECTS        = 117;
+    private static final int DOWNLOAD_FILE             = 118;
+    private static final int REPORT_ERROR              = 119;
+    private static final int RESEND_POST_DATA          = 120;
+    private static final int PAGE_FINISHED             = 121;
+    private static final int REQUEST_FOCUS             = 122;
+    private static final int SCALE_CHANGED             = 123;
+    private static final int RECEIVED_CERTIFICATE      = 124;
+    private static final int SWITCH_OUT_HISTORY        = 125;
+    private static final int EXCEEDED_DATABASE_QUOTA   = 126;
 
     // Message triggered by the client to resume execution
-    private static final int NOTIFY               = 200;
+    private static final int NOTIFY                    = 200;
 
     // Result transportation object for returning results across thread
     // boundaries.
@@ -388,6 +389,23 @@
                 }
                 break;
 
+            case EXCEEDED_DATABASE_QUOTA:
+                if (mWebChromeClient != null) {
+                    HashMap<String, Object> map =
+                            (HashMap<String, Object>) 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 @@
         }
         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<String, Object> 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 f9400061..0b874fa 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -157,4 +157,21 @@
             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 98e66b6..5a2cd26 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -159,6 +159,8 @@
     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;
 
@@ -901,6 +903,19 @@
     }
 
     /**
+     * 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.
      * @hide pending api council approval
@@ -928,6 +943,35 @@
     }
 
     /**
+     * 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. <b>Note: The default is false.</b>
      * @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 0000000..a0faf76
--- /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 1415597..b364952 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -233,6 +233,27 @@
     }
 
     /**
+     * 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.
      * @return True if the user confirmed or false if the user cancelled.
@@ -396,6 +417,14 @@
     // 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