/*
 * 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.Activity;
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;
import java.util.List;
import java.util.Map;

/**
 * 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.
    // Start with 100 to indicate it is not in load for the empty page.
    private volatile int mLatestProgress = 100;
    // Back/Forward list
    private final WebBackForwardList mBackForwardList;
    // Back/Forward list client
    private volatile WebBackForwardListClient mWebBackForwardListClient;
    // 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 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 REACHED_APPCACHE_MAXSIZE            = 127;
    private static final int JS_TIMEOUT                          = 128;
    private static final int ADD_MESSAGE_TO_CONSOLE              = 129;
    private static final int GEOLOCATION_PERMISSIONS_SHOW_PROMPT = 130;
    private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT = 131;
    private static final int RECEIVED_TOUCH_ICON_URL             = 132;
    private static final int GET_VISITED_HISTORY                 = 133;
    private static final int OPEN_FILE_CHOOSER                   = 134;
    private static final int ADD_HISTORY_ITEM                    = 135;
    private static final int HISTORY_INDEX_CHANGED               = 136;
    private static final int AUTH_CREDENTIALS                    = 137;
    private static final int SET_INSTALLABLE_WEBAPP              = 138;
    private static final int NOTIFY_SEARCHBOX_LISTENERS          = 139;
    private static final int AUTO_LOGIN                          = 140;

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

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

        public ResultTransport(E defaultResult) {
            mResult = defaultResult;
        }

        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(this);
    }

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

    /**
     * Get the WebViewClient.
     * @return the current WebViewClient instance.
     *
     *@hide pending API council approval.
     */
    public WebViewClient getWebViewClient() {
       return mWebViewClient;
    }

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

    /**
     * Get the WebChromeClient.
     * @return the current WebChromeClient instance.
     */
    public WebChromeClient getWebChromeClient() {
       return mWebChromeClient;
    }

    /**
     * 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;
    }

    void setWebBackForwardListClient(WebBackForwardListClient client) {
        mWebBackForwardListClient = client;
    }

    WebBackForwardListClient getWebBackForwardListClient() {
        return mWebBackForwardListClient;
    }

    /**
     * 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:
                String startedUrl = msg.getData().getString("url");
                mWebView.onPageStarted(startedUrl);
                if (mWebViewClient != null) {
                    mWebViewClient.onPageStarted(mWebView, startedUrl, (Bitmap) msg.obj);
                }
                break;

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

            case RECEIVED_TOUCH_ICON_URL:
                if (mWebChromeClient != null) {
                    mWebChromeClient.onReceivedTouchIconUrl(mWebView,
                            (String) msg.obj, msg.arg1 == 1);
                }
                break;

            case RECEIVED_TITLE:
                if (mWebChromeClient != null) {
                    mWebChromeClient.onReceivedTitle(mWebView,
                            (String) msg.obj);
                }
                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();
                        }
                    }
                    mWebView.dismissZoomControl();
                }
                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();
                    long totalUsedQuota =
                            ((Long) map.get("totalUsedQuota")).longValue();
                    long estimatedSize =
                            ((Long) map.get("estimatedSize")).longValue();
                    WebStorage.QuotaUpdater quotaUpdater =
                        (WebStorage.QuotaUpdater) map.get("quotaUpdater");

                    mWebChromeClient.onExceededDatabaseQuota(url,
                            databaseIdentifier, currentQuota, estimatedSize,
                            totalUsedQuota, quotaUpdater);
                }
                break;

            case REACHED_APPCACHE_MAXSIZE:
                if (mWebChromeClient != null) {
                    HashMap<String, Object> map =
                            (HashMap<String, Object>) msg.obj;
                    long spaceNeeded =
                            ((Long) map.get("spaceNeeded")).longValue();
                    long totalUsedQuota =
                        ((Long) map.get("totalUsedQuota")).longValue();
                    WebStorage.QuotaUpdater quotaUpdater =
                        (WebStorage.QuotaUpdater) map.get("quotaUpdater");

                    mWebChromeClient.onReachedMaxAppCacheSize(spaceNeeded,
                            totalUsedQuota, quotaUpdater);
                }
                break;

            case GEOLOCATION_PERMISSIONS_SHOW_PROMPT:
                if (mWebChromeClient != null) {
                    HashMap<String, Object> map =
                            (HashMap<String, Object>) msg.obj;
                    String origin = (String) map.get("origin");
                    GeolocationPermissions.Callback callback =
                            (GeolocationPermissions.Callback)
                            map.get("callback");
                    mWebChromeClient.onGeolocationPermissionsShowPrompt(origin,
                            callback);
                }
                break;

            case GEOLOCATION_PERMISSIONS_HIDE_PROMPT:
                if (mWebChromeClient != null) {
                    mWebChromeClient.onGeolocationPermissionsHidePrompt();
                }
                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)) {
                        if (!canShowAlertDialog()) {
                            res.cancel();
                            res.setReady();
                            break;
                        }
                        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();
                                            }
                                        })
                                .setOnCancelListener(
                                        new DialogInterface.OnCancelListener() {
                                            public void onCancel(
                                                    DialogInterface dialog) {
                                                res.cancel();
                                            }
                                        })
                                .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)) {
                        if (!canShowAlertDialog()) {
                            res.cancel();
                            res.setReady();
                            break;
                        }
                        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();
                                            }})
                                .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_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)) {
                        if (!canShowAlertDialog()) {
                            res.cancel();
                            res.setReady();
                            break;
                        }
                        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)) {
                        if (!canShowAlertDialog()) {
                            res.cancel();
                            res.setReady();
                            break;
                        }
                        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;

            case ADD_MESSAGE_TO_CONSOLE:
                if (mWebChromeClient == null) {
                    break;
                }
                String message = msg.getData().getString("message");
                String sourceID = msg.getData().getString("sourceID");
                int lineNumber = msg.getData().getInt("lineNumber");
                int msgLevel = msg.getData().getInt("msgLevel");
                int numberOfMessageLevels = ConsoleMessage.MessageLevel.values().length;
                // Sanity bounds check as we'll index an array with msgLevel
                if (msgLevel < 0 || msgLevel >= numberOfMessageLevels) {
                    msgLevel = 0;
                }

                ConsoleMessage.MessageLevel messageLevel =
                        ConsoleMessage.MessageLevel.values()[msgLevel];

                if (!mWebChromeClient.onConsoleMessage(new ConsoleMessage(message, sourceID,
                        lineNumber, messageLevel))) {
                    // If false was returned the user did not provide their own console function so
                    //  we should output some default messages to the system log.
                    String logTag = "Web Console";
                    String logMessage = message + " at " + sourceID + ":" + lineNumber;

                    switch (messageLevel) {
                        case TIP:
                            Log.v(logTag, logMessage);
                            break;
                        case LOG:
                            Log.i(logTag, logMessage);
                            break;
                        case WARNING:
                            Log.w(logTag, logMessage);
                            break;
                        case ERROR:
                            Log.e(logTag, logMessage);
                            break;
                        case DEBUG:
                            Log.d(logTag, logMessage);
                            break;
                    }
                }

                break;

            case GET_VISITED_HISTORY:
                if (mWebChromeClient != null) {
                    mWebChromeClient.getVisitedHistory((ValueCallback<String[]>)msg.obj);
                }
                break;

            case OPEN_FILE_CHOOSER:
                if (mWebChromeClient != null) {
                    UploadFileMessageData data = (UploadFileMessageData)msg.obj;
                    mWebChromeClient.openFileChooser(data.getUploadFile(), data.getAcceptType());
                }
                break;

            case ADD_HISTORY_ITEM:
                if (mWebBackForwardListClient != null) {
                    mWebBackForwardListClient.onNewHistoryItem(
                            (WebHistoryItem) msg.obj);
                }
                break;

            case HISTORY_INDEX_CHANGED:
                if (mWebBackForwardListClient != null) {
                    mWebBackForwardListClient.onIndexChanged(
                            (WebHistoryItem) msg.obj, msg.arg1);
                }
                break;
            case AUTH_CREDENTIALS: {
                String host = msg.getData().getString("host");
                String realm = msg.getData().getString("realm");
                username = msg.getData().getString("username");
                password = msg.getData().getString("password");
                mWebView.setHttpAuthUsernamePassword(
                        host, realm, username, password);
                break;
            }
            case SET_INSTALLABLE_WEBAPP:
                if (mWebChromeClient != null) {
                    mWebChromeClient.setInstallableWebApp();
                }
                break;
            case NOTIFY_SEARCHBOX_LISTENERS:
                SearchBoxImpl searchBox = (SearchBoxImpl) mWebView.getSearchBox();

                @SuppressWarnings("unchecked")
                List<String> suggestions = (List<String>) msg.obj;
                searchBox.handleSuggestions(msg.getData().getString("query"), suggestions);
                break;
            case AUTO_LOGIN: {
                if (mWebViewClient != null) {
                    String realm = msg.getData().getString("realm");
                    String account = msg.getData().getString("account");
                    String args = msg.getData().getString("args");
                    mWebViewClient.onReceivedLoginRequest(mWebView, realm,
                            account, args);
                }
                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 static final boolean PERF_PROBE = false;
    private long mWebCoreThreadTime;
    private long mWebCoreIdleTime;

    /*
     * If PERF_PROBE is true, this block needs to be added to MessageQueue.java.
     * startWait() and finishWait() should be called before and after wait().

    private WaitCallback mWaitCallback = null;
    public static interface WaitCallback {
        void startWait();
        void finishWait();
    }
    public final void setWaitCallback(WaitCallback callback) {
        mWaitCallback = callback;
    }
    */

    // un-comment this block if PERF_PROBE is true
    /*
    private IdleCallback mIdleCallback = new IdleCallback();

    private final class IdleCallback implements MessageQueue.WaitCallback {
        private long mStartTime = 0;

        public void finishWait() {
            mWebCoreIdleTime += SystemClock.uptimeMillis() - mStartTime;
        }

        public void startWait() {
            mStartTime = SystemClock.uptimeMillis();
        }
    }
    */

    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 (PERF_PROBE) {
            mWebCoreThreadTime = SystemClock.currentThreadTimeMillis();
            mWebCoreIdleTime = 0;
            Network.getInstance(mContext).startTiming();
            // un-comment this if PERF_PROBE is true
//            Looper.myQueue().setWaitCallback(mIdleCallback);
        }
        Message msg = obtainMessage(PAGE_STARTED);
        msg.obj = favicon;
        msg.getData().putString("url", url);
        sendMessage(msg);
    }

    public void onPageFinished(String url) {
        // Performance probe
        if (PERF_PROBE) {
            // un-comment this if PERF_PROBE is true
//            Looper.myQueue().setWaitCallback(null);
            Log.d("WebCore", "WebCore thread used " + 
                    (SystemClock.currentThreadTimeMillis() - mWebCoreThreadTime)
                    + " ms and idled " + mWebCoreIdleTime + " ms");
            Network.getInstance(mContext).stopTiming();
        }
        Message msg = obtainMessage(PAGE_FINISHED, url);
        sendMessage(msg);
    }

    // Because this method is public and because CallbackProxy is mistakenly
    // party of the public classes, we cannot remove this method.
    public void onTooManyRedirects(Message cancelMsg, Message continueMsg) {
        // deprecated.
    }

    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>(false);
        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));
    }

    WebResourceResponse shouldInterceptRequest(String url) {
        if (mWebViewClient == null) {
            return null;
        }
        // Note: This method does _not_ send a message.
        WebResourceResponse r =
                mWebViewClient.shouldInterceptRequest(mWebView, url);
        if (r == null) {
            sendMessage(obtainMessage(LOAD_RESOURCE, url));
        }
        return r;
    }

    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);
    }

    void onReceivedLoginRequest(String realm, String account, String args) {
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebViewClient == null) {
            return;
        }
        Message msg = obtainMessage(AUTO_LOGIN);
        Bundle bundle = msg.getData();
        bundle.putString("realm", realm);
        bundle.putString("account", account);
        bundle.putString("args", args);
        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;
    }

    public void onReceivedHttpAuthCredentials(String host, String realm,
            String username, String password) {
        Message msg = obtainMessage(AUTH_CREDENTIALS);
        msg.getData().putString("host", host);
        msg.getData().putString("realm", realm);
        msg.getData().putString("username", username);
        msg.getData().putString("password", password);
        sendMessage(msg);
    }

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

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

    public BrowserFrame 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) {
            WebViewCore core = w.getWebViewCore();
            // If WebView.destroy() has been called, core may be null.  Skip
            // initialization in that case and return null.
            if (core != null) {
                core.initializeSubwindow();
                return core.getBrowserFrame();
            }
        }
        return null;
    }

    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));
    }

    /* package */ void onReceivedTouchIconUrl(String url, boolean precomposed) {
        // We should have a current item but we do not want to crash so check
        // for null.
        WebHistoryItem i = mBackForwardList.getCurrentItem();
        if (i != null) {
            i.setTouchIconUrl(url, precomposed);
        }
        // Do an unsynchronized quick check to avoid posting if no callback has
        // been set.
        if (mWebChromeClient == null) {
            return;
        }
        sendMessage(obtainMessage(RECEIVED_TOUCH_ICON_URL,
                precomposed ? 1 : 0, 0, url));
    }

    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 estimatedSize The estimated size of the database.
     * @param totalUsedQuota is the sum of all origins' quota.
     * @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,
            long estimatedSize, long totalUsedQuota,
            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("estimatedSize", estimatedSize);
        map.put("totalUsedQuota", totalUsedQuota);
        map.put("quotaUpdater", quotaUpdater);
        exceededQuota.obj = map;
        sendMessage(exceededQuota);
    }

    /**
     * Called by WebViewCore to inform the Java side that the appcache has
     * exceeded its max size.
     * @param spaceNeeded is the amount of disk space that would be needed
     * in order for the last appcache operation to succeed.
     * @param totalUsedQuota is the sum of all origins' quota.
     * @param quotaUpdater An instance of a class encapsulating a callback
     * to WebViewCore to run when the decision to allow or deny a bigger
     * app cache size has been made.
     */
    public void onReachedMaxAppCacheSize(long spaceNeeded,
            long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
        if (mWebChromeClient == null) {
            quotaUpdater.updateQuota(0);
            return;
        }

        Message msg = obtainMessage(REACHED_APPCACHE_MAXSIZE);
        HashMap<String, Object> map = new HashMap();
        map.put("spaceNeeded", spaceNeeded);
        map.put("totalUsedQuota", totalUsedQuota);
        map.put("quotaUpdater", quotaUpdater);
        msg.obj = map;
        sendMessage(msg);
    }

    /**
     * Called by WebViewCore to instruct the browser to display a prompt to ask
     * the user to set the Geolocation permission state for the given origin.
     * @param origin The origin requesting Geolocation permsissions.
     * @param callback The callback to call once a permission state has been
     *     obtained.
     */
    public void onGeolocationPermissionsShowPrompt(String origin,
            GeolocationPermissions.Callback callback) {
        if (mWebChromeClient == null) {
            return;
        }

        Message showMessage =
                obtainMessage(GEOLOCATION_PERMISSIONS_SHOW_PROMPT);
        HashMap<String, Object> map = new HashMap();
        map.put("origin", origin);
        map.put("callback", callback);
        showMessage.obj = map;
        sendMessage(showMessage);
    }

    /**
     * Called by WebViewCore to instruct the browser to hide the Geolocation
     * permissions prompt.
     */
    public void onGeolocationPermissionsHidePrompt() {
        if (mWebChromeClient == null) {
            return;
        }

        Message hideMessage = obtainMessage(GEOLOCATION_PERMISSIONS_HIDE_PROMPT);
        sendMessage(hideMessage);
    }

    /**
     * Called by WebViewCore when we have a message to be added to the JavaScript
     * error console. Sends a message to the Java side with the details.
     * @param message The message to add to the console.
     * @param lineNumber The lineNumber of the source file on which the error
     *     occurred.
     * @param sourceID The filename of the source file in which the error
     *     occurred.
     * @param msgLevel The message level, corresponding to the MessageLevel enum in
     *     WebCore/page/Console.h
     */
    public void addMessageToConsole(String message, int lineNumber, String sourceID, int msgLevel) {
        if (mWebChromeClient == null) {
            return;
        }

        Message msg = obtainMessage(ADD_MESSAGE_TO_CONSOLE);
        msg.getData().putString("message", message);
        msg.getData().putString("sourceID", sourceID);
        msg.getData().putInt("lineNumber", lineNumber);
        msg.getData().putInt("msgLevel", msgLevel);
        sendMessage(msg);
    }

    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();
    }

    public void getVisitedHistory(ValueCallback<String[]> callback) {
        if (mWebChromeClient == null) {
            return;
        }
        Message msg = obtainMessage(GET_VISITED_HISTORY);
        msg.obj = callback;
        sendMessage(msg);
    }

    private static class UploadFileMessageData {
        private UploadFile mCallback;
        private String mAcceptType;

        public UploadFileMessageData(UploadFile uploadFile, String acceptType) {
            mCallback = uploadFile;
            mAcceptType = acceptType;
        }

        public UploadFile getUploadFile() {
            return mCallback;
        }

        public String getAcceptType() {
            return mAcceptType;
        }
    }

    private class UploadFile implements ValueCallback<Uri> {
        private Uri mValue;
        public void onReceiveValue(Uri value) {
            mValue = value;
            synchronized (CallbackProxy.this) {
                CallbackProxy.this.notify();
            }
        }
        public Uri getResult() {
            return mValue;
        }
    }

    /**
     * Called by WebViewCore to open a file chooser.
     */
    /* package */ Uri openFileChooser(String acceptType) {
        if (mWebChromeClient == null) {
            return null;
        }
        Message myMessage = obtainMessage(OPEN_FILE_CHOOSER);
        UploadFile uploadFile = new UploadFile();
        UploadFileMessageData data = new UploadFileMessageData(uploadFile, acceptType);
        myMessage.obj = data;
        synchronized (this) {
            sendMessage(myMessage);
            try {
                wait();
            } catch (InterruptedException e) {
                Log.e(LOGTAG,
                        "Caught exception while waiting for openFileChooser");
                Log.e(LOGTAG, Log.getStackTraceString(e));
            }
        }
        return uploadFile.getResult();
    }

    void onNewHistoryItem(WebHistoryItem item) {
        if (mWebBackForwardListClient == null) {
            return;
        }
        Message msg = obtainMessage(ADD_HISTORY_ITEM, item);
        sendMessage(msg);
    }

    void onIndexChanged(WebHistoryItem item, int index) {
        if (mWebBackForwardListClient == null) {
            return;
        }
        Message msg = obtainMessage(HISTORY_INDEX_CHANGED, index, 0, item);
        sendMessage(msg);
    }

    void setInstallableWebApp() {
        if (mWebChromeClient == null) {
            return;
        }
        sendMessage(obtainMessage(SET_INSTALLABLE_WEBAPP));
    }

    boolean canShowAlertDialog() {
        // We can only display the alert dialog if mContext is
        // an Activity context.
        // FIXME: Should we display dialogs if mContext does
        // not have the window focus (e.g. if the user is viewing
        // another Activity when the alert should be displayed?
        // See bug 3166409
        return mContext instanceof Activity;
    }

    void onSearchboxSuggestionsReceived(String query, List<String> suggestions) {
        Message msg = obtainMessage(NOTIFY_SEARCHBOX_LISTENERS);
        msg.obj = suggestions;
        msg.getData().putString("query", query);

        sendMessage(msg);
    }
}
