/*
 * Copyright (C) 2007 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;

import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslCertificate;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.Browser;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.android.internal.R;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

/**
 * This class is a proxy class for handling WebCore -> UI thread messaging. All
 * the callback functions are called from the WebCore thread and messages are
 * posted to the UI thread for the actual client callback.
 */
/*
 * This class is created in the UI thread so its handler and any private classes
 * that extend Handler will operate in the UI thread.
 */
class CallbackProxy extends Handler {
    // Logging tag
    private static final String LOGTAG = "CallbackProxy";
    // Instance of WebViewClient that is the client callback.
    private volatile WebViewClient mWebViewClient;
    // Instance of WebChromeClient for handling all chrome functions.
    private volatile WebChromeClient mWebChromeClient;
    // Instance of WebView for handling UI requests.
    private final WebView mWebView;
    // Client registered callback listener for download events
    private volatile DownloadListener mDownloadListener;
    // Keep track of multiple progress updates.
    private boolean mProgressUpdatePending;
    // Keep track of the last progress amount.
    private volatile int mLatestProgress;
    // Back/Forward list
    private final WebBackForwardList mBackForwardList;
    // Used to call startActivity during url override.
    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 EXCEEDED_DATABASE_QUOTA   = 126;
    private static final int JS_TIMEOUT                = 127;

    // Message triggered by the client to resume execution
    private static final int NOTIFY                    = 200;

    // Result transportation object for returning results across thread
    // boundaries.
    private class ResultTransport<E> {
        // Private result object
        private E mResult;

        public synchronized void setResult(E result) {
            mResult = result;
        }

        public synchronized E getResult() {
            return mResult;
        }
    }

    /**
     * Construct a new CallbackProxy.
     */
    public CallbackProxy(Context context, WebView w) {
        // Used to start a default activity.
        mContext = context;
        mWebView = w;
        mBackForwardList = new WebBackForwardList();
    }

    /**
     * Set the WebViewClient.
     * @param client An implementation of WebViewClient.
     */
    public void setWebViewClient(WebViewClient client) {
        mWebViewClient = client;
    }

    /**
     * Set the WebChromeClient.
     * @param client An implementation of WebChromeClient.
     */
    public void setWebChromeClient(WebChromeClient client) {
        mWebChromeClient = client;
    }

    /**
     * Set the client DownloadListener.
     * @param client An implementation of DownloadListener.
     */
    public void setDownloadListener(DownloadListener client) {
        mDownloadListener = client;
    }

    /**
     * Get the Back/Forward list to return to the user or to update the cached
     * history list.
     */
    public WebBackForwardList getBackForwardList() {
        return mBackForwardList;
    }

    /**
     * Called by the UI side.  Calling overrideUrlLoading from the WebCore
     * side will post a message to call this method.
     */
    public boolean uiOverrideUrlLoading(String overrideUrl) {
        if (overrideUrl == null || overrideUrl.length() == 0) {
            return false;
        }
        boolean override = false;
        if (mWebViewClient != null) {
            override = mWebViewClient.shouldOverrideUrlLoading(mWebView,
                    overrideUrl);
        } else {
            Intent intent = new Intent(Intent.ACTION_VIEW,
                    Uri.parse(overrideUrl));
            intent.addCategory(Intent.CATEGORY_BROWSABLE);
            // If another application is running a WebView and launches the
            // Browser through this Intent, we want to reuse the same window if
            // possible.
            intent.putExtra(Browser.EXTRA_APPLICATION_ID,
                    mContext.getPackageName());
            try {
                mContext.startActivity(intent);
                override = true;
            } catch (ActivityNotFoundException ex) {
                // If no application can handle the URL, assume that the
                // browser can handle it.
            }
        }
        return override;
    }

    /**
     * Called by UI side.
     */
    public boolean uiOverrideKeyEvent(KeyEvent event) {
        if (mWebViewClient != null) {
            return mWebViewClient.shouldOverrideKeyEvent(mWebView, event);
        }
        return false;
    }

    @Override
    public void handleMessage(Message msg) {
        // We don't have to do synchronization because this function operates
        // in the UI thread. The WebViewClient and WebChromeClient functions
        // that check for a non-null callback are ok because java ensures atomic
        // 32-bit reads and writes.
        switch (msg.what) {
            case PAGE_STARTED:
                if (mWebViewClient != null) {
                    mWebViewClient.onPageStarted(mWebView,
                            msg.getData().getString("url"),
                            (Bitmap) msg.obj);
                }
                break;

            case PAGE_FINISHED:
                if (mWebViewClient != null) {
                    mWebViewClient.onPageFinished(mWebView, (String) msg.obj);
                }
                break;
                
            case RECEIVED_ICON:
                if (mWebChromeClient != null) {
                    mWebChromeClient.onReceivedIcon(mWebView, (Bitmap) msg.obj);
                }
                break;

            case RECEIVED_TITLE:
                if (mWebChromeClient != null) {
                    mWebChromeClient.onReceivedTitle(mWebView,
                            (String) msg.obj);
                }
                break;

            case TOO_MANY_REDIRECTS:
                Message cancelMsg =
                        (Message) msg.getData().getParcelable("cancelMsg");
                Message continueMsg =
                        (Message) msg.getData().getParcelable("continueMsg");
                if (mWebViewClient != null) {
                    mWebViewClient.onTooManyRedirects(mWebView, cancelMsg,
                            continueMsg);
                } else {
                    cancelMsg.sendToTarget();
                }
                break;

            case REPORT_ERROR:
                if (mWebViewClient != null) {
                    int reasonCode = msg.arg1;
                    final String description  = msg.getData().getString("description");
                    final String failUrl  = msg.getData().getString("failingUrl");
                    mWebViewClient.onReceivedError(mWebView, reasonCode,
                            description, failUrl);
                }
                break;

            case RESEND_POST_DATA:
                Message resend =
                        (Message) msg.getData().getParcelable("resend");
                Message dontResend =
                        (Message) msg.getData().getParcelable("dontResend");
                if (mWebViewClient != null) {
                    mWebViewClient.onFormResubmission(mWebView, dontResend,
                            resend);
                } else {
                    dontResend.sendToTarget();
                }
                break;

            case OVERRIDE_URL:
                String overrideUrl = msg.getData().getString("url");
                boolean override = uiOverrideUrlLoading(overrideUrl);
                ResultTransport<Boolean> result =
                        (ResultTransport<Boolean>) msg.obj;
                synchronized (this) {
                    result.setResult(override);
                    notify();
                }
                break;

            case AUTH_REQUEST:
                if (mWebViewClient != null) {
                    HttpAuthHandler handler = (HttpAuthHandler) msg.obj;
                    String host = msg.getData().getString("host");
                    String realm = msg.getData().getString("realm");
                    mWebViewClient.onReceivedHttpAuthRequest(mWebView, handler,
                            host, realm);
                }
                break;

            case SSL_ERROR:
                if (mWebViewClient != null) {
                    HashMap<String, Object> map = 
                        (HashMap<String, Object>) msg.obj;
                    mWebViewClient.onReceivedSslError(mWebView,
                            (SslErrorHandler) map.get("handler"),
                            (SslError) map.get("error"));
                }
                break;

            case PROGRESS:
                // Synchronize to ensure mLatestProgress is not modified after
                // setProgress is called and before mProgressUpdatePending is
                // changed.
                synchronized (this) {
                    if (mWebChromeClient != null) {
                        mWebChromeClient.onProgressChanged(mWebView,
                                mLatestProgress);
                    }
                    mProgressUpdatePending = false;
                }
                break;

            case UPDATE_VISITED:
                if (mWebViewClient != null) {
                    mWebViewClient.doUpdateVisitedHistory(mWebView,
                            (String) msg.obj, msg.arg1 != 0);
                }
                break;

            case LOAD_RESOURCE:
                if (mWebViewClient != null) {
                    mWebViewClient.onLoadResource(mWebView, (String) msg.obj);
                }
                break;

            case DOWNLOAD_FILE:
                if (mDownloadListener != null) {
                    String url = msg.getData().getString("url");
                    String userAgent = msg.getData().getString("userAgent");
                    String contentDisposition =
                        msg.getData().getString("contentDisposition");
                    String mimetype = msg.getData().getString("mimetype");
                    Long contentLength = msg.getData().getLong("contentLength");

                    mDownloadListener.onDownloadStart(url, userAgent,
                            contentDisposition, mimetype, contentLength);
                }
                break;

            case CREATE_WINDOW:
                if (mWebChromeClient != null) {
                    if (!mWebChromeClient.onCreateWindow(mWebView,
                                msg.arg1 == 1, msg.arg2 == 1,
                                (Message) msg.obj)) {
                        synchronized (this) {
                            notify();
                        }
                    }
                }
                break;

            case REQUEST_FOCUS:
                if (mWebChromeClient != null) {
                    mWebChromeClient.onRequestFocus(mWebView);
                }
                break;

            case CLOSE_WINDOW:
                if (mWebChromeClient != null) {
                    mWebChromeClient.onCloseWindow((WebView) msg.obj);
                }
                break;

            case SAVE_PASSWORD:
                Bundle bundle = msg.getData();
                String schemePlusHost = bundle.getString("host");
                String username = bundle.getString("username");
                String password = bundle.getString("password");
                // If the client returned false it means that the notify message
                // will not be sent and we should notify WebCore ourselves.
                if (!mWebView.onSavePassword(schemePlusHost, username, password,
                            (Message) msg.obj)) {
                    synchronized (this) {
                        notify();
                    }
                }
                break;

            case ASYNC_KEYEVENTS:
                if (mWebViewClient != null) {
                    mWebViewClient.onUnhandledKeyEvent(mWebView,
                            (KeyEvent) msg.obj);
                }
                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;
                    String message = msg.getData().getString("message");
                    String url = msg.getData().getString("url");
                    if (!mWebChromeClient.onJsAlert(mWebView, url, message,
                            res)) {
                        new AlertDialog.Builder(mContext)
                                .setTitle(getJsDialogTitle(url))
                                .setMessage(message)
                                .setPositiveButton(R.string.ok,
                                        new AlertDialog.OnClickListener() {
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int which) {
                                                res.confirm();
                                            }
                                        })
                                .setCancelable(false)
                                .show();
                    }
                    res.setReady();
                }
                break;

            case JS_CONFIRM:
                if (mWebChromeClient != null) {
                    final JsResult res = (JsResult) msg.obj;
                    String message = msg.getData().getString("message");
                    String url = msg.getData().getString("url");
                    if (!mWebChromeClient.onJsConfirm(mWebView, url, message,
                            res)) {
                        new AlertDialog.Builder(mContext)
                                .setTitle(getJsDialogTitle(url))
                                .setMessage(message)
                                .setPositiveButton(R.string.ok, 
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int which) {
                                                res.confirm();
                                            }})
                                .setNegativeButton(R.string.cancel, 
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int which) {
                                                res.cancel();
                                            }})
                                .show();
                    }
                    // Tell the JsResult that it is ready for client
                    // interaction.
                    res.setReady();
                }
                break;

            case JS_PROMPT:
                if (mWebChromeClient != null) {
                    final JsPromptResult res = (JsPromptResult) msg.obj;
                    String message = msg.getData().getString("message");
                    String defaultVal = msg.getData().getString("default");
                    String url = msg.getData().getString("url");
                    if (!mWebChromeClient.onJsPrompt(mWebView, url, message,
                                defaultVal, res)) {
                        final LayoutInflater factory = LayoutInflater
                                .from(mContext);
                        final View view = factory.inflate(R.layout.js_prompt,
                                null);
                        final EditText v = (EditText) view
                                .findViewById(R.id.value);
                        v.setText(defaultVal);
                        ((TextView) view.findViewById(R.id.message))
                                .setText(message);
                        new AlertDialog.Builder(mContext)
                                .setTitle(getJsDialogTitle(url))
                                .setView(view)
                                .setPositiveButton(R.string.ok,
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int whichButton) {
                                                res.confirm(v.getText()
                                                        .toString());
                                            }
                                        })
                                .setNegativeButton(R.string.cancel,
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int whichButton) {
                                                res.cancel();
                                            }
                                        })
                                .setOnCancelListener(
                                        new DialogInterface.OnCancelListener() {
                                            public void onCancel(
                                                    DialogInterface dialog) {
                                                res.cancel();
                                            }
                                        })
                                .show();
                    }
                    // Tell the JsResult that it is ready for client
                    // interaction.
                    res.setReady();
                }
                break;

            case JS_UNLOAD:
                if (mWebChromeClient != null) {
                    final JsResult res = (JsResult) msg.obj;
                    String message = msg.getData().getString("message");
                    String url = msg.getData().getString("url");
                    if (!mWebChromeClient.onJsBeforeUnload(mWebView, url,
                            message, res)) {
                        final String m = mContext.getString(
                                R.string.js_dialog_before_unload, message);
                        new AlertDialog.Builder(mContext)
                                .setMessage(m)
                                .setPositiveButton(R.string.ok,
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int which) {
                                                res.confirm();
                                            }
                                        })
                                .setNegativeButton(R.string.cancel,
                                        new DialogInterface.OnClickListener() {
                                            public void onClick(
                                                    DialogInterface dialog,
                                                    int which) {
                                                res.cancel();
                                            }
                                        })
                                .show();
                    }
                    res.setReady();
                }
                break;

            case JS_TIMEOUT:
                if(mWebChromeClient != null) {
                    final JsResult res = (JsResult) msg.obj;
                    if(mWebChromeClient.onJsTimeout()) {
                        res.confirm();
                    } else {
                        res.cancel();
                    }
                    res.setReady();
                }
                break;

            case RECEIVED_CERTIFICATE:
                mWebView.setCertificate((SslCertificate) msg.obj);
                break;

            case NOTIFY:
                synchronized (this) {
                    notify();
                }
                break;

            case SCALE_CHANGED:
                if (mWebViewClient != null) {
                    mWebViewClient.onScaleChanged(mWebView, msg.getData()
                            .getFloat("old"), msg.getData().getFloat("new"));
                }
                break;

            case SWITCH_OUT_HISTORY:
                mWebView.switchOutDrawHistory();
                break;
        }
    }

    /**
     * Return the latest progress.
     */
    public int getProgress() {
        return mLatestProgress;
    }

    /**
     * Called by WebCore side to switch out of history Picture drawing mode
     */
    void switchOutDrawHistory() {
        sendMessage(obtainMessage(SWITCH_OUT_HISTORY));
    }

    private String getJsDialogTitle(String url) {
        String title = url;
        if (URLUtil.isDataUrl(url)) {
            // For data: urls, we just display 'JavaScript' similar to Safari.
            title = mContext.getString(R.string.js_dialog_title_default);
        } else {
            try {
                URL aUrl = new URL(url);
                // For example: "The page at 'http://www.mit.edu' says:"
                title = mContext.getString(R.string.js_dialog_title,
                        aUrl.getProtocol() + "://" + aUrl.getHost());
            } catch (MalformedURLException ex) {
                // do nothing. just use the url as the title
            }
        }
        return title;
    }

    //--------------------------------------------------------------------------
    // WebViewClient functions.
    // NOTE: shouldOverrideKeyEvent is never called from the WebCore thread so
    // it is not necessary to include it here.
    //--------------------------------------------------------------------------

    // Performance probe
    private long mWebCoreThreadTime;

    public void onPageStarted(String url, Bitmap favicon) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        // Performance probe
        if (false) {
            mWebCoreThreadTime = SystemClock.currentThreadTimeMillis();
            Network.getInstance(mContext).startTiming();
        }
        Message msg = obtainMessage(PAGE_STARTED);
        msg.obj = favicon;
        msg.getData().putString("url", url);
        sendMessage(msg);
    }

    public void onPageFinished(String url) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        // Performance probe
        if (false) {
            Log.d("WebCore", "WebCore thread used " + 
                    (SystemClock.currentThreadTimeMillis() - mWebCoreThreadTime)
                    + " ms");
            Network.getInstance(mContext).stopTiming();
        }
        Message msg = obtainMessage(PAGE_FINISHED, url);
        sendMessage(msg);
    }

    public void onTooManyRedirects(Message cancelMsg, Message continueMsg) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            cancelMsg.sendToTarget();
            return;
        }

        Message msg = obtainMessage(TOO_MANY_REDIRECTS);
        Bundle bundle = msg.getData();
        bundle.putParcelable("cancelMsg", cancelMsg);
        bundle.putParcelable("continueMsg", continueMsg);
        sendMessage(msg);
    }

    public void onReceivedError(int errorCode, String description,
            String failingUrl) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }

        Message msg = obtainMessage(REPORT_ERROR);
        msg.arg1 = errorCode;
        msg.getData().putString("description", description);
        msg.getData().putString("failingUrl", failingUrl);
        sendMessage(msg);
    }

    public void onFormResubmission(Message dontResend, 
            Message resend) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            dontResend.sendToTarget();
            return;
        }

        Message msg = obtainMessage(RESEND_POST_DATA);
        Bundle bundle = msg.getData();
        bundle.putParcelable("resend", resend);
        bundle.putParcelable("dontResend", dontResend);
        sendMessage(msg);
    }

    /**
     * Called by the WebCore side
     */
    public boolean shouldOverrideUrlLoading(String url) {
        // We have a default behavior if no client exists so always send the
        // message.
        ResultTransport<Boolean> res = new ResultTransport<Boolean>();
        Message msg = obtainMessage(OVERRIDE_URL);
        msg.getData().putString("url", url);
        msg.obj = res;
        synchronized (this) {
            sendMessage(msg);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG, "Caught exception while waiting for overrideUrl");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
        return res.getResult().booleanValue();
    }

    public void onReceivedHttpAuthRequest(HttpAuthHandler handler,
            String hostName, String realmName) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            handler.cancel();
            return;
        }
        Message msg = obtainMessage(AUTH_REQUEST, handler);
        msg.getData().putString("host", hostName);
        msg.getData().putString("realm", realmName);
        sendMessage(msg);
    }
    /**
     * @hide - hide this because it contains a parameter of type SslError.
     * SslError is located in a hidden package.
     */
    public void onReceivedSslError(SslErrorHandler handler, SslError error) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            handler.cancel();
            return;
        }
        Message msg = obtainMessage(SSL_ERROR);
        //, handler);
        HashMap<String, Object> map = new HashMap();
        map.put("handler", handler);
        map.put("error", error);
        msg.obj = map;
        sendMessage(msg);
    }
    /**
     * @hide - hide this because it contains a parameter of type SslCertificate,
     * which is located in a hidden package.
     */

    public void onReceivedCertificate(SslCertificate certificate) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        // here, certificate can be null (if the site is not secure)
        sendMessage(obtainMessage(RECEIVED_CERTIFICATE, certificate));
    }

    public void doUpdateVisitedHistory(String url, boolean isReload) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        sendMessage(obtainMessage(UPDATE_VISITED, isReload ? 1 : 0, 0, url));
    }

    public void onLoadResource(String url) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        sendMessage(obtainMessage(LOAD_RESOURCE, url));
    }

    public void onUnhandledKeyEvent(KeyEvent event) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        sendMessage(obtainMessage(ASYNC_KEYEVENTS, event));
    }

    public void onScaleChanged(float oldScale, float newScale) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        Message msg = obtainMessage(SCALE_CHANGED);
        Bundle bundle = msg.getData();
        bundle.putFloat("old", oldScale);
        bundle.putFloat("new", newScale);
        sendMessage(msg);
    }

    //--------------------------------------------------------------------------
    // DownloadListener functions.
    //--------------------------------------------------------------------------

    /**
     * Starts a download if a download listener has been registered, otherwise
     * return false.
     */
    public boolean onDownloadStart(String url, String userAgent,
            String contentDisposition, String mimetype, long contentLength) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mDownloadListener == null) {
            // Cancel the download if there is no browser client.
            return false;
        }

        Message msg = obtainMessage(DOWNLOAD_FILE);
        Bundle bundle = msg.getData();
        bundle.putString("url", url);
        bundle.putString("userAgent", userAgent);
        bundle.putString("mimetype", mimetype);
        bundle.putLong("contentLength", contentLength);
        bundle.putString("contentDisposition", contentDisposition);
        sendMessage(msg);
        return true;
    }


    //--------------------------------------------------------------------------
    // WebView specific functions that do not interact with a client. These
    // functions just need to operate within the UI thread.
    //--------------------------------------------------------------------------

    public boolean onSavePassword(String schemePlusHost, String username,
            String password, Message resumeMsg) {
        // resumeMsg should be null at this point because we want to create it
        // within the CallbackProxy.
        if (DebugFlags.CALLBACK_PROXY) {
            junit.framework.Assert.assertNull(resumeMsg);
        }
        resumeMsg = obtainMessage(NOTIFY);

        Message msg = obtainMessage(SAVE_PASSWORD, resumeMsg);
        Bundle bundle = msg.getData();
        bundle.putString("host", schemePlusHost);
        bundle.putString("username", username);
        bundle.putString("password", password);
        synchronized (this) {
            sendMessage(msg);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG,
                        "Caught exception while waiting for onSavePassword");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
        // Doesn't matter here
        return false;
    }

    //--------------------------------------------------------------------------
    // WebChromeClient methods
    //--------------------------------------------------------------------------

    public void onProgressChanged(int newProgress) {
        // Synchronize so that mLatestProgress is up-to-date.
        synchronized (this) {
            mLatestProgress = newProgress;
            if (mWebChromeClient == null) {
                return;
            }
            if (!mProgressUpdatePending) {
                sendEmptyMessage(PROGRESS);
                mProgressUpdatePending = true;
            }
        }
    }

    public WebView createWindow(boolean dialog, boolean userGesture) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return null;
        }

        WebView.WebViewTransport transport = mWebView.new WebViewTransport();
        final Message msg = obtainMessage(NOTIFY);
        msg.obj = transport;
        synchronized (this) {
            sendMessage(obtainMessage(CREATE_WINDOW, dialog ? 1 : 0,
                    userGesture ? 1 : 0, msg));
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG,
                        "Caught exception while waiting for createWindow");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }

        WebView w = transport.getWebView();
        if (w != null) {
            w.getWebViewCore().initializeSubwindow();
        }
        return w;
    }

    public void onRequestFocus() {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return;
        }

        sendEmptyMessage(REQUEST_FOCUS);
    }

    public void onCloseWindow(WebView window) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return;
        }
        sendMessage(obtainMessage(CLOSE_WINDOW, window));
    }

    public void onReceivedIcon(Bitmap icon) {
        // The current item might be null if the icon was already stored in the
        // database and this is a new WebView.
        WebHistoryItem i = mBackForwardList.getCurrentItem();
        if (i != null) {
            i.setFavicon(icon);
        }
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return;
        }
        sendMessage(obtainMessage(RECEIVED_ICON, icon));
    }

    public void onReceivedTitle(String title) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return;
        }
        sendMessage(obtainMessage(RECEIVED_TITLE, title));
    }

    public void onJsAlert(String url, String message) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return;
        }
        JsResult result = new JsResult(this, false);
        Message alert = obtainMessage(JS_ALERT, result);
        alert.getData().putString("message", message);
        alert.getData().putString("url", url);
        synchronized (this) {
            sendMessage(alert);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG, "Caught exception while waiting for jsAlert");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
    }

    public boolean onJsConfirm(String url, String message) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return false;
        }
        JsResult result = new JsResult(this, false);
        Message confirm = obtainMessage(JS_CONFIRM, result);
        confirm.getData().putString("message", message);
        confirm.getData().putString("url", url);
        synchronized (this) {
            sendMessage(confirm);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG, "Caught exception while waiting for jsConfirm");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
        return result.getResult();
    }

    public String onJsPrompt(String url, String message, String defaultValue) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return null;
        }
        JsPromptResult result = new JsPromptResult(this);
        Message prompt = obtainMessage(JS_PROMPT, result);
        prompt.getData().putString("message", message);
        prompt.getData().putString("default", defaultValue);
        prompt.getData().putString("url", url);
        synchronized (this) {
            sendMessage(prompt);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG, "Caught exception while waiting for jsPrompt");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
        return result.getStringResult();
    }

    public boolean onJsBeforeUnload(String url, String message) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return true;
        }
        JsResult result = new JsResult(this, true);
        Message confirm = obtainMessage(JS_UNLOAD, result);
        confirm.getData().putString("message", message);
        confirm.getData().putString("url", url);
        synchronized (this) {
            sendMessage(confirm);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG, "Caught exception while waiting for jsUnload");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
        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);
    }

    /**
     * @hide pending API council approval
     */
    public boolean onJsTimeout() {
        //always interrupt timedout JS by default
        if (mWebChromeClient == null) {
            return true;
        }
        JsResult result = new JsResult(this, true);
        Message timeout = obtainMessage(JS_TIMEOUT, result);
        synchronized (this) {
            sendMessage(timeout);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG, "Caught exception while waiting for jsUnload");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
        return result.getResult();
    }
}
