/*
 * Copyright (C) 2012 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.accessibilityservice.AccessibilityServiceInfo;
import android.animation.ObjectAnimator;
import android.annotation.Widget;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Picture;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.RegionIterator;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.net.Proxy;
import android.net.ProxyProperties;
import android.net.Uri;
import android.net.http.SslCertificate;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
import android.security.KeyChain;
import android.text.Editable;
import android.text.InputType;
import android.text.Selection;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.HardwareCanvas;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.SoundEffectConstants;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebView.HitTestResult;
import android.webkit.WebView.PictureListener;
import android.webkit.WebViewCore.DrawData;
import android.webkit.WebViewCore.EventHub;
import android.webkit.WebViewCore.TextFieldInitData;
import android.webkit.WebViewCore.TextSelectionData;
import android.webkit.WebViewCore.WebKitHitTest;
import android.widget.AbsoluteLayout;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.OverScroller;
import android.widget.PopupWindow;
import android.widget.Scroller;
import android.widget.TextView;
import android.widget.Toast;

import junit.framework.Assert;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

/**
 * Implements a backend provider for the {@link WebView} public API.
 * @hide
 */
// TODO: Check if any WebView published API methods are called from within here, and if so
// we should bounce the call out via the proxy to enable any sub-class to override it.
@Widget
@SuppressWarnings("deprecation")
public final class WebViewClassic implements WebViewProvider, WebViewProvider.ScrollDelegate,
        WebViewProvider.ViewDelegate {
    /**
     * InputConnection used for ContentEditable. This captures changes
     * to the text and sends them either as key strokes or text changes.
     */
    class WebViewInputConnection extends BaseInputConnection {
        // Used for mapping characters to keys typed.
        private KeyCharacterMap mKeyCharacterMap;
        private boolean mIsKeySentByMe;
        private int mInputType;
        private int mImeOptions;
        private String mHint;
        private int mMaxLength;
        private boolean mIsAutoFillable;
        private boolean mIsAutoCompleteEnabled;
        private String mName;
        private int mBatchLevel;

        public WebViewInputConnection() {
            super(mWebView, true);
        }

        public void setAutoFillable(int queryId) {
            mIsAutoFillable = getSettings().getAutoFillEnabled()
                    && (queryId != WebTextView.FORM_NOT_AUTOFILLABLE);
            int variation = mInputType & EditorInfo.TYPE_MASK_VARIATION;
            if (variation != EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD
                    && (mIsAutoFillable || mIsAutoCompleteEnabled)) {
                if (mName != null && mName.length() > 0) {
                    requestFormData(mName, mFieldPointer, mIsAutoFillable,
                            mIsAutoCompleteEnabled);
                }
            }
        }

        @Override
        public boolean beginBatchEdit() {
            if (mBatchLevel == 0) {
                beginTextBatch();
            }
            mBatchLevel++;
            return false;
        }

        @Override
        public boolean endBatchEdit() {
            mBatchLevel--;
            if (mBatchLevel == 0) {
                commitTextBatch();
            }
            return false;
        }

        public boolean getIsAutoFillable() {
            return mIsAutoFillable;
        }

        @Override
        public boolean sendKeyEvent(KeyEvent event) {
            // Some IMEs send key events directly using sendKeyEvents.
            // WebViewInputConnection should treat these as text changes.
            if (!mIsKeySentByMe) {
                if (event.getAction() == KeyEvent.ACTION_UP) {
                    if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                        return deleteSurroundingText(1, 0);
                    } else if (event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL) {
                        return deleteSurroundingText(0, 1);
                    } else if (event.getUnicodeChar() != 0){
                        String newComposingText =
                                Character.toString((char)event.getUnicodeChar());
                        return commitText(newComposingText, 1);
                    }
                } else if (event.getAction() == KeyEvent.ACTION_DOWN &&
                        (event.getKeyCode() == KeyEvent.KEYCODE_DEL
                        || event.getKeyCode() == KeyEvent.KEYCODE_FORWARD_DEL
                        || event.getUnicodeChar() != 0)) {
                    return true; // only act on action_down
                }
            }
            return super.sendKeyEvent(event);
        }

        public void setTextAndKeepSelection(CharSequence text) {
            Editable editable = getEditable();
            int selectionStart = Selection.getSelectionStart(editable);
            int selectionEnd = Selection.getSelectionEnd(editable);
            text = limitReplaceTextByMaxLength(text, editable.length());
            editable.replace(0, editable.length(), text);
            restartInput();
            // Keep the previous selection.
            selectionStart = Math.min(selectionStart, editable.length());
            selectionEnd = Math.min(selectionEnd, editable.length());
            setSelection(selectionStart, selectionEnd);
            finishComposingText();
        }

        public void replaceSelection(CharSequence text) {
            Editable editable = getEditable();
            int selectionStart = Selection.getSelectionStart(editable);
            int selectionEnd = Selection.getSelectionEnd(editable);
            text = limitReplaceTextByMaxLength(text, selectionEnd - selectionStart);
            setNewText(selectionStart, selectionEnd, text);
            editable.replace(selectionStart, selectionEnd, text);
            restartInput();
            // Move caret to the end of the new text
            int newCaret = selectionStart + text.length();
            setSelection(newCaret, newCaret);
        }

        @Override
        public boolean setComposingText(CharSequence text, int newCursorPosition) {
            Editable editable = getEditable();
            int start = getComposingSpanStart(editable);
            int end = getComposingSpanEnd(editable);
            if (start < 0 || end < 0) {
                start = Selection.getSelectionStart(editable);
                end = Selection.getSelectionEnd(editable);
            }
            if (end < start) {
                int temp = end;
                end = start;
                start = temp;
            }
            CharSequence limitedText = limitReplaceTextByMaxLength(text, end - start);
            setNewText(start, end, limitedText);
            if (limitedText != text) {
                newCursorPosition -= text.length() - limitedText.length();
            }
            super.setComposingText(limitedText, newCursorPosition);
            updateSelection();
            if (limitedText != text) {
                int lastCaret = start + limitedText.length();
                finishComposingText();
                setSelection(lastCaret, lastCaret);
            }
            return true;
        }

        @Override
        public boolean commitText(CharSequence text, int newCursorPosition) {
            setComposingText(text, newCursorPosition);
            finishComposingText();
            return true;
        }

        @Override
        public boolean deleteSurroundingText(int leftLength, int rightLength) {
            // This code is from BaseInputConnection#deleteSurroundText.
            // We have to delete the same text in webkit.
            Editable content = getEditable();
            int a = Selection.getSelectionStart(content);
            int b = Selection.getSelectionEnd(content);

            if (a > b) {
                int tmp = a;
                a = b;
                b = tmp;
            }

            int ca = getComposingSpanStart(content);
            int cb = getComposingSpanEnd(content);
            if (cb < ca) {
                int tmp = ca;
                ca = cb;
                cb = tmp;
            }
            if (ca != -1 && cb != -1) {
                if (ca < a) a = ca;
                if (cb > b) b = cb;
            }

            int endDelete = Math.min(content.length(), b + rightLength);
            if (endDelete > b) {
                setNewText(b, endDelete, "");
            }
            int startDelete = Math.max(0, a - leftLength);
            if (startDelete < a) {
                setNewText(startDelete, a, "");
            }
            return super.deleteSurroundingText(leftLength, rightLength);
        }

        @Override
        public boolean performEditorAction(int editorAction) {

            boolean handled = true;
            switch (editorAction) {
            case EditorInfo.IME_ACTION_NEXT:
                mWebView.requestFocus(View.FOCUS_FORWARD);
                break;
            case EditorInfo.IME_ACTION_PREVIOUS:
                mWebView.requestFocus(View.FOCUS_BACKWARD);
                break;
            case EditorInfo.IME_ACTION_DONE:
                WebViewClassic.this.hideSoftKeyboard();
                break;
            case EditorInfo.IME_ACTION_GO:
            case EditorInfo.IME_ACTION_SEARCH:
                WebViewClassic.this.hideSoftKeyboard();
                String text = getEditable().toString();
                passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_DOWN,
                        KeyEvent.KEYCODE_ENTER));
                passToJavaScript(text, new KeyEvent(KeyEvent.ACTION_UP,
                        KeyEvent.KEYCODE_ENTER));
                break;

            default:
                handled = super.performEditorAction(editorAction);
                break;
            }

            return handled;
        }

        public void initEditorInfo(WebViewCore.TextFieldInitData initData) {
            int type = initData.mType;
            int inputType = InputType.TYPE_CLASS_TEXT
                    | InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
            int imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
                    | EditorInfo.IME_FLAG_NO_FULLSCREEN;
            if (!initData.mIsSpellCheckEnabled) {
                inputType |= InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
            }
            if (WebTextView.TEXT_AREA != type) {
                if (initData.mIsTextFieldNext) {
                    imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_NEXT;
                }
                if (initData.mIsTextFieldPrev) {
                    imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS;
                }
            }
            int action = EditorInfo.IME_ACTION_GO;
            switch (type) {
                case WebTextView.NORMAL_TEXT_FIELD:
                    break;
                case WebTextView.TEXT_AREA:
                    inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE
                            | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
                            | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT;
                    action = EditorInfo.IME_ACTION_NONE;
                    break;
                case WebTextView.PASSWORD:
                    inputType |= EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
                    break;
                case WebTextView.SEARCH:
                    action = EditorInfo.IME_ACTION_SEARCH;
                    break;
                case WebTextView.EMAIL:
                    // inputType needs to be overwritten because of the different text variation.
                    inputType = InputType.TYPE_CLASS_TEXT
                            | InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
                    break;
                case WebTextView.NUMBER:
                    // inputType needs to be overwritten because of the different class.
                    inputType = InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_NORMAL
                            | InputType.TYPE_NUMBER_FLAG_SIGNED | InputType.TYPE_NUMBER_FLAG_DECIMAL;
                    // Number and telephone do not have both a Tab key and an
                    // action, so set the action to NEXT
                    break;
                case WebTextView.TELEPHONE:
                    // inputType needs to be overwritten because of the different class.
                    inputType = InputType.TYPE_CLASS_PHONE;
                    break;
                case WebTextView.URL:
                    // TYPE_TEXT_VARIATION_URI prevents Tab key from showing, so
                    // exclude it for now.
                    inputType |= InputType.TYPE_TEXT_VARIATION_URI;
                    break;
                default:
                    break;
            }
            imeOptions |= action;
            mHint = initData.mLabel;
            mInputType = inputType;
            mImeOptions = imeOptions;
            mMaxLength = initData.mMaxLength;
            mIsAutoCompleteEnabled = initData.mIsAutoCompleteEnabled;
            mName = initData.mName;
            mAutoCompletePopup.clearAdapter();
        }

        public void setupEditorInfo(EditorInfo outAttrs) {
            outAttrs.inputType = mInputType;
            outAttrs.imeOptions = mImeOptions;
            outAttrs.hintText = mHint;
            outAttrs.initialCapsMode = getCursorCapsMode(InputType.TYPE_CLASS_TEXT);

            Editable editable = getEditable();
            int selectionStart = Selection.getSelectionStart(editable);
            int selectionEnd = Selection.getSelectionEnd(editable);
            if (selectionStart < 0 || selectionEnd < 0) {
                selectionStart = editable.length();
                selectionEnd = selectionStart;
            }
            outAttrs.initialSelStart = selectionStart;
            outAttrs.initialSelEnd = selectionEnd;
        }

        @Override
        public boolean setSelection(int start, int end) {
            boolean result = super.setSelection(start, end);
            updateSelection();
            return result;
        }

        @Override
        public boolean setComposingRegion(int start, int end) {
            boolean result = super.setComposingRegion(start, end);
            updateSelection();
            return result;
        }

        /**
         * Send the selection and composing spans to the IME.
         */
        private void updateSelection() {
            Editable editable = getEditable();
            int selectionStart = Selection.getSelectionStart(editable);
            int selectionEnd = Selection.getSelectionEnd(editable);
            int composingStart = getComposingSpanStart(editable);
            int composingEnd = getComposingSpanEnd(editable);
            InputMethodManager imm = InputMethodManager.peekInstance();
            if (imm != null) {
                imm.updateSelection(mWebView, selectionStart, selectionEnd,
                        composingStart, composingEnd);
            }
        }

        /**
         * Sends a text change to webkit indirectly. If it is a single-
         * character add or delete, it sends it as a key stroke. If it cannot
         * be represented as a key stroke, it sends it as a field change.
         * @param start The start offset (inclusive) of the text being changed.
         * @param end The end offset (exclusive) of the text being changed.
         * @param text The new text to replace the changed text.
         */
        private void setNewText(int start, int end, CharSequence text) {
            mIsKeySentByMe = true;
            Editable editable = getEditable();
            CharSequence original = editable.subSequence(start, end);
            boolean isCharacterAdd = false;
            boolean isCharacterDelete = false;
            int textLength = text.length();
            int originalLength = original.length();
            int selectionStart = Selection.getSelectionStart(editable);
            int selectionEnd = Selection.getSelectionEnd(editable);
            if (selectionStart == selectionEnd) {
                if (textLength > originalLength) {
                    isCharacterAdd = (textLength == originalLength + 1)
                            && TextUtils.regionMatches(text, 0, original, 0,
                                    originalLength);
                } else if (originalLength > textLength) {
                    isCharacterDelete = (textLength == originalLength - 1)
                            && TextUtils.regionMatches(text, 0, original, 0,
                                    textLength);
                }
            }
            if (isCharacterAdd) {
                sendCharacter(text.charAt(textLength - 1));
            } else if (isCharacterDelete) {
                sendKey(KeyEvent.KEYCODE_DEL);
            } else if ((textLength != originalLength) ||
                    !TextUtils.regionMatches(text, 0, original, 0,
                            textLength)) {
                // Send a message so that key strokes and text replacement
                // do not come out of order.
                Message replaceMessage = mPrivateHandler.obtainMessage(
                        REPLACE_TEXT, start,  end, text.toString());
                mPrivateHandler.sendMessage(replaceMessage);
            }
            if (mAutoCompletePopup != null) {
                StringBuilder newText = new StringBuilder();
                newText.append(editable.subSequence(0, start));
                newText.append(text);
                newText.append(editable.subSequence(end, editable.length()));
                mAutoCompletePopup.setText(newText.toString());
            }
            mIsKeySentByMe = false;
        }

        /**
         * Send a single character to the WebView as a key down and up event.
         * @param c The character to be sent.
         */
        private void sendCharacter(char c) {
            if (mKeyCharacterMap == null) {
                mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
            }
            char[] chars = new char[1];
            chars[0] = c;
            KeyEvent[] events = mKeyCharacterMap.getEvents(chars);
            if (events != null) {
                for (KeyEvent event : events) {
                    sendKeyEvent(event);
                }
            } else {
                Message msg = mPrivateHandler.obtainMessage(KEY_PRESS, (int) c, 0);
                mPrivateHandler.sendMessage(msg);
            }
        }

        /**
         * Send a key event for a specific key code, not a standard
         * unicode character.
         * @param keyCode The key code to send.
         */
        private void sendKey(int keyCode) {
            long eventTime = SystemClock.uptimeMillis();
            sendKeyEvent(new KeyEvent(eventTime, eventTime,
                    KeyEvent.ACTION_DOWN, keyCode, 0, 0,
                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                    KeyEvent.FLAG_SOFT_KEYBOARD));
            sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
                    KeyEvent.ACTION_UP, keyCode, 0, 0,
                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                    KeyEvent.FLAG_SOFT_KEYBOARD));
        }

        private CharSequence limitReplaceTextByMaxLength(CharSequence text,
                int numReplaced) {
            if (mMaxLength > 0) {
                Editable editable = getEditable();
                int maxReplace = mMaxLength - editable.length() + numReplaced;
                if (maxReplace < text.length()) {
                    maxReplace = Math.max(maxReplace, 0);
                    // New length is greater than the maximum. trim it down.
                    text = text.subSequence(0, maxReplace);
                }
            }
            return text;
        }

        private void restartInput() {
            InputMethodManager imm = InputMethodManager.peekInstance();
            if (imm != null) {
                // Since the text has changed, do not allow the IME to replace the
                // existing text as though it were a completion.
                imm.restartInput(mWebView);
            }
        }
    }

    private class PastePopupWindow extends PopupWindow implements View.OnClickListener {
        private ViewGroup mContentView;
        private TextView mPasteTextView;

        public PastePopupWindow() {
            super(mContext, null,
                    com.android.internal.R.attr.textSelectHandleWindowStyle);
            setClippingEnabled(true);
            LinearLayout linearLayout = new LinearLayout(mContext);
            linearLayout.setOrientation(LinearLayout.HORIZONTAL);
            mContentView = linearLayout;
            mContentView.setBackgroundResource(
                    com.android.internal.R.drawable.text_edit_paste_window);

            LayoutInflater inflater = (LayoutInflater)mContext.
                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            ViewGroup.LayoutParams wrapContent = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

            mPasteTextView = (TextView) inflater.inflate(
                    com.android.internal.R.layout.text_edit_action_popup_text, null);
            mPasteTextView.setLayoutParams(wrapContent);
            mContentView.addView(mPasteTextView);
            mPasteTextView.setText(com.android.internal.R.string.paste);
            mPasteTextView.setOnClickListener(this);
            this.setContentView(mContentView);
        }

        public void show(Point cursorBottom, Point cursorTop,
                int windowLeft, int windowTop) {
            measureContent();

            int width = mContentView.getMeasuredWidth();
            int height = mContentView.getMeasuredHeight();
            int y = cursorTop.y - height;
            int x = cursorTop.x - (width / 2);
            if (y < windowTop) {
                // There's not enough room vertically, move it below the
                // handle.
                ensureSelectionHandles();
                y = cursorBottom.y + mSelectHandleCenter.getIntrinsicHeight();
                x = cursorBottom.x - (width / 2);
            }
            if (x < windowLeft) {
                x = windowLeft;
            }
            if (!isShowing()) {
                showAtLocation(mWebView, Gravity.NO_GRAVITY, x, y);
            }
            update(x, y, width, height);
        }

        public void hide() {
            dismiss();
        }

        @Override
        public void onClick(View view) {
            pasteFromClipboard();
            selectionDone();
        }

        protected void measureContent() {
            final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
            mContentView.measure(
                    View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
                            View.MeasureSpec.AT_MOST),
                    View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
                            View.MeasureSpec.AT_MOST));
        }
    }

    // if AUTO_REDRAW_HACK is true, then the CALL key will toggle redrawing
    // the screen all-the-time. Good for profiling our drawing code
    static private final boolean AUTO_REDRAW_HACK = false;

    // The rate at which edit text is scrolled in content pixels per millisecond
    static private final float TEXT_SCROLL_RATE = 0.01f;

    // The presumed scroll rate for the first scroll of edit text
    static private final long TEXT_SCROLL_FIRST_SCROLL_MS = 16;

    // Buffer pixels of the caret rectangle when moving edit text into view
    // after resize.
    static private final int EDIT_RECT_BUFFER = 10;

    static private final long SELECTION_HANDLE_ANIMATION_MS = 150;

    // true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
    private boolean mAutoRedraw;

    // Reference to the AlertDialog displayed by InvokeListBox.
    // It's used to dismiss the dialog in destroy if not done before.
    private AlertDialog mListBoxDialog = null;

    // Reference to the save password dialog so it can be dimissed in
    // destroy if not done before.
    private AlertDialog mSavePasswordDialog = null;

    static final String LOGTAG = "webview";

    private ZoomManager mZoomManager;

    private final Rect mInvScreenRect = new Rect();
    private final Rect mScreenRect = new Rect();
    private final RectF mVisibleContentRect = new RectF();
    private boolean mIsWebViewVisible = true;
    WebViewInputConnection mInputConnection = null;
    private int mFieldPointer;
    private PastePopupWindow mPasteWindow;
    private AutoCompletePopup mAutoCompletePopup;
    Rect mEditTextContentBounds = new Rect();
    Rect mEditTextContent = new Rect();
    int mEditTextLayerId;
    boolean mIsEditingText = false;
    ArrayList<Message> mBatchedTextChanges = new ArrayList<Message>();
    boolean mIsBatchingTextChanges = false;
    private long mLastEditScroll = 0;

    private static class OnTrimMemoryListener implements ComponentCallbacks2 {
        private static OnTrimMemoryListener sInstance = null;

        static void init(Context c) {
            if (sInstance == null) {
                sInstance = new OnTrimMemoryListener(c.getApplicationContext());
            }
        }

        private OnTrimMemoryListener(Context c) {
            c.registerComponentCallbacks(this);
        }

        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            // Ignore
        }

        @Override
        public void onLowMemory() {
            // Ignore
        }

        @Override
        public void onTrimMemory(int level) {
            if (DebugFlags.WEB_VIEW) {
                Log.d("WebView", "onTrimMemory: " + level);
            }
            // When framework reset EGL context during high memory pressure, all
            // the existing GL resources for the html5 video will be destroyed
            // at native side.
            // Here we just need to clean up the Surface Texture which is static.
            if (level > TRIM_MEMORY_UI_HIDDEN) {
                HTML5VideoInline.cleanupSurfaceTexture();
                HTML5VideoView.release();
            }
            WebViewClassic.nativeOnTrimMemory(level);
        }
    }

    // A final CallbackProxy shared by WebViewCore and BrowserFrame.
    private CallbackProxy mCallbackProxy;

    private WebViewDatabaseClassic mDatabase;

    // SSL certificate for the main top-level page (if secure)
    private SslCertificate mCertificate;

    // Native WebView pointer that is 0 until the native object has been
    // created.
    private int mNativeClass;
    // This would be final but it needs to be set to null when the WebView is
    // destroyed.
    private WebViewCore mWebViewCore;
    // Handler for dispatching UI messages.
    /* package */ final Handler mPrivateHandler = new PrivateHandler();
    // Used to ignore changes to webkit text that arrives to the UI side after
    // more key events.
    private int mTextGeneration;

    /* package */ void incrementTextGeneration() { mTextGeneration++; }

    // Used by WebViewCore to create child views.
    /* package */ ViewManager mViewManager;

    // Used to display in full screen mode
    PluginFullScreenHolder mFullScreenHolder;

    /**
     * Position of the last touch event in pixels.
     * Use integer to prevent loss of dragging delta calculation accuracy;
     * which was done in float and converted to integer, and resulted in gradual
     * and compounding touch position and view dragging mismatch.
     */
    private int mLastTouchX;
    private int mLastTouchY;
    private int mStartTouchX;
    private int mStartTouchY;
    private float mAverageAngle;

    /**
     * Time of the last touch event.
     */
    private long mLastTouchTime;

    /**
     * Time of the last time sending touch event to WebViewCore
     */
    private long mLastSentTouchTime;

    /**
     * The minimum elapsed time before sending another ACTION_MOVE event to
     * WebViewCore. This really should be tuned for each type of the devices.
     * For example in Google Map api test case, it takes Dream device at least
     * 150ms to do a full cycle in the WebViewCore by processing a touch event,
     * triggering the layout and drawing the picture. While the same process
     * takes 60+ms on the current high speed device. If we make
     * TOUCH_SENT_INTERVAL too small, there will be multiple touch events sent
     * to WebViewCore queue and the real layout and draw events will be pushed
     * to further, which slows down the refresh rate. Choose 50 to favor the
     * current high speed devices. For Dream like devices, 100 is a better
     * choice. Maybe make this in the buildspec later.
     * (Update 12/14/2010: changed to 0 since current device should be able to
     * handle the raw events and Map team voted to have the raw events too.
     */
    private static final int TOUCH_SENT_INTERVAL = 0;
    private int mCurrentTouchInterval = TOUCH_SENT_INTERVAL;

    /**
     * Helper class to get velocity for fling
     */
    VelocityTracker mVelocityTracker;
    private int mMaximumFling;
    private float mLastVelocity;
    private float mLastVelX;
    private float mLastVelY;

    // The id of the native layer being scrolled.
    private int mCurrentScrollingLayerId;
    private Rect mScrollingLayerRect = new Rect();

    // only trigger accelerated fling if the new velocity is at least
    // MINIMUM_VELOCITY_RATIO_FOR_ACCELERATION times of the previous velocity
    private static final float MINIMUM_VELOCITY_RATIO_FOR_ACCELERATION = 0.2f;

    /**
     * Touch mode
     * TODO: Some of this is now unnecessary as it is handled by
     * WebInputTouchDispatcher (such as click, long press, and double tap).
     */
    private int mTouchMode = TOUCH_DONE_MODE;
    private static final int TOUCH_INIT_MODE = 1;
    private static final int TOUCH_DRAG_START_MODE = 2;
    private static final int TOUCH_DRAG_MODE = 3;
    private static final int TOUCH_SHORTPRESS_START_MODE = 4;
    private static final int TOUCH_SHORTPRESS_MODE = 5;
    private static final int TOUCH_DOUBLE_TAP_MODE = 6;
    private static final int TOUCH_DONE_MODE = 7;
    private static final int TOUCH_PINCH_DRAG = 8;
    private static final int TOUCH_DRAG_LAYER_MODE = 9;
    private static final int TOUCH_DRAG_TEXT_MODE = 10;

    // true when the touch movement exceeds the slop
    private boolean mConfirmMove;
    private boolean mTouchInEditText;

    // Whether or not to draw the cursor ring.
    private boolean mDrawCursorRing = true;

    // true if onPause has been called (and not onResume)
    private boolean mIsPaused;

    private HitTestResult mInitialHitTestResult;
    private WebKitHitTest mFocusedNode;

    /**
     * Customizable constant
     */
    // pre-computed square of ViewConfiguration.getScaledTouchSlop()
    private int mTouchSlopSquare;
    // pre-computed square of ViewConfiguration.getScaledDoubleTapSlop()
    private int mDoubleTapSlopSquare;
    // pre-computed density adjusted navigation slop
    private int mNavSlop;
    // This should be ViewConfiguration.getTapTimeout()
    // But system time out is 100ms, which is too short for the browser.
    // In the browser, if it switches out of tap too soon, jump tap won't work.
    // In addition, a double tap on a trackpad will always have a duration of
    // 300ms, so this value must be at least that (otherwise we will timeout the
    // first tap and convert it to a long press).
    private static final int TAP_TIMEOUT = 300;
    // This should be ViewConfiguration.getLongPressTimeout()
    // But system time out is 500ms, which is too short for the browser.
    // With a short timeout, it's difficult to treat trigger a short press.
    private static final int LONG_PRESS_TIMEOUT = 1000;
    // needed to avoid flinging after a pause of no movement
    private static final int MIN_FLING_TIME = 250;
    // draw unfiltered after drag is held without movement
    private static final int MOTIONLESS_TIME = 100;
    // The amount of content to overlap between two screens when going through
    // pages with the space bar, in pixels.
    private static final int PAGE_SCROLL_OVERLAP = 24;

    /**
     * These prevent calling requestLayout if either dimension is fixed. This
     * depends on the layout parameters and the measure specs.
     */
    boolean mWidthCanMeasure;
    boolean mHeightCanMeasure;

    // Remember the last dimensions we sent to the native side so we can avoid
    // sending the same dimensions more than once.
    int mLastWidthSent;
    int mLastHeightSent;
    // Since view height sent to webkit could be fixed to avoid relayout, this
    // value records the last sent actual view height.
    int mLastActualHeightSent;

    private int mContentWidth;   // cache of value from WebViewCore
    private int mContentHeight;  // cache of value from WebViewCore

    // Need to have the separate control for horizontal and vertical scrollbar
    // style than the View's single scrollbar style
    private boolean mOverlayHorizontalScrollbar = true;
    private boolean mOverlayVerticalScrollbar = false;

    // our standard speed. this way small distances will be traversed in less
    // time than large distances, but we cap the duration, so that very large
    // distances won't take too long to get there.
    private static final int STD_SPEED = 480;  // pixels per second
    // time for the longest scroll animation
    private static final int MAX_DURATION = 750;   // milliseconds

    // Used by OverScrollGlow
    OverScroller mScroller;
    Scroller mEditTextScroller;

    private boolean mInOverScrollMode = false;
    private static Paint mOverScrollBackground;
    private static Paint mOverScrollBorder;

    private boolean mWrapContent;
    private static final int MOTIONLESS_FALSE           = 0;
    private static final int MOTIONLESS_PENDING         = 1;
    private static final int MOTIONLESS_TRUE            = 2;
    private static final int MOTIONLESS_IGNORE          = 3;
    private int mHeldMotionless;

    // Lazily-instantiated instance for injecting accessibility.
    private AccessibilityInjector mAccessibilityInjector;

    /**
     * How long the caret handle will last without being touched.
     */
    private static final long CARET_HANDLE_STAMINA_MS = 3000;

    private Drawable mSelectHandleLeft;
    private Drawable mSelectHandleRight;
    private Drawable mSelectHandleCenter;
    private Point mSelectOffset;
    private Point mSelectCursorBase = new Point();
    private Rect mSelectHandleBaseBounds = new Rect();
    private int mSelectCursorBaseLayerId;
    private QuadF mSelectCursorBaseTextQuad = new QuadF();
    private Point mSelectCursorExtent = new Point();
    private Rect mSelectHandleExtentBounds = new Rect();
    private int mSelectCursorExtentLayerId;
    private QuadF mSelectCursorExtentTextQuad = new QuadF();
    private Point mSelectDraggingCursor;
    private QuadF mSelectDraggingTextQuad;
    private boolean mIsCaretSelection;
    static final int HANDLE_ID_BASE = 0;
    static final int HANDLE_ID_EXTENT = 1;

    // the color used to highlight the touch rectangles
    static final int HIGHLIGHT_COLOR = 0x6633b5e5;
    // the region indicating where the user touched on the screen
    private Region mTouchHighlightRegion = new Region();
    // the paint for the touch highlight
    private Paint mTouchHightlightPaint = new Paint();
    // debug only
    private static final boolean DEBUG_TOUCH_HIGHLIGHT = true;
    private static final int TOUCH_HIGHLIGHT_ELAPSE_TIME = 2000;
    private Paint mTouchCrossHairColor;
    private int mTouchHighlightX;
    private int mTouchHighlightY;
    private boolean mShowTapHighlight;

    // Basically this proxy is used to tell the Video to update layer tree at
    // SetBaseLayer time and to pause when WebView paused.
    private HTML5VideoViewProxy mHTML5VideoViewProxy;

    // If we are using a set picture, don't send view updates to webkit
    private boolean mBlockWebkitViewMessages = false;

    // cached value used to determine if we need to switch drawing models
    private boolean mHardwareAccelSkia = false;

    /*
     * Private message ids
     */
    private static final int REMEMBER_PASSWORD          = 1;
    private static final int NEVER_REMEMBER_PASSWORD    = 2;
    private static final int SWITCH_TO_SHORTPRESS       = 3;
    private static final int SWITCH_TO_LONGPRESS        = 4;
    private static final int RELEASE_SINGLE_TAP         = 5;
    private static final int REQUEST_FORM_DATA          = 6;
    private static final int DRAG_HELD_MOTIONLESS       = 8;
    private static final int PREVENT_DEFAULT_TIMEOUT    = 10;
    private static final int SCROLL_SELECT_TEXT         = 11;


    private static final int FIRST_PRIVATE_MSG_ID = REMEMBER_PASSWORD;
    private static final int LAST_PRIVATE_MSG_ID = SCROLL_SELECT_TEXT;

    /*
     * Package message ids
     */
    static final int SCROLL_TO_MSG_ID                   = 101;
    static final int NEW_PICTURE_MSG_ID                 = 105;
    static final int WEBCORE_INITIALIZED_MSG_ID         = 107;
    static final int UPDATE_TEXTFIELD_TEXT_MSG_ID       = 108;
    static final int UPDATE_ZOOM_RANGE                  = 109;
    static final int TAKE_FOCUS                         = 110;
    static final int CLEAR_TEXT_ENTRY                   = 111;
    static final int UPDATE_TEXT_SELECTION_MSG_ID       = 112;
    static final int SHOW_RECT_MSG_ID                   = 113;
    static final int LONG_PRESS_CENTER                  = 114;
    static final int PREVENT_TOUCH_ID                   = 115;
    static final int WEBCORE_NEED_TOUCH_EVENTS          = 116;
    // obj=Rect in doc coordinates
    static final int INVAL_RECT_MSG_ID                  = 117;
    static final int REQUEST_KEYBOARD                   = 118;
    static final int SHOW_FULLSCREEN                    = 120;
    static final int HIDE_FULLSCREEN                    = 121;
    static final int UPDATE_MATCH_COUNT                 = 126;
    static final int CENTER_FIT_RECT                    = 127;
    static final int SET_SCROLLBAR_MODES                = 129;
    static final int HIT_TEST_RESULT                    = 130;
    static final int SAVE_WEBARCHIVE_FINISHED           = 131;
    static final int SET_AUTOFILLABLE                   = 132;
    static final int AUTOFILL_COMPLETE                  = 133;
    static final int SCREEN_ON                          = 134;
    static final int UPDATE_ZOOM_DENSITY                = 135;
    static final int EXIT_FULLSCREEN_VIDEO              = 136;
    static final int COPY_TO_CLIPBOARD                  = 137;
    static final int INIT_EDIT_FIELD                    = 138;
    static final int REPLACE_TEXT                       = 139;
    static final int CLEAR_CARET_HANDLE                 = 140;
    static final int KEY_PRESS                          = 141;
    static final int RELOCATE_AUTO_COMPLETE_POPUP       = 142;
    static final int FOCUS_NODE_CHANGED                 = 143;
    static final int AUTOFILL_FORM                      = 144;
    static final int SCROLL_EDIT_TEXT                   = 145;
    static final int EDIT_TEXT_SIZE_CHANGED             = 146;
    static final int SHOW_CARET_HANDLE                  = 147;
    static final int UPDATE_CONTENT_BOUNDS              = 148;
    static final int SCROLL_HANDLE_INTO_VIEW            = 149;

    private static final int FIRST_PACKAGE_MSG_ID = SCROLL_TO_MSG_ID;
    private static final int LAST_PACKAGE_MSG_ID = HIT_TEST_RESULT;

    static final String[] HandlerPrivateDebugString = {
        "REMEMBER_PASSWORD", //              = 1;
        "NEVER_REMEMBER_PASSWORD", //        = 2;
        "SWITCH_TO_SHORTPRESS", //           = 3;
        "SWITCH_TO_LONGPRESS", //            = 4;
        "RELEASE_SINGLE_TAP", //             = 5;
        "REQUEST_FORM_DATA", //              = 6;
        "RESUME_WEBCORE_PRIORITY", //        = 7;
        "DRAG_HELD_MOTIONLESS", //           = 8;
        "", //             = 9;
        "PREVENT_DEFAULT_TIMEOUT", //        = 10;
        "SCROLL_SELECT_TEXT" //              = 11;
    };

    static final String[] HandlerPackageDebugString = {
        "SCROLL_TO_MSG_ID", //               = 101;
        "102", //                            = 102;
        "103", //                            = 103;
        "104", //                            = 104;
        "NEW_PICTURE_MSG_ID", //             = 105;
        "UPDATE_TEXT_ENTRY_MSG_ID", //       = 106;
        "WEBCORE_INITIALIZED_MSG_ID", //     = 107;
        "UPDATE_TEXTFIELD_TEXT_MSG_ID", //   = 108;
        "UPDATE_ZOOM_RANGE", //              = 109;
        "UNHANDLED_NAV_KEY", //              = 110;
        "CLEAR_TEXT_ENTRY", //               = 111;
        "UPDATE_TEXT_SELECTION_MSG_ID", //   = 112;
        "SHOW_RECT_MSG_ID", //               = 113;
        "LONG_PRESS_CENTER", //              = 114;
        "PREVENT_TOUCH_ID", //               = 115;
        "WEBCORE_NEED_TOUCH_EVENTS", //      = 116;
        "INVAL_RECT_MSG_ID", //              = 117;
        "REQUEST_KEYBOARD", //               = 118;
        "DO_MOTION_UP", //                   = 119;
        "SHOW_FULLSCREEN", //                = 120;
        "HIDE_FULLSCREEN", //                = 121;
        "DOM_FOCUS_CHANGED", //              = 122;
        "REPLACE_BASE_CONTENT", //           = 123;
        "RETURN_LABEL", //                   = 125;
        "UPDATE_MATCH_COUNT", //             = 126;
        "CENTER_FIT_RECT", //                = 127;
        "REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID", // = 128;
        "SET_SCROLLBAR_MODES", //            = 129;
        "SELECTION_STRING_CHANGED", //       = 130;
        "SET_TOUCH_HIGHLIGHT_RECTS", //      = 131;
        "SAVE_WEBARCHIVE_FINISHED", //       = 132;
        "SET_AUTOFILLABLE", //               = 133;
        "AUTOFILL_COMPLETE", //              = 134;
        "SELECT_AT", //                      = 135;
        "SCREEN_ON", //                      = 136;
        "ENTER_FULLSCREEN_VIDEO", //         = 137;
        "UPDATE_SELECTION", //               = 138;
        "UPDATE_ZOOM_DENSITY" //             = 139;
    };

    // If the site doesn't use the viewport meta tag to specify the viewport,
    // use DEFAULT_VIEWPORT_WIDTH as the default viewport width
    static final int DEFAULT_VIEWPORT_WIDTH = 980;

    // normally we try to fit the content to the minimum preferred width
    // calculated by the Webkit. To avoid the bad behavior when some site's
    // minimum preferred width keeps growing when changing the viewport width or
    // the minimum preferred width is huge, an upper limit is needed.
    static int sMaxViewportWidth = DEFAULT_VIEWPORT_WIDTH;

    // initial scale in percent. 0 means using default.
    private int mInitialScaleInPercent = 0;

    // Whether or not a scroll event should be sent to webkit.  This is only set
    // to false when restoring the scroll position.
    private boolean mSendScrollEvent = true;

    private int mSnapScrollMode = SNAP_NONE;
    private static final int SNAP_NONE = 0;
    private static final int SNAP_LOCK = 1; // not a separate state
    private static final int SNAP_X = 2; // may be combined with SNAP_LOCK
    private static final int SNAP_Y = 4; // may be combined with SNAP_LOCK
    private boolean mSnapPositive;

    // keep these in sync with their counterparts in WebView.cpp
    private static final int DRAW_EXTRAS_NONE = 0;
    private static final int DRAW_EXTRAS_SELECTION = 1;
    private static final int DRAW_EXTRAS_CURSOR_RING = 2;

    // keep this in sync with WebCore:ScrollbarMode in WebKit
    private static final int SCROLLBAR_AUTO = 0;
    private static final int SCROLLBAR_ALWAYSOFF = 1;
    // as we auto fade scrollbar, this is ignored.
    private static final int SCROLLBAR_ALWAYSON = 2;
    private int mHorizontalScrollBarMode = SCROLLBAR_AUTO;
    private int mVerticalScrollBarMode = SCROLLBAR_AUTO;

    /**
     * Max distance to overscroll by in pixels.
     * This how far content can be pulled beyond its normal bounds by the user.
     */
    private int mOverscrollDistance;

    /**
     * Max distance to overfling by in pixels.
     * This is how far flinged content can move beyond the end of its normal bounds.
     */
    private int mOverflingDistance;

    private OverScrollGlow mOverScrollGlow;

    // Used to match key downs and key ups
    private Vector<Integer> mKeysPressed;

    /* package */ static boolean mLogEvent = true;

    // for event log
    private long mLastTouchUpTime = 0;

    private WebViewCore.AutoFillData mAutoFillData;

    private static boolean sNotificationsEnabled = true;

    /**
     * URI scheme for telephone number
     */
    public static final String SCHEME_TEL = "tel:";
    /**
     * URI scheme for email address
     */
    public static final String SCHEME_MAILTO = "mailto:";
    /**
     * URI scheme for map address
     */
    public static final String SCHEME_GEO = "geo:0,0?q=";

    private int mBackgroundColor = Color.WHITE;

    private static final long SELECT_SCROLL_INTERVAL = 1000 / 60; // 60 / second
    private int mAutoScrollX = 0;
    private int mAutoScrollY = 0;
    private int mMinAutoScrollX = 0;
    private int mMaxAutoScrollX = 0;
    private int mMinAutoScrollY = 0;
    private int mMaxAutoScrollY = 0;
    private Rect mScrollingLayerBounds = new Rect();
    private boolean mSentAutoScrollMessage = false;

    // used for serializing asynchronously handled touch events.
    private WebViewInputDispatcher mInputDispatcher;

    // Used to track whether picture updating was paused due to a window focus change.
    private boolean mPictureUpdatePausedForFocusChange = false;

    // Used to notify listeners of a new picture.
    private PictureListener mPictureListener;

    // Used to notify listeners about find-on-page results.
    private WebView.FindListener mFindListener;

    // Used to prevent resending save password message
    private Message mResumeMsg;

    /**
     * Refer to {@link WebView#requestFocusNodeHref(Message)} for more information
     */
    static class FocusNodeHref {
        static final String TITLE = "title";
        static final String URL = "url";
        static final String SRC = "src";
    }

    public WebViewClassic(WebView webView, WebView.PrivateAccess privateAccess) {
        mWebView = webView;
        mWebViewPrivate = privateAccess;
        mContext = webView.getContext();
    }

    /**
     * See {@link WebViewProvider#init(Map, boolean)}
     */
    @Override
    public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
        Context context = mContext;

        // Used by the chrome stack to find application paths
        JniUtil.setContext(context);

        mCallbackProxy = new CallbackProxy(context, this);
        mViewManager = new ViewManager(this);
        L10nUtils.setApplicationContext(context.getApplicationContext());
        mWebViewCore = new WebViewCore(context, this, mCallbackProxy, javaScriptInterfaces);
        mDatabase = WebViewDatabaseClassic.getInstance(context);
        mScroller = new OverScroller(context, null, 0, 0, false); //TODO Use OverScroller's flywheel
        mZoomManager = new ZoomManager(this, mCallbackProxy);

        /* The init method must follow the creation of certain member variables,
         * such as the mZoomManager.
         */
        init();
        setupPackageListener(context);
        setupProxyListener(context);
        setupTrustStorageListener(context);
        updateMultiTouchSupport(context);

        if (privateBrowsing) {
            startPrivateBrowsing();
        }

        mAutoFillData = new WebViewCore.AutoFillData();
        mEditTextScroller = new Scroller(context);

        // Calculate channel distance
        calculateChannelDistance(context);
    }

    /**
     * Calculate sChannelDistance based on the screen information.
     * @param context A Context object used to access application assets.
     */
    private void calculateChannelDistance(Context context) {
        // The channel distance is adjusted for density and screen size
        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        final double screenSize = Math.hypot((double)(metrics.widthPixels/metrics.densityDpi),
                (double)(metrics.heightPixels/metrics.densityDpi));
        if (screenSize < 3.0) {
            sChannelDistance = 16;
        } else if (screenSize < 5.0) {
            sChannelDistance = 22;
        } else if (screenSize < 7.0) {
            sChannelDistance = 28;
        } else {
            sChannelDistance = 34;
        }
        sChannelDistance = (int)(sChannelDistance * metrics.density);
        if (sChannelDistance < 16) sChannelDistance = 16;

        if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "sChannelDistance : " + sChannelDistance
                    + ", density : " + metrics.density
                    + ", screenSize : " + screenSize
                    + ", metrics.heightPixels : " + metrics.heightPixels
                    + ", metrics.widthPixels : " + metrics.widthPixels
                    + ", metrics.densityDpi : " + metrics.densityDpi);
        }
    }

    // WebViewProvider bindings

    static class Factory implements WebViewFactoryProvider,  WebViewFactoryProvider.Statics {
        @Override
        public String findAddress(String addr) {
            return WebViewClassic.findAddress(addr);
        }
        @Override
        public void setPlatformNotificationsEnabled(boolean enable) {
            if (enable) {
                WebViewClassic.enablePlatformNotifications();
            } else {
                WebViewClassic.disablePlatformNotifications();
            }
        }

        @Override
        public Statics getStatics() { return this; }

        @Override
        public WebViewProvider createWebView(WebView webView, WebView.PrivateAccess privateAccess) {
            return new WebViewClassic(webView, privateAccess);
        }

        @Override
        public GeolocationPermissions getGeolocationPermissions() {
            return GeolocationPermissionsClassic.getInstance();
        }

        @Override
        public CookieManager getCookieManager() {
            return CookieManagerClassic.getInstance();
        }

        @Override
        public WebIconDatabase getWebIconDatabase() {
            return WebIconDatabaseClassic.getInstance();
        }

        @Override
        public WebStorage getWebStorage() {
            return WebStorageClassic.getInstance();
        }

        @Override
        public WebViewDatabase getWebViewDatabase(Context context) {
            return WebViewDatabaseClassic.getInstance(context);
        }

        @Override
        public String getDefaultUserAgent(Context context) {
            return WebSettingsClassic.getDefaultUserAgentForLocale(context,
                    Locale.getDefault());
        }
    }

    private void onHandleUiEvent(MotionEvent event, int eventType, int flags) {
        switch (eventType) {
        case WebViewInputDispatcher.EVENT_TYPE_LONG_PRESS:
            HitTestResult hitTest = getHitTestResult();
            if (hitTest != null) {
                mWebView.performLongClick();
            }
            break;
        case WebViewInputDispatcher.EVENT_TYPE_DOUBLE_TAP:
            mZoomManager.handleDoubleTap(event.getX(), event.getY());
            break;
        case WebViewInputDispatcher.EVENT_TYPE_TOUCH:
            onHandleUiTouchEvent(event);
            break;
        case WebViewInputDispatcher.EVENT_TYPE_CLICK:
            if (mFocusedNode != null && mFocusedNode.mIntentUrl != null) {
                mWebView.playSoundEffect(SoundEffectConstants.CLICK);
                overrideLoading(mFocusedNode.mIntentUrl);
            }
            break;
        }
    }

    private void onHandleUiTouchEvent(MotionEvent ev) {
        final ScaleGestureDetector detector =
                mZoomManager.getScaleGestureDetector();

        int action = ev.getActionMasked();
        final boolean pointerUp = action == MotionEvent.ACTION_POINTER_UP;
        final boolean configChanged =
            action == MotionEvent.ACTION_POINTER_UP ||
            action == MotionEvent.ACTION_POINTER_DOWN;
        final int skipIndex = pointerUp ? ev.getActionIndex() : -1;

        // Determine focal point
        float sumX = 0, sumY = 0;
        final int count = ev.getPointerCount();
        for (int i = 0; i < count; i++) {
            if (skipIndex == i) continue;
            sumX += ev.getX(i);
            sumY += ev.getY(i);
        }
        final int div = pointerUp ? count - 1 : count;
        float x = sumX / div;
        float y = sumY / div;

        if (configChanged) {
            mLastTouchX = Math.round(x);
            mLastTouchY = Math.round(y);
            mLastTouchTime = ev.getEventTime();
            mWebView.cancelLongPress();
            mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
        }

        if (detector != null) {
            detector.onTouchEvent(ev);
            if (detector.isInProgress()) {
                mLastTouchTime = ev.getEventTime();

                if (!mZoomManager.supportsPanDuringZoom()) {
                    return;
                }
                mTouchMode = TOUCH_DRAG_MODE;
                if (mVelocityTracker == null) {
                    mVelocityTracker = VelocityTracker.obtain();
                }
            }
        }

        if (action == MotionEvent.ACTION_POINTER_DOWN) {
            cancelTouch();
            action = MotionEvent.ACTION_DOWN;
        } else if (action == MotionEvent.ACTION_MOVE) {
            // negative x or y indicate it is on the edge, skip it.
            if (x < 0 || y < 0) {
                return;
            }
        }

        handleTouchEventCommon(ev, action, Math.round(x), Math.round(y));
    }

    // The webview that is bound to this WebViewClassic instance. Primarily needed for supplying
    // as the first param in the WebViewClient and WebChromeClient callbacks.
    final private WebView mWebView;
    // Callback interface, provides priviledged access into the WebView instance.
    final private WebView.PrivateAccess mWebViewPrivate;
    // Cached reference to mWebView.getContext(), for convenience.
    final private Context mContext;

    /**
     * @return The webview proxy that this classic webview is bound to.
     */
    public WebView getWebView() {
        return mWebView;
    }

    @Override
    public ViewDelegate getViewDelegate() {
        return this;
    }

    @Override
    public ScrollDelegate getScrollDelegate() {
        return this;
    }

    public static WebViewClassic fromWebView(WebView webView) {
        return webView == null ? null : (WebViewClassic) webView.getWebViewProvider();
    }

    // Accessors, purely for convenience (and to reduce code churn during webview proxy migration).
    int getScrollX() {
        return mWebView.getScrollX();
    }

    int getScrollY() {
        return mWebView.getScrollY();
    }

    int getWidth() {
        return mWebView.getWidth();
    }

    int getHeight() {
        return mWebView.getHeight();
    }

    Context getContext() {
        return mContext;
    }

    void invalidate() {
        mWebView.invalidate();
    }

    // Setters for the Scroll X & Y, without invoking the onScrollChanged etc code paths.
    void setScrollXRaw(int mScrollX) {
        mWebViewPrivate.setScrollXRaw(mScrollX);
    }

    void setScrollYRaw(int mScrollY) {
        mWebViewPrivate.setScrollYRaw(mScrollY);
    }

    private static class TrustStorageListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
                handleCertTrustChanged();
            }
        }
    }
    private static TrustStorageListener sTrustStorageListener;

    /**
     * Handles update to the trust storage.
     */
    private static void handleCertTrustChanged() {
        // send a message for indicating trust storage change
        WebViewCore.sendStaticMessage(EventHub.TRUST_STORAGE_UPDATED, null);
    }

    /*
     * @param context This method expects this to be a valid context.
     */
    private static void setupTrustStorageListener(Context context) {
        if (sTrustStorageListener != null ) {
            return;
        }
        IntentFilter filter = new IntentFilter();
        filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
        sTrustStorageListener = new TrustStorageListener();
        Intent current =
            context.getApplicationContext().registerReceiver(sTrustStorageListener, filter);
        if (current != null) {
            handleCertTrustChanged();
        }
    }

    private static class ProxyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
                handleProxyBroadcast(intent);
            }
        }
    }

    /*
     * Receiver for PROXY_CHANGE_ACTION, will be null when it is not added handling broadcasts.
     */
    private static ProxyReceiver sProxyReceiver;

    /*
     * @param context This method expects this to be a valid context
     */
    private static synchronized void setupProxyListener(Context context) {
        if (sProxyReceiver != null || sNotificationsEnabled == false) {
            return;
        }
        IntentFilter filter = new IntentFilter();
        filter.addAction(Proxy.PROXY_CHANGE_ACTION);
        sProxyReceiver = new ProxyReceiver();
        Intent currentProxy = context.getApplicationContext().registerReceiver(
                sProxyReceiver, filter);
        if (currentProxy != null) {
            handleProxyBroadcast(currentProxy);
        }
    }

    /*
     * @param context This method expects this to be a valid context
     */
    private static synchronized void disableProxyListener(Context context) {
        if (sProxyReceiver == null)
            return;

        context.getApplicationContext().unregisterReceiver(sProxyReceiver);
        sProxyReceiver = null;
    }

    private static void handleProxyBroadcast(Intent intent) {
        ProxyProperties proxyProperties = (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
        if (proxyProperties == null || proxyProperties.getHost() == null) {
            WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, null);
            return;
        }
        WebViewCore.sendStaticMessage(EventHub.PROXY_CHANGED, proxyProperties);
    }

    /*
     * A variable to track if there is a receiver added for ACTION_PACKAGE_ADDED
     * or ACTION_PACKAGE_REMOVED.
     */
    private static boolean sPackageInstallationReceiverAdded = false;

    /*
     * A set of Google packages we monitor for the
     * navigator.isApplicationInstalled() API. Add additional packages as
     * needed.
     */
    private static Set<String> sGoogleApps;
    static {
        sGoogleApps = new HashSet<String>();
        sGoogleApps.add("com.google.android.youtube");
    }

    private static class PackageListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            final String packageName = intent.getData().getSchemeSpecificPart();
            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
            if (Intent.ACTION_PACKAGE_REMOVED.equals(action) && replacing) {
                // if it is replacing, refreshPlugins() when adding
                return;
            }

            if (sGoogleApps.contains(packageName)) {
                if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
                    WebViewCore.sendStaticMessage(EventHub.ADD_PACKAGE_NAME, packageName);
                } else {
                    WebViewCore.sendStaticMessage(EventHub.REMOVE_PACKAGE_NAME, packageName);
                }
            }

            PluginManager pm = PluginManager.getInstance(context);
            if (pm.containsPluginPermissionAndSignatures(packageName)) {
                pm.refreshPlugins(Intent.ACTION_PACKAGE_ADDED.equals(action));
            }
        }
    }

    private void setupPackageListener(Context context) {

        /*
         * we must synchronize the instance check and the creation of the
         * receiver to ensure that only ONE receiver exists for all WebView
         * instances.
         */
        synchronized (WebViewClassic.class) {

            // if the receiver already exists then we do not need to register it
            // again
            if (sPackageInstallationReceiverAdded) {
                return;
            }

            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            filter.addDataScheme("package");
            BroadcastReceiver packageListener = new PackageListener();
            context.getApplicationContext().registerReceiver(packageListener, filter);
            sPackageInstallationReceiverAdded = true;
        }

        // check if any of the monitored apps are already installed
        AsyncTask<Void, Void, Set<String>> task = new AsyncTask<Void, Void, Set<String>>() {

            @Override
            protected Set<String> doInBackground(Void... unused) {
                Set<String> installedPackages = new HashSet<String>();
                PackageManager pm = mContext.getPackageManager();
                for (String name : sGoogleApps) {
                    try {
                        pm.getPackageInfo(name,
                                PackageManager.GET_ACTIVITIES | PackageManager.GET_SERVICES);
                        installedPackages.add(name);
                    } catch (PackageManager.NameNotFoundException e) {
                        // package not found
                    }
                }
                return installedPackages;
            }

            // Executes on the UI thread
            @Override
            protected void onPostExecute(Set<String> installedPackages) {
                if (mWebViewCore != null) {
                    mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAMES, installedPackages);
                }
            }
        };
        task.execute();
    }

    void updateMultiTouchSupport(Context context) {
        mZoomManager.updateMultiTouchSupport(context);
    }

    void updateJavaScriptEnabled(boolean enabled) {
        if (isAccessibilityInjectionEnabled()) {
            getAccessibilityInjector().updateJavaScriptEnabled(enabled);
        }
    }

    private void init() {
        OnTrimMemoryListener.init(mContext);
        mWebView.setWillNotDraw(false);
        mWebView.setClickable(true);
        mWebView.setLongClickable(true);

        final ViewConfiguration configuration = ViewConfiguration.get(mContext);
        int slop = configuration.getScaledTouchSlop();
        mTouchSlopSquare = slop * slop;
        slop = configuration.getScaledDoubleTapSlop();
        mDoubleTapSlopSquare = slop * slop;
        final float density = WebViewCore.getFixedDisplayDensity(mContext);
        // use one line height, 16 based on our current default font, for how
        // far we allow a touch be away from the edge of a link
        mNavSlop = (int) (16 * density);
        mZoomManager.init(density);
        mMaximumFling = configuration.getScaledMaximumFlingVelocity();

        // Compute the inverse of the density squared.
        DRAG_LAYER_INVERSE_DENSITY_SQUARED = 1 / (density * density);

        mOverscrollDistance = configuration.getScaledOverscrollDistance();
        mOverflingDistance = configuration.getScaledOverflingDistance();

        setScrollBarStyle(mWebViewPrivate.super_getScrollBarStyle());
        // Initially use a size of two, since the user is likely to only hold
        // down two keys at a time (shift + another key)
        mKeysPressed = new Vector<Integer>(2);
        mHTML5VideoViewProxy = null ;
    }

    @Override
    public boolean shouldDelayChildPressedState() {
        return true;
    }

    @Override
    public boolean performAccessibilityAction(int action, Bundle arguments) {
        if (!mWebView.isEnabled()) {
            // Only default actions are supported while disabled.
            return mWebViewPrivate.super_performAccessibilityAction(action, arguments);
        }

        if (getAccessibilityInjector().supportsAccessibilityAction(action)) {
            return getAccessibilityInjector().performAccessibilityAction(action, arguments);
        }

        switch (action) {
            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
                final int convertedContentHeight = contentToViewY(getContentHeight());
                final int adjustedViewHeight = getHeight() - mWebView.getPaddingTop()
                        - mWebView.getPaddingBottom();
                final int maxScrollY = Math.max(convertedContentHeight - adjustedViewHeight, 0);
                final boolean canScrollBackward = (getScrollY() > 0);
                final boolean canScrollForward = ((getScrollY() - maxScrollY) > 0);
                if ((action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) && canScrollBackward) {
                    mWebView.scrollBy(0, adjustedViewHeight);
                    return true;
                }
                if ((action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) && canScrollForward) {
                    mWebView.scrollBy(0, -adjustedViewHeight);
                    return true;
                }
                return false;
            }
        }

        return mWebViewPrivate.super_performAccessibilityAction(action, arguments);
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        if (!mWebView.isEnabled()) {
            // Only default actions are supported while disabled.
            return;
        }

        info.setScrollable(isScrollableForAccessibility());

        final int convertedContentHeight = contentToViewY(getContentHeight());
        final int adjustedViewHeight = getHeight() - mWebView.getPaddingTop()
                - mWebView.getPaddingBottom();
        final int maxScrollY = Math.max(convertedContentHeight - adjustedViewHeight, 0);
        final boolean canScrollBackward = (getScrollY() > 0);
        final boolean canScrollForward = ((getScrollY() - maxScrollY) > 0);

        if (canScrollForward) {
            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
        }

        if (canScrollForward) {
            info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
        }

        getAccessibilityInjector().onInitializeAccessibilityNodeInfo(info);
    }

    @Override
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        event.setScrollable(isScrollableForAccessibility());
        event.setScrollX(getScrollX());
        event.setScrollY(getScrollY());
        final int convertedContentWidth = contentToViewX(getContentWidth());
        final int adjustedViewWidth = getWidth() - mWebView.getPaddingLeft()
                - mWebView.getPaddingLeft();
        event.setMaxScrollX(Math.max(convertedContentWidth - adjustedViewWidth, 0));
        final int convertedContentHeight = contentToViewY(getContentHeight());
        final int adjustedViewHeight = getHeight() - mWebView.getPaddingTop()
                - mWebView.getPaddingBottom();
        event.setMaxScrollY(Math.max(convertedContentHeight - adjustedViewHeight, 0));
    }

    /* package */ void handleSelectionChangedWebCoreThread(String selection, int token) {
        if (isAccessibilityInjectionEnabled()) {
            getAccessibilityInjector().onSelectionStringChangedWebCoreThread(selection, token);
        }
    }

    private boolean isAccessibilityInjectionEnabled() {
        final AccessibilityManager manager = AccessibilityManager.getInstance(mContext);
        if (!manager.isEnabled()) {
            return false;
        }

        // Accessibility scripts should be injected only when a speaking service
        // is enabled. This may need to change later to accommodate Braille.
        final List<AccessibilityServiceInfo> services = manager.getEnabledAccessibilityServiceList(
                AccessibilityServiceInfo.FEEDBACK_SPOKEN);
        if (services.isEmpty()) {
            return false;
        }

        return true;
    }

    private AccessibilityInjector getAccessibilityInjector() {
        if (mAccessibilityInjector == null) {
            mAccessibilityInjector = new AccessibilityInjector(this);
        }
        return mAccessibilityInjector;
    }

    private boolean isScrollableForAccessibility() {
        return (contentToViewX(getContentWidth()) > getWidth() - mWebView.getPaddingLeft()
                - mWebView.getPaddingRight()
                || contentToViewY(getContentHeight()) > getHeight() - mWebView.getPaddingTop()
                - mWebView.getPaddingBottom());
    }

    @Override
    public void setOverScrollMode(int mode) {
        if (mode != View.OVER_SCROLL_NEVER) {
            if (mOverScrollGlow == null) {
                mOverScrollGlow = new OverScrollGlow(this);
            }
        } else {
            mOverScrollGlow = null;
        }
    }

    /* package */ void adjustDefaultZoomDensity(int zoomDensity) {
        final float density = WebViewCore.getFixedDisplayDensity(mContext)
                * 100 / zoomDensity;
        updateDefaultZoomDensity(density);
    }

    /* package */ void updateDefaultZoomDensity(float density) {
        mNavSlop = (int) (16 * density);
        mZoomManager.updateDefaultZoomDensity(density);
    }

    /* package */ int getScaledNavSlop() {
        return viewToContentDimension(mNavSlop);
    }

    /* package */ boolean onSavePassword(String schemePlusHost, String username,
            String password, final Message resumeMsg) {
        boolean rVal = false;
        if (resumeMsg == null) {
            // null resumeMsg implies saving password silently
            mDatabase.setUsernamePassword(schemePlusHost, username, password);
        } else {
            if (mResumeMsg != null) {
                Log.w(LOGTAG, "onSavePassword should not be called while dialog is up");
                resumeMsg.sendToTarget();
                return true;
            }
            mResumeMsg = resumeMsg;
            final Message remember = mPrivateHandler.obtainMessage(
                    REMEMBER_PASSWORD);
            remember.getData().putString("host", schemePlusHost);
            remember.getData().putString("username", username);
            remember.getData().putString("password", password);
            remember.obj = resumeMsg;

            final Message neverRemember = mPrivateHandler.obtainMessage(
                    NEVER_REMEMBER_PASSWORD);
            neverRemember.getData().putString("host", schemePlusHost);
            neverRemember.getData().putString("username", username);
            neverRemember.getData().putString("password", password);
            neverRemember.obj = resumeMsg;

            mSavePasswordDialog = new AlertDialog.Builder(mContext)
                    .setTitle(com.android.internal.R.string.save_password_label)
                    .setMessage(com.android.internal.R.string.save_password_message)
                    .setPositiveButton(com.android.internal.R.string.save_password_notnow,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (mResumeMsg != null) {
                                resumeMsg.sendToTarget();
                                mResumeMsg = null;
                            }
                            mSavePasswordDialog = null;
                        }
                    })
                    .setNeutralButton(com.android.internal.R.string.save_password_remember,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (mResumeMsg != null) {
                                remember.sendToTarget();
                                mResumeMsg = null;
                            }
                            mSavePasswordDialog = null;
                        }
                    })
                    .setNegativeButton(com.android.internal.R.string.save_password_never,
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (mResumeMsg != null) {
                                neverRemember.sendToTarget();
                                mResumeMsg = null;
                            }
                            mSavePasswordDialog = null;
                        }
                    })
                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            if (mResumeMsg != null) {
                                resumeMsg.sendToTarget();
                                mResumeMsg = null;
                            }
                            mSavePasswordDialog = null;
                        }
                    }).show();
            // Return true so that WebViewCore will pause while the dialog is
            // up.
            rVal = true;
        }
        return rVal;
    }

    @Override
    public void setScrollBarStyle(int style) {
        if (style == View.SCROLLBARS_INSIDE_INSET
                || style == View.SCROLLBARS_OUTSIDE_INSET) {
            mOverlayHorizontalScrollbar = mOverlayVerticalScrollbar = false;
        } else {
            mOverlayHorizontalScrollbar = mOverlayVerticalScrollbar = true;
        }
    }

    /**
     * See {@link WebView#setHorizontalScrollbarOverlay(boolean)}
     */
    @Override
    public void setHorizontalScrollbarOverlay(boolean overlay) {
        mOverlayHorizontalScrollbar = overlay;
    }

    /**
     * See {@link WebView#setVerticalScrollbarOverlay(boolean)
     */
    @Override
    public void setVerticalScrollbarOverlay(boolean overlay) {
        mOverlayVerticalScrollbar = overlay;
    }

    /**
     * See {@link WebView#overlayHorizontalScrollbar()}
     */
    @Override
    public boolean overlayHorizontalScrollbar() {
        return mOverlayHorizontalScrollbar;
    }

    /**
     * See {@link WebView#overlayVerticalScrollbar()}
     */
    @Override
    public boolean overlayVerticalScrollbar() {
        return mOverlayVerticalScrollbar;
    }

    /*
     * Return the width of the view where the content of WebView should render
     * to.
     * Note: this can be called from WebCoreThread.
     */
    /* package */ int getViewWidth() {
        if (!mWebView.isVerticalScrollBarEnabled() || mOverlayVerticalScrollbar) {
            return getWidth();
        } else {
            return Math.max(0, getWidth() - mWebView.getVerticalScrollbarWidth());
        }
    }

    // Interface to enable the browser to override title bar handling.
    public interface TitleBarDelegate {
        int getTitleHeight();
        public void onSetEmbeddedTitleBar(final View title);
    }

    /**
     * Returns the height (in pixels) of the embedded title bar (if any). Does not care about
     * scrolling
     */
    protected int getTitleHeight() {
        if (mWebView instanceof TitleBarDelegate) {
            return ((TitleBarDelegate) mWebView).getTitleHeight();
        }
        return 0;
    }

    /**
     * See {@link WebView#getVisibleTitleHeight()}
     */
    @Override
    @Deprecated
    public int getVisibleTitleHeight() {
        // Actually, this method returns the height of the embedded title bar if one is set via the
        // hidden setEmbeddedTitleBar method.
        return getVisibleTitleHeightImpl();
    }

    private int getVisibleTitleHeightImpl() {
        // need to restrict mScrollY due to over scroll
        return Math.max(getTitleHeight() - Math.max(0, getScrollY()),
                getOverlappingActionModeHeight());
    }

    private int mCachedOverlappingActionModeHeight = -1;

    private int getOverlappingActionModeHeight() {
        if (mFindCallback == null) {
            return 0;
        }
        if (mCachedOverlappingActionModeHeight < 0) {
            mWebView.getGlobalVisibleRect(mGlobalVisibleRect, mGlobalVisibleOffset);
            mCachedOverlappingActionModeHeight = Math.max(0,
                    mFindCallback.getActionModeGlobalBottom() - mGlobalVisibleRect.top);
        }
        return mCachedOverlappingActionModeHeight;
    }

    /*
     * Return the height of the view where the content of WebView should render
     * to.  Note that this excludes mTitleBar, if there is one.
     * Note: this can be called from WebCoreThread.
     */
    /* package */ int getViewHeight() {
        return getViewHeightWithTitle() - getVisibleTitleHeightImpl();
    }

    int getViewHeightWithTitle() {
        int height = getHeight();
        if (mWebView.isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
            height -= mWebViewPrivate.getHorizontalScrollbarHeight();
        }
        return height;
    }

    /**
     * See {@link WebView#getCertificate()}
     */
    @Override
    public SslCertificate getCertificate() {
        return mCertificate;
    }

    /**
     * See {@link WebView#setCertificate(SslCertificate)}
     */
    @Override
    public void setCertificate(SslCertificate certificate) {
        if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "setCertificate=" + certificate);
        }
        // here, the certificate can be null (if the site is not secure)
        mCertificate = certificate;
    }

    //-------------------------------------------------------------------------
    // Methods called by activity
    //-------------------------------------------------------------------------

    /**
     * See {@link WebView#savePassword(String, String, String)}
     */
    @Override
    public void savePassword(String host, String username, String password) {
        mDatabase.setUsernamePassword(host, username, password);
    }

    /**
     * See {@link WebView#setHttpAuthUsernamePassword(String, String, String, String)}
     */
    @Override
    public void setHttpAuthUsernamePassword(String host, String realm,
            String username, String password) {
        mDatabase.setHttpAuthUsernamePassword(host, realm, username, password);
    }

    /**
     * See {@link WebView#getHttpAuthUsernamePassword(String, String)}
     */
    @Override
    public String[] getHttpAuthUsernamePassword(String host, String realm) {
        return mDatabase.getHttpAuthUsernamePassword(host, realm);
    }

    /**
     * Remove Find or Select ActionModes, if active.
     */
    private void clearActionModes() {
        if (mSelectCallback != null) {
            mSelectCallback.finish();
        }
        if (mFindCallback != null) {
            mFindCallback.finish();
        }
    }

    /**
     * Called to clear state when moving from one page to another, or changing
     * in some other way that makes elements associated with the current page
     * (such as ActionModes) no longer relevant.
     */
    private void clearHelpers() {
        hideSoftKeyboard();
        clearActionModes();
        dismissFullScreenMode();
        cancelDialogs();
    }

    private void cancelDialogs() {
        if (mListBoxDialog != null) {
            mListBoxDialog.cancel();
            mListBoxDialog = null;
        }
        if (mSavePasswordDialog != null) {
            mSavePasswordDialog.dismiss();
            mSavePasswordDialog = null;
        }
    }

    /**
     * See {@link WebView#destroy()}
     */
    @Override
    public void destroy() {
        if (mWebView.getViewRootImpl() != null) {
            Log.e(LOGTAG, Log.getStackTraceString(
                    new Throwable("Error: WebView.destroy() called while still attached!")));
        }
        ensureFunctorDetached();
        destroyJava();
        destroyNative();
    }

    private void ensureFunctorDetached() {
        if (mWebView.isHardwareAccelerated()) {
            int drawGLFunction = nativeGetDrawGLFunction(mNativeClass);
            ViewRootImpl viewRoot = mWebView.getViewRootImpl();
            if (drawGLFunction != 0 && viewRoot != null) {
                viewRoot.detachFunctor(drawGLFunction);
            }
        }
    }

    private void destroyJava() {
        mCallbackProxy.blockMessages();
        if (mAccessibilityInjector != null) {
            mAccessibilityInjector.destroy();
            mAccessibilityInjector = null;
        }
        if (mWebViewCore != null) {
            // Tell WebViewCore to destroy itself
            synchronized (this) {
                WebViewCore webViewCore = mWebViewCore;
                mWebViewCore = null; // prevent using partial webViewCore
                webViewCore.destroy();
            }
            // Remove any pending messages that might not be serviced yet.
            mPrivateHandler.removeCallbacksAndMessages(null);
        }
    }

    private void destroyNative() {
        if (mNativeClass == 0) return;
        int nptr = mNativeClass;
        mNativeClass = 0;
        if (Thread.currentThread() == mPrivateHandler.getLooper().getThread()) {
            // We are on the main thread and can safely delete
            nativeDestroy(nptr);
        } else {
            mPrivateHandler.post(new DestroyNativeRunnable(nptr));
        }
    }

    private static class DestroyNativeRunnable implements Runnable {

        private int mNativePtr;

        public DestroyNativeRunnable(int nativePtr) {
            mNativePtr = nativePtr;
        }

        @Override
        public void run() {
            // nativeDestroy also does a stopGL()
            nativeDestroy(mNativePtr);
        }

    }

    /**
     * See {@link WebView#enablePlatformNotifications()}
     */
    @Deprecated
    public static void enablePlatformNotifications() {
        synchronized (WebViewClassic.class) {
            sNotificationsEnabled = true;
            Context context = JniUtil.getContext();
            if (context != null)
                setupProxyListener(context);
        }
    }

    /**
     * See {@link WebView#disablePlatformNotifications()}
     */
    @Deprecated
    public static void disablePlatformNotifications() {
        synchronized (WebViewClassic.class) {
            sNotificationsEnabled = false;
            Context context = JniUtil.getContext();
            if (context != null)
                disableProxyListener(context);
        }
    }

    /**
     * Sets JavaScript engine flags.
     *
     * @param flags JS engine flags in a String
     *
     * This is an implementation detail.
     */
    public void setJsFlags(String flags) {
        mWebViewCore.sendMessage(EventHub.SET_JS_FLAGS, flags);
    }

    /**
     * See {@link WebView#setNetworkAvailable(boolean)}
     */
    @Override
    public void setNetworkAvailable(boolean networkUp) {
        mWebViewCore.sendMessage(EventHub.SET_NETWORK_STATE,
                networkUp ? 1 : 0, 0);
    }

    /**
     * Inform WebView about the current network type.
     */
    public void setNetworkType(String type, String subtype) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("type", type);
        map.put("subtype", subtype);
        mWebViewCore.sendMessage(EventHub.SET_NETWORK_TYPE, map);
    }

    /**
     * See {@link WebView#saveState(Bundle)}
     */
    @Override
    public WebBackForwardList saveState(Bundle outState) {
        if (outState == null) {
            return null;
        }
        // We grab a copy of the back/forward list because a client of WebView
        // may have invalidated the history list by calling clearHistory.
        WebBackForwardListClassic list = copyBackForwardList();
        final int currentIndex = list.getCurrentIndex();
        final int size = list.getSize();
        // We should fail saving the state if the list is empty or the index is
        // not in a valid range.
        if (currentIndex < 0 || currentIndex >= size || size == 0) {
            return null;
        }
        outState.putInt("index", currentIndex);
        // FIXME: This should just be a byte[][] instead of ArrayList but
        // Parcel.java does not have the code to handle multi-dimensional
        // arrays.
        ArrayList<byte[]> history = new ArrayList<byte[]>(size);
        for (int i = 0; i < size; i++) {
            WebHistoryItemClassic item = list.getItemAtIndex(i);
            if (null == item) {
                // FIXME: this shouldn't happen
                // need to determine how item got set to null
                Log.w(LOGTAG, "saveState: Unexpected null history item.");
                return null;
            }
            byte[] data = item.getFlattenedData();
            if (data == null) {
                // It would be very odd to not have any data for a given history
                // item. And we will fail to rebuild the history list without
                // flattened data.
                return null;
            }
            history.add(data);
        }
        outState.putSerializable("history", history);
        if (mCertificate != null) {
            outState.putBundle("certificate",
                               SslCertificate.saveState(mCertificate));
        }
        outState.putBoolean("privateBrowsingEnabled", isPrivateBrowsingEnabled());
        mZoomManager.saveZoomState(outState);
        return list;
    }

    /**
     * See {@link WebView#savePicture(Bundle, File)}
     */
    @Override
    @Deprecated
    public boolean savePicture(Bundle b, final File dest) {
        if (dest == null || b == null) {
            return false;
        }
        final Picture p = capturePicture();
        // Use a temporary file while writing to ensure the destination file
        // contains valid data.
        final File temp = new File(dest.getPath() + ".writing");
        new Thread(new Runnable() {
            @Override
            public void run() {
                FileOutputStream out = null;
                try {
                    out = new FileOutputStream(temp);
                    p.writeToStream(out);
                    // Writing the picture succeeded, rename the temporary file
                    // to the destination.
                    temp.renameTo(dest);
                } catch (Exception e) {
                    // too late to do anything about it.
                } finally {
                    if (out != null) {
                        try {
                            out.close();
                        } catch (Exception e) {
                            // Can't do anything about that
                        }
                    }
                    temp.delete();
                }
            }
        }).start();
        // now update the bundle
        b.putInt("scrollX", getScrollX());
        b.putInt("scrollY", getScrollY());
        mZoomManager.saveZoomState(b);
        return true;
    }

    private void restoreHistoryPictureFields(Picture p, Bundle b) {
        int sx = b.getInt("scrollX", 0);
        int sy = b.getInt("scrollY", 0);

        mDrawHistory = true;
        mHistoryPicture = p;

        setScrollXRaw(sx);
        setScrollYRaw(sy);
        mZoomManager.restoreZoomState(b);
        final float scale = mZoomManager.getScale();
        mHistoryWidth = Math.round(p.getWidth() * scale);
        mHistoryHeight = Math.round(p.getHeight() * scale);

        invalidate();
    }

    /**
     * See {@link WebView#restorePicture(Bundle, File)};
     */
    @Override
    @Deprecated
    public boolean restorePicture(Bundle b, File src) {
        if (src == null || b == null) {
            return false;
        }
        if (!src.exists()) {
            return false;
        }
        try {
            final FileInputStream in = new FileInputStream(src);
            final Bundle copy = new Bundle(b);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        final Picture p = Picture.createFromStream(in);
                        if (p != null) {
                            // Post a runnable on the main thread to update the
                            // history picture fields.
                            mPrivateHandler.post(new Runnable() {
                                @Override
                                public void run() {
                                    restoreHistoryPictureFields(p, copy);
                                }
                            });
                        }
                    } finally {
                        try {
                            in.close();
                        } catch (Exception e) {
                            // Nothing we can do now.
                        }
                    }
                }
            }).start();
        } catch (FileNotFoundException e){
            e.printStackTrace();
        }
        return true;
    }

    /**
     * Saves the view data to the output stream. The output is highly
     * version specific, and may not be able to be loaded by newer versions
     * of WebView.
     * @param stream The {@link OutputStream} to save to
     * @param callback The {@link ValueCallback} to call with the result
     */
    public void saveViewState(OutputStream stream, ValueCallback<Boolean> callback) {
        if (mWebViewCore == null) {
            callback.onReceiveValue(false);
            return;
        }
        mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SAVE_VIEW_STATE,
                new WebViewCore.SaveViewStateRequest(stream, callback));
    }

    /**
     * Loads the view data from the input stream. See
     * {@link #saveViewState(java.io.OutputStream, ValueCallback)} for more information.
     * @param stream The {@link InputStream} to load from
     */
    public void loadViewState(InputStream stream) {
        mBlockWebkitViewMessages = true;
        new AsyncTask<InputStream, Void, DrawData>() {

            @Override
            protected DrawData doInBackground(InputStream... params) {
                try {
                    return ViewStateSerializer.deserializeViewState(params[0]);
                } catch (IOException e) {
                    return null;
                }
            }

            @Override
            protected void onPostExecute(DrawData draw) {
                if (draw == null) {
                    Log.e(LOGTAG, "Failed to load view state!");
                    return;
                }
                int viewWidth = getViewWidth();
                int viewHeight = getViewHeightWithTitle() - getTitleHeight();
                draw.mViewSize = new Point(viewWidth, viewHeight);
                draw.mViewState.mDefaultScale = getDefaultZoomScale();
                mLoadedPicture = draw;
                setNewPicture(mLoadedPicture, true);
                mLoadedPicture.mViewState = null;
            }

        }.execute(stream);
    }

    /**
     * Clears the view state set with {@link #loadViewState(InputStream)}.
     * This WebView will then switch to showing the content from webkit
     */
    public void clearViewState() {
        mBlockWebkitViewMessages = false;
        mLoadedPicture = null;
        invalidate();
    }

    /**
     * See {@link WebView#restoreState(Bundle)}
     */
    @Override
    public WebBackForwardList restoreState(Bundle inState) {
        WebBackForwardListClassic returnList = null;
        if (inState == null) {
            return returnList;
        }
        if (inState.containsKey("index") && inState.containsKey("history")) {
            mCertificate = SslCertificate.restoreState(
                inState.getBundle("certificate"));

            final WebBackForwardListClassic list = mCallbackProxy.getBackForwardList();
            final int index = inState.getInt("index");
            // We can't use a clone of the list because we need to modify the
            // shared copy, so synchronize instead to prevent concurrent
            // modifications.
            synchronized (list) {
                final List<byte[]> history =
                        (List<byte[]>) inState.getSerializable("history");
                final int size = history.size();
                // Check the index bounds so we don't crash in native code while
                // restoring the history index.
                if (index < 0 || index >= size) {
                    return null;
                }
                for (int i = 0; i < size; i++) {
                    byte[] data = history.remove(0);
                    if (data == null) {
                        // If we somehow have null data, we cannot reconstruct
                        // the item and thus our history list cannot be rebuilt.
                        return null;
                    }
                    WebHistoryItem item = new WebHistoryItemClassic(data);
                    list.addHistoryItem(item);
                }
                // Grab the most recent copy to return to the caller.
                returnList = copyBackForwardList();
                // Update the copy to have the correct index.
                returnList.setCurrentIndex(index);
            }
            // Restore private browsing setting.
            if (inState.getBoolean("privateBrowsingEnabled")) {
                getSettings().setPrivateBrowsingEnabled(true);
            }
            mZoomManager.restoreZoomState(inState);
            // Remove all pending messages because we are restoring previous
            // state.
            mWebViewCore.removeMessages();
            if (isAccessibilityInjectionEnabled()) {
                getAccessibilityInjector().addAccessibilityApisIfNecessary();
            }
            // Send a restore state message.
            mWebViewCore.sendMessage(EventHub.RESTORE_STATE, index);
        }
        return returnList;
    }

    /**
     * See {@link WebView#loadUrl(String, Map)}
     */
    @Override
    public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
        loadUrlImpl(url, additionalHttpHeaders);
    }

    private void loadUrlImpl(String url, Map<String, String> extraHeaders) {
        switchOutDrawHistory();
        WebViewCore.GetUrlData arg = new WebViewCore.GetUrlData();
        arg.mUrl = url;
        arg.mExtraHeaders = extraHeaders;
        mWebViewCore.sendMessage(EventHub.LOAD_URL, arg);
        clearHelpers();
    }

    /**
     * See {@link WebView#loadUrl(String)}
     */
    @Override
    public void loadUrl(String url) {
        loadUrlImpl(url);
    }

    private void loadUrlImpl(String url) {
        if (url == null) {
            return;
        }
        loadUrlImpl(url, null);
    }

    /**
     * See {@link WebView#postUrl(String, byte[])}
     */
    @Override
    public void postUrl(String url, byte[] postData) {
        if (URLUtil.isNetworkUrl(url)) {
            switchOutDrawHistory();
            WebViewCore.PostUrlData arg = new WebViewCore.PostUrlData();
            arg.mUrl = url;
            arg.mPostData = postData;
            mWebViewCore.sendMessage(EventHub.POST_URL, arg);
            clearHelpers();
        } else {
            loadUrlImpl(url);
        }
    }

    /**
     * See {@link WebView#loadData(String, String, String)}
     */
    @Override
    public void loadData(String data, String mimeType, String encoding) {
        loadDataImpl(data, mimeType, encoding);
    }

    private void loadDataImpl(String data, String mimeType, String encoding) {
        StringBuilder dataUrl = new StringBuilder("data:");
        dataUrl.append(mimeType);
        if ("base64".equals(encoding)) {
            dataUrl.append(";base64");
        }
        dataUrl.append(",");
        dataUrl.append(data);
        loadUrlImpl(dataUrl.toString());
    }

    /**
     * See {@link WebView#loadDataWithBaseURL(String, String, String, String, String)}
     */
    @Override
    public void loadDataWithBaseURL(String baseUrl, String data,
            String mimeType, String encoding, String historyUrl) {

        if (baseUrl != null && baseUrl.toLowerCase().startsWith("data:")) {
            loadDataImpl(data, mimeType, encoding);
            return;
        }
        switchOutDrawHistory();
        WebViewCore.BaseUrlData arg = new WebViewCore.BaseUrlData();
        arg.mBaseUrl = baseUrl;
        arg.mData = data;
        arg.mMimeType = mimeType;
        arg.mEncoding = encoding;
        arg.mHistoryUrl = historyUrl;
        mWebViewCore.sendMessage(EventHub.LOAD_DATA, arg);
        clearHelpers();
    }

    /**
     * See {@link WebView#saveWebArchive(String)}
     */
    @Override
    public void saveWebArchive(String filename) {
        saveWebArchiveImpl(filename, false, null);
    }

    /* package */ static class SaveWebArchiveMessage {
        SaveWebArchiveMessage (String basename, boolean autoname, ValueCallback<String> callback) {
            mBasename = basename;
            mAutoname = autoname;
            mCallback = callback;
        }

        /* package */ final String mBasename;
        /* package */ final boolean mAutoname;
        /* package */ final ValueCallback<String> mCallback;
        /* package */ String mResultFile;
    }

    /**
     * See {@link WebView#saveWebArchive(String, boolean, ValueCallback)}
     */
    @Override
    public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
        saveWebArchiveImpl(basename, autoname, callback);
    }

    private void saveWebArchiveImpl(String basename, boolean autoname,
            ValueCallback<String> callback) {
        mWebViewCore.sendMessage(EventHub.SAVE_WEBARCHIVE,
            new SaveWebArchiveMessage(basename, autoname, callback));
    }

    /**
     * See {@link WebView#stopLoading()}
     */
    @Override
    public void stopLoading() {
        // TODO: should we clear all the messages in the queue before sending
        // STOP_LOADING?
        switchOutDrawHistory();
        mWebViewCore.sendMessage(EventHub.STOP_LOADING);
    }

    /**
     * See {@link WebView#reload()}
     */
    @Override
    public void reload() {
        clearHelpers();
        switchOutDrawHistory();
        mWebViewCore.sendMessage(EventHub.RELOAD);
    }

    /**
     * See {@link WebView#canGoBack()}
     */
    @Override
    public boolean canGoBack() {
        WebBackForwardListClassic l = mCallbackProxy.getBackForwardList();
        synchronized (l) {
            if (l.getClearPending()) {
                return false;
            } else {
                return l.getCurrentIndex() > 0;
            }
        }
    }

    /**
     * See {@link WebView#goBack()}
     */
    @Override
    public void goBack() {
        goBackOrForwardImpl(-1);
    }

    /**
     * See {@link WebView#canGoForward()}
     */
    @Override
    public boolean canGoForward() {
        WebBackForwardListClassic l = mCallbackProxy.getBackForwardList();
        synchronized (l) {
            if (l.getClearPending()) {
                return false;
            } else {
                return l.getCurrentIndex() < l.getSize() - 1;
            }
        }
    }

    /**
     * See {@link WebView#goForward()}
     */
    @Override
    public void goForward() {
        goBackOrForwardImpl(1);
    }

    /**
     * See {@link WebView#canGoBackOrForward(int)}
     */
    @Override
    public boolean canGoBackOrForward(int steps) {
        WebBackForwardListClassic l = mCallbackProxy.getBackForwardList();
        synchronized (l) {
            if (l.getClearPending()) {
                return false;
            } else {
                int newIndex = l.getCurrentIndex() + steps;
                return newIndex >= 0 && newIndex < l.getSize();
            }
        }
    }

    /**
     * See {@link WebView#goBackOrForward(int)}
     */
    @Override
    public void goBackOrForward(int steps) {
        goBackOrForwardImpl(steps);
    }

    private void goBackOrForwardImpl(int steps) {
        goBackOrForward(steps, false);
    }

    private void goBackOrForward(int steps, boolean ignoreSnapshot) {
        if (steps != 0) {
            clearHelpers();
            mWebViewCore.sendMessage(EventHub.GO_BACK_FORWARD, steps,
                    ignoreSnapshot ? 1 : 0);
        }
    }

    /**
     * See {@link WebView#isPrivateBrowsingEnabled()}
     */
    @Override
    public boolean isPrivateBrowsingEnabled() {
        WebSettingsClassic settings = getSettings();
        return (settings != null) ? settings.isPrivateBrowsingEnabled() : false;
    }

    private void startPrivateBrowsing() {
        getSettings().setPrivateBrowsingEnabled(true);
    }

    private boolean extendScroll(int y) {
        int finalY = mScroller.getFinalY();
        int newY = pinLocY(finalY + y);
        if (newY == finalY) return false;
        mScroller.setFinalY(newY);
        mScroller.extendDuration(computeDuration(0, y));
        return true;
    }

    /**
     * See {@link WebView#pageUp(boolean)}
     */
    @Override
    public boolean pageUp(boolean top) {
        if (mNativeClass == 0) {
            return false;
        }
        if (top) {
            // go to the top of the document
            return pinScrollTo(getScrollX(), 0, true, 0);
        }
        // Page up
        int h = getHeight();
        int y;
        if (h > 2 * PAGE_SCROLL_OVERLAP) {
            y = -h + PAGE_SCROLL_OVERLAP;
        } else {
            y = -h / 2;
        }
        return mScroller.isFinished() ? pinScrollBy(0, y, true, 0)
                : extendScroll(y);
    }

    /**
     * See {@link WebView#pageDown(boolean)}
     */
    @Override
    public boolean pageDown(boolean bottom) {
        if (mNativeClass == 0) {
            return false;
        }
        if (bottom) {
            return pinScrollTo(getScrollX(), computeRealVerticalScrollRange(), true, 0);
        }
        // Page down.
        int h = getHeight();
        int y;
        if (h > 2 * PAGE_SCROLL_OVERLAP) {
            y = h - PAGE_SCROLL_OVERLAP;
        } else {
            y = h / 2;
        }
        return mScroller.isFinished() ? pinScrollBy(0, y, true, 0)
                : extendScroll(y);
    }

    /**
     * See {@link WebView#clearView()}
     */
    @Override
    public void clearView() {
        mContentWidth = 0;
        mContentHeight = 0;
        setBaseLayer(0, false, false);
        mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
    }

    /**
     * See {@link WebView#capturePicture()}
     */
    @Override
    public Picture capturePicture() {
        if (mNativeClass == 0) return null;
        Picture result = new Picture();
        nativeCopyBaseContentToPicture(result);
        return result;
    }

    /**
     * See {@link WebView#getScale()}
     */
    @Override
    public float getScale() {
        return mZoomManager.getScale();
    }

    /**
     * Compute the reading level scale of the WebView
     * @param scale The current scale.
     * @return The reading level scale.
     */
    /*package*/ float computeReadingLevelScale(float scale) {
        return mZoomManager.computeReadingLevelScale(scale);
    }

    /**
     * See {@link WebView#setInitialScale(int)}
     */
    @Override
    public void setInitialScale(int scaleInPercent) {
        mZoomManager.setInitialScaleInPercent(scaleInPercent);
    }

    /**
     * See {@link WebView#invokeZoomPicker()}
     */
    @Override
    public void invokeZoomPicker() {
        if (!getSettings().supportZoom()) {
            Log.w(LOGTAG, "This WebView doesn't support zoom.");
            return;
        }
        clearHelpers();
        mZoomManager.invokeZoomPicker();
    }

    /**
     * See {@link WebView#getHitTestResult()}
     */
    @Override
    public HitTestResult getHitTestResult() {
        return mInitialHitTestResult;
    }

    // No left edge for double-tap zoom alignment
    static final int NO_LEFTEDGE = -1;

    int getBlockLeftEdge(int x, int y, float readingScale) {
        float invReadingScale = 1.0f / readingScale;
        int readingWidth = (int) (getViewWidth() * invReadingScale);
        int left = NO_LEFTEDGE;
        if (mFocusedNode != null) {
            final int length = mFocusedNode.mEnclosingParentRects.length;
            for (int i = 0; i < length; i++) {
                Rect rect = mFocusedNode.mEnclosingParentRects[i];
                if (rect.width() < mFocusedNode.mHitTestSlop) {
                    // ignore bounding boxes that are too small
                    continue;
                } else if (rect.width() > readingWidth) {
                    // stop when bounding box doesn't fit the screen width
                    // at reading scale
                    break;
                }

                left = rect.left;
            }
        }

        return left;
    }

    /**
     * See {@link WebView#requestFocusNodeHref(Message)}
     */
    @Override
    public void requestFocusNodeHref(Message hrefMsg) {
        if (hrefMsg == null) {
            return;
        }
        int contentX = viewToContentX(mLastTouchX + getScrollX());
        int contentY = viewToContentY(mLastTouchY + getScrollY());
        if (mFocusedNode != null && mFocusedNode.mHitTestX == contentX
                && mFocusedNode.mHitTestY == contentY) {
            hrefMsg.getData().putString(FocusNodeHref.URL, mFocusedNode.mLinkUrl);
            hrefMsg.getData().putString(FocusNodeHref.TITLE, mFocusedNode.mAnchorText);
            hrefMsg.getData().putString(FocusNodeHref.SRC, mFocusedNode.mImageUrl);
            hrefMsg.sendToTarget();
            return;
        }
        mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
                contentX, contentY, hrefMsg);
    }

    /**
     * See {@link WebView#requestImageRef(Message)}
     */
    @Override
    public void requestImageRef(Message msg) {
        if (0 == mNativeClass) return; // client isn't initialized
        String url = mFocusedNode != null ? mFocusedNode.mImageUrl : null;
        Bundle data = msg.getData();
        data.putString("url", url);
        msg.setData(data);
        msg.sendToTarget();
    }

    static int pinLoc(int x, int viewMax, int docMax) {
//        Log.d(LOGTAG, "-- pinLoc " + x + " " + viewMax + " " + docMax);
        if (docMax < viewMax) {   // the doc has room on the sides for "blank"
            // pin the short document to the top/left of the screen
            x = 0;
//            Log.d(LOGTAG, "--- center " + x);
        } else if (x < 0) {
            x = 0;
//            Log.d(LOGTAG, "--- zero");
        } else if (x + viewMax > docMax) {
            x = docMax - viewMax;
//            Log.d(LOGTAG, "--- pin " + x);
        }
        return x;
    }

    // Expects x in view coordinates
    int pinLocX(int x) {
        if (mInOverScrollMode) return x;
        return pinLoc(x, getViewWidth(), computeRealHorizontalScrollRange());
    }

    // Expects y in view coordinates
    int pinLocY(int y) {
        if (mInOverScrollMode) return y;
        return pinLoc(y, getViewHeightWithTitle(),
                      computeRealVerticalScrollRange() + getTitleHeight());
    }

    /**
     * Given a distance in view space, convert it to content space. Note: this
     * does not reflect translation, just scaling, so this should not be called
     * with coordinates, but should be called for dimensions like width or
     * height.
     */
    private int viewToContentDimension(int d) {
        return Math.round(d * mZoomManager.getInvScale());
    }

    /**
     * Given an x coordinate in view space, convert it to content space.  Also
     * may be used for absolute heights.
     */
    /*package*/ int viewToContentX(int x) {
        return viewToContentDimension(x);
    }

    /**
     * Given a y coordinate in view space, convert it to content space.
     * Takes into account the height of the title bar if there is one
     * embedded into the WebView.
     */
    /*package*/ int viewToContentY(int y) {
        return viewToContentDimension(y - getTitleHeight());
    }

    /**
     * Given a x coordinate in view space, convert it to content space.
     * Returns the result as a float.
     */
    private float viewToContentXf(int x) {
        return x * mZoomManager.getInvScale();
    }

    /**
     * Given a y coordinate in view space, convert it to content space.
     * Takes into account the height of the title bar if there is one
     * embedded into the WebView. Returns the result as a float.
     */
    private float viewToContentYf(int y) {
        return (y - getTitleHeight()) * mZoomManager.getInvScale();
    }

    /**
     * Given a distance in content space, convert it to view space. Note: this
     * does not reflect translation, just scaling, so this should not be called
     * with coordinates, but should be called for dimensions like width or
     * height.
     */
    /*package*/ int contentToViewDimension(int d) {
        return Math.round(d * mZoomManager.getScale());
    }

    /**
     * Given an x coordinate in content space, convert it to view
     * space.
     */
    /*package*/ int contentToViewX(int x) {
        return contentToViewDimension(x);
    }

    /**
     * Given a y coordinate in content space, convert it to view
     * space.  Takes into account the height of the title bar.
     */
    /*package*/ int contentToViewY(int y) {
        return contentToViewDimension(y) + getTitleHeight();
    }

    private Rect contentToViewRect(Rect x) {
        return new Rect(contentToViewX(x.left), contentToViewY(x.top),
                        contentToViewX(x.right), contentToViewY(x.bottom));
    }

    /*  To invalidate a rectangle in content coordinates, we need to transform
        the rect into view coordinates, so we can then call invalidate(...).

        Normally, we would just call contentToView[XY](...), which eventually
        calls Math.round(coordinate * mActualScale). However, for invalidates,
        we need to account for the slop that occurs with antialiasing. To
        address that, we are a little more liberal in the size of the rect that
        we invalidate.

        This liberal calculation calls floor() for the top/left, and ceil() for
        the bottom/right coordinates. This catches the possible extra pixels of
        antialiasing that we might have missed with just round().
     */

    // Called by JNI to invalidate the View, given rectangle coordinates in
    // content space
    private void viewInvalidate(int l, int t, int r, int b) {
        final float scale = mZoomManager.getScale();
        final int dy = getTitleHeight();
        mWebView.invalidate((int)Math.floor(l * scale),
                (int)Math.floor(t * scale) + dy,
                (int)Math.ceil(r * scale),
                (int)Math.ceil(b * scale) + dy);
    }

    // Called by JNI to invalidate the View after a delay, given rectangle
    // coordinates in content space
    private void viewInvalidateDelayed(long delay, int l, int t, int r, int b) {
        final float scale = mZoomManager.getScale();
        final int dy = getTitleHeight();
        mWebView.postInvalidateDelayed(delay,
                (int)Math.floor(l * scale),
                (int)Math.floor(t * scale) + dy,
                (int)Math.ceil(r * scale),
                (int)Math.ceil(b * scale) + dy);
    }

    private void invalidateContentRect(Rect r) {
        viewInvalidate(r.left, r.top, r.right, r.bottom);
    }

    // stop the scroll animation, and don't let a subsequent fling add
    // to the existing velocity
    private void abortAnimation() {
        mScroller.abortAnimation();
        mLastVelocity = 0;
    }

    /* call from webcoreview.draw(), so we're still executing in the UI thread
    */
    private void recordNewContentSize(int w, int h, boolean updateLayout) {

        // premature data from webkit, ignore
        if ((w | h) == 0) {
            invalidate();
            return;
        }

        // don't abort a scroll animation if we didn't change anything
        if (mContentWidth != w || mContentHeight != h) {
            // record new dimensions
            mContentWidth = w;
            mContentHeight = h;
            // If history Picture is drawn, don't update scroll. They will be
            // updated when we get out of that mode.
            if (!mDrawHistory) {
                // repin our scroll, taking into account the new content size
                updateScrollCoordinates(pinLocX(getScrollX()), pinLocY(getScrollY()));
                if (!mScroller.isFinished()) {
                    // We are in the middle of a scroll.  Repin the final scroll
                    // position.
                    mScroller.setFinalX(pinLocX(mScroller.getFinalX()));
                    mScroller.setFinalY(pinLocY(mScroller.getFinalY()));
                }
            }
            invalidate();
        }
        contentSizeChanged(updateLayout);
    }

    // Used to avoid sending many visible rect messages.
    private Rect mLastVisibleRectSent = new Rect();
    private Rect mLastGlobalRect = new Rect();
    private Rect mVisibleRect = new Rect();
    private Rect mGlobalVisibleRect = new Rect();
    private Point mScrollOffset = new Point();

    Rect sendOurVisibleRect() {
        if (mZoomManager.isPreventingWebkitUpdates()) return mLastVisibleRectSent;
        calcOurContentVisibleRect(mVisibleRect);
        // Rect.equals() checks for null input.
        if (!mVisibleRect.equals(mLastVisibleRectSent)) {
            if (!mBlockWebkitViewMessages) {
                mScrollOffset.set(mVisibleRect.left, mVisibleRect.top);
                mWebViewCore.removeMessages(EventHub.SET_SCROLL_OFFSET);
                mWebViewCore.sendMessage(EventHub.SET_SCROLL_OFFSET,
                        mSendScrollEvent ? 1 : 0, mScrollOffset);
            }
            mLastVisibleRectSent.set(mVisibleRect);
            mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
        }
        if (mWebView.getGlobalVisibleRect(mGlobalVisibleRect)
                && !mGlobalVisibleRect.equals(mLastGlobalRect)) {
            if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "sendOurVisibleRect=(" + mGlobalVisibleRect.left + ","
                        + mGlobalVisibleRect.top + ",r=" + mGlobalVisibleRect.right + ",b="
                        + mGlobalVisibleRect.bottom);
            }
            // TODO: the global offset is only used by windowRect()
            // in ChromeClientAndroid ; other clients such as touch
            // and mouse events could return view + screen relative points.
            if (!mBlockWebkitViewMessages) {
                mWebViewCore.sendMessage(EventHub.SET_GLOBAL_BOUNDS, mGlobalVisibleRect);
            }
            mLastGlobalRect.set(mGlobalVisibleRect);
        }
        return mVisibleRect;
    }

    private Point mGlobalVisibleOffset = new Point();
    // Sets r to be the visible rectangle of our webview in view coordinates
    private void calcOurVisibleRect(Rect r) {
        mWebView.getGlobalVisibleRect(r, mGlobalVisibleOffset);
        r.offset(-mGlobalVisibleOffset.x, -mGlobalVisibleOffset.y);
    }

    // Sets r to be our visible rectangle in content coordinates
    private void calcOurContentVisibleRect(Rect r) {
        calcOurVisibleRect(r);
        r.left = viewToContentX(r.left);
        // viewToContentY will remove the total height of the title bar.  Add
        // the visible height back in to account for the fact that if the title
        // bar is partially visible, the part of the visible rect which is
        // displaying our content is displaced by that amount.
        r.top = viewToContentY(r.top + getVisibleTitleHeightImpl());
        r.right = viewToContentX(r.right);
        r.bottom = viewToContentY(r.bottom);
    }

    private final Rect mTempContentVisibleRect = new Rect();
    // Sets r to be our visible rectangle in content coordinates. We use this
    // method on the native side to compute the position of the fixed layers.
    // Uses floating coordinates (necessary to correctly place elements when
    // the scale factor is not 1)
    private void calcOurContentVisibleRectF(RectF r) {
        calcOurVisibleRect(mTempContentVisibleRect);
        viewToContentVisibleRect(r, mTempContentVisibleRect);
    }

    static class ViewSizeData {
        int mWidth;
        int mHeight;
        float mHeightWidthRatio;
        int mActualViewHeight;
        int mTextWrapWidth;
        int mAnchorX;
        int mAnchorY;
        float mScale;
        boolean mIgnoreHeight;
    }

    /**
     * Compute unzoomed width and height, and if they differ from the last
     * values we sent, send them to webkit (to be used as new viewport)
     *
     * @param force ensures that the message is sent to webkit even if the width
     * or height has not changed since the last message
     *
     * @return true if new values were sent
     */
    boolean sendViewSizeZoom(boolean force) {
        if (mBlockWebkitViewMessages) return false;
        if (mZoomManager.isPreventingWebkitUpdates()) return false;

        int viewWidth = getViewWidth();
        int newWidth = Math.round(viewWidth * mZoomManager.getInvScale());
        // This height could be fixed and be different from actual visible height.
        int viewHeight = getViewHeightWithTitle() - getTitleHeight();
        int newHeight = Math.round(viewHeight * mZoomManager.getInvScale());
        // Make the ratio more accurate than (newHeight / newWidth), since the
        // latter both are calculated and rounded.
        float heightWidthRatio = (float) viewHeight / viewWidth;
        /*
         * Because the native side may have already done a layout before the
         * View system was able to measure us, we have to send a height of 0 to
         * remove excess whitespace when we grow our width. This will trigger a
         * layout and a change in content size. This content size change will
         * mean that contentSizeChanged will either call this method directly or
         * indirectly from onSizeChanged.
         */
        if (newWidth > mLastWidthSent && mWrapContent) {
            newHeight = 0;
            heightWidthRatio = 0;
        }
        // Actual visible content height.
        int actualViewHeight = Math.round(getViewHeight() * mZoomManager.getInvScale());
        // Avoid sending another message if the dimensions have not changed.
        if (newWidth != mLastWidthSent || newHeight != mLastHeightSent || force ||
                actualViewHeight != mLastActualHeightSent) {
            ViewSizeData data = new ViewSizeData();
            data.mWidth = newWidth;
            data.mHeight = newHeight;
            data.mHeightWidthRatio = heightWidthRatio;
            data.mActualViewHeight = actualViewHeight;
            data.mTextWrapWidth = Math.round(viewWidth / mZoomManager.getTextWrapScale());
            data.mScale = mZoomManager.getScale();
            data.mIgnoreHeight = mZoomManager.isFixedLengthAnimationInProgress()
                    && !mHeightCanMeasure;
            data.mAnchorX = mZoomManager.getDocumentAnchorX();
            data.mAnchorY = mZoomManager.getDocumentAnchorY();
            mWebViewCore.sendMessage(EventHub.VIEW_SIZE_CHANGED, data);
            mLastWidthSent = newWidth;
            mLastHeightSent = newHeight;
            mLastActualHeightSent = actualViewHeight;
            mZoomManager.clearDocumentAnchor();
            return true;
        }
        return false;
    }

    /**
     * Update the double-tap zoom.
     */
    /* package */ void updateDoubleTapZoom(int doubleTapZoom) {
        mZoomManager.updateDoubleTapZoom(doubleTapZoom);
    }

    private int computeRealHorizontalScrollRange() {
        if (mDrawHistory) {
            return mHistoryWidth;
        } else {
            // to avoid rounding error caused unnecessary scrollbar, use floor
            return (int) Math.floor(mContentWidth * mZoomManager.getScale());
        }
    }

    @Override
    public int computeHorizontalScrollRange() {
        int range = computeRealHorizontalScrollRange();

        // Adjust reported range if overscrolled to compress the scroll bars
        final int scrollX = getScrollX();
        final int overscrollRight = computeMaxScrollX();
        if (scrollX < 0) {
            range -= scrollX;
        } else if (scrollX > overscrollRight) {
            range += scrollX - overscrollRight;
        }

        return range;
    }

    @Override
    public int computeHorizontalScrollOffset() {
        return Math.max(getScrollX(), 0);
    }

    private int computeRealVerticalScrollRange() {
        if (mDrawHistory) {
            return mHistoryHeight;
        } else {
            // to avoid rounding error caused unnecessary scrollbar, use floor
            return (int) Math.floor(mContentHeight * mZoomManager.getScale());
        }
    }

    @Override
    public int computeVerticalScrollRange() {
        int range = computeRealVerticalScrollRange();

        // Adjust reported range if overscrolled to compress the scroll bars
        final int scrollY = getScrollY();
        final int overscrollBottom = computeMaxScrollY();
        if (scrollY < 0) {
            range -= scrollY;
        } else if (scrollY > overscrollBottom) {
            range += scrollY - overscrollBottom;
        }

        return range;
    }

    @Override
    public int computeVerticalScrollOffset() {
        return Math.max(getScrollY() - getTitleHeight(), 0);
    }

    @Override
    public int computeVerticalScrollExtent() {
        return getViewHeight();
    }

    @Override
    public void onDrawVerticalScrollBar(Canvas canvas,
                                           Drawable scrollBar,
                                           int l, int t, int r, int b) {
        if (getScrollY() < 0) {
            t -= getScrollY();
        }
        scrollBar.setBounds(l, t + getVisibleTitleHeightImpl(), r, b);
        scrollBar.draw(canvas);
    }

    @Override
    public void onOverScrolled(int scrollX, int scrollY, boolean clampedX,
            boolean clampedY) {
        // Special-case layer scrolling so that we do not trigger normal scroll
        // updating.
        if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
            scrollEditText(scrollX, scrollY);
            return;
        }
        if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
            scrollLayerTo(scrollX, scrollY);
            animateHandles();
            return;
        }
        mInOverScrollMode = false;
        int maxX = computeMaxScrollX();
        int maxY = computeMaxScrollY();
        if (maxX == 0) {
            // do not over scroll x if the page just fits the screen
            scrollX = pinLocX(scrollX);
        } else if (scrollX < 0 || scrollX > maxX) {
            mInOverScrollMode = true;
        }
        if (scrollY < 0 || scrollY > maxY) {
            mInOverScrollMode = true;
        }

        int oldX = getScrollX();
        int oldY = getScrollY();

        mWebViewPrivate.super_scrollTo(scrollX, scrollY);

        animateHandles();

        if (mOverScrollGlow != null) {
            mOverScrollGlow.pullGlow(getScrollX(), getScrollY(), oldX, oldY, maxX, maxY);
        }
    }

    /**
     * See {@link WebView#getUrl()}
     */
    @Override
    public String getUrl() {
        WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
        return h != null ? h.getUrl() : null;
    }

    /**
     * See {@link WebView#getOriginalUrl()}
     */
    @Override
    public String getOriginalUrl() {
        WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
        return h != null ? h.getOriginalUrl() : null;
    }

    /**
     * See {@link WebView#getTitle()}
     */
    @Override
    public String getTitle() {
        WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
        return h != null ? h.getTitle() : null;
    }

    /**
     * See {@link WebView#getFavicon()}
     */
    @Override
    public Bitmap getFavicon() {
        WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
        return h != null ? h.getFavicon() : null;
    }

    /**
     * See {@link WebView#getTouchIconUrl()}
     */
    @Override
    public String getTouchIconUrl() {
        WebHistoryItemClassic h = mCallbackProxy.getBackForwardList().getCurrentItem();
        return h != null ? h.getTouchIconUrl() : null;
    }

    /**
     * See {@link WebView#getProgress()}
     */
    @Override
    public int getProgress() {
        return mCallbackProxy.getProgress();
    }

    /**
     * See {@link WebView#getContentHeight()}
     */
    @Override
    public int getContentHeight() {
        return mContentHeight;
    }

    /**
     * See {@link WebView#getContentWidth()}
     */
    @Override
    public int getContentWidth() {
        return mContentWidth;
    }

    public int getPageBackgroundColor() {
        if (mNativeClass == 0) return Color.WHITE;
        return nativeGetBackgroundColor(mNativeClass);
    }

    /**
     * See {@link WebView#pauseTimers()}
     */
    @Override
    public void pauseTimers() {
        mWebViewCore.sendMessage(EventHub.PAUSE_TIMERS);
    }

    /**
     * See {@link WebView#resumeTimers()}
     */
    @Override
    public void resumeTimers() {
        mWebViewCore.sendMessage(EventHub.RESUME_TIMERS);
    }

    /**
     * See {@link WebView#onPause()}
     */
    @Override
    public void onPause() {
        if (!mIsPaused) {
            mIsPaused = true;
            mWebViewCore.sendMessage(EventHub.ON_PAUSE);
            // We want to pause the current playing video when switching out
            // from the current WebView/tab.
            if (mHTML5VideoViewProxy != null) {
                mHTML5VideoViewProxy.pauseAndDispatch();
            }
            if (mNativeClass != 0) {
                nativeSetPauseDrawing(mNativeClass, true);
            }

            cancelDialogs();
            WebCoreThreadWatchdog.pause();
        }
    }

    @Override
    public void onWindowVisibilityChanged(int visibility) {
        updateDrawingState();
    }

    void updateDrawingState() {
        if (mNativeClass == 0 || mIsPaused) return;
        if (mWebView.getWindowVisibility() != View.VISIBLE) {
            nativeSetPauseDrawing(mNativeClass, true);
        } else if (mWebView.getVisibility() != View.VISIBLE) {
            nativeSetPauseDrawing(mNativeClass, true);
        } else {
            nativeSetPauseDrawing(mNativeClass, false);
        }
    }

    /**
     * See {@link WebView#onResume()}
     */
    @Override
    public void onResume() {
        if (mIsPaused) {
            mIsPaused = false;
            mWebViewCore.sendMessage(EventHub.ON_RESUME);
            if (mNativeClass != 0) {
                nativeSetPauseDrawing(mNativeClass, false);
            }
        }
        // We get a call to onResume for new WebViews (i.e. mIsPaused will be false). We need
        // to ensure that the Watchdog thread is running for the new WebView, so call
        // it outside the if block above.
        WebCoreThreadWatchdog.resume();
    }

    /**
     * See {@link WebView#isPaused()}
     */
    @Override
    public boolean isPaused() {
        return mIsPaused;
    }

    /**
     * See {@link WebView#freeMemory()}
     */
    @Override
    public void freeMemory() {
        mWebViewCore.sendMessage(EventHub.FREE_MEMORY);
    }

    /**
     * See {@link WebView#clearCache(boolean)}
     */
    @Override
    public void clearCache(boolean includeDiskFiles) {
        // Note: this really needs to be a static method as it clears cache for all
        // WebView. But we need mWebViewCore to send message to WebCore thread, so
        // we can't make this static.
        mWebViewCore.sendMessage(EventHub.CLEAR_CACHE,
                includeDiskFiles ? 1 : 0, 0);
    }

    /**
     * See {@link WebView#clearFormData()}
     */
    @Override
    public void clearFormData() {
        if (mAutoCompletePopup != null) {
            mAutoCompletePopup.clearAdapter();
        }
    }

    /**
     * See {@link WebView#clearHistory()}
     */
    @Override
    public void clearHistory() {
        mCallbackProxy.getBackForwardList().setClearPending();
        mWebViewCore.sendMessage(EventHub.CLEAR_HISTORY);
    }

    /**
     * See {@link WebView#clearSslPreferences()}
     */
    @Override
    public void clearSslPreferences() {
        mWebViewCore.sendMessage(EventHub.CLEAR_SSL_PREF_TABLE);
    }

    /**
     * See {@link WebView#copyBackForwardList()}
     */
    @Override
    public WebBackForwardListClassic copyBackForwardList() {
        return mCallbackProxy.getBackForwardList().clone();
    }

    /**
     * See {@link WebView#setFindListener(WebView.FindListener)}.
     * @hide
     */
     @Override
    public void setFindListener(WebView.FindListener listener) {
         mFindListener = listener;
     }

    /**
     * See {@link WebView#findNext(boolean)}
     */
    @Override
    public void findNext(boolean forward) {
        if (0 == mNativeClass) return; // client isn't initialized
        if (mFindRequest != null) {
            mWebViewCore.sendMessage(EventHub.FIND_NEXT, forward ? 1 : 0, mFindRequest);
        }
    }

    /**
     * See {@link WebView#findAll(String)}
     */
    @Override
    public int findAll(String find) {
        return findAllBody(find, false);
    }

    @Override
    public void findAllAsync(String find) {
        findAllBody(find, true);
    }

    private int findAllBody(String find, boolean isAsync) {
        if (0 == mNativeClass) return 0; // client isn't initialized
        mFindRequest = null;
        if (find == null) return 0;
        mWebViewCore.removeMessages(EventHub.FIND_ALL);
        mFindRequest = new WebViewCore.FindAllRequest(find);
        if (isAsync) {
            mWebViewCore.sendMessage(EventHub.FIND_ALL, mFindRequest);
            return 0; // no need to wait for response
        }
        synchronized(mFindRequest) {
            try {
                mWebViewCore.sendMessageAtFrontOfQueue(EventHub.FIND_ALL, mFindRequest);
                while (mFindRequest.mMatchCount == -1) {
                    mFindRequest.wait();
                }
            }
            catch (InterruptedException e) {
                return 0;
            }
            return mFindRequest.mMatchCount;
        }
    }

    /**
     * Start an ActionMode for finding text in this WebView.  Only works if this
     *              WebView is attached to the view system.
     * @param text If non-null, will be the initial text to search for.
     *             Otherwise, the last String searched for in this WebView will
     *             be used to start.
     * @param showIme If true, show the IME, assuming the user will begin typing.
     *             If false and text is non-null, perform a find all.
     * @return boolean True if the find dialog is shown, false otherwise.
     */
    @Override
    public boolean showFindDialog(String text, boolean showIme) {
        FindActionModeCallback callback = new FindActionModeCallback(mContext);
        if (mWebView.getParent() == null || mWebView.startActionMode(callback) == null) {
            // Could not start the action mode, so end Find on page
            return false;
        }
        mCachedOverlappingActionModeHeight = -1;
        mFindCallback = callback;
        setFindIsUp(true);
        mFindCallback.setWebView(getWebView());
        if (showIme) {
            mFindCallback.showSoftInput();
        } else if (text != null) {
            mFindCallback.setText(text);
            mFindCallback.findAll();
            return true;
        }
        if (text == null) {
            text = mFindRequest == null ? null : mFindRequest.mSearchText;
        }
        if (text != null) {
            mFindCallback.setText(text);
            mFindCallback.findAll();
        }
        return true;
    }

    /**
     * Keep track of the find callback so that we can remove its titlebar if
     * necessary.
     */
    private FindActionModeCallback mFindCallback;

    /**
     * Toggle whether the find dialog is showing, for both native and Java.
     */
    private void setFindIsUp(boolean isUp) {
        mFindIsUp = isUp;
    }

    // Used to know whether the find dialog is open.  Affects whether
    // or not we draw the highlights for matches.
    private boolean mFindIsUp;

    // Keep track of the last find request sent.
    private WebViewCore.FindAllRequest mFindRequest = null;

    /**
     * Return the first substring consisting of the address of a physical
     * location. Currently, only addresses in the United States are detected,
     * and consist of:
     * - a house number
     * - a street name
     * - a street type (Road, Circle, etc), either spelled out or abbreviated
     * - a city name
     * - a state or territory, either spelled out or two-letter abbr.
     * - an optional 5 digit or 9 digit zip code.
     *
     * All names must be correctly capitalized, and the zip code, if present,
     * must be valid for the state. The street type must be a standard USPS
     * spelling or abbreviation. The state or territory must also be spelled
     * or abbreviated using USPS standards. The house number may not exceed
     * five digits.
     * @param addr The string to search for addresses.
     *
     * @return the address, or if no address is found, return null.
     */
    public static String findAddress(String addr) {
        return findAddress(addr, false);
    }

    /**
     * Return the first substring consisting of the address of a physical
     * location. Currently, only addresses in the United States are detected,
     * and consist of:
     * - a house number
     * - a street name
     * - a street type (Road, Circle, etc), either spelled out or abbreviated
     * - a city name
     * - a state or territory, either spelled out or two-letter abbr.
     * - an optional 5 digit or 9 digit zip code.
     *
     * Names are optionally capitalized, and the zip code, if present,
     * must be valid for the state. The street type must be a standard USPS
     * spelling or abbreviation. The state or territory must also be spelled
     * or abbreviated using USPS standards. The house number may not exceed
     * five digits.
     * @param addr The string to search for addresses.
     * @param caseInsensitive addr Set to true to make search ignore case.
     *
     * @return the address, or if no address is found, return null.
     */
    public static String findAddress(String addr, boolean caseInsensitive) {
        return WebViewCore.nativeFindAddress(addr, caseInsensitive);
    }

    /**
     * See {@link WebView#clearMatches()}
     */
    @Override
    public void clearMatches() {
        if (mNativeClass == 0)
            return;
        mWebViewCore.removeMessages(EventHub.FIND_ALL);
        mWebViewCore.sendMessage(EventHub.FIND_ALL, null);
    }


    /**
     * Called when the find ActionMode ends.
     */
    @Override
    public void notifyFindDialogDismissed() {
        mFindCallback = null;
        mCachedOverlappingActionModeHeight = -1;
        if (mWebViewCore == null) {
            return;
        }
        clearMatches();
        setFindIsUp(false);
        // Now that the dialog has been removed, ensure that we scroll to a
        // location that is not beyond the end of the page.
        pinScrollTo(getScrollX(), getScrollY(), false, 0);
        invalidate();
    }

    /**
     * See {@link WebView#documentHasImages(Message)}
     */
    @Override
    public void documentHasImages(Message response) {
        if (response == null) {
            return;
        }
        mWebViewCore.sendMessage(EventHub.DOC_HAS_IMAGES, response);
    }

    /**
     * Request the scroller to abort any ongoing animation
     */
    public void stopScroll() {
        mScroller.forceFinished(true);
        mLastVelocity = 0;
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            int oldX = getScrollX();
            int oldY = getScrollY();
            int x = mScroller.getCurrX();
            int y = mScroller.getCurrY();
            invalidate();  // So we draw again

            if (!mScroller.isFinished()) {
                int rangeX = computeMaxScrollX();
                int rangeY = computeMaxScrollY();
                int overflingDistance = mOverflingDistance;

                // Use the layer's scroll data if needed.
                if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
                    oldX = mScrollingLayerRect.left;
                    oldY = mScrollingLayerRect.top;
                    rangeX = mScrollingLayerRect.right;
                    rangeY = mScrollingLayerRect.bottom;
                    // No overscrolling for layers.
                    overflingDistance = 0;
                } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
                    oldX = getTextScrollX();
                    oldY = getTextScrollY();
                    rangeX = getMaxTextScrollX();
                    rangeY = getMaxTextScrollY();
                    overflingDistance = 0;
                }

                mWebViewPrivate.overScrollBy(x - oldX, y - oldY, oldX, oldY,
                        rangeX, rangeY,
                        overflingDistance, overflingDistance, false);

                if (mOverScrollGlow != null) {
                    mOverScrollGlow.absorbGlow(x, y, oldX, oldY, rangeX, rangeY);
                }
            } else {
                if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
                    // Update the layer position instead of WebView.
                    scrollLayerTo(x, y);
                } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
                    scrollEditText(x, y);
                } else {
                    setScrollXRaw(x);
                    setScrollYRaw(y);
                }
                abortAnimation();
                nativeSetIsScrolling(false);
                if (!mBlockWebkitViewMessages) {
                    WebViewCore.resumePriority();
                    if (!mSelectingText) {
                        WebViewCore.resumeUpdatePicture(mWebViewCore);
                    }
                }
                if (oldX != getScrollX() || oldY != getScrollY()) {
                    sendOurVisibleRect();
                }
            }
        } else {
            mWebViewPrivate.super_computeScroll();
        }
    }

    private void scrollLayerTo(int x, int y) {
        int dx = mScrollingLayerRect.left - x;
        int dy = mScrollingLayerRect.top - y;
        if ((dx == 0 && dy == 0) || mNativeClass == 0) {
            return;
        }
        if (mSelectingText) {
            if (mSelectCursorBaseLayerId == mCurrentScrollingLayerId) {
                mSelectCursorBase.offset(dx, dy);
                mSelectCursorBaseTextQuad.offset(dx, dy);
            }
            if (mSelectCursorExtentLayerId == mCurrentScrollingLayerId) {
                mSelectCursorExtent.offset(dx, dy);
                mSelectCursorExtentTextQuad.offset(dx, dy);
            }
        }
        if (mAutoCompletePopup != null &&
                mCurrentScrollingLayerId == mEditTextLayerId) {
            mEditTextContentBounds.offset(dx, dy);
            mAutoCompletePopup.resetRect();
        }
        nativeScrollLayer(mNativeClass, mCurrentScrollingLayerId, x, y);
        mScrollingLayerRect.left = x;
        mScrollingLayerRect.top = y;
        mWebViewCore.sendMessage(WebViewCore.EventHub.SCROLL_LAYER, mCurrentScrollingLayerId,
                mScrollingLayerRect);
        mWebViewPrivate.onScrollChanged(getScrollX(), getScrollY(), getScrollX(), getScrollY());
        invalidate();
    }

    private static int computeDuration(int dx, int dy) {
        int distance = Math.max(Math.abs(dx), Math.abs(dy));
        int duration = distance * 1000 / STD_SPEED;
        return Math.min(duration, MAX_DURATION);
    }

    // helper to pin the scrollBy parameters (already in view coordinates)
    // returns true if the scroll was changed
    private boolean pinScrollBy(int dx, int dy, boolean animate, int animationDuration) {
        return pinScrollTo(getScrollX() + dx, getScrollY() + dy, animate, animationDuration);
    }
    // helper to pin the scrollTo parameters (already in view coordinates)
    // returns true if the scroll was changed
    private boolean pinScrollTo(int x, int y, boolean animate, int animationDuration) {
        abortAnimation();
        x = pinLocX(x);
        y = pinLocY(y);
        int dx = x - getScrollX();
        int dy = y - getScrollY();

        if ((dx | dy) == 0) {
            return false;
        }
        if (animate) {
            //        Log.d(LOGTAG, "startScroll: " + dx + " " + dy);
            mScroller.startScroll(getScrollX(), getScrollY(), dx, dy,
                    animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
            invalidate();
        } else {
            mWebView.scrollTo(x, y);
        }
        return true;
    }

    // Scale from content to view coordinates, and pin.
    // Also called by jni webview.cpp
    private boolean setContentScrollBy(int cx, int cy, boolean animate) {
        if (mDrawHistory) {
            // disallow WebView to change the scroll position as History Picture
            // is used in the view system.
            // TODO: as we switchOutDrawHistory when trackball or navigation
            // keys are hit, this should be safe. Right?
            return false;
        }
        cx = contentToViewDimension(cx);
        cy = contentToViewDimension(cy);
        if (mHeightCanMeasure) {
            // move our visible rect according to scroll request
            if (cy != 0) {
                Rect tempRect = new Rect();
                calcOurVisibleRect(tempRect);
                tempRect.offset(cx, cy);
                mWebView.requestRectangleOnScreen(tempRect);
            }
            // FIXME: We scroll horizontally no matter what because currently
            // ScrollView and ListView will not scroll horizontally.
            // FIXME: Why do we only scroll horizontally if there is no
            // vertical scroll?
//                Log.d(LOGTAG, "setContentScrollBy cy=" + cy);
            return cy == 0 && cx != 0 && pinScrollBy(cx, 0, animate, 0);
        } else {
            return pinScrollBy(cx, cy, animate, 0);
        }
    }

    /**
     * Called by CallbackProxy when the page starts loading.
     * @param url The URL of the page which has started loading.
     */
    /* package */ void onPageStarted(String url) {
        // every time we start a new page, we want to reset the
        // WebView certificate:  if the new site is secure, we
        // will reload it and get a new certificate set;
        // if the new site is not secure, the certificate must be
        // null, and that will be the case
        mWebView.setCertificate(null);

        if (isAccessibilityInjectionEnabled()) {
            getAccessibilityInjector().onPageStarted(url);
        }

        // Don't start out editing.
        mIsEditingText = false;
    }

    /**
     * Called by CallbackProxy when the page finishes loading.
     * @param url The URL of the page which has finished loading.
     */
    /* package */ void onPageFinished(String url) {
        mZoomManager.onPageFinished(url);

        if (isAccessibilityInjectionEnabled()) {
            getAccessibilityInjector().onPageFinished(url);
        }
    }

    // scale from content to view coordinates, and pin
    private void contentScrollTo(int cx, int cy, boolean animate) {
        if (mDrawHistory) {
            // disallow WebView to change the scroll position as History Picture
            // is used in the view system.
            return;
        }
        int vx = contentToViewX(cx);
        int vy = contentToViewY(cy);
        pinScrollTo(vx, vy, animate, 0);
    }

    /**
     * These are from webkit, and are in content coordinate system (unzoomed)
     */
    private void contentSizeChanged(boolean updateLayout) {
        // suppress 0,0 since we usually see real dimensions soon after
        // this avoids drawing the prev content in a funny place. If we find a
        // way to consolidate these notifications, this check may become
        // obsolete
        if ((mContentWidth | mContentHeight) == 0) {
            return;
        }

        if (mHeightCanMeasure) {
            if (mWebView.getMeasuredHeight() != contentToViewDimension(mContentHeight)
                    || updateLayout) {
                mWebView.requestLayout();
            }
        } else if (mWidthCanMeasure) {
            if (mWebView.getMeasuredWidth() != contentToViewDimension(mContentWidth)
                    || updateLayout) {
                mWebView.requestLayout();
            }
        } else {
            // If we don't request a layout, try to send our view size to the
            // native side to ensure that WebCore has the correct dimensions.
            sendViewSizeZoom(false);
        }
    }

    /**
     * See {@link WebView#setWebViewClient(WebViewClient)}
     */
    @Override
    public void setWebViewClient(WebViewClient client) {
        mCallbackProxy.setWebViewClient(client);
    }

    /**
     * Gets the WebViewClient
     * @return the current WebViewClient instance.
     *
     * This is an implementation detail.
     */
    public WebViewClient getWebViewClient() {
        return mCallbackProxy.getWebViewClient();
    }

    /**
     * See {@link WebView#setDownloadListener(DownloadListener)}
     */
    @Override
    public void setDownloadListener(DownloadListener listener) {
        mCallbackProxy.setDownloadListener(listener);
    }

    /**
     * See {@link WebView#setWebChromeClient(WebChromeClient)}
     */
    @Override
    public void setWebChromeClient(WebChromeClient client) {
        mCallbackProxy.setWebChromeClient(client);
    }

    /**
     * Gets the chrome handler.
     * @return the current WebChromeClient instance.
     *
     * This is an implementation detail.
     */
    public WebChromeClient getWebChromeClient() {
        return mCallbackProxy.getWebChromeClient();
    }

    /**
     * Set the back/forward list client. This is an implementation of
     * WebBackForwardListClient for handling new items and changes in the
     * history index.
     * @param client An implementation of WebBackForwardListClient.
     */
    public void setWebBackForwardListClient(WebBackForwardListClient client) {
        mCallbackProxy.setWebBackForwardListClient(client);
    }

    /**
     * Gets the WebBackForwardListClient.
     */
    public WebBackForwardListClient getWebBackForwardListClient() {
        return mCallbackProxy.getWebBackForwardListClient();
    }

    /**
     * See {@link WebView#setPictureListener(PictureListener)}
     */
    @Override
    @Deprecated
    public void setPictureListener(PictureListener listener) {
        mPictureListener = listener;
    }

    /* FIXME: Debug only! Remove for SDK! */
    public void externalRepresentation(Message callback) {
        mWebViewCore.sendMessage(EventHub.REQUEST_EXT_REPRESENTATION, callback);
    }

    /* FIXME: Debug only! Remove for SDK! */
    public void documentAsText(Message callback) {
        mWebViewCore.sendMessage(EventHub.REQUEST_DOC_AS_TEXT, callback);
    }

    /**
     * See {@link WebView#addJavascriptInterface(Object, String)}
     */
    @Override
    public void addJavascriptInterface(Object object, String name) {

        if (object == null) {
            return;
        }
        WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();

        arg.mObject = object;
        arg.mInterfaceName = name;

        // starting with JELLY_BEAN_MR1, annotations are mandatory for enabling access to
        // methods that are accessible from JS.
        if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            arg.mRequireAnnotation = true;
        } else {
            arg.mRequireAnnotation = false;
        }
        mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
    }

    /**
     * See {@link WebView#removeJavascriptInterface(String)}
     */
    @Override
    public void removeJavascriptInterface(String interfaceName) {
        if (mWebViewCore != null) {
            WebViewCore.JSInterfaceData arg = new WebViewCore.JSInterfaceData();
            arg.mInterfaceName = interfaceName;
            mWebViewCore.sendMessage(EventHub.REMOVE_JS_INTERFACE, arg);
        }
    }

    /**
     * See {@link WebView#getSettings()}
     * Note this returns WebSettingsClassic, a sub-class of WebSettings, which can be used
     * to access extension APIs.
     */
    @Override
    public WebSettingsClassic getSettings() {
        return (mWebViewCore != null) ? mWebViewCore.getSettings() : null;
    }

    /**
     * See {@link WebView#getPluginList()}
     */
    @Deprecated
    public static synchronized PluginList getPluginList() {
        return new PluginList();
    }

    /**
     * See {@link WebView#refreshPlugins(boolean)}
     */
    @Deprecated
    public void refreshPlugins(boolean reloadOpenPages) {
    }

    //-------------------------------------------------------------------------
    // Override View methods
    //-------------------------------------------------------------------------

    @Override
    protected void finalize() throws Throwable {
        try {
            destroy();
        } finally {
            super.finalize();
        }
    }

    private void drawContent(Canvas canvas) {
        if (mDrawHistory) {
            canvas.scale(mZoomManager.getScale(), mZoomManager.getScale());
            canvas.drawPicture(mHistoryPicture);
            return;
        }
        if (mNativeClass == 0) return;

        boolean animateZoom = mZoomManager.isFixedLengthAnimationInProgress();
        boolean animateScroll = ((!mScroller.isFinished()
                || mVelocityTracker != null)
                && (mTouchMode != TOUCH_DRAG_MODE ||
                mHeldMotionless != MOTIONLESS_TRUE));
        if (mTouchMode == TOUCH_DRAG_MODE) {
            if (mHeldMotionless == MOTIONLESS_PENDING) {
                mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
                mHeldMotionless = MOTIONLESS_FALSE;
            }
            if (mHeldMotionless == MOTIONLESS_FALSE) {
                mPrivateHandler.sendMessageDelayed(mPrivateHandler
                        .obtainMessage(DRAG_HELD_MOTIONLESS), MOTIONLESS_TIME);
                mHeldMotionless = MOTIONLESS_PENDING;
            }
        }
        int saveCount = canvas.save();
        if (animateZoom) {
            mZoomManager.animateZoom(canvas);
        } else if (!canvas.isHardwareAccelerated()) {
            canvas.scale(mZoomManager.getScale(), mZoomManager.getScale());
        }

        boolean UIAnimationsRunning = false;
        // Currently for each draw we compute the animation values;
        // We may in the future decide to do that independently.
        if (mNativeClass != 0 && !canvas.isHardwareAccelerated()
                && nativeEvaluateLayersAnimations(mNativeClass)) {
            UIAnimationsRunning = true;
            // If we have unfinished (or unstarted) animations,
            // we ask for a repaint. We only need to do this in software
            // rendering (with hardware rendering we already have a different
            // method of requesting a repaint)
            mWebViewCore.sendMessage(EventHub.NOTIFY_ANIMATION_STARTED);
            invalidate();
        }

        // decide which adornments to draw
        int extras = DRAW_EXTRAS_NONE;
        if (!mFindIsUp && mShowTextSelectionExtra) {
            extras = DRAW_EXTRAS_SELECTION;
        }

        calcOurContentVisibleRectF(mVisibleContentRect);
        if (canvas.isHardwareAccelerated()) {
            Rect invScreenRect = mIsWebViewVisible ? mInvScreenRect : null;
            Rect screenRect = mIsWebViewVisible ? mScreenRect : null;

            int functor = nativeCreateDrawGLFunction(mNativeClass, invScreenRect,
                    screenRect, mVisibleContentRect, getScale(), extras);
            ((HardwareCanvas) canvas).callDrawGLFunction(functor);
            if (mHardwareAccelSkia != getSettings().getHardwareAccelSkiaEnabled()) {
                mHardwareAccelSkia = getSettings().getHardwareAccelSkiaEnabled();
                nativeUseHardwareAccelSkia(mHardwareAccelSkia);
            }

        } else {
            DrawFilter df = null;
            if (mZoomManager.isZoomAnimating() || UIAnimationsRunning) {
                df = mZoomFilter;
            } else if (animateScroll) {
                df = mScrollFilter;
            }
            canvas.setDrawFilter(df);
            nativeDraw(canvas, mVisibleContentRect, mBackgroundColor, extras);
            canvas.setDrawFilter(null);
        }

        canvas.restoreToCount(saveCount);
        drawTextSelectionHandles(canvas);

        if (extras == DRAW_EXTRAS_CURSOR_RING) {
            if (mTouchMode == TOUCH_SHORTPRESS_START_MODE) {
                mTouchMode = TOUCH_SHORTPRESS_MODE;
            }
        }
    }

    /**
     * Draw the background when beyond bounds
     * @param canvas Canvas to draw into
     */
    private void drawOverScrollBackground(Canvas canvas) {
        if (mOverScrollBackground == null) {
            mOverScrollBackground = new Paint();
            Bitmap bm = BitmapFactory.decodeResource(
                    mContext.getResources(),
                    com.android.internal.R.drawable.status_bar_background);
            mOverScrollBackground.setShader(new BitmapShader(bm,
                    Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
            mOverScrollBorder = new Paint();
            mOverScrollBorder.setStyle(Paint.Style.STROKE);
            mOverScrollBorder.setStrokeWidth(0);
            mOverScrollBorder.setColor(0xffbbbbbb);
        }

        int top = 0;
        int right = computeRealHorizontalScrollRange();
        int bottom = top + computeRealVerticalScrollRange();
        // first draw the background and anchor to the top of the view
        canvas.save();
        canvas.translate(getScrollX(), getScrollY());
        canvas.clipRect(-getScrollX(), top - getScrollY(), right - getScrollX(), bottom
                - getScrollY(), Region.Op.DIFFERENCE);
        canvas.drawPaint(mOverScrollBackground);
        canvas.restore();
        // then draw the border
        canvas.drawRect(-1, top - 1, right, bottom, mOverScrollBorder);
        // next clip the region for the content
        canvas.clipRect(0, top, right, bottom);
    }

    @Override
    public void onDraw(Canvas canvas) {
        if (inFullScreenMode()) {
            return; // no need to draw anything if we aren't visible.
        }
        // if mNativeClass is 0, the WebView is either destroyed or not
        // initialized. In either case, just draw the background color and return
        if (mNativeClass == 0) {
            canvas.drawColor(mBackgroundColor);
            return;
        }

        // if both mContentWidth and mContentHeight are 0, it means there is no
        // valid Picture passed to WebView yet. This can happen when WebView
        // just starts. Draw the background and return.
        if ((mContentWidth | mContentHeight) == 0 && mHistoryPicture == null) {
            canvas.drawColor(mBackgroundColor);
            return;
        }

        if (canvas.isHardwareAccelerated()) {
            mZoomManager.setHardwareAccelerated();
        } else {
            mWebViewCore.resumeWebKitDraw();
        }

        int saveCount = canvas.save();
        if (mInOverScrollMode && !getSettings()
                .getUseWebViewBackgroundForOverscrollBackground()) {
            drawOverScrollBackground(canvas);
        }

        canvas.translate(0, getTitleHeight());
        drawContent(canvas);
        canvas.restoreToCount(saveCount);

        if (AUTO_REDRAW_HACK && mAutoRedraw) {
            invalidate();
        }
        mWebViewCore.signalRepaintDone();

        if (mOverScrollGlow != null && mOverScrollGlow.drawEdgeGlows(canvas)) {
            invalidate();
        }

        if (mFocusTransition != null) {
            mFocusTransition.draw(canvas);
        } else if (shouldDrawHighlightRect()) {
            RegionIterator iter = new RegionIterator(mTouchHighlightRegion);
            Rect r = new Rect();
            while (iter.next(r)) {
                canvas.drawRect(r, mTouchHightlightPaint);
            }
        }
        if (DEBUG_TOUCH_HIGHLIGHT) {
            if (getSettings().getNavDump()) {
                if ((mTouchHighlightX | mTouchHighlightY) != 0) {
                    if (mTouchCrossHairColor == null) {
                        mTouchCrossHairColor = new Paint();
                        mTouchCrossHairColor.setColor(Color.RED);
                    }
                    canvas.drawLine(mTouchHighlightX - mNavSlop,
                            mTouchHighlightY - mNavSlop, mTouchHighlightX
                                    + mNavSlop + 1, mTouchHighlightY + mNavSlop
                                    + 1, mTouchCrossHairColor);
                    canvas.drawLine(mTouchHighlightX + mNavSlop + 1,
                            mTouchHighlightY - mNavSlop, mTouchHighlightX
                                    - mNavSlop,
                            mTouchHighlightY + mNavSlop + 1,
                            mTouchCrossHairColor);
                }
            }
        }
    }

    private void removeTouchHighlight() {
        setTouchHighlightRects(null);
    }

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
        if (params.height == AbsoluteLayout.LayoutParams.WRAP_CONTENT) {
            mWrapContent = true;
        }
        mWebViewPrivate.super_setLayoutParams(params);
    }

    @Override
    public boolean performLongClick() {
        // performLongClick() is the result of a delayed message. If we switch
        // to windows overview, the WebView will be temporarily removed from the
        // view system. In that case, do nothing.
        if (mWebView.getParent() == null) return false;

        // A multi-finger gesture can look like a long press; make sure we don't take
        // long press actions if we're scaling.
        final ScaleGestureDetector detector = mZoomManager.getScaleGestureDetector();
        if (detector != null && detector.isInProgress()) {
            return false;
        }

        if (mSelectingText) return false; // long click does nothing on selection
        /* if long click brings up a context menu, the super function
         * returns true and we're done. Otherwise, nothing happened when
         * the user clicked. */
        if (mWebViewPrivate.super_performLongClick()) {
            return true;
        }
        /* In the case where the application hasn't already handled the long
         * click action, look for a word under the  click. If one is found,
         * animate the text selection into view.
         * FIXME: no animation code yet */
        final boolean isSelecting = selectText();
        if (isSelecting) {
            mWebView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
        } else if (focusCandidateIsEditableText()) {
            mSelectCallback = new SelectActionModeCallback();
            mSelectCallback.setWebView(this);
            mSelectCallback.setTextSelected(false);
            mWebView.startActionMode(mSelectCallback);
        }
        return isSelecting;
    }

    /**
     * Select the word at the last click point.
     *
     * This is an implementation detail.
     */
    public boolean selectText() {
        int x = viewToContentX(mLastTouchX + getScrollX());
        int y = viewToContentY(mLastTouchY + getScrollY());
        return selectText(x, y);
    }

    /**
     * Select the word at the indicated content coordinates.
     */
    boolean selectText(int x, int y) {
        if (mWebViewCore == null) {
            return false;
        }
        mWebViewCore.sendMessage(EventHub.SELECT_WORD_AT, x, y);
        return true;
    }

    private int mOrientation = Configuration.ORIENTATION_UNDEFINED;

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        mCachedOverlappingActionModeHeight = -1;
        if (mSelectingText && mOrientation != newConfig.orientation) {
            selectionDone();
        }
        mOrientation = newConfig.orientation;
        if (mWebViewCore != null && !mBlockWebkitViewMessages) {
            mWebViewCore.sendMessage(EventHub.CLEAR_CONTENT);
        }
    }

    /**
     * Keep track of the Callback so we can end its ActionMode or remove its
     * titlebar.
     */
    private SelectActionModeCallback mSelectCallback;

    void setBaseLayer(int layer, boolean showVisualIndicator,
            boolean isPictureAfterFirstLayout) {
        if (mNativeClass == 0)
            return;
        boolean queueFull;
        final int scrollingLayer = (mTouchMode == TOUCH_DRAG_LAYER_MODE)
                ? mCurrentScrollingLayerId : 0;
        queueFull = nativeSetBaseLayer(mNativeClass, layer,
                                       showVisualIndicator, isPictureAfterFirstLayout,
                                       scrollingLayer);

        if (queueFull) {
            mWebViewCore.pauseWebKitDraw();
        } else {
            mWebViewCore.resumeWebKitDraw();
        }

        if (mHTML5VideoViewProxy != null) {
            mHTML5VideoViewProxy.setBaseLayer(layer);
        }
    }

    int getBaseLayer() {
        if (mNativeClass == 0) {
            return 0;
        }
        return nativeGetBaseLayer(mNativeClass);
    }

    private void onZoomAnimationStart() {
    }

    private void onZoomAnimationEnd() {
        mPrivateHandler.sendEmptyMessage(RELOCATE_AUTO_COMPLETE_POPUP);
    }

    void onFixedLengthZoomAnimationStart() {
        WebViewCore.pauseUpdatePicture(getWebViewCore());
        onZoomAnimationStart();
    }

    void onFixedLengthZoomAnimationEnd() {
        if (!mBlockWebkitViewMessages && !mSelectingText) {
            WebViewCore.resumeUpdatePicture(mWebViewCore);
        }
        onZoomAnimationEnd();
    }

    private static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
                                         Paint.DITHER_FLAG |
                                         Paint.SUBPIXEL_TEXT_FLAG;
    private static final int SCROLL_BITS = Paint.FILTER_BITMAP_FLAG |
                                           Paint.DITHER_FLAG;

    private final DrawFilter mZoomFilter =
            new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
    // If we need to trade better quality for speed, set mScrollFilter to null
    private final DrawFilter mScrollFilter =
            new PaintFlagsDrawFilter(SCROLL_BITS, 0);

    private class SelectionHandleAlpha {
        private int mAlpha = 0;
        private int mTargetAlpha = 0;

        public void setAlpha(int alpha) {
            mAlpha = alpha;
            // TODO: Use partial invalidate
            invalidate();
        }

        public int getAlpha() {
            return mAlpha;
        }

        public void setTargetAlpha(int alpha) {
            mTargetAlpha = alpha;
        }

        public int getTargetAlpha() {
            return mTargetAlpha;
        }

    }

    private void startSelectingText() {
        mSelectingText = true;
        mShowTextSelectionExtra = true;
        animateHandles();
    }

    private void animateHandle(boolean canShow, ObjectAnimator animator,
            Point selectionPoint, int selectionLayerId,
            SelectionHandleAlpha alpha) {
        boolean isVisible = canShow && mSelectingText
                && ((mSelectionStarted && mSelectDraggingCursor == selectionPoint)
                || isHandleVisible(selectionPoint, selectionLayerId));
        int targetValue = isVisible ? 255 : 0;
        if (targetValue != alpha.getTargetAlpha()) {
            alpha.setTargetAlpha(targetValue);
            animator.setIntValues(targetValue);
            animator.setDuration(SELECTION_HANDLE_ANIMATION_MS);
            animator.start();
        }
    }

    private void animateHandles() {
        boolean canShowBase = mSelectingText;
        boolean canShowExtent = mSelectingText && !mIsCaretSelection;
        animateHandle(canShowBase, mBaseHandleAlphaAnimator, mSelectCursorBase,
                mSelectCursorBaseLayerId, mBaseAlpha);
        animateHandle(canShowExtent, mExtentHandleAlphaAnimator,
                mSelectCursorExtent, mSelectCursorExtentLayerId,
                mExtentAlpha);
    }

    private void endSelectingText() {
        mSelectingText = false;
        mShowTextSelectionExtra = false;
        animateHandles();
    }

    private void ensureSelectionHandles() {
        if (mSelectHandleCenter == null) {
            mSelectHandleCenter = mContext.getResources().getDrawable(
                    com.android.internal.R.drawable.text_select_handle_middle).mutate();
            mSelectHandleLeft = mContext.getResources().getDrawable(
                    com.android.internal.R.drawable.text_select_handle_left).mutate();
            mSelectHandleRight = mContext.getResources().getDrawable(
                    com.android.internal.R.drawable.text_select_handle_right).mutate();
            // All handles have the same height, so we can save effort with
            // this assumption.
            mSelectOffset = new Point(0,
                    -mSelectHandleLeft.getIntrinsicHeight());
        }
    }

    private void drawHandle(Point point, int handleId, Rect bounds,
            int alpha, Canvas canvas) {
        int offset;
        int width;
        int height;
        Drawable drawable;
        boolean isLeft = nativeIsHandleLeft(mNativeClass, handleId);
        if (isLeft) {
            drawable = mSelectHandleLeft;
            width = mSelectHandleLeft.getIntrinsicWidth();
            height = mSelectHandleLeft.getIntrinsicHeight();
            // Magic formula copied from TextView
            offset = (width * 3) / 4;
        } else {
            drawable = mSelectHandleRight;
            width = mSelectHandleRight.getIntrinsicWidth();
            height = mSelectHandleRight.getIntrinsicHeight();
            // Magic formula copied from TextView
            offset = width / 4;
        }
        int x = contentToViewDimension(point.x);
        int y = contentToViewDimension(point.y);
        bounds.set(x - offset, y, x - offset + width, y + height);
        drawable.setBounds(bounds);
        drawable.setAlpha(alpha);
        drawable.draw(canvas);
    }

    private void drawTextSelectionHandles(Canvas canvas) {
        if (mBaseAlpha.getAlpha() == 0 && mExtentAlpha.getAlpha() == 0) {
            return;
        }
        ensureSelectionHandles();
        if (mIsCaretSelection) {
            // Caret handle is centered
            int x = contentToViewDimension(mSelectCursorBase.x) -
                    (mSelectHandleCenter.getIntrinsicWidth() / 2);
            int y = contentToViewDimension(mSelectCursorBase.y);
            mSelectHandleBaseBounds.set(x, y,
                    x + mSelectHandleCenter.getIntrinsicWidth(),
                    y + mSelectHandleCenter.getIntrinsicHeight());
            mSelectHandleCenter.setBounds(mSelectHandleBaseBounds);
            mSelectHandleCenter.setAlpha(mBaseAlpha.getAlpha());
            mSelectHandleCenter.draw(canvas);
        } else {
            drawHandle(mSelectCursorBase, HANDLE_ID_BASE,
                    mSelectHandleBaseBounds, mBaseAlpha.getAlpha(), canvas);
            drawHandle(mSelectCursorExtent, HANDLE_ID_EXTENT,
                    mSelectHandleExtentBounds, mExtentAlpha.getAlpha(), canvas);
        }
    }

    private boolean isHandleVisible(Point selectionPoint, int layerId) {
        boolean isVisible = true;
        if (mIsEditingText) {
            isVisible = mEditTextContentBounds.contains(selectionPoint.x,
                    selectionPoint.y);
        }
        if (isVisible) {
            isVisible = nativeIsPointVisible(mNativeClass, layerId,
                    selectionPoint.x, selectionPoint.y);
        }
        return isVisible;
    }

    /**
     * Takes an int[4] array as an output param with the values being
     * startX, startY, endX, endY
     */
    private void getSelectionHandles(int[] handles) {
        handles[0] = mSelectCursorBase.x;
        handles[1] = mSelectCursorBase.y;
        handles[2] = mSelectCursorExtent.x;
        handles[3] = mSelectCursorExtent.y;
    }

    // draw history
    private boolean mDrawHistory = false;
    private Picture mHistoryPicture = null;
    private int mHistoryWidth = 0;
    private int mHistoryHeight = 0;

    // Only check the flag, can be called from WebCore thread
    boolean drawHistory() {
        return mDrawHistory;
    }

    int getHistoryPictureWidth() {
        return (mHistoryPicture != null) ? mHistoryPicture.getWidth() : 0;
    }

    // Should only be called in UI thread
    void switchOutDrawHistory() {
        if (null == mWebViewCore) return; // CallbackProxy may trigger this
        if (mDrawHistory && (getProgress() == 100 || nativeHasContent())) {
            mDrawHistory = false;
            mHistoryPicture = null;
            invalidate();
            int oldScrollX = getScrollX();
            int oldScrollY = getScrollY();
            setScrollXRaw(pinLocX(getScrollX()));
            setScrollYRaw(pinLocY(getScrollY()));
            if (oldScrollX != getScrollX() || oldScrollY != getScrollY()) {
                mWebViewPrivate.onScrollChanged(getScrollX(), getScrollY(), oldScrollX, oldScrollY);
            } else {
                sendOurVisibleRect();
            }
        }
    }

    /**
     *  Delete text from start to end in the focused textfield. If there is no
     *  focus, or if start == end, silently fail.  If start and end are out of
     *  order, swap them.
     *  @param  start   Beginning of selection to delete.
     *  @param  end     End of selection to delete.
     */
    /* package */ void deleteSelection(int start, int end) {
        mTextGeneration++;
        WebViewCore.TextSelectionData data
                = new WebViewCore.TextSelectionData(start, end, 0);
        mWebViewCore.sendMessage(EventHub.DELETE_SELECTION, mTextGeneration, 0,
                data);
    }

    /**
     *  Set the selection to (start, end) in the focused textfield. If start and
     *  end are out of order, swap them.
     *  @param  start   Beginning of selection.
     *  @param  end     End of selection.
     */
    /* package */ void setSelection(int start, int end) {
        if (mWebViewCore != null) {
            mWebViewCore.sendMessage(EventHub.SET_SELECTION, start, end);
        }
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        if (mInputConnection == null) {
            mInputConnection = new WebViewInputConnection();
            mAutoCompletePopup = new AutoCompletePopup(this, mInputConnection);
        }
        mInputConnection.setupEditorInfo(outAttrs);
        return mInputConnection;
    }

    private void relocateAutoCompletePopup() {
        if (mAutoCompletePopup != null) {
            mAutoCompletePopup.resetRect();
            mAutoCompletePopup.setText(mInputConnection.getEditable());
        }
    }

    /**
     * Called in response to a message from webkit telling us that the soft
     * keyboard should be launched.
     */
    private void displaySoftKeyboard(boolean isTextView) {
        InputMethodManager imm = (InputMethodManager)
                mContext.getSystemService(Context.INPUT_METHOD_SERVICE);

        // bring it back to the default level scale so that user can enter text
        boolean zoom = mZoomManager.getScale() < mZoomManager.getDefaultScale();
        if (zoom) {
            mZoomManager.setZoomCenter(mLastTouchX, mLastTouchY);
            mZoomManager.setZoomScale(mZoomManager.getDefaultScale(), false);
        }
        // Used by plugins and contentEditable.
        // Also used if the navigation cache is out of date, and
        // does not recognize that a textfield is in focus.  In that
        // case, use WebView as the targeted view.
        // see http://b/issue?id=2457459
        imm.showSoftInput(mWebView, 0);
    }

    // Called by WebKit to instruct the UI to hide the keyboard
    private void hideSoftKeyboard() {
        InputMethodManager imm = InputMethodManager.peekInstance();
        if (imm != null && (imm.isActive(mWebView))) {
            imm.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
        }
    }

    /**
     * Called by AutoCompletePopup to find saved form data associated with the
     * textfield
     * @param name Name of the textfield.
     * @param nodePointer Pointer to the node of the textfield, so it can be
     *          compared to the currently focused textfield when the data is
     *          retrieved.
     * @param autoFillable true if WebKit has determined this field is part of
     *          a form that can be auto filled.
     * @param autoComplete true if the attribute "autocomplete" is set to true
     *          on the textfield.
     */
    /* package */ void requestFormData(String name, int nodePointer,
            boolean autoFillable, boolean autoComplete) {
        if (mWebViewCore.getSettings().getSaveFormData()) {
            Message update = mPrivateHandler.obtainMessage(REQUEST_FORM_DATA);
            update.arg1 = nodePointer;
            RequestFormData updater = new RequestFormData(name, getUrl(),
                    update, autoFillable, autoComplete);
            Thread t = new Thread(updater);
            t.start();
        }
    }

    /*
     * This class requests an Adapter for the AutoCompletePopup which shows past
     * entries stored in the database.  It is a Runnable so that it can be done
     * in its own thread, without slowing down the UI.
     */
    private class RequestFormData implements Runnable {
        private String mName;
        private String mUrl;
        private Message mUpdateMessage;
        private boolean mAutoFillable;
        private boolean mAutoComplete;
        private WebSettingsClassic mWebSettings;

        public RequestFormData(String name, String url, Message msg,
                boolean autoFillable, boolean autoComplete) {
            mName = name;
            mUrl = WebTextView.urlForAutoCompleteData(url);
            mUpdateMessage = msg;
            mAutoFillable = autoFillable;
            mAutoComplete = autoComplete;
            mWebSettings = getSettings();
        }

        @Override
        public void run() {
            ArrayList<String> pastEntries = new ArrayList<String>();

            if (mAutoFillable) {
                // Note that code inside the adapter click handler in AutoCompletePopup depends
                // on the AutoFill item being at the top of the drop down list. If you change
                // the order, make sure to do it there too!
                if (mWebSettings != null && mWebSettings.getAutoFillProfile() != null) {
                    pastEntries.add(mWebView.getResources().getText(
                            com.android.internal.R.string.autofill_this_form).toString() +
                            " " +
                    mAutoFillData.getPreviewString());
                    mAutoCompletePopup.setIsAutoFillProfileSet(true);
                } else {
                    // There is no autofill profile set up yet, so add an option that
                    // will invite the user to set their profile up.
                    pastEntries.add(mWebView.getResources().getText(
                            com.android.internal.R.string.setup_autofill).toString());
                    mAutoCompletePopup.setIsAutoFillProfileSet(false);
                }
            }

            if (mAutoComplete) {
                pastEntries.addAll(mDatabase.getFormData(mUrl, mName));
            }

            if (pastEntries.size() > 0) {
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                        mContext,
                        com.android.internal.R.layout.web_text_view_dropdown,
                        pastEntries);
                mUpdateMessage.obj = adapter;
                mUpdateMessage.sendToTarget();
            }
        }
    }

    /**
     * Dump the display tree to "/sdcard/displayTree.txt"
     *
     * debug only
     */
    public void dumpDisplayTree() {
        nativeDumpDisplayTree(getUrl());
    }

    /**
     * Dump the dom tree to adb shell if "toFile" is False, otherwise dump it to
     * "/sdcard/domTree.txt"
     *
     * debug only
     */
    public void dumpDomTree(boolean toFile) {
        mWebViewCore.sendMessage(EventHub.DUMP_DOMTREE, toFile ? 1 : 0, 0);
    }

    /**
     * Dump the render tree to adb shell if "toFile" is False, otherwise dump it
     * to "/sdcard/renderTree.txt"
     *
     * debug only
     */
    public void dumpRenderTree(boolean toFile) {
        mWebViewCore.sendMessage(EventHub.DUMP_RENDERTREE, toFile ? 1 : 0, 0);
    }

    /**
     * Called by DRT on UI thread, need to proxy to WebCore thread.
     *
     * debug only
     */
    public void setUseMockDeviceOrientation() {
        mWebViewCore.sendMessage(EventHub.SET_USE_MOCK_DEVICE_ORIENTATION);
    }

    /**
     * Sets use of the Geolocation mock client. Also resets that client. Called
     * by DRT on UI thread, need to proxy to WebCore thread.
     *
     * debug only
     */
    public void setUseMockGeolocation() {
        mWebViewCore.sendMessage(EventHub.SET_USE_MOCK_GEOLOCATION);
    }

    /**
     * Called by DRT on WebCore thread.
     *
     * debug only
     */
    public void setMockGeolocationPosition(double latitude, double longitude, double accuracy) {
        mWebViewCore.setMockGeolocationPosition(latitude, longitude, accuracy);
    }

    /**
     * Called by DRT on WebCore thread.
     *
     * debug only
     */
    public void setMockGeolocationError(int code, String message) {
        mWebViewCore.setMockGeolocationError(code, message);
    }

    /**
     * Called by DRT on WebCore thread.
     *
     * debug only
     */
    public void setMockGeolocationPermission(boolean allow) {
        mWebViewCore.setMockGeolocationPermission(allow);
    }

    /**
     * Called by DRT on WebCore thread.
     *
     * debug only
     */
    public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
            boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
        mWebViewCore.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
                canProvideGamma, gamma);
    }

    // This is used to determine long press with the center key.  Does not
    // affect long press with the trackball/touch.
    private boolean mGotCenterDown = false;

    @Override
    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
        if (mBlockWebkitViewMessages) {
            return false;
        }
        // send complex characters to webkit for use by JS and plugins
        if (keyCode == KeyEvent.KEYCODE_UNKNOWN && event.getCharacters() != null) {
            // pass the key to DOM
            sendBatchableInputMessage(EventHub.KEY_DOWN, 0, 0, event);
            sendBatchableInputMessage(EventHub.KEY_UP, 0, 0, event);
            // return true as DOM handles the key
            return true;
        }
        return false;
    }

    private boolean isEnterActionKey(int keyCode) {
        return keyCode == KeyEvent.KEYCODE_DPAD_CENTER
                || keyCode == KeyEvent.KEYCODE_ENTER
                || keyCode == KeyEvent.KEYCODE_NUMPAD_ENTER;
    }

    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (mAutoCompletePopup != null) {
            return mAutoCompletePopup.onKeyPreIme(keyCode, event);
        }
        return false;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "keyDown at " + System.currentTimeMillis()
                    + "keyCode=" + keyCode
                    + ", " + event + ", unicode=" + event.getUnicodeChar());
        }
        if (mIsCaretSelection) {
            selectionDone();
        }
        if (mBlockWebkitViewMessages) {
            return false;
        }

        // don't implement accelerator keys here; defer to host application
        if (event.isCtrlPressed()) {
            return false;
        }

        if (mNativeClass == 0) {
            return false;
        }

        // do this hack up front, so it always works, regardless of touch-mode
        if (AUTO_REDRAW_HACK && (keyCode == KeyEvent.KEYCODE_CALL)) {
            mAutoRedraw = !mAutoRedraw;
            if (mAutoRedraw) {
                invalidate();
            }
            return true;
        }

        // Bubble up the key event if
        // 1. it is a system key; or
        // 2. the host application wants to handle it;
        if (event.isSystem()
                || mCallbackProxy.uiOverrideKeyEvent(event)) {
            return false;
        }

        // See if the accessibility injector needs to handle this event.
        if (isAccessibilityInjectionEnabled()
                && getAccessibilityInjector().handleKeyEventIfNecessary(event)) {
            return true;
        }

        if (keyCode == KeyEvent.KEYCODE_PAGE_UP) {
            if (event.hasNoModifiers()) {
                pageUp(false);
                return true;
            } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
                pageUp(true);
                return true;
            }
        }

        if (keyCode == KeyEvent.KEYCODE_PAGE_DOWN) {
            if (event.hasNoModifiers()) {
                pageDown(false);
                return true;
            } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) {
                pageDown(true);
                return true;
            }
        }

        if (keyCode == KeyEvent.KEYCODE_MOVE_HOME && event.hasNoModifiers()) {
            pageUp(true);
            return true;
        }

        if (keyCode == KeyEvent.KEYCODE_MOVE_END && event.hasNoModifiers()) {
            pageDown(true);
            return true;
        }

        if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
                && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
            switchOutDrawHistory();
        }

        if (isEnterActionKey(keyCode)) {
            switchOutDrawHistory();
            if (event.getRepeatCount() == 0) {
                if (mSelectingText) {
                    return true; // discard press if copy in progress
                }
                mGotCenterDown = true;
                mPrivateHandler.sendMessageDelayed(mPrivateHandler
                        .obtainMessage(LONG_PRESS_CENTER), LONG_PRESS_TIMEOUT);
            }
        }

        if (getSettings().getNavDump()) {
            switch (keyCode) {
                case KeyEvent.KEYCODE_4:
                    dumpDisplayTree();
                    break;
                case KeyEvent.KEYCODE_5:
                case KeyEvent.KEYCODE_6:
                    dumpDomTree(keyCode == KeyEvent.KEYCODE_5);
                    break;
                case KeyEvent.KEYCODE_7:
                case KeyEvent.KEYCODE_8:
                    dumpRenderTree(keyCode == KeyEvent.KEYCODE_7);
                    break;
            }
        }

        // pass the key to DOM
        sendKeyEvent(event);
        // return true as DOM handles the key
        return true;
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "keyUp at " + System.currentTimeMillis()
                    + ", " + event + ", unicode=" + event.getUnicodeChar());
        }
        if (mBlockWebkitViewMessages) {
            return false;
        }

        if (mNativeClass == 0) {
            return false;
        }

        // special CALL handling when cursor node's href is "tel:XXX"
        if (keyCode == KeyEvent.KEYCODE_CALL
                && mInitialHitTestResult != null
                && mInitialHitTestResult.getType() == HitTestResult.PHONE_TYPE) {
            String text = mInitialHitTestResult.getExtra();
            Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(text));
            mContext.startActivity(intent);
            return true;
        }

        // Bubble up the key event if
        // 1. it is a system key; or
        // 2. the host application wants to handle it;
        if (event.isSystem()
                || mCallbackProxy.uiOverrideKeyEvent(event)) {
            return false;
        }

        // See if the accessibility injector needs to handle this event.
        if (isAccessibilityInjectionEnabled()
                && getAccessibilityInjector().handleKeyEventIfNecessary(event)) {
            return true;
        }

        if (isEnterActionKey(keyCode)) {
            // remove the long press message first
            mPrivateHandler.removeMessages(LONG_PRESS_CENTER);
            mGotCenterDown = false;

            if (mSelectingText) {
                copySelection();
                selectionDone();
                return true; // discard press if copy in progress
            }
        }

        // pass the key to DOM
        sendKeyEvent(event);
        // return true as DOM handles the key
        return true;
    }

    private boolean startSelectActionMode() {
        mSelectCallback = new SelectActionModeCallback();
        mSelectCallback.setTextSelected(!mIsCaretSelection);
        mSelectCallback.setWebView(this);
        if (mWebView.startActionMode(mSelectCallback) == null) {
            // There is no ActionMode, so do not allow the user to modify a
            // selection.
            selectionDone();
            return false;
        }
        mWebView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
        return true;
    }

    private void showPasteWindow() {
        ClipboardManager cm = (ClipboardManager)(mContext
                .getSystemService(Context.CLIPBOARD_SERVICE));
        if (cm.hasPrimaryClip()) {
            Point cursorPoint = new Point(contentToViewX(mSelectCursorBase.x),
                    contentToViewY(mSelectCursorBase.y));
            Point cursorTop = calculateBaseCaretTop();
            cursorTop.set(contentToViewX(cursorTop.x),
                    contentToViewY(cursorTop.y));

            int[] location = new int[2];
            mWebView.getLocationInWindow(location);
            int offsetX = location[0] - getScrollX();
            int offsetY = location[1] - getScrollY();
            cursorPoint.offset(offsetX, offsetY);
            cursorTop.offset(offsetX, offsetY);
            if (mPasteWindow == null) {
                mPasteWindow = new PastePopupWindow();
            }
            mPasteWindow.show(cursorPoint, cursorTop, location[0], location[1]);
        }
    }

    /**
     * Given segment AB, this finds the point C along AB that is closest to
     * point and then returns it scale along AB. The scale factor is AC/AB.
     *
     * @param x The x coordinate of the point near segment AB that determines
     * the scale factor.
     * @param y The y coordinate of the point near segment AB that determines
     * the scale factor.
     * @param a The first point of the line segment.
     * @param b The second point of the line segment.
     * @return The scale factor AC/AB, where C is the point on AB closest to
     *         point.
     */
    private static float scaleAlongSegment(int x, int y, PointF a, PointF b) {
        // The bottom line of the text box is line AB
        float abX = b.x - a.x;
        float abY = b.y - a.y;
        float ab2 = (abX * abX) + (abY * abY);

        // The line from first point in text bounds to bottom is AP
        float apX = x - a.x;
        float apY = y - a.y;
        float abDotAP = (apX * abX) + (apY * abY);
        float scale = abDotAP / ab2;
        return scale;
    }

    private Point calculateBaseCaretTop() {
        return calculateCaretTop(mSelectCursorBase, mSelectCursorBaseTextQuad);
    }

    private Point calculateDraggingCaretTop() {
        return calculateCaretTop(mSelectDraggingCursor, mSelectDraggingTextQuad);
    }

    /**
     * Assuming arbitrary shape of a quadralateral forming text bounds, this
     * calculates the top of a caret.
     */
    private static Point calculateCaretTop(Point base, QuadF quad) {
        float scale = scaleAlongSegment(base.x, base.y, quad.p4, quad.p3);
        int x = Math.round(scaleCoordinate(scale, quad.p1.x, quad.p2.x));
        int y = Math.round(scaleCoordinate(scale, quad.p1.y, quad.p2.y));
        return new Point(x, y);
    }

    private void hidePasteButton() {
        if (mPasteWindow != null) {
            mPasteWindow.hide();
        }
    }

    private void syncSelectionCursors() {
        mSelectCursorBaseLayerId =
                nativeGetHandleLayerId(mNativeClass, HANDLE_ID_BASE,
                        mSelectCursorBase, mSelectCursorBaseTextQuad);
        mSelectCursorExtentLayerId =
                nativeGetHandleLayerId(mNativeClass, HANDLE_ID_EXTENT,
                        mSelectCursorExtent, mSelectCursorExtentTextQuad);
    }

    private boolean setupWebkitSelect() {
        syncSelectionCursors();
        if (!mIsCaretSelection && !startSelectActionMode()) {
            selectionDone();
            return false;
        }
        startSelectingText();
        mTouchMode = TOUCH_DRAG_MODE;
        return true;
    }

    private void updateWebkitSelection(boolean isSnapped) {
        int handleId = (mSelectDraggingCursor == mSelectCursorBase)
                ? HANDLE_ID_BASE : HANDLE_ID_EXTENT;
        int x = mSelectDraggingCursor.x;
        int y = mSelectDraggingCursor.y;
        if (isSnapped) {
            // "center" the cursor in the snapping quad
            Point top = calculateDraggingCaretTop();
            x = Math.round((top.x + x) / 2);
            y = Math.round((top.y + y) / 2);
        }
        mWebViewCore.removeMessages(EventHub.SELECT_TEXT);
        mWebViewCore.sendMessageAtFrontOfQueue(EventHub.SELECT_TEXT,
                x, y, (Integer)handleId);
    }

    private void resetCaretTimer() {
        mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
        if (!mSelectionStarted) {
            mPrivateHandler.sendEmptyMessageDelayed(CLEAR_CARET_HANDLE,
                    CARET_HANDLE_STAMINA_MS);
        }
    }

    /**
     * Select all of the text in this WebView.
     *
     * This is an implementation detail.
     */
    public void selectAll() {
        mWebViewCore.sendMessage(EventHub.SELECT_ALL);
    }

    /**
     * Called when the selection has been removed.
     */
    void selectionDone() {
        if (mSelectingText) {
            hidePasteButton();
            endSelectingText();
            // finish is idempotent, so this is fine even if selectionDone was
            // called by mSelectCallback.onDestroyActionMode
            if (mSelectCallback != null) {
                mSelectCallback.finish();
                mSelectCallback = null;
            }
            invalidate(); // redraw without selection
            mAutoScrollX = 0;
            mAutoScrollY = 0;
            mSentAutoScrollMessage = false;
        }
    }

    /**
     * Copy the selection to the clipboard
     *
     * This is an implementation detail.
     */
    public boolean copySelection() {
        boolean copiedSomething = false;
        String selection = getSelection();
        if (selection != null && selection != "") {
            if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "copySelection \"" + selection + "\"");
            }
            Toast.makeText(mContext
                    , com.android.internal.R.string.text_copied
                    , Toast.LENGTH_SHORT).show();
            copiedSomething = true;
            ClipboardManager cm = (ClipboardManager)mContext
                    .getSystemService(Context.CLIPBOARD_SERVICE);
            cm.setText(selection);
            int[] handles = new int[4];
            getSelectionHandles(handles);
            mWebViewCore.sendMessage(EventHub.COPY_TEXT, handles);
        }
        invalidate(); // remove selection region and pointer
        return copiedSomething;
    }

    /**
     * Cut the selected text into the clipboard
     *
     * This is an implementation detail
     */
    public void cutSelection() {
        copySelection();
        int[] handles = new int[4];
        getSelectionHandles(handles);
        mWebViewCore.sendMessage(EventHub.DELETE_TEXT, handles);
    }

    /**
     * Paste text from the clipboard to the cursor position.
     *
     * This is an implementation detail
     */
    public void pasteFromClipboard() {
        ClipboardManager cm = (ClipboardManager)mContext
                .getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clipData = cm.getPrimaryClip();
        if (clipData != null) {
            ClipData.Item clipItem = clipData.getItemAt(0);
            CharSequence pasteText = clipItem.coerceToText(mContext);
            if (mInputConnection != null) {
                mInputConnection.replaceSelection(pasteText);
            }
        }
    }

    /**
     * Returns the currently highlighted text as a string.
     */
    String getSelection() {
        if (mNativeClass == 0) return "";
        return nativeGetSelection();
    }

    @Override
    public void onAttachedToWindow() {
        if (mWebView.hasWindowFocus()) setActive(true);

        if (isAccessibilityInjectionEnabled()) {
            getAccessibilityInjector().toggleAccessibilityFeedback(true);
        }

        updateHwAccelerated();
    }

    @Override
    public void onDetachedFromWindow() {
        clearHelpers();
        mZoomManager.dismissZoomPicker();
        if (mWebView.hasWindowFocus()) setActive(false);

        if (isAccessibilityInjectionEnabled()) {
            getAccessibilityInjector().toggleAccessibilityFeedback(false);
        }

        updateHwAccelerated();

        ensureFunctorDetached();
    }

    @Override
    public void onVisibilityChanged(View changedView, int visibility) {
        // The zoomManager may be null if the webview is created from XML that
        // specifies the view's visibility param as not visible (see http://b/2794841)
        if (visibility != View.VISIBLE && mZoomManager != null) {
            mZoomManager.dismissZoomPicker();
        }
        updateDrawingState();
    }

    void setActive(boolean active) {
        if (active) {
            if (mWebView.hasFocus()) {
                // If our window regained focus, and we have focus, then begin
                // drawing the cursor ring
                mDrawCursorRing = true;
                setFocusControllerActive(true);
            } else {
                mDrawCursorRing = false;
                setFocusControllerActive(false);
            }
        } else {
            if (!mZoomManager.isZoomPickerVisible()) {
                /*
                 * The external zoom controls come in their own window, so our
                 * window loses focus. Our policy is to not draw the cursor ring
                 * if our window is not focused, but this is an exception since
                 * the user can still navigate the web page with the zoom
                 * controls showing.
                 */
                mDrawCursorRing = false;
            }
            mKeysPressed.clear();
            mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
            mTouchMode = TOUCH_DONE_MODE;
            setFocusControllerActive(false);
        }
        invalidate();
    }

    // To avoid drawing the cursor ring, and remove the TextView when our window
    // loses focus.
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        setActive(hasWindowFocus);
        if (hasWindowFocus) {
            JWebCoreJavaBridge.setActiveWebView(this);
            if (mPictureUpdatePausedForFocusChange) {
                WebViewCore.resumeUpdatePicture(mWebViewCore);
                mPictureUpdatePausedForFocusChange = false;
            }
        } else {
            JWebCoreJavaBridge.removeActiveWebView(this);
            final WebSettings settings = getSettings();
            if (settings != null && settings.enableSmoothTransition() &&
                    mWebViewCore != null && !WebViewCore.isUpdatePicturePaused(mWebViewCore)) {
                WebViewCore.pauseUpdatePicture(mWebViewCore);
                mPictureUpdatePausedForFocusChange = true;
            }
        }
    }

    /*
     * Pass a message to WebCore Thread, telling the WebCore::Page's
     * FocusController to be  "inactive" so that it will
     * not draw the blinking cursor.  It gets set to "active" to draw the cursor
     * in WebViewCore.cpp, when the WebCore thread receives key events/clicks.
     */
    /* package */ void setFocusControllerActive(boolean active) {
        if (mWebViewCore == null) return;
        mWebViewCore.sendMessage(EventHub.SET_ACTIVE, active ? 1 : 0, 0);
        // Need to send this message after the document regains focus.
        if (active && mListBoxMessage != null) {
            mWebViewCore.sendMessage(mListBoxMessage);
            mListBoxMessage = null;
        }
    }

    @Override
    public void onFocusChanged(boolean focused, int direction,
            Rect previouslyFocusedRect) {
        if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "MT focusChanged " + focused + ", " + direction);
        }
        if (focused) {
            mDrawCursorRing = true;
            setFocusControllerActive(true);
        } else {
            mDrawCursorRing = false;
            setFocusControllerActive(false);
            mKeysPressed.clear();
        }
        if (!mTouchHighlightRegion.isEmpty()) {
            mWebView.invalidate(mTouchHighlightRegion.getBounds());
        }
    }

    // updateRectsForGL() happens almost every draw call, in order to avoid creating
    // any object in this code path, we move the local variable out to be a private
    // final member, and we marked them as mTemp*.
    private final Point mTempVisibleRectOffset = new Point();
    private final Rect mTempVisibleRect = new Rect();

    void updateRectsForGL() {
        // Use the getGlobalVisibleRect() to get the intersection among the parents
        // visible == false means we're clipped - send a null rect down to indicate that
        // we should not draw
        boolean visible = mWebView.getGlobalVisibleRect(mTempVisibleRect, mTempVisibleRectOffset);
        mInvScreenRect.set(mTempVisibleRect);
        if (visible) {
            // Then need to invert the Y axis, just for GL
            View rootView = mWebView.getRootView();
            int rootViewHeight = rootView.getHeight();
            mScreenRect.set(mInvScreenRect);
            int savedWebViewBottom = mInvScreenRect.bottom;
            mInvScreenRect.bottom = rootViewHeight - mInvScreenRect.top - getVisibleTitleHeightImpl();
            mInvScreenRect.top = rootViewHeight - savedWebViewBottom;
            mIsWebViewVisible = true;
        } else {
            mIsWebViewVisible = false;
        }

        mTempVisibleRect.offset(-mTempVisibleRectOffset.x, -mTempVisibleRectOffset.y);
        viewToContentVisibleRect(mVisibleContentRect, mTempVisibleRect);

        nativeUpdateDrawGLFunction(mNativeClass, mIsWebViewVisible ? mInvScreenRect : null,
                mIsWebViewVisible ? mScreenRect : null,
                mVisibleContentRect, getScale());
    }

    // Input : viewRect, rect in view/screen coordinate.
    // Output: contentRect, rect in content/document coordinate.
    private void viewToContentVisibleRect(RectF contentRect, Rect viewRect) {
        contentRect.left = viewToContentXf(viewRect.left) / mWebView.getScaleX();
        // viewToContentY will remove the total height of the title bar.  Add
        // the visible height back in to account for the fact that if the title
        // bar is partially visible, the part of the visible rect which is
        // displaying our content is displaced by that amount.
        contentRect.top = viewToContentYf(viewRect.top + getVisibleTitleHeightImpl())
                / mWebView.getScaleY();
        contentRect.right = viewToContentXf(viewRect.right) / mWebView.getScaleX();
        contentRect.bottom = viewToContentYf(viewRect.bottom) / mWebView.getScaleY();
    }

    @Override
    public boolean setFrame(int left, int top, int right, int bottom) {
        boolean changed = mWebViewPrivate.super_setFrame(left, top, right, bottom);
        if (!changed && mHeightCanMeasure) {
            // When mHeightCanMeasure is true, we will set mLastHeightSent to 0
            // in WebViewCore after we get the first layout. We do call
            // requestLayout() when we get contentSizeChanged(). But the View
            // system won't call onSizeChanged if the dimension is not changed.
            // In this case, we need to call sendViewSizeZoom() explicitly to
            // notify the WebKit about the new dimensions.
            sendViewSizeZoom(false);
        }
        updateRectsForGL();
        return changed;
    }

    @Override
    public void onSizeChanged(int w, int h, int ow, int oh) {
        // adjust the max viewport width depending on the view dimensions. This
        // is to ensure the scaling is not going insane. So do not shrink it if
        // the view size is temporarily smaller, e.g. when soft keyboard is up.
        int newMaxViewportWidth = (int) (Math.max(w, h) / mZoomManager.getDefaultMinZoomScale());
        if (newMaxViewportWidth > sMaxViewportWidth) {
            sMaxViewportWidth = newMaxViewportWidth;
        }

        mZoomManager.onSizeChanged(w, h, ow, oh);

        if (mLoadedPicture != null && mDelaySetPicture == null) {
            // Size changes normally result in a new picture
            // Re-set the loaded picture to simulate that
            // However, do not update the base layer as that hasn't changed
            setNewPicture(mLoadedPicture, false);
        }
        if (mIsEditingText) {
            scrollEditIntoView();
        }
        relocateAutoCompletePopup();
    }

    /**
     * Scrolls the edit field into view using the minimum scrolling necessary.
     * If the edit field is too large to fit in the visible window, the caret
     * dimensions are used so that at least the caret is visible.
     * A buffer of EDIT_RECT_BUFFER in view pixels is used to offset the
     * edit rectangle to ensure a margin with the edge of the screen.
     */
    private void scrollEditIntoView() {
        Rect visibleRect = new Rect(viewToContentX(getScrollX()),
                viewToContentY(getScrollY()),
                viewToContentX(getScrollX() + getWidth()),
                viewToContentY(getScrollY() + getViewHeightWithTitle()));
        if (visibleRect.contains(mEditTextContentBounds)) {
            return; // no need to scroll
        }
        syncSelectionCursors();
        nativeFindMaxVisibleRect(mNativeClass, mEditTextLayerId, visibleRect);
        final int buffer = Math.max(1, viewToContentDimension(EDIT_RECT_BUFFER));
        Rect showRect = new Rect(
                Math.max(0, mEditTextContentBounds.left - buffer),
                Math.max(0, mEditTextContentBounds.top - buffer),
                mEditTextContentBounds.right + buffer,
                mEditTextContentBounds.bottom + buffer);
        Point caretTop = calculateBaseCaretTop();
        if (visibleRect.width() < mEditTextContentBounds.width()) {
            // The whole edit won't fit in the width, so use the caret rect
            if (mSelectCursorBase.x < caretTop.x) {
                showRect.left = Math.max(0, mSelectCursorBase.x - buffer);
                showRect.right = caretTop.x + buffer;
            } else {
                showRect.left = Math.max(0, caretTop.x - buffer);
                showRect.right = mSelectCursorBase.x + buffer;
            }
        }
        if (visibleRect.height() < mEditTextContentBounds.height()) {
            // The whole edit won't fit in the height, so use the caret rect
            if (mSelectCursorBase.y > caretTop.y) {
                showRect.top = Math.max(0, caretTop.y - buffer);
                showRect.bottom = mSelectCursorBase.y + buffer;
            } else {
                showRect.top = Math.max(0, mSelectCursorBase.y - buffer);
                showRect.bottom = caretTop.y + buffer;
            }
        }

        if (visibleRect.contains(showRect)) {
            return; // no need to scroll
        }

        int scrollX = viewToContentX(getScrollX());
        if (visibleRect.left > showRect.left) {
            // We are scrolled too far
            scrollX += showRect.left - visibleRect.left;
        } else if (visibleRect.right < showRect.right) {
            // We aren't scrolled enough to include the right
            scrollX += showRect.right - visibleRect.right;
        }
        int scrollY = viewToContentY(getScrollY());
        if (visibleRect.top > showRect.top) {
            scrollY += showRect.top - visibleRect.top;
        } else if (visibleRect.bottom < showRect.bottom) {
            scrollY += showRect.bottom - visibleRect.bottom;
        }

        contentScrollTo(scrollX, scrollY, false);
    }

    @Override
    public void onScrollChanged(int l, int t, int oldl, int oldt) {
        if (!mInOverScrollMode) {
            sendOurVisibleRect();
            // update WebKit if visible title bar height changed. The logic is same
            // as getVisibleTitleHeightImpl.
            int titleHeight = getTitleHeight();
            if (Math.max(titleHeight - t, 0) != Math.max(titleHeight - oldt, 0)) {
                sendViewSizeZoom(false);
            }
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        switch (event.getAction()) {
            case KeyEvent.ACTION_DOWN:
                mKeysPressed.add(Integer.valueOf(event.getKeyCode()));
                break;
            case KeyEvent.ACTION_MULTIPLE:
                // Always accept the action.
                break;
            case KeyEvent.ACTION_UP:
                int location = mKeysPressed.indexOf(Integer.valueOf(event.getKeyCode()));
                if (location == -1) {
                    // We did not receive the key down for this key, so do not
                    // handle the key up.
                    return false;
                } else {
                    // We did receive the key down.  Handle the key up, and
                    // remove it from our pressed keys.
                    mKeysPressed.remove(location);
                }
                break;
            default:
                // Accept the action.  This should not happen, unless a new
                // action is added to KeyEvent.
                break;
        }
        return mWebViewPrivate.super_dispatchKeyEvent(event);
    }
    
    private static final int SNAP_BOUND = 16;
    private static int sChannelDistance = 16;
    private int mFirstTouchX = -1; // the first touched point
    private int mFirstTouchY = -1;
    private int mDistanceX = 0;
    private int mDistanceY = 0;

    private boolean inFullScreenMode() {
        return mFullScreenHolder != null;
    }

    private void dismissFullScreenMode() {
        if (inFullScreenMode()) {
            mFullScreenHolder.hide();
            mFullScreenHolder = null;
            invalidate();
        }
    }

    void onPinchToZoomAnimationStart() {
        // cancel the single touch handling
        cancelTouch();
        onZoomAnimationStart();
    }

    void onPinchToZoomAnimationEnd(ScaleGestureDetector detector) {
        onZoomAnimationEnd();
        // start a drag, TOUCH_PINCH_DRAG, can't use TOUCH_INIT_MODE as
        // it may trigger the unwanted click, can't use TOUCH_DRAG_MODE
        // as it may trigger the unwanted fling.
        mTouchMode = TOUCH_PINCH_DRAG;
        mConfirmMove = true;
        startTouch(detector.getFocusX(), detector.getFocusY(), mLastTouchTime);
    }

    // See if there is a layer at x, y and switch to TOUCH_DRAG_LAYER_MODE if a
    // layer is found.
    private void startScrollingLayer(float x, float y) {
        if (mNativeClass == 0)
            return;

        int contentX = viewToContentX((int) x + getScrollX());
        int contentY = viewToContentY((int) y + getScrollY());
        mCurrentScrollingLayerId = nativeScrollableLayer(mNativeClass,
                contentX, contentY, mScrollingLayerRect, mScrollingLayerBounds);
        if (mCurrentScrollingLayerId != 0) {
            mTouchMode = TOUCH_DRAG_LAYER_MODE;
        }
    }

    // 1/(density * density) used to compute the distance between points.
    // Computed in init().
    private float DRAG_LAYER_INVERSE_DENSITY_SQUARED;

    // The distance between two points reported in onTouchEvent scaled by the
    // density of the screen.
    private static final int DRAG_LAYER_FINGER_DISTANCE = 20000;

    @Override
    public boolean onHoverEvent(MotionEvent event) {
        if (mNativeClass == 0) {
            return false;
        }
        int x = viewToContentX((int) event.getX() + getScrollX());
        int y = viewToContentY((int) event.getY() + getScrollY());
        mWebViewCore.sendMessage(EventHub.SET_MOVE_MOUSE, x, y);
        mWebViewPrivate.super_onHoverEvent(event);
        return true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mNativeClass == 0 || (!mWebView.isClickable() && !mWebView.isLongClickable())) {
            return false;
        }

        if (mInputDispatcher == null) {
            return false;
        }

        if (mWebView.isFocusable() && mWebView.isFocusableInTouchMode()
                && !mWebView.isFocused()) {
            mWebView.requestFocus();
        }

        if (mInputDispatcher.postPointerEvent(ev, getScrollX(),
                getScrollY() - getTitleHeight(), mZoomManager.getInvScale())) {
            mInputDispatcher.dispatchUiEvents();
            return true;
        } else {
            Log.w(LOGTAG, "mInputDispatcher rejected the event!");
            return false;
        }
    }

    /*
    * Common code for single touch and multi-touch.
    * (x, y) denotes current focus point, which is the touch point for single touch
    * and the middle point for multi-touch.
    */
    private void handleTouchEventCommon(MotionEvent event, int action, int x, int y) {
        ScaleGestureDetector detector = mZoomManager.getScaleGestureDetector();

        long eventTime = event.getEventTime();

        // Due to the touch screen edge effect, a touch closer to the edge
        // always snapped to the edge. As getViewWidth() can be different from
        // getWidth() due to the scrollbar, adjusting the point to match
        // getViewWidth(). Same applied to the height.
        x = Math.min(x, getViewWidth() - 1);
        y = Math.min(y, getViewHeightWithTitle() - 1);

        int deltaX = mLastTouchX - x;
        int deltaY = mLastTouchY - y;
        int contentX = viewToContentX(x + getScrollX());
        int contentY = viewToContentY(y + getScrollY());

        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                mConfirmMove = false;

                // Channel Scrolling
                mFirstTouchX = x;
                mFirstTouchY = y;
                mDistanceX = mDistanceY = 0;

                if (!mEditTextScroller.isFinished()) {
                    mEditTextScroller.abortAnimation();
                }
                if (!mScroller.isFinished()) {
                    // stop the current scroll animation, but if this is
                    // the start of a fling, allow it to add to the current
                    // fling's velocity
                    mScroller.abortAnimation();
                    mTouchMode = TOUCH_DRAG_START_MODE;
                    mConfirmMove = true;
                    nativeSetIsScrolling(false);
                } else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
                    mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
                    removeTouchHighlight();
                    if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) {
                        mTouchMode = TOUCH_DOUBLE_TAP_MODE;
                    } else {
                        mTouchMode = TOUCH_INIT_MODE;
                    }
                } else { // the normal case
                    mTouchMode = TOUCH_INIT_MODE;
                    if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
                        EventLog.writeEvent(EventLogTags.BROWSER_DOUBLE_TAP_DURATION,
                                (eventTime - mLastTouchUpTime), eventTime);
                    }
                    mSelectionStarted = false;
                    if (mSelectingText) {
                        ensureSelectionHandles();
                        int shiftedY = y - getTitleHeight() + getScrollY();
                        int shiftedX = x + getScrollX();
                        if (mSelectHandleBaseBounds.contains(shiftedX, shiftedY)) {
                            mSelectionStarted = true;
                            mSelectDraggingCursor = mSelectCursorBase;
                            mSelectDraggingTextQuad = mSelectCursorBaseTextQuad;
                            if (mIsCaretSelection) {
                                mPrivateHandler.removeMessages(CLEAR_CARET_HANDLE);
                                hidePasteButton();
                            }
                        } else if (mSelectHandleExtentBounds
                                .contains(shiftedX, shiftedY)) {
                            mSelectionStarted = true;
                            mSelectDraggingCursor = mSelectCursorExtent;
                            mSelectDraggingTextQuad = mSelectCursorExtentTextQuad;
                        } else if (mIsCaretSelection) {
                            selectionDone();
                        }
                        if (DebugFlags.WEB_VIEW) {
                            Log.v(LOGTAG, "select=" + contentX + "," + contentY);
                        }
                    }
                }
                // Trigger the link
                if (!mSelectingText && (mTouchMode == TOUCH_INIT_MODE
                        || mTouchMode == TOUCH_DOUBLE_TAP_MODE)) {
                    mPrivateHandler.sendEmptyMessageDelayed(
                            SWITCH_TO_SHORTPRESS, TAP_TIMEOUT);
                    mPrivateHandler.sendEmptyMessageDelayed(
                            SWITCH_TO_LONGPRESS, LONG_PRESS_TIMEOUT);
                }
                startTouch(x, y, eventTime);
                if (mIsEditingText) {
                    mTouchInEditText = mEditTextContentBounds
                            .contains(contentX, contentY);
                }
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                if (!mConfirmMove && (deltaX * deltaX + deltaY * deltaY)
                        >= mTouchSlopSquare) {
                    mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                    mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
                    mConfirmMove = true;
                    if (mTouchMode == TOUCH_DOUBLE_TAP_MODE) {
                        mTouchMode = TOUCH_INIT_MODE;
                    }
                    removeTouchHighlight();
                }
                if (mSelectingText && mSelectionStarted) {
                    if (DebugFlags.WEB_VIEW) {
                        Log.v(LOGTAG, "extend=" + contentX + "," + contentY);
                    }
                    ViewParent parent = mWebView.getParent();
                    if (parent != null) {
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                    if (deltaX != 0 || deltaY != 0) {
                        int handleX = contentX +
                                viewToContentDimension(mSelectOffset.x);
                        int handleY = contentY +
                                viewToContentDimension(mSelectOffset.y);
                        mSelectDraggingCursor.set(handleX, handleY);
                        boolean inCursorText =
                                mSelectDraggingTextQuad.containsPoint(handleX, handleY);
                        boolean inEditBounds = mEditTextContentBounds
                                .contains(handleX, handleY);
                        if (mIsEditingText && !inEditBounds) {
                            beginScrollEdit();
                        } else {
                            endScrollEdit();
                        }
                        boolean snapped = false;
                        if (inCursorText || (mIsEditingText && !inEditBounds)) {
                            snapDraggingCursor();
                            snapped = true;
                        }
                        updateWebkitSelection(snapped);
                        if (!inCursorText && mIsEditingText && inEditBounds) {
                            // Visually snap even if we have moved the handle.
                            snapDraggingCursor();
                        }
                        mLastTouchX = x;
                        mLastTouchY = y;
                        invalidate();
                    }
                    break;
                }

                if (mTouchMode == TOUCH_DONE_MODE) {
                    // no dragging during scroll zoom animation, or when prevent
                    // default is yes
                    break;
                }
                if (mVelocityTracker == null) {
                    Log.e(LOGTAG, "Got null mVelocityTracker when "
                            + " mTouchMode = " + mTouchMode);
                } else {
                    mVelocityTracker.addMovement(event);
                }

                if (mTouchMode != TOUCH_DRAG_MODE &&
                        mTouchMode != TOUCH_DRAG_LAYER_MODE &&
                        mTouchMode != TOUCH_DRAG_TEXT_MODE) {

                    if (!mConfirmMove) {
                        break;
                    }

                    if ((detector == null || !detector.isInProgress())
                            && SNAP_NONE == mSnapScrollMode) {
                        int ax = Math.abs(x - mFirstTouchX);
                        int ay = Math.abs(y - mFirstTouchY);
                        if (ax < SNAP_BOUND && ay < SNAP_BOUND) {
                            break;
                        } else if (ax < SNAP_BOUND) {
                            mSnapScrollMode = SNAP_Y;
                        } else if (ay < SNAP_BOUND) {
                            mSnapScrollMode = SNAP_X;
                        }
                    }

                    mTouchMode = TOUCH_DRAG_MODE;
                    mLastTouchX = x;
                    mLastTouchY = y;
                    deltaX = 0;
                    deltaY = 0;

                    startScrollingLayer(x, y);
                    startDrag();
                }

                // do pan
                boolean keepScrollBarsVisible = false;
                if (deltaX == 0 && deltaY == 0) {
                    keepScrollBarsVisible = true;
                } else {
                    if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
                        mDistanceX += Math.abs(deltaX);
                        mDistanceY += Math.abs(deltaY);
                        if (mSnapScrollMode == SNAP_X) {
                            if (mDistanceY > sChannelDistance) {
                                mSnapScrollMode = SNAP_NONE;
                            } else if (mDistanceX > sChannelDistance) {
                                mDistanceX = mDistanceY = 0;
                        }
                    } else {
                            if (mDistanceX > sChannelDistance) {
                                mSnapScrollMode = SNAP_NONE;
                            } else if (mDistanceY > sChannelDistance) {
                                mDistanceX = mDistanceY = 0;
                            }
                        }
                    }
                    if (mSnapScrollMode != SNAP_NONE) {
                        if ((mSnapScrollMode & SNAP_X) == SNAP_X) {
                            deltaY = 0;
                        } else {
                            deltaX = 0;
                        }
                    }
                    if (deltaX * deltaX + deltaY * deltaY > mTouchSlopSquare) {
                        mHeldMotionless = MOTIONLESS_FALSE;
                    } else {
                        mHeldMotionless = MOTIONLESS_TRUE;
                        keepScrollBarsVisible = true;
                    }

                    mLastTouchTime = eventTime;
                    boolean allDrag = doDrag(deltaX, deltaY);
                    if (allDrag) {
                        mLastTouchX = x;
                        mLastTouchY = y;
                    } else {
                        int contentDeltaX = (int)Math.floor(deltaX * mZoomManager.getInvScale());
                        int roundedDeltaX = contentToViewDimension(contentDeltaX);
                        int contentDeltaY = (int)Math.floor(deltaY * mZoomManager.getInvScale());
                        int roundedDeltaY = contentToViewDimension(contentDeltaY);
                        mLastTouchX -= roundedDeltaX;
                        mLastTouchY -= roundedDeltaY;
                    }
                }

                break;
            }
            case MotionEvent.ACTION_UP: {
                mFirstTouchX  = mFirstTouchY = -1;
                if (mIsEditingText && mSelectionStarted) {
                    endScrollEdit();
                    mPrivateHandler.sendEmptyMessageDelayed(SCROLL_HANDLE_INTO_VIEW,
                            TEXT_SCROLL_FIRST_SCROLL_MS);
                    if (!mConfirmMove && mIsCaretSelection) {
                        showPasteWindow();
                        stopTouch();
                        break;
                    }
                }
                mLastTouchUpTime = eventTime;
                if (mSentAutoScrollMessage) {
                    mAutoScrollX = mAutoScrollY = 0;
                }
                switch (mTouchMode) {
                    case TOUCH_DOUBLE_TAP_MODE: // double tap
                        mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                        mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
                        mTouchMode = TOUCH_DONE_MODE;
                        break;
                    case TOUCH_INIT_MODE: // tap
                    case TOUCH_SHORTPRESS_START_MODE:
                    case TOUCH_SHORTPRESS_MODE:
                        mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                        mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
                        if (!mConfirmMove) {
                            if (mSelectingText) {
                                // tapping on selection or controls does nothing
                                if (!mSelectionStarted) {
                                    selectionDone();
                                }
                                break;
                            }
                            // only trigger double tap if the WebView is
                            // scalable
                            if (mTouchMode == TOUCH_INIT_MODE
                                    && (canZoomIn() || canZoomOut())) {
                                mPrivateHandler.sendEmptyMessageDelayed(
                                        RELEASE_SINGLE_TAP, ViewConfiguration
                                                .getDoubleTapTimeout());
                            }
                            break;
                        }
                    case TOUCH_DRAG_MODE:
                    case TOUCH_DRAG_LAYER_MODE:
                    case TOUCH_DRAG_TEXT_MODE:
                        mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
                        // if the user waits a while w/o moving before the
                        // up, we don't want to do a fling
                        if (eventTime - mLastTouchTime <= MIN_FLING_TIME) {
                            if (mVelocityTracker == null) {
                                Log.e(LOGTAG, "Got null mVelocityTracker");
                            } else {
                                mVelocityTracker.addMovement(event);
                            }
                            // set to MOTIONLESS_IGNORE so that it won't keep
                            // removing and sending message in
                            // drawCoreAndCursorRing()
                            mHeldMotionless = MOTIONLESS_IGNORE;
                            doFling();
                            break;
                        } else {
                            if (mScroller.springBack(getScrollX(), getScrollY(), 0,
                                    computeMaxScrollX(), 0,
                                    computeMaxScrollY())) {
                                invalidate();
                            }
                        }
                        // redraw in high-quality, as we're done dragging
                        mHeldMotionless = MOTIONLESS_TRUE;
                        invalidate();
                        // fall through
                    case TOUCH_DRAG_START_MODE:
                        // TOUCH_DRAG_START_MODE should not happen for the real
                        // device as we almost certain will get a MOVE. But this
                        // is possible on emulator.
                        mLastVelocity = 0;
                        WebViewCore.resumePriority();
                        if (!mSelectingText) {
                            WebViewCore.resumeUpdatePicture(mWebViewCore);
                        }
                        break;
                }
                stopTouch();
                break;
            }
            case MotionEvent.ACTION_CANCEL: {
                if (mTouchMode == TOUCH_DRAG_MODE) {
                    mScroller.springBack(getScrollX(), getScrollY(), 0,
                            computeMaxScrollX(), 0, computeMaxScrollY());
                    invalidate();
                }
                cancelTouch();
                break;
            }
        }
    }

    /**
     * Returns the text scroll speed in content pixels per millisecond based on
     * the touch location.
     * @param coordinate The x or y touch coordinate in content space
     * @param min The minimum coordinate (x or y) of the edit content bounds
     * @param max The maximum coordinate (x or y) of the edit content bounds
     */
    private static float getTextScrollSpeed(int coordinate, int min, int max) {
        if (coordinate < min) {
            return (coordinate - min) * TEXT_SCROLL_RATE;
        } else if (coordinate >= max) {
            return (coordinate - max + 1) * TEXT_SCROLL_RATE;
        } else {
            return 0.0f;
        }
    }

    private static int getSelectionCoordinate(int coordinate, int min, int max) {
        return Math.max(Math.min(coordinate, max), min);
    }

    private void beginScrollEdit() {
        if (mLastEditScroll == 0) {
            mLastEditScroll = SystemClock.uptimeMillis() -
                    TEXT_SCROLL_FIRST_SCROLL_MS;
            scrollEditWithCursor();
        }
    }

    private void scrollDraggedSelectionHandleIntoView() {
        if (mSelectDraggingCursor == null) {
            return;
        }
        int x = mSelectDraggingCursor.x;
        int y = mSelectDraggingCursor.y;
        if (!mEditTextContentBounds.contains(x,y)) {
            int left = Math.min(0, x - mEditTextContentBounds.left - EDIT_RECT_BUFFER);
            int right = Math.max(0, x - mEditTextContentBounds.right + EDIT_RECT_BUFFER);
            int deltaX = left + right;
            int above = Math.min(0, y - mEditTextContentBounds.top - EDIT_RECT_BUFFER);
            int below = Math.max(0, y - mEditTextContentBounds.bottom + EDIT_RECT_BUFFER);
            int deltaY = above + below;
            if (deltaX != 0 || deltaY != 0) {
                int scrollX = getTextScrollX() + deltaX;
                int scrollY = getTextScrollY() + deltaY;
                scrollX = clampBetween(scrollX, 0, getMaxTextScrollX());
                scrollY = clampBetween(scrollY, 0, getMaxTextScrollY());
                scrollEditText(scrollX, scrollY);
            }
        }
    }

    private void endScrollEdit() {
        mLastEditScroll = 0;
    }

    private static int clampBetween(int value, int min, int max) {
        return Math.max(min, Math.min(value, max));
    }

    private static int getTextScrollDelta(float speed, long deltaT) {
        float distance = speed * deltaT;
        int intDistance = (int)Math.floor(distance);
        float probability = distance - intDistance;
        if (Math.random() < probability) {
            intDistance++;
        }
        return intDistance;
    }
    /**
     * Scrolls edit text a distance based on the last touch point,
     * the last scroll time, and the edit text content bounds.
     */
    private void scrollEditWithCursor() {
        if (mLastEditScroll != 0) {
            int x = viewToContentX(mLastTouchX + getScrollX() + mSelectOffset.x);
            float scrollSpeedX = getTextScrollSpeed(x, mEditTextContentBounds.left,
                    mEditTextContentBounds.right);
            int y = viewToContentY(mLastTouchY + getScrollY() + mSelectOffset.y);
            float scrollSpeedY = getTextScrollSpeed(y, mEditTextContentBounds.top,
                    mEditTextContentBounds.bottom);
            if (scrollSpeedX == 0.0f && scrollSpeedY == 0.0f) {
                endScrollEdit();
            } else {
                long currentTime = SystemClock.uptimeMillis();
                long timeSinceLastUpdate = currentTime - mLastEditScroll;
                int deltaX = getTextScrollDelta(scrollSpeedX, timeSinceLastUpdate);
                int deltaY = getTextScrollDelta(scrollSpeedY, timeSinceLastUpdate);
                int scrollX = getTextScrollX() + deltaX;
                scrollX = clampBetween(scrollX, 0, getMaxTextScrollX());
                int scrollY = getTextScrollY() + deltaY;
                scrollY = clampBetween(scrollY, 0, getMaxTextScrollY());

                mLastEditScroll = currentTime;
                if (scrollX == getTextScrollX() && scrollY == getTextScrollY()) {
                    // By probability no text scroll this time. Try again later.
                    mPrivateHandler.sendEmptyMessageDelayed(SCROLL_EDIT_TEXT,
                            TEXT_SCROLL_FIRST_SCROLL_MS);
                } else {
                    int selectionX = getSelectionCoordinate(x,
                            mEditTextContentBounds.left, mEditTextContentBounds.right);
                    int selectionY = getSelectionCoordinate(y,
                            mEditTextContentBounds.top, mEditTextContentBounds.bottom);
                    int oldX = mSelectDraggingCursor.x;
                    int oldY = mSelectDraggingCursor.y;
                    mSelectDraggingCursor.set(selectionX, selectionY);
                    updateWebkitSelection(false);
                    scrollEditText(scrollX, scrollY);
                    mSelectDraggingCursor.set(oldX, oldY);
                }
            }
        }
    }

    private void startTouch(float x, float y, long eventTime) {
        // Remember where the motion event started
        mStartTouchX = mLastTouchX = Math.round(x);
        mStartTouchY = mLastTouchY = Math.round(y);
        mLastTouchTime = eventTime;
        mVelocityTracker = VelocityTracker.obtain();
        mSnapScrollMode = SNAP_NONE;
    }

    private void startDrag() {
        WebViewCore.reducePriority();
        // to get better performance, pause updating the picture
        WebViewCore.pauseUpdatePicture(mWebViewCore);
        nativeSetIsScrolling(true);

        if (mHorizontalScrollBarMode != SCROLLBAR_ALWAYSOFF
                || mVerticalScrollBarMode != SCROLLBAR_ALWAYSOFF) {
            mZoomManager.invokeZoomPicker();
        }
    }

    private boolean doDrag(int deltaX, int deltaY) {
        boolean allDrag = true;
        if ((deltaX | deltaY) != 0) {
            int oldX = getScrollX();
            int oldY = getScrollY();
            int rangeX = computeMaxScrollX();
            int rangeY = computeMaxScrollY();
            final int contentX = (int)Math.floor(deltaX * mZoomManager.getInvScale());
            final int contentY = (int)Math.floor(deltaY * mZoomManager.getInvScale());

            // Assume page scrolling and change below if we're wrong
            mTouchMode = TOUCH_DRAG_MODE;

            // Check special scrolling before going to main page scrolling.
            if (mIsEditingText && mTouchInEditText && canTextScroll(deltaX, deltaY)) {
                // Edit text scrolling
                oldX = getTextScrollX();
                rangeX = getMaxTextScrollX();
                deltaX = contentX;
                oldY = getTextScrollY();
                rangeY = getMaxTextScrollY();
                deltaY = contentY;
                mTouchMode = TOUCH_DRAG_TEXT_MODE;
                allDrag = false;
            } else if (mCurrentScrollingLayerId != 0) {
                // Check the scrolling bounds to see if we will actually do any
                // scrolling.  The rectangle is in document coordinates.
                final int maxX = mScrollingLayerRect.right;
                final int maxY = mScrollingLayerRect.bottom;
                final int resultX = clampBetween(maxX, 0,
                        mScrollingLayerRect.left + contentX);
                final int resultY = clampBetween(maxY, 0,
                        mScrollingLayerRect.top + contentY);

                if (resultX != mScrollingLayerRect.left
                        || resultY != mScrollingLayerRect.top
                        || (contentX | contentY) == 0) {
                    // In case we switched to dragging the page.
                    mTouchMode = TOUCH_DRAG_LAYER_MODE;
                    deltaX = contentX;
                    deltaY = contentY;
                    oldX = mScrollingLayerRect.left;
                    oldY = mScrollingLayerRect.top;
                    rangeX = maxX;
                    rangeY = maxY;
                    allDrag = false;
                }
            }

            if (mOverScrollGlow != null) {
                mOverScrollGlow.setOverScrollDeltas(deltaX, deltaY);
            }

            mWebViewPrivate.overScrollBy(deltaX, deltaY, oldX, oldY,
                    rangeX, rangeY,
                    mOverscrollDistance, mOverscrollDistance, true);
            if (mOverScrollGlow != null && mOverScrollGlow.isAnimating()) {
                invalidate();
            }
        }
        mZoomManager.keepZoomPickerVisible();
        return allDrag;
    }

    private void stopTouch() {
        if (mScroller.isFinished() && !mSelectingText
                && (mTouchMode == TOUCH_DRAG_MODE
                || mTouchMode == TOUCH_DRAG_LAYER_MODE)) {
            WebViewCore.resumePriority();
            WebViewCore.resumeUpdatePicture(mWebViewCore);
            nativeSetIsScrolling(false);
        }

        // we also use mVelocityTracker == null to tell us that we are
        // not "moving around", so we can take the slower/prettier
        // mode in the drawing code
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }

        // Release any pulled glows
        if (mOverScrollGlow != null) {
            mOverScrollGlow.releaseAll();
        }

        if (mSelectingText) {
            mSelectionStarted = false;
            syncSelectionCursors();
            if (mIsCaretSelection) {
                resetCaretTimer();
            }
            invalidate();
        }
    }

    private void cancelTouch() {
        // we also use mVelocityTracker == null to tell us that we are
        // not "moving around", so we can take the slower/prettier
        // mode in the drawing code
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }

        if ((mTouchMode == TOUCH_DRAG_MODE
                || mTouchMode == TOUCH_DRAG_LAYER_MODE) && !mSelectingText) {
            WebViewCore.resumePriority();
            WebViewCore.resumeUpdatePicture(mWebViewCore);
            nativeSetIsScrolling(false);
        }
        mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
        mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
        mPrivateHandler.removeMessages(DRAG_HELD_MOTIONLESS);
        removeTouchHighlight();
        mHeldMotionless = MOTIONLESS_TRUE;
        mTouchMode = TOUCH_DONE_MODE;
    }

    private void snapDraggingCursor() {
        float scale = scaleAlongSegment(
                mSelectDraggingCursor.x, mSelectDraggingCursor.y,
                mSelectDraggingTextQuad.p4, mSelectDraggingTextQuad.p3);
        // clamp scale to ensure point is on the bottom segment
        scale = Math.max(0.0f, scale);
        scale = Math.min(scale, 1.0f);
        float newX = scaleCoordinate(scale,
                mSelectDraggingTextQuad.p4.x, mSelectDraggingTextQuad.p3.x);
        float newY = scaleCoordinate(scale,
                mSelectDraggingTextQuad.p4.y, mSelectDraggingTextQuad.p3.y);
        int x = Math.round(newX);
        int y = Math.round(newY);
        if (mIsEditingText) {
            x = clampBetween(x, mEditTextContentBounds.left,
                    mEditTextContentBounds.right);
            y = clampBetween(y, mEditTextContentBounds.top,
                    mEditTextContentBounds.bottom);
        }
        mSelectDraggingCursor.set(x, y);
    }

    private static float scaleCoordinate(float scale, float coord1, float coord2) {
        float diff = coord2 - coord1;
        return coord1 + (scale * diff);
    }

    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_SCROLL: {
                    final float vscroll;
                    final float hscroll;
                    if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
                        vscroll = 0;
                        hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
                    } else {
                        vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
                        hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
                    }
                    if (hscroll != 0 || vscroll != 0) {
                        final int vdelta = (int) (vscroll *
                                mWebViewPrivate.getVerticalScrollFactor());
                        final int hdelta = (int) (hscroll *
                                mWebViewPrivate.getHorizontalScrollFactor());

                        abortAnimation();
                        int oldTouchMode = mTouchMode;
                        startScrollingLayer(event.getX(), event.getY());
                        doDrag(hdelta, vdelta);
                        mTouchMode = oldTouchMode;
                        return true;
                    }
                }
            }
        }
        return mWebViewPrivate.super_onGenericMotionEvent(event);
    }

    private long mTrackballFirstTime = 0;
    private long mTrackballLastTime = 0;
    private float mTrackballRemainsX = 0.0f;
    private float mTrackballRemainsY = 0.0f;
    private int mTrackballXMove = 0;
    private int mTrackballYMove = 0;
    private boolean mSelectingText = false;
    private boolean mShowTextSelectionExtra = false;
    private boolean mSelectionStarted = false;
    private static final int TRACKBALL_KEY_TIMEOUT = 1000;
    private static final int TRACKBALL_TIMEOUT = 200;
    private static final int TRACKBALL_WAIT = 100;
    private static final int TRACKBALL_SCALE = 400;
    private static final int TRACKBALL_SCROLL_COUNT = 5;
    private static final int TRACKBALL_MOVE_COUNT = 10;
    private static final int TRACKBALL_MULTIPLIER = 3;
    private static final int SELECT_CURSOR_OFFSET = 16;
    private static final int SELECT_SCROLL = 5;
    private int mSelectX = 0;
    private int mSelectY = 0;
    private boolean mTrackballDown = false;
    private long mTrackballUpTime = 0;
    private long mLastCursorTime = 0;
    private Rect mLastCursorBounds;
    private SelectionHandleAlpha mBaseAlpha = new SelectionHandleAlpha();
    private SelectionHandleAlpha mExtentAlpha = new SelectionHandleAlpha();
    private ObjectAnimator mBaseHandleAlphaAnimator =
            ObjectAnimator.ofInt(mBaseAlpha, "alpha", 0);
    private ObjectAnimator mExtentHandleAlphaAnimator =
            ObjectAnimator.ofInt(mExtentAlpha, "alpha", 0);

    // Set by default; BrowserActivity clears to interpret trackball data
    // directly for movement. Currently, the framework only passes
    // arrow key events, not trackball events, from one child to the next
    private boolean mMapTrackballToArrowKeys = true;

    private DrawData mDelaySetPicture;
    private DrawData mLoadedPicture;

    @Override
    public void setMapTrackballToArrowKeys(boolean setMap) {
        mMapTrackballToArrowKeys = setMap;
    }

    void resetTrackballTime() {
        mTrackballLastTime = 0;
    }

    @Override
    public boolean onTrackballEvent(MotionEvent ev) {
        long time = ev.getEventTime();
        if ((ev.getMetaState() & KeyEvent.META_ALT_ON) != 0) {
            if (ev.getY() > 0) pageDown(true);
            if (ev.getY() < 0) pageUp(true);
            return true;
        }
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            if (mSelectingText) {
                return true; // discard press if copy in progress
            }
            mTrackballDown = true;
            if (mNativeClass == 0) {
                return false;
            }
            if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "onTrackballEvent down ev=" + ev
                        + " time=" + time
                        + " mLastCursorTime=" + mLastCursorTime);
            }
            if (mWebView.isInTouchMode()) mWebView.requestFocusFromTouch();
            return false; // let common code in onKeyDown at it
        }
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            // LONG_PRESS_CENTER is set in common onKeyDown
            mPrivateHandler.removeMessages(LONG_PRESS_CENTER);
            mTrackballDown = false;
            mTrackballUpTime = time;
            if (mSelectingText) {
                copySelection();
                selectionDone();
                return true; // discard press if copy in progress
            }
            if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "onTrackballEvent up ev=" + ev
                        + " time=" + time
                );
            }
            return false; // let common code in onKeyUp at it
        }
        if ((mMapTrackballToArrowKeys && (ev.getMetaState() & KeyEvent.META_SHIFT_ON) == 0) ||
                AccessibilityManager.getInstance(mContext).isEnabled()) {
            if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent gmail quit");
            return false;
        }
        if (mTrackballDown) {
            if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent down quit");
            return true; // discard move if trackball is down
        }
        if (time - mTrackballUpTime < TRACKBALL_TIMEOUT) {
            if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent up timeout quit");
            return true;
        }
        // TODO: alternatively we can do panning as touch does
        switchOutDrawHistory();
        if (time - mTrackballLastTime > TRACKBALL_TIMEOUT) {
            if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "onTrackballEvent time="
                        + time + " last=" + mTrackballLastTime);
            }
            mTrackballFirstTime = time;
            mTrackballXMove = mTrackballYMove = 0;
        }
        mTrackballLastTime = time;
        if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "onTrackballEvent ev=" + ev + " time=" + time);
        }
        mTrackballRemainsX += ev.getX();
        mTrackballRemainsY += ev.getY();
        doTrackball(time, ev.getMetaState());
        return true;
    }

    private int scaleTrackballX(float xRate, int width) {
        int xMove = (int) (xRate / TRACKBALL_SCALE * width);
        int nextXMove = xMove;
        if (xMove > 0) {
            if (xMove > mTrackballXMove) {
                xMove -= mTrackballXMove;
            }
        } else if (xMove < mTrackballXMove) {
            xMove -= mTrackballXMove;
        }
        mTrackballXMove = nextXMove;
        return xMove;
    }

    private int scaleTrackballY(float yRate, int height) {
        int yMove = (int) (yRate / TRACKBALL_SCALE * height);
        int nextYMove = yMove;
        if (yMove > 0) {
            if (yMove > mTrackballYMove) {
                yMove -= mTrackballYMove;
            }
        } else if (yMove < mTrackballYMove) {
            yMove -= mTrackballYMove;
        }
        mTrackballYMove = nextYMove;
        return yMove;
    }

    private int keyCodeToSoundsEffect(int keyCode) {
        switch(keyCode) {
            case KeyEvent.KEYCODE_DPAD_UP:
                return SoundEffectConstants.NAVIGATION_UP;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                return SoundEffectConstants.NAVIGATION_RIGHT;
            case KeyEvent.KEYCODE_DPAD_DOWN:
                return SoundEffectConstants.NAVIGATION_DOWN;
            case KeyEvent.KEYCODE_DPAD_LEFT:
                return SoundEffectConstants.NAVIGATION_LEFT;
        }
        return 0;
    }

    private void doTrackball(long time, int metaState) {
        int elapsed = (int) (mTrackballLastTime - mTrackballFirstTime);
        if (elapsed == 0) {
            elapsed = TRACKBALL_TIMEOUT;
        }
        float xRate = mTrackballRemainsX * 1000 / elapsed;
        float yRate = mTrackballRemainsY * 1000 / elapsed;
        int viewWidth = getViewWidth();
        int viewHeight = getViewHeight();
        float ax = Math.abs(xRate);
        float ay = Math.abs(yRate);
        float maxA = Math.max(ax, ay);
        if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "doTrackball elapsed=" + elapsed
                    + " xRate=" + xRate
                    + " yRate=" + yRate
                    + " mTrackballRemainsX=" + mTrackballRemainsX
                    + " mTrackballRemainsY=" + mTrackballRemainsY);
        }
        int width = mContentWidth - viewWidth;
        int height = mContentHeight - viewHeight;
        if (width < 0) width = 0;
        if (height < 0) height = 0;
        ax = Math.abs(mTrackballRemainsX * TRACKBALL_MULTIPLIER);
        ay = Math.abs(mTrackballRemainsY * TRACKBALL_MULTIPLIER);
        maxA = Math.max(ax, ay);
        int count = Math.max(0, (int) maxA);
        int oldScrollX = getScrollX();
        int oldScrollY = getScrollY();
        if (count > 0) {
            int selectKeyCode = ax < ay ? mTrackballRemainsY < 0 ?
                    KeyEvent.KEYCODE_DPAD_UP : KeyEvent.KEYCODE_DPAD_DOWN :
                    mTrackballRemainsX < 0 ? KeyEvent.KEYCODE_DPAD_LEFT :
                    KeyEvent.KEYCODE_DPAD_RIGHT;
            count = Math.min(count, TRACKBALL_MOVE_COUNT);
            if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "doTrackball keyCode=" + selectKeyCode
                        + " count=" + count
                        + " mTrackballRemainsX=" + mTrackballRemainsX
                        + " mTrackballRemainsY=" + mTrackballRemainsY);
            }
            if (mNativeClass != 0) {
                for (int i = 0; i < count; i++) {
                    letPageHandleNavKey(selectKeyCode, time, true, metaState);
                }
                letPageHandleNavKey(selectKeyCode, time, false, metaState);
            }
            mTrackballRemainsX = mTrackballRemainsY = 0;
        }
        if (count >= TRACKBALL_SCROLL_COUNT) {
            int xMove = scaleTrackballX(xRate, width);
            int yMove = scaleTrackballY(yRate, height);
            if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "doTrackball pinScrollBy"
                        + " count=" + count
                        + " xMove=" + xMove + " yMove=" + yMove
                        + " mScrollX-oldScrollX=" + (getScrollX()-oldScrollX)
                        + " mScrollY-oldScrollY=" + (getScrollY()-oldScrollY)
                        );
            }
            if (Math.abs(getScrollX() - oldScrollX) > Math.abs(xMove)) {
                xMove = 0;
            }
            if (Math.abs(getScrollY() - oldScrollY) > Math.abs(yMove)) {
                yMove = 0;
            }
            if (xMove != 0 || yMove != 0) {
                pinScrollBy(xMove, yMove, true, 0);
            }
        }
    }

    /**
     * Compute the maximum horizontal scroll position. Used by {@link OverScrollGlow}.
     * @return Maximum horizontal scroll position within real content
     */
    int computeMaxScrollX() {
        return Math.max(computeRealHorizontalScrollRange() - getViewWidth(), 0);
    }

    /**
     * Compute the maximum vertical scroll position. Used by {@link OverScrollGlow}.
     * @return Maximum vertical scroll position within real content
     */
    int computeMaxScrollY() {
        return Math.max(computeRealVerticalScrollRange() + getTitleHeight()
                - getViewHeightWithTitle(), 0);
    }

    boolean updateScrollCoordinates(int x, int y) {
        int oldX = getScrollX();
        int oldY = getScrollY();
        setScrollXRaw(x);
        setScrollYRaw(y);
        if (oldX != getScrollX() || oldY != getScrollY()) {
            mWebViewPrivate.onScrollChanged(getScrollX(), getScrollY(), oldX, oldY);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void flingScroll(int vx, int vy) {
        mScroller.fling(getScrollX(), getScrollY(), vx, vy, 0, computeMaxScrollX(), 0,
                computeMaxScrollY(), mOverflingDistance, mOverflingDistance);
        invalidate();
    }

    private void doFling() {
        if (mVelocityTracker == null) {
            return;
        }
        int maxX = computeMaxScrollX();
        int maxY = computeMaxScrollY();

        mVelocityTracker.computeCurrentVelocity(1000, mMaximumFling);
        int vx = (int) mVelocityTracker.getXVelocity();
        int vy = (int) mVelocityTracker.getYVelocity();

        int scrollX = getScrollX();
        int scrollY = getScrollY();
        int overscrollDistance = mOverscrollDistance;
        int overflingDistance = mOverflingDistance;

        // Use the layer's scroll data if applicable.
        if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
            scrollX = mScrollingLayerRect.left;
            scrollY = mScrollingLayerRect.top;
            maxX = mScrollingLayerRect.right;
            maxY = mScrollingLayerRect.bottom;
            // No overscrolling for layers.
            overscrollDistance = overflingDistance = 0;
        } else if (mTouchMode == TOUCH_DRAG_TEXT_MODE) {
            scrollX = getTextScrollX();
            scrollY = getTextScrollY();
            maxX = getMaxTextScrollX();
            maxY = getMaxTextScrollY();
            // No overscrolling for edit text.
            overscrollDistance = overflingDistance = 0;
        }

        if (mSnapScrollMode != SNAP_NONE) {
            if ((mSnapScrollMode & SNAP_X) == SNAP_X) {
                vy = 0;
            } else {
                vx = 0;
            }
        }
        if ((maxX == 0 && vy == 0) || (maxY == 0 && vx == 0)) {
            WebViewCore.resumePriority();
            if (!mSelectingText) {
                WebViewCore.resumeUpdatePicture(mWebViewCore);
            }
            if (mScroller.springBack(scrollX, scrollY, 0, maxX, 0, maxY)) {
                invalidate();
            }
            return;
        }
        float currentVelocity = mScroller.getCurrVelocity();
        float velocity = (float) Math.hypot(vx, vy);
        if (mLastVelocity > 0 && currentVelocity > 0 && velocity
                > mLastVelocity * MINIMUM_VELOCITY_RATIO_FOR_ACCELERATION) {
            float deltaR = (float) (Math.abs(Math.atan2(mLastVelY, mLastVelX)
                    - Math.atan2(vy, vx)));
            final float circle = (float) (Math.PI) * 2.0f;
            if (deltaR > circle * 0.9f || deltaR < circle * 0.1f) {
                vx += currentVelocity * mLastVelX / mLastVelocity;
                vy += currentVelocity * mLastVelY / mLastVelocity;
                velocity = (float) Math.hypot(vx, vy);
                if (DebugFlags.WEB_VIEW) {
                    Log.v(LOGTAG, "doFling vx= " + vx + " vy=" + vy);
                }
            } else if (DebugFlags.WEB_VIEW) {
                Log.v(LOGTAG, "doFling missed " + deltaR / circle);
            }
        } else if (DebugFlags.WEB_VIEW) {
            Log.v(LOGTAG, "doFling start last=" + mLastVelocity
                    + " current=" + currentVelocity
                    + " vx=" + vx + " vy=" + vy
                    + " maxX=" + maxX + " maxY=" + maxY
                    + " scrollX=" + scrollX + " scrollY=" + scrollY
                    + " layer=" + mCurrentScrollingLayerId);
        }

        // Allow sloppy flings without overscrolling at the edges.
        if ((scrollX == 0 || scrollX == maxX) && Math.abs(vx) < Math.abs(vy)) {
            vx = 0;
        }
        if ((scrollY == 0 || scrollY == maxY) && Math.abs(vy) < Math.abs(vx)) {
            vy = 0;
        }

        if (overscrollDistance < overflingDistance) {
            if ((vx > 0 && scrollX == -overscrollDistance) ||
                    (vx < 0 && scrollX == maxX + overscrollDistance)) {
                vx = 0;
            }
            if ((vy > 0 && scrollY == -overscrollDistance) ||
                    (vy < 0 && scrollY == maxY + overscrollDistance)) {
                vy = 0;
            }
        }

        mLastVelX = vx;
        mLastVelY = vy;
        mLastVelocity = velocity;

        // no horizontal overscroll if the content just fits
        mScroller.fling(scrollX, scrollY, -vx, -vy, 0, maxX, 0, maxY,
                maxX == 0 ? 0 : overflingDistance, overflingDistance);

        invalidate();
    }

    /**
     * See {@link WebView#getZoomControls()}
     */
    @Override
    @Deprecated
    public View getZoomControls() {
        if (!getSettings().supportZoom()) {
            Log.w(LOGTAG, "This WebView doesn't support zoom.");
            return null;
        }
        return mZoomManager.getExternalZoomPicker();
    }

    void dismissZoomControl() {
        mZoomManager.dismissZoomPicker();
    }

    float getDefaultZoomScale() {
        return mZoomManager.getDefaultScale();
    }

    /**
     * Return the overview scale of the WebView
     * @return The overview scale.
     */
    float getZoomOverviewScale() {
        return mZoomManager.getZoomOverviewScale();
    }

    /**
     * See {@link WebView#canZoomIn()}
     */
    @Override
    public boolean canZoomIn() {
        return mZoomManager.canZoomIn();
    }

    /**
     * See {@link WebView#canZoomOut()}
     */
    @Override
    public boolean canZoomOut() {
        return mZoomManager.canZoomOut();
    }

    /**
     * See {@link WebView#zoomIn()}
     */
    @Override
    public boolean zoomIn() {
        return mZoomManager.zoomIn();
    }

    /**
     * See {@link WebView#zoomOut()}
     */
    @Override
    public boolean zoomOut() {
        return mZoomManager.zoomOut();
    }

    /*
     * Return true if the rect (e.g. plugin) is fully visible and maximized
     * inside the WebView.
     */
    boolean isRectFitOnScreen(Rect rect) {
        final int rectWidth = rect.width();
        final int rectHeight = rect.height();
        final int viewWidth = getViewWidth();
        final int viewHeight = getViewHeightWithTitle();
        float scale = Math.min((float) viewWidth / rectWidth, (float) viewHeight / rectHeight);
        scale = mZoomManager.computeScaleWithLimits(scale);
        return !mZoomManager.willScaleTriggerZoom(scale)
                && contentToViewX(rect.left) >= getScrollX()
                && contentToViewX(rect.right) <= getScrollX() + viewWidth
                && contentToViewY(rect.top) >= getScrollY()
                && contentToViewY(rect.bottom) <= getScrollY() + viewHeight;
    }

    /*
     * Maximize and center the rectangle, specified in the document coordinate
     * space, inside the WebView. If the zoom doesn't need to be changed, do an
     * animated scroll to center it. If the zoom needs to be changed, find the
     * zoom center and do a smooth zoom transition. The rect is in document
     * coordinates
     */
    void centerFitRect(Rect rect) {
        final int rectWidth = rect.width();
        final int rectHeight = rect.height();
        final int viewWidth = getViewWidth();
        final int viewHeight = getViewHeightWithTitle();
        float scale = Math.min((float) viewWidth / rectWidth, (float) viewHeight
                / rectHeight);
        scale = mZoomManager.computeScaleWithLimits(scale);
        if (!mZoomManager.willScaleTriggerZoom(scale)) {
            pinScrollTo(contentToViewX(rect.left + rectWidth / 2) - viewWidth / 2,
                    contentToViewY(rect.top + rectHeight / 2) - viewHeight / 2,
                    true, 0);
        } else {
            float actualScale = mZoomManager.getScale();
            float oldScreenX = rect.left * actualScale - getScrollX();
            float rectViewX = rect.left * scale;
            float rectViewWidth = rectWidth * scale;
            float newMaxWidth = mContentWidth * scale;
            float newScreenX = (viewWidth - rectViewWidth) / 2;
            // pin the newX to the WebView
            if (newScreenX > rectViewX) {
                newScreenX = rectViewX;
            } else if (newScreenX > (newMaxWidth - rectViewX - rectViewWidth)) {
                newScreenX = viewWidth - (newMaxWidth - rectViewX);
            }
            float zoomCenterX = (oldScreenX * scale - newScreenX * actualScale)
                    / (scale - actualScale);
            float oldScreenY = rect.top * actualScale + getTitleHeight()
                    - getScrollY();
            float rectViewY = rect.top * scale + getTitleHeight();
            float rectViewHeight = rectHeight * scale;
            float newMaxHeight = mContentHeight * scale + getTitleHeight();
            float newScreenY = (viewHeight - rectViewHeight) / 2;
            // pin the newY to the WebView
            if (newScreenY > rectViewY) {
                newScreenY = rectViewY;
            } else if (newScreenY > (newMaxHeight - rectViewY - rectViewHeight)) {
                newScreenY = viewHeight - (newMaxHeight - rectViewY);
            }
            float zoomCenterY = (oldScreenY * scale - newScreenY * actualScale)
                    / (scale - actualScale);
            mZoomManager.setZoomCenter(zoomCenterX, zoomCenterY);
            mZoomManager.startZoomAnimation(scale, false);
        }
    }

    // Called by JNI to handle a touch on a node representing an email address,
    // address, or phone number
    private void overrideLoading(String url) {
        mCallbackProxy.uiOverrideUrlLoading(url);
    }

    @Override
    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
        // Check if we are destroyed
        if (mWebViewCore == null) return false;
        // FIXME: If a subwindow is showing find, and the user touches the
        // background window, it can steal focus.
        if (mFindIsUp) return false;
        boolean result = false;
        result = mWebViewPrivate.super_requestFocus(direction, previouslyFocusedRect);
        if (mWebViewCore.getSettings().getNeedInitialFocus()
                && !mWebView.isInTouchMode()) {
            // For cases such as GMail, where we gain focus from a direction,
            // we want to move to the first available link.
            // FIXME: If there are no visible links, we may not want to
            int fakeKeyDirection = 0;
            switch(direction) {
                case View.FOCUS_UP:
                    fakeKeyDirection = KeyEvent.KEYCODE_DPAD_UP;
                    break;
                case View.FOCUS_DOWN:
                    fakeKeyDirection = KeyEvent.KEYCODE_DPAD_DOWN;
                    break;
                case View.FOCUS_LEFT:
                    fakeKeyDirection = KeyEvent.KEYCODE_DPAD_LEFT;
                    break;
                case View.FOCUS_RIGHT:
                    fakeKeyDirection = KeyEvent.KEYCODE_DPAD_RIGHT;
                    break;
                default:
                    return result;
            }
            mWebViewCore.sendMessage(EventHub.SET_INITIAL_FOCUS, fakeKeyDirection);
        }
        return result;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int measuredHeight = heightSize;
        int measuredWidth = widthSize;

        // Grab the content size from WebViewCore.
        int contentHeight = contentToViewDimension(mContentHeight);
        int contentWidth = contentToViewDimension(mContentWidth);

//        Log.d(LOGTAG, "------- measure " + heightMode);

        if (heightMode != MeasureSpec.EXACTLY) {
            mHeightCanMeasure = true;
            measuredHeight = contentHeight;
            if (heightMode == MeasureSpec.AT_MOST) {
                // If we are larger than the AT_MOST height, then our height can
                // no longer be measured and we should scroll internally.
                if (measuredHeight > heightSize) {
                    measuredHeight = heightSize;
                    mHeightCanMeasure = false;
                    measuredHeight |= View.MEASURED_STATE_TOO_SMALL;
                }
            }
        } else {
            mHeightCanMeasure = false;
        }
        if (mNativeClass != 0) {
            nativeSetHeightCanMeasure(mHeightCanMeasure);
        }
        // For the width, always use the given size unless unspecified.
        if (widthMode == MeasureSpec.UNSPECIFIED) {
            mWidthCanMeasure = true;
            measuredWidth = contentWidth;
        } else {
            if (measuredWidth < contentWidth) {
                measuredWidth |= View.MEASURED_STATE_TOO_SMALL;
            }
            mWidthCanMeasure = false;
        }

        synchronized (this) {
            mWebViewPrivate.setMeasuredDimension(measuredWidth, measuredHeight);
        }
    }

    @Override
    public boolean requestChildRectangleOnScreen(View child,
                                                 Rect rect,
                                                 boolean immediate) {
        if (mNativeClass == 0) {
            return false;
        }
        // don't scroll while in zoom animation. When it is done, we will adjust
        // the necessary components
        if (mZoomManager.isFixedLengthAnimationInProgress()) {
            return false;
        }

        rect.offset(child.getLeft() - child.getScrollX(),
                child.getTop() - child.getScrollY());

        Rect content = new Rect(viewToContentX(getScrollX()),
                viewToContentY(getScrollY()),
                viewToContentX(getScrollX() + getWidth()
                - mWebView.getVerticalScrollbarWidth()),
                viewToContentY(getScrollY() + getViewHeightWithTitle()));
        int screenTop = contentToViewY(content.top);
        int screenBottom = contentToViewY(content.bottom);
        int height = screenBottom - screenTop;
        int scrollYDelta = 0;

        if (rect.bottom > screenBottom) {
            int oneThirdOfScreenHeight = height / 3;
            if (rect.height() > 2 * oneThirdOfScreenHeight) {
                // If the rectangle is too tall to fit in the bottom two thirds
                // of the screen, place it at the top.
                scrollYDelta = rect.top - screenTop;
            } else {
                // If the rectangle will still fit on screen, we want its
                // top to be in the top third of the screen.
                scrollYDelta = rect.top - (screenTop + oneThirdOfScreenHeight);
            }
        } else if (rect.top < screenTop) {
            scrollYDelta = rect.top - screenTop;
        }

        int screenLeft = contentToViewX(content.left);
        int screenRight = contentToViewX(content.right);
        int width = screenRight - screenLeft;
        int scrollXDelta = 0;

        if (rect.right > screenRight && rect.left > screenLeft) {
            if (rect.width() > width) {
                scrollXDelta += (rect.left - screenLeft);
            } else {
                scrollXDelta += (rect.right - screenRight);
            }
        } else if (rect.left < screenLeft) {
            scrollXDelta -= (screenLeft - rect.left);
        }

        if ((scrollYDelta | scrollXDelta) != 0) {
            return pinScrollBy(scrollXDelta, scrollYDelta, !immediate, 0);
        }

        return false;
    }

    /* package */ void replaceTextfieldText(int oldStart, int oldEnd,
            String replace, int newStart, int newEnd) {
        WebViewCore.ReplaceTextData arg = new WebViewCore.ReplaceTextData();
        arg.mReplace = replace;
        arg.mNewStart = newStart;
        arg.mNewEnd = newEnd;
        mTextGeneration++;
        arg.mTextGeneration = mTextGeneration;
        sendBatchableInputMessage(EventHub.REPLACE_TEXT, oldStart, oldEnd, arg);
    }

    /* package */ void passToJavaScript(String currentText, KeyEvent event) {
        // check if mWebViewCore has been destroyed
        if (mWebViewCore == null) {
            return;
        }
        WebViewCore.JSKeyData arg = new WebViewCore.JSKeyData();
        arg.mEvent = event;
        arg.mCurrentText = currentText;
        // Increase our text generation number, and pass it to webcore thread
        mTextGeneration++;
        mWebViewCore.sendMessage(EventHub.PASS_TO_JS, mTextGeneration, 0, arg);
        // WebKit's document state is not saved until about to leave the page.
        // To make sure the host application, like Browser, has the up to date
        // document state when it goes to background, we force to save the
        // document state.
        mWebViewCore.removeMessages(EventHub.SAVE_DOCUMENT_STATE);
        mWebViewCore.sendMessageDelayed(EventHub.SAVE_DOCUMENT_STATE, null, 1000);
    }

    public synchronized WebViewCore getWebViewCore() {
        return mWebViewCore;
    }

    private boolean canTextScroll(int directionX, int directionY) {
        int scrollX = getTextScrollX();
        int scrollY = getTextScrollY();
        int maxScrollX = getMaxTextScrollX();
        int maxScrollY = getMaxTextScrollY();
        boolean canScrollX = (directionX > 0)
                ? (scrollX < maxScrollX)
                : (scrollX > 0);
        boolean canScrollY = (directionY > 0)
                ? (scrollY < maxScrollY)
                : (scrollY > 0);
        return canScrollX || canScrollY;
    }

    private int getTextScrollX() {
        return -mEditTextContent.left;
    }

    private int getTextScrollY() {
        return -mEditTextContent.top;
    }

    private int getMaxTextScrollX() {
        return Math.max(0, mEditTextContent.width() - mEditTextContentBounds.width());
    }

    private int getMaxTextScrollY() {
        return Math.max(0, mEditTextContent.height() - mEditTextContentBounds.height());
    }

    //-------------------------------------------------------------------------
    // Methods can be called from a separate thread, like WebViewCore
    // If it needs to call the View system, it has to send message.
    //-------------------------------------------------------------------------

    /**
     * General handler to receive message coming from webkit thread
     */
    class PrivateHandler extends Handler implements WebViewInputDispatcher.UiCallbacks {
        @Override
        public void handleMessage(Message msg) {
            // exclude INVAL_RECT_MSG_ID since it is frequently output
            if (DebugFlags.WEB_VIEW && msg.what != INVAL_RECT_MSG_ID) {
                if (msg.what >= FIRST_PRIVATE_MSG_ID
                        && msg.what <= LAST_PRIVATE_MSG_ID) {
                    Log.v(LOGTAG, HandlerPrivateDebugString[msg.what
                            - FIRST_PRIVATE_MSG_ID]);
                } else if (msg.what >= FIRST_PACKAGE_MSG_ID
                        && msg.what <= LAST_PACKAGE_MSG_ID) {
                    Log.v(LOGTAG, HandlerPackageDebugString[msg.what
                            - FIRST_PACKAGE_MSG_ID]);
                } else {
                    Log.v(LOGTAG, Integer.toString(msg.what));
                }
            }
            if (mWebViewCore == null) {
                // after WebView's destroy() is called, skip handling messages.
                return;
            }
            if (mBlockWebkitViewMessages
                    && msg.what != WEBCORE_INITIALIZED_MSG_ID) {
                // Blocking messages from webkit
                return;
            }
            switch (msg.what) {
                case REMEMBER_PASSWORD: {
                    mDatabase.setUsernamePassword(
                            msg.getData().getString("host"),
                            msg.getData().getString("username"),
                            msg.getData().getString("password"));
                    ((Message) msg.obj).sendToTarget();
                    break;
                }
                case NEVER_REMEMBER_PASSWORD: {
                    mDatabase.setUsernamePassword(msg.getData().getString("host"), null, null);
                    ((Message) msg.obj).sendToTarget();
                    break;
                }
                case SCROLL_SELECT_TEXT: {
                    if (mAutoScrollX == 0 && mAutoScrollY == 0) {
                        mSentAutoScrollMessage = false;
                        break;
                    }
                    if (mCurrentScrollingLayerId == 0) {
                        pinScrollBy(mAutoScrollX, mAutoScrollY, true, 0);
                    } else {
                        scrollLayerTo(mScrollingLayerRect.left + mAutoScrollX,
                                mScrollingLayerRect.top + mAutoScrollY);
                    }
                    sendEmptyMessageDelayed(
                            SCROLL_SELECT_TEXT, SELECT_SCROLL_INTERVAL);
                    break;
                }
                case SCROLL_TO_MSG_ID: {
                    // arg1 = animate, arg2 = onlyIfImeIsShowing
                    // obj = Point(x, y)
                    if (msg.arg2 == 1) {
                        // This scroll is intended to bring the textfield into
                        // view, but is only necessary if the IME is showing
                        InputMethodManager imm = InputMethodManager.peekInstance();
                        if (imm == null || !imm.isAcceptingText()
                                || !imm.isActive(mWebView)) {
                            break;
                        }
                    }
                    final Point p = (Point) msg.obj;
                    contentScrollTo(p.x, p.y, msg.arg1 == 1);
                    break;
                }
                case UPDATE_ZOOM_RANGE: {
                    WebViewCore.ViewState viewState = (WebViewCore.ViewState) msg.obj;
                    // mScrollX contains the new minPrefWidth
                    mZoomManager.updateZoomRange(viewState, getViewWidth(), viewState.mScrollX);
                    break;
                }
                case UPDATE_ZOOM_DENSITY: {
                    final float density = (Float) msg.obj;
                    mZoomManager.updateDefaultZoomDensity(density);
                    break;
                }
                case NEW_PICTURE_MSG_ID: {
                    // called for new content
                    final WebViewCore.DrawData draw = (WebViewCore.DrawData) msg.obj;
                    setNewPicture(draw, true);
                    break;
                }
                case WEBCORE_INITIALIZED_MSG_ID:
                    // nativeCreate sets mNativeClass to a non-zero value
                    String drawableDir = BrowserFrame.getRawResFilename(
                            BrowserFrame.DRAWABLEDIR, mContext);
                    nativeCreate(msg.arg1, drawableDir, ActivityManager.isHighEndGfx());
                    if (mDelaySetPicture != null) {
                        setNewPicture(mDelaySetPicture, true);
                        mDelaySetPicture = null;
                    }
                    if (mIsPaused) {
                        nativeSetPauseDrawing(mNativeClass, true);
                    }
                    mInputDispatcher = new WebViewInputDispatcher(this,
                            mWebViewCore.getInputDispatcherCallbacks());
                    break;
                case UPDATE_TEXTFIELD_TEXT_MSG_ID:
                    // Make sure that the textfield is currently focused
                    // and representing the same node as the pointer.
                    if (msg.arg2 == mTextGeneration) {
                        String text = (String) msg.obj;
                        if (null == text) {
                            text = "";
                        }
                        if (mInputConnection != null &&
                                mFieldPointer == msg.arg1) {
                            mInputConnection.setTextAndKeepSelection(text);
                        }
                    }
                    break;
                case UPDATE_TEXT_SELECTION_MSG_ID:
                    updateTextSelectionFromMessage(msg.arg1, msg.arg2,
                            (WebViewCore.TextSelectionData) msg.obj);
                    break;
                case TAKE_FOCUS:
                    int direction = msg.arg1;
                    View focusSearch = mWebView.focusSearch(direction);
                    if (focusSearch != null && focusSearch != mWebView) {
                        focusSearch.requestFocus();
                    }
                    break;
                case CLEAR_TEXT_ENTRY:
                    hideSoftKeyboard();
                    break;
                case INVAL_RECT_MSG_ID: {
                    Rect r = (Rect)msg.obj;
                    if (r == null) {
                        invalidate();
                    } else {
                        // we need to scale r from content into view coords,
                        // which viewInvalidate() does for us
                        viewInvalidate(r.left, r.top, r.right, r.bottom);
                    }
                    break;
                }
                case REQUEST_FORM_DATA:
                    if (mFieldPointer == msg.arg1) {
                        ArrayAdapter<String> adapter = (ArrayAdapter<String>)msg.obj;
                        mAutoCompletePopup.setAdapter(adapter);
                    }
                    break;

                case LONG_PRESS_CENTER:
                    // as this is shared by keydown and trackballdown, reset all
                    // the states
                    mGotCenterDown = false;
                    mTrackballDown = false;
                    mWebView.performLongClick();
                    break;

                case WEBCORE_NEED_TOUCH_EVENTS:
                    mInputDispatcher.setWebKitWantsTouchEvents(msg.arg1 != 0);
                    break;

                case REQUEST_KEYBOARD:
                    if (msg.arg1 == 0) {
                        hideSoftKeyboard();
                    } else {
                        displaySoftKeyboard(false);
                    }
                    break;

                case DRAG_HELD_MOTIONLESS:
                    mHeldMotionless = MOTIONLESS_TRUE;
                    invalidate();
                    break;

                case SCREEN_ON:
                    mWebView.setKeepScreenOn(msg.arg1 == 1);
                    break;

                case EXIT_FULLSCREEN_VIDEO:
                    if (mHTML5VideoViewProxy != null) {
                        mHTML5VideoViewProxy.exitFullScreenVideo();
                    }
                    break;

                case SHOW_FULLSCREEN: {
                    View view = (View) msg.obj;
                    int orientation = msg.arg1;
                    int npp = msg.arg2;

                    if (inFullScreenMode()) {
                        Log.w(LOGTAG, "Should not have another full screen.");
                        dismissFullScreenMode();
                    }
                    mFullScreenHolder = new PluginFullScreenHolder(WebViewClassic.this, orientation, npp);
                    mFullScreenHolder.setContentView(view);
                    mFullScreenHolder.show();
                    invalidate();

                    break;
                }
                case HIDE_FULLSCREEN:
                    dismissFullScreenMode();
                    break;

                case SHOW_RECT_MSG_ID: {
                    WebViewCore.ShowRectData data = (WebViewCore.ShowRectData) msg.obj;
                    int left = contentToViewX(data.mLeft);
                    int width = contentToViewDimension(data.mWidth);
                    int maxWidth = contentToViewDimension(data.mContentWidth);
                    int viewWidth = getViewWidth();
                    int x = (int) (left + data.mXPercentInDoc * width -
                                   data.mXPercentInView * viewWidth);
                    if (DebugFlags.WEB_VIEW) {
                        Log.v(LOGTAG, "showRectMsg=(left=" + left + ",width=" +
                              width + ",maxWidth=" + maxWidth +
                              ",viewWidth=" + viewWidth + ",x="
                              + x + ",xPercentInDoc=" + data.mXPercentInDoc +
                              ",xPercentInView=" + data.mXPercentInView+ ")");
                    }
                    // use the passing content width to cap x as the current
                    // mContentWidth may not be updated yet
                    x = Math.max(0,
                            (Math.min(maxWidth, x + viewWidth)) - viewWidth);
                    int top = contentToViewY(data.mTop);
                    int height = contentToViewDimension(data.mHeight);
                    int maxHeight = contentToViewDimension(data.mContentHeight);
                    int viewHeight = getViewHeight();
                    int y = (int) (top + data.mYPercentInDoc * height -
                                   data.mYPercentInView * viewHeight);
                    if (DebugFlags.WEB_VIEW) {
                        Log.v(LOGTAG, "showRectMsg=(top=" + top + ",height=" +
                              height + ",maxHeight=" + maxHeight +
                              ",viewHeight=" + viewHeight + ",y="
                              + y + ",yPercentInDoc=" + data.mYPercentInDoc +
                              ",yPercentInView=" + data.mYPercentInView+ ")");
                    }
                    // use the passing content height to cap y as the current
                    // mContentHeight may not be updated yet
                    y = Math.max(0,
                            (Math.min(maxHeight, y + viewHeight) - viewHeight));
                    // We need to take into account the visible title height
                    // when scrolling since y is an absolute view position.
                    y = Math.max(0, y - getVisibleTitleHeightImpl());
                    mWebView.scrollTo(x, y);
                    }
                    break;

                case CENTER_FIT_RECT:
                    centerFitRect((Rect)msg.obj);
                    break;

                case SET_SCROLLBAR_MODES:
                    mHorizontalScrollBarMode = msg.arg1;
                    mVerticalScrollBarMode = msg.arg2;
                    break;

                case FOCUS_NODE_CHANGED:
                    mIsEditingText = (msg.arg1 == mFieldPointer);
                    if (mAutoCompletePopup != null && !mIsEditingText) {
                        mAutoCompletePopup.clearAdapter();
                    }
                    // fall through to HIT_TEST_RESULT
                case HIT_TEST_RESULT:
                    WebKitHitTest hit = (WebKitHitTest) msg.obj;
                    mFocusedNode = hit;
                    setTouchHighlightRects(hit);
                    setHitTestResult(hit);
                    break;

                case SAVE_WEBARCHIVE_FINISHED:
                    SaveWebArchiveMessage saveMessage = (SaveWebArchiveMessage)msg.obj;
                    if (saveMessage.mCallback != null) {
                        saveMessage.mCallback.onReceiveValue(saveMessage.mResultFile);
                    }
                    break;

                case SET_AUTOFILLABLE:
                    mAutoFillData = (WebViewCore.AutoFillData) msg.obj;
                    if (mInputConnection != null) {
                        mInputConnection.setAutoFillable(mAutoFillData.getQueryId());
                        mAutoCompletePopup.setAutoFillQueryId(mAutoFillData.getQueryId());
                    }
                    break;

                case AUTOFILL_COMPLETE:
                    if (mAutoCompletePopup != null) {
                        ArrayList<String> pastEntries = new ArrayList<String>();
                        mAutoCompletePopup.setAdapter(new ArrayAdapter<String>(
                                mContext,
                                com.android.internal.R.layout.web_text_view_dropdown,
                                pastEntries));
                    }
                    break;

                case COPY_TO_CLIPBOARD:
                    copyToClipboard((String) msg.obj);
                    break;

                case INIT_EDIT_FIELD:
                    if (mInputConnection != null) {
                        TextFieldInitData initData = (TextFieldInitData) msg.obj;
                        mTextGeneration = 0;
                        mFieldPointer = initData.mFieldPointer;
                        mInputConnection.initEditorInfo(initData);
                        mInputConnection.setTextAndKeepSelection(initData.mText);
                        mEditTextContentBounds.set(initData.mContentBounds);
                        mEditTextLayerId = initData.mNodeLayerId;
                        nativeMapLayerRect(mNativeClass, mEditTextLayerId,
                                mEditTextContentBounds);
                        mEditTextContent.set(initData.mClientRect);
                        relocateAutoCompletePopup();
                    }
                    break;

                case REPLACE_TEXT:{
                    String text = (String)msg.obj;
                    int start = msg.arg1;
                    int end = msg.arg2;
                    int cursorPosition = start + text.length();
                    replaceTextfieldText(start, end, text,
                            cursorPosition, cursorPosition);
                    selectionDone();
                    break;
                }

                case UPDATE_MATCH_COUNT: {
                    WebViewCore.FindAllRequest request = (WebViewCore.FindAllRequest)msg.obj;
                    if (request == null) {
                        if (mFindCallback != null) {
                            mFindCallback.updateMatchCount(0, 0, true);
                        }
                    } else if (request == mFindRequest) {
                        int matchCount, matchIndex;
                        synchronized (mFindRequest) {
                            matchCount = request.mMatchCount;
                            matchIndex = request.mMatchIndex;
                        }
                        if (mFindCallback != null) {
                            mFindCallback.updateMatchCount(matchIndex, matchCount, false);
                        }
                        if (mFindListener != null) {
                            mFindListener.onFindResultReceived(matchIndex, matchCount, true);
                        }
                    }
                    break;
                }

                case CLEAR_CARET_HANDLE:
                    if (mIsCaretSelection) {
                        selectionDone();
                    }
                    break;

                case KEY_PRESS:
                    sendBatchableInputMessage(EventHub.KEY_PRESS, msg.arg1, 0, null);
                    break;

                case RELOCATE_AUTO_COMPLETE_POPUP:
                    relocateAutoCompletePopup();
                    break;

                case AUTOFILL_FORM:
                    mWebViewCore.sendMessage(EventHub.AUTOFILL_FORM,
                            msg.arg1, /* unused */0);
                    break;

                case EDIT_TEXT_SIZE_CHANGED:
                    if (msg.arg1 == mFieldPointer) {
                        mEditTextContent.set((Rect)msg.obj);
                    }
                    break;

                case SHOW_CARET_HANDLE:
                    if (!mSelectingText && mIsEditingText && mIsCaretSelection) {
                        setupWebkitSelect();
                        resetCaretTimer();
                        showPasteWindow();
                    }
                    break;

                case UPDATE_CONTENT_BOUNDS:
                    mEditTextContentBounds.set((Rect) msg.obj);
                    nativeMapLayerRect(mNativeClass, mEditTextLayerId,
                            mEditTextContentBounds);
                    break;

                case SCROLL_EDIT_TEXT:
                    scrollEditWithCursor();
                    break;

                case SCROLL_HANDLE_INTO_VIEW:
                    scrollDraggedSelectionHandleIntoView();
                    break;

                default:
                    super.handleMessage(msg);
                    break;
            }
        }

        @Override
        public Looper getUiLooper() {
            return getLooper();
        }

        @Override
        public void dispatchUiEvent(MotionEvent event, int eventType, int flags) {
            onHandleUiEvent(event, eventType, flags);
        }

        @Override
        public Context getContext() {
            return WebViewClassic.this.getContext();
        }

        @Override
        public boolean shouldInterceptTouchEvent(MotionEvent event) {
            if (!mSelectingText) {
                return false;
            }
            ensureSelectionHandles();
            int y = Math.round(event.getY() - getTitleHeight() + getScrollY());
            int x = Math.round(event.getX() + getScrollX());
            boolean isPressingHandle;
            if (mIsCaretSelection) {
                isPressingHandle = mSelectHandleCenter.getBounds()
                        .contains(x, y);
            } else {
                isPressingHandle =
                        mSelectHandleBaseBounds.contains(x, y)
                        || mSelectHandleExtentBounds.contains(x, y);
            }
            return isPressingHandle;
        }

        @Override
        public void showTapHighlight(boolean show) {
            if (mShowTapHighlight != show) {
                mShowTapHighlight = show;
                invalidate();
            }
        }

        @Override
        public void clearPreviousHitTest() {
            setHitTestResult(null);
        }
    }

    private void setHitTestTypeFromUrl(String url) {
        String substr = null;
        if (url.startsWith(SCHEME_GEO)) {
            mInitialHitTestResult.setType(HitTestResult.GEO_TYPE);
            substr = url.substring(SCHEME_GEO.length());
        } else if (url.startsWith(SCHEME_TEL)) {
            mInitialHitTestResult.setType(HitTestResult.PHONE_TYPE);
            substr = url.substring(SCHEME_TEL.length());
        } else if (url.startsWith(SCHEME_MAILTO)) {
            mInitialHitTestResult.setType(HitTestResult.EMAIL_TYPE);
            substr = url.substring(SCHEME_MAILTO.length());
        } else {
            mInitialHitTestResult.setType(HitTestResult.SRC_ANCHOR_TYPE);
            mInitialHitTestResult.setExtra(url);
            return;
        }
        try {
            mInitialHitTestResult.setExtra(URLDecoder.decode(substr, "UTF-8"));
        } catch (Throwable e) {
            Log.w(LOGTAG, "Failed to decode URL! " + substr, e);
            mInitialHitTestResult.setType(HitTestResult.UNKNOWN_TYPE);
        }
    }

    private void setHitTestResult(WebKitHitTest hit) {
        if (hit == null) {
            mInitialHitTestResult = null;
            return;
        }
        mInitialHitTestResult = new HitTestResult();
        if (hit.mLinkUrl != null) {
            setHitTestTypeFromUrl(hit.mLinkUrl);
            if (hit.mImageUrl != null
                    && mInitialHitTestResult.getType() == HitTestResult.SRC_ANCHOR_TYPE) {
                mInitialHitTestResult.setType(HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
                mInitialHitTestResult.setExtra(hit.mImageUrl);
            }
        } else if (hit.mImageUrl != null) {
            mInitialHitTestResult.setType(HitTestResult.IMAGE_TYPE);
            mInitialHitTestResult.setExtra(hit.mImageUrl);
        } else if (hit.mEditable) {
            mInitialHitTestResult.setType(HitTestResult.EDIT_TEXT_TYPE);
        } else if (hit.mIntentUrl != null) {
            setHitTestTypeFromUrl(hit.mIntentUrl);
        }
    }

    private boolean shouldDrawHighlightRect() {
        if (mFocusedNode == null || mInitialHitTestResult == null) {
            return false;
        }
        if (mTouchHighlightRegion.isEmpty()) {
            return false;
        }
        if (mFocusedNode.mHasFocus && !mWebView.isInTouchMode()) {
            return mDrawCursorRing && !mFocusedNode.mEditable;
        }
        if (mFocusedNode.mHasFocus && mFocusedNode.mEditable) {
            return false;
        }
        return mShowTapHighlight;
    }


    private FocusTransitionDrawable mFocusTransition = null;
    static class FocusTransitionDrawable extends Drawable {
        Region mPreviousRegion;
        Region mNewRegion;
        float mProgress = 0;
        WebViewClassic mWebView;
        Paint mPaint;
        int mMaxAlpha;
        Point mTranslate;

        public FocusTransitionDrawable(WebViewClassic view) {
            mWebView = view;
            mPaint = new Paint(mWebView.mTouchHightlightPaint);
            mMaxAlpha = mPaint.getAlpha();
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
        }

        @Override
        public void setAlpha(int alpha) {
        }

        @Override
        public int getOpacity() {
            return 0;
        }

        public void setProgress(float p) {
            mProgress = p;
            if (mWebView.mFocusTransition == this) {
                if (mProgress == 1f)
                    mWebView.mFocusTransition = null;
                mWebView.invalidate();
            }
        }

        public float getProgress() {
            return mProgress;
        }

        @Override
        public void draw(Canvas canvas) {
            if (mTranslate == null) {
                Rect bounds = mPreviousRegion.getBounds();
                Point from = new Point(bounds.centerX(), bounds.centerY());
                mNewRegion.getBounds(bounds);
                Point to = new Point(bounds.centerX(), bounds.centerY());
                mTranslate = new Point(from.x - to.x, from.y - to.y);
            }
            int alpha = (int) (mProgress * mMaxAlpha);
            RegionIterator iter = new RegionIterator(mPreviousRegion);
            Rect r = new Rect();
            mPaint.setAlpha(mMaxAlpha - alpha);
            float tx = mTranslate.x * mProgress;
            float ty = mTranslate.y * mProgress;
            int save = canvas.save(Canvas.MATRIX_SAVE_FLAG);
            canvas.translate(-tx, -ty);
            while (iter.next(r)) {
                canvas.drawRect(r, mPaint);
            }
            canvas.restoreToCount(save);
            iter = new RegionIterator(mNewRegion);
            r = new Rect();
            mPaint.setAlpha(alpha);
            save = canvas.save(Canvas.MATRIX_SAVE_FLAG);
            tx = mTranslate.x - tx;
            ty = mTranslate.y - ty;
            canvas.translate(tx, ty);
            while (iter.next(r)) {
                canvas.drawRect(r, mPaint);
            }
            canvas.restoreToCount(save);
        }
    };

    private boolean shouldAnimateTo(WebKitHitTest hit) {
        // TODO: Don't be annoying or throw out the animation entirely
        return false;
    }

    private void setTouchHighlightRects(WebKitHitTest hit) {
        FocusTransitionDrawable transition = null;
        if (shouldAnimateTo(hit)) {
            transition = new FocusTransitionDrawable(this);
        }
        Rect[] rects = hit != null ? hit.mTouchRects : null;
        if (!mTouchHighlightRegion.isEmpty()) {
            mWebView.invalidate(mTouchHighlightRegion.getBounds());
            if (transition != null) {
                transition.mPreviousRegion = new Region(mTouchHighlightRegion);
            }
            mTouchHighlightRegion.setEmpty();
        }
        if (rects != null) {
            mTouchHightlightPaint.setColor(hit.mTapHighlightColor);
            for (Rect rect : rects) {
                Rect viewRect = contentToViewRect(rect);
                // some sites, like stories in nytimes.com, set
                // mouse event handler in the top div. It is not
                // user friendly to highlight the div if it covers
                // more than half of the screen.
                if (viewRect.width() < getWidth() >> 1
                        || viewRect.height() < getHeight() >> 1) {
                    mTouchHighlightRegion.union(viewRect);
                } else if (DebugFlags.WEB_VIEW) {
                    Log.d(LOGTAG, "Skip the huge selection rect:"
                            + viewRect);
                }
            }
            mWebView.invalidate(mTouchHighlightRegion.getBounds());
            if (transition != null && transition.mPreviousRegion != null) {
                transition.mNewRegion = new Region(mTouchHighlightRegion);
                mFocusTransition = transition;
                ObjectAnimator animator = ObjectAnimator.ofFloat(
                        mFocusTransition, "progress", 1f);
                animator.start();
            }
        }
    }

    // Interface to allow the profiled WebView to hook the page swap notifications.
    public interface PageSwapDelegate {
        void onPageSwapOccurred(boolean notifyAnimationStarted);
    }

    long mLastSwapTime;
    double mAverageSwapFps;

    /** Called by JNI when pages are swapped (only occurs with hardware
     * acceleration) */
    protected void pageSwapCallback(boolean notifyAnimationStarted) {
        if (DebugFlags.MEASURE_PAGE_SWAP_FPS) {
            long now = System.currentTimeMillis();
            long diff = now - mLastSwapTime;
            mAverageSwapFps = ((1000.0 / diff) + mAverageSwapFps) / 2;
            Log.d(LOGTAG, "page swap fps: " + mAverageSwapFps);
            mLastSwapTime = now;
        }
        mWebViewCore.resumeWebKitDraw();
        if (notifyAnimationStarted) {
            mWebViewCore.sendMessage(EventHub.NOTIFY_ANIMATION_STARTED);
        }
        if (mWebView instanceof PageSwapDelegate) {
            // This provides a hook for ProfiledWebView to observe the tile page swaps.
            ((PageSwapDelegate) mWebView).onPageSwapOccurred(notifyAnimationStarted);
        }

        if (mPictureListener != null) {
            // trigger picture listener for hardware layers. Software layers are
            // triggered in setNewPicture
            Picture picture = mContext.getApplicationInfo().targetSdkVersion <
                    Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
            mPictureListener.onNewPicture(getWebView(), picture);
        }
    }

    void setNewPicture(final WebViewCore.DrawData draw, boolean updateBaseLayer) {
        if (mNativeClass == 0) {
            if (mDelaySetPicture != null) {
                throw new IllegalStateException("Tried to setNewPicture with"
                        + " a delay picture already set! (memory leak)");
            }
            // Not initialized yet, delay set
            mDelaySetPicture = draw;
            return;
        }
        WebViewCore.ViewState viewState = draw.mViewState;
        boolean isPictureAfterFirstLayout = viewState != null;

        if (updateBaseLayer) {
            setBaseLayer(draw.mBaseLayer,
                    getSettings().getShowVisualIndicator(),
                    isPictureAfterFirstLayout);
        }
        final Point viewSize = draw.mViewSize;
        // We update the layout (i.e. request a layout from the
        // view system) if the last view size that we sent to
        // WebCore matches the view size of the picture we just
        // received in the fixed dimension.
        final boolean updateLayout = viewSize.x == mLastWidthSent
                && viewSize.y == mLastHeightSent;
        // Don't send scroll event for picture coming from webkit,
        // since the new picture may cause a scroll event to override
        // the saved history scroll position.
        mSendScrollEvent = false;
        recordNewContentSize(draw.mContentSize.x,
                draw.mContentSize.y, updateLayout);
        if (isPictureAfterFirstLayout) {
            // Reset the last sent data here since dealing with new page.
            mLastWidthSent = 0;
            mZoomManager.onFirstLayout(draw);
            int scrollX = viewState.mShouldStartScrolledRight
                    ? getContentWidth() : viewState.mScrollX;
            int scrollY = viewState.mScrollY;
            contentScrollTo(scrollX, scrollY, false);
            if (!mDrawHistory) {
                // As we are on a new page, hide the keyboard
                hideSoftKeyboard();
            }
        }
        mSendScrollEvent = true;

        int functor = 0;
        boolean forceInval = isPictureAfterFirstLayout;
        ViewRootImpl viewRoot = mWebView.getViewRootImpl();
        if (mWebView.isHardwareAccelerated()
                && mWebView.getLayerType() != View.LAYER_TYPE_SOFTWARE
                && viewRoot != null) {
            functor = nativeGetDrawGLFunction(mNativeClass);
            if (functor != 0) {
                // force an invalidate if functor attach not successful
                forceInval |= !viewRoot.attachFunctor(functor);
            }
        }

        if (functor == 0
                || forceInval
                || mWebView.getLayerType() != View.LAYER_TYPE_NONE) {
            // invalidate the screen so that the next repaint will show new content
            // TODO: partial invalidate
            mWebView.invalidate();
        }

        // update the zoom information based on the new picture
        if (mZoomManager.onNewPicture(draw))
            invalidate();

        if (isPictureAfterFirstLayout) {
            mViewManager.postReadyToDrawAll();
        }
        scrollEditWithCursor();

        if (mPictureListener != null) {
            if (!mWebView.isHardwareAccelerated()
                    || mWebView.getLayerType() == View.LAYER_TYPE_SOFTWARE) {
                // trigger picture listener for software layers. Hardware layers are
                // triggered in pageSwapCallback
                Picture picture = mContext.getApplicationInfo().targetSdkVersion <
                        Build.VERSION_CODES.JELLY_BEAN_MR2 ? capturePicture() : null;
                mPictureListener.onNewPicture(getWebView(), picture);
            }
        }
    }

    /**
     * Used when receiving messages for REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID
     * and UPDATE_TEXT_SELECTION_MSG_ID.
     */
    private void updateTextSelectionFromMessage(int nodePointer,
            int textGeneration, WebViewCore.TextSelectionData data) {
        if (textGeneration == mTextGeneration) {
            if (mInputConnection != null && mFieldPointer == nodePointer) {
                mInputConnection.setSelection(data.mStart, data.mEnd);
            }
        }
        nativeSetTextSelection(mNativeClass, data.mSelectTextPtr);

        if ((data.mSelectionReason == TextSelectionData.REASON_ACCESSIBILITY_INJECTOR)
                || (!mSelectingText && data.mStart != data.mEnd
                        && data.mSelectionReason != TextSelectionData.REASON_SELECT_WORD)) {
            selectionDone();
            mShowTextSelectionExtra = true;
            invalidate();
            return;
        }

        if (data.mSelectTextPtr != 0 &&
                (data.mStart != data.mEnd ||
                (mFieldPointer == nodePointer && mFieldPointer != 0) ||
                (nodePointer == 0 && data.mStart == 0 && data.mEnd == 0))) {
            mIsEditingText = (mFieldPointer == nodePointer) && nodePointer != 0;
            mIsCaretSelection = (data.mStart == data.mEnd && nodePointer != 0);
            if (mIsCaretSelection &&
                    (mInputConnection == null ||
                    mInputConnection.getEditable().length() == 0)) {
                // There's no text, don't show caret handle.
                selectionDone();
            } else {
                if (!mSelectingText) {
                    setupWebkitSelect();
                } else {
                    syncSelectionCursors();
                }
                animateHandles();
                if (mIsCaretSelection) {
                    resetCaretTimer();
                }
            }
        } else {
            selectionDone();
        }
        invalidate();
    }

    private void scrollEditText(int scrollX, int scrollY) {
        // Scrollable edit text. Scroll it.
        float maxScrollX = getMaxTextScrollX();
        float scrollPercentX = ((float)scrollX)/maxScrollX;
        mEditTextContent.offsetTo(-scrollX, -scrollY);
        mWebViewCore.removeMessages(EventHub.SCROLL_TEXT_INPUT);
        mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, 0,
                scrollY, (Float)scrollPercentX);
        animateHandles();
    }

    private void beginTextBatch() {
        mIsBatchingTextChanges = true;
    }

    private void commitTextBatch() {
        if (mWebViewCore != null) {
            mWebViewCore.sendMessages(mBatchedTextChanges);
        }
        mBatchedTextChanges.clear();
        mIsBatchingTextChanges = false;
    }

    void sendBatchableInputMessage(int what, int arg1, int arg2,
            Object obj) {
        if (mWebViewCore == null) {
            return;
        }
        Message message = Message.obtain(null, what, arg1, arg2, obj);
        if (mIsBatchingTextChanges) {
            mBatchedTextChanges.add(message);
        } else {
            mWebViewCore.sendMessage(message);
        }
    }

    // Class used to use a dropdown for a <select> element
    private class InvokeListBox implements Runnable {
        // Whether the listbox allows multiple selection.
        private boolean     mMultiple;
        // Passed in to a list with multiple selection to tell
        // which items are selected.
        private int[]       mSelectedArray;
        // Passed in to a list with single selection to tell
        // where the initial selection is.
        private int         mSelection;

        private Container[] mContainers;

        // Need these to provide stable ids to my ArrayAdapter,
        // which normally does not have stable ids. (Bug 1250098)
        private class Container extends Object {
            /**
             * Possible values for mEnabled.  Keep in sync with OptionStatus in
             * WebViewCore.cpp
             */
            final static int OPTGROUP = -1;
            final static int OPTION_DISABLED = 0;
            final static int OPTION_ENABLED = 1;

            String  mString;
            int     mEnabled;
            int     mId;

            @Override
            public String toString() {
                return mString;
            }
        }

        /**
         *  Subclass ArrayAdapter so we can disable OptionGroupLabels,
         *  and allow filtering.
         */
        private class MyArrayListAdapter extends ArrayAdapter<Container> {
            public MyArrayListAdapter() {
                super(WebViewClassic.this.mContext,
                        mMultiple ? com.android.internal.R.layout.select_dialog_multichoice :
                        com.android.internal.R.layout.webview_select_singlechoice,
                        mContainers);
            }

            @Override
            public View getView(int position, View convertView,
                    ViewGroup parent) {
                // Always pass in null so that we will get a new CheckedTextView
                // Otherwise, an item which was previously used as an <optgroup>
                // element (i.e. has no check), could get used as an <option>
                // element, which needs a checkbox/radio, but it would not have
                // one.
                convertView = super.getView(position, null, parent);
                Container c = item(position);
                if (c != null && Container.OPTION_ENABLED != c.mEnabled) {
                    // ListView does not draw dividers between disabled and
                    // enabled elements.  Use a LinearLayout to provide dividers
                    LinearLayout layout = new LinearLayout(mContext);
                    layout.setOrientation(LinearLayout.VERTICAL);
                    if (position > 0) {
                        View dividerTop = new View(mContext);
                        dividerTop.setBackgroundResource(
                                android.R.drawable.divider_horizontal_bright);
                        layout.addView(dividerTop);
                    }

                    if (Container.OPTGROUP == c.mEnabled) {
                        // Currently select_dialog_multichoice uses CheckedTextViews.
                        // If that changes, the class cast will no longer be valid.
                        if (mMultiple) {
                            Assert.assertTrue(convertView instanceof CheckedTextView);
                            ((CheckedTextView) convertView).setCheckMarkDrawable(null);
                        }
                    } else {
                        // c.mEnabled == Container.OPTION_DISABLED
                        // Draw the disabled element in a disabled state.
                        convertView.setEnabled(false);
                    }

                    layout.addView(convertView);
                    if (position < getCount() - 1) {
                        View dividerBottom = new View(mContext);
                        dividerBottom.setBackgroundResource(
                                android.R.drawable.divider_horizontal_bright);
                        layout.addView(dividerBottom);
                    }
                    return layout;
                }
                return convertView;
            }

            @Override
            public boolean hasStableIds() {
                // AdapterView's onChanged method uses this to determine whether
                // to restore the old state.  Return false so that the old (out
                // of date) state does not replace the new, valid state.
                return false;
            }

            private Container item(int position) {
                if (position < 0 || position >= getCount()) {
                    return null;
                }
                return getItem(position);
            }

            @Override
            public long getItemId(int position) {
                Container item = item(position);
                if (item == null) {
                    return -1;
                }
                return item.mId;
            }

            @Override
            public boolean areAllItemsEnabled() {
                return false;
            }

            @Override
            public boolean isEnabled(int position) {
                Container item = item(position);
                if (item == null) {
                    return false;
                }
                return Container.OPTION_ENABLED == item.mEnabled;
            }
        }

        private InvokeListBox(String[] array, int[] enabled, int[] selected) {
            mMultiple = true;
            mSelectedArray = selected;

            int length = array.length;
            mContainers = new Container[length];
            for (int i = 0; i < length; i++) {
                mContainers[i] = new Container();
                mContainers[i].mString = array[i];
                mContainers[i].mEnabled = enabled[i];
                mContainers[i].mId = i;
            }
        }

        private InvokeListBox(String[] array, int[] enabled, int selection) {
            mSelection = selection;
            mMultiple = false;

            int length = array.length;
            mContainers = new Container[length];
            for (int i = 0; i < length; i++) {
                mContainers[i] = new Container();
                mContainers[i].mString = array[i];
                mContainers[i].mEnabled = enabled[i];
                mContainers[i].mId = i;
            }
        }

        /*
         * Whenever the data set changes due to filtering, this class ensures
         * that the checked item remains checked.
         */
        private class SingleDataSetObserver extends DataSetObserver {
            private long        mCheckedId;
            private ListView    mListView;
            private Adapter     mAdapter;

            /*
             * Create a new observer.
             * @param id The ID of the item to keep checked.
             * @param l ListView for getting and clearing the checked states
             * @param a Adapter for getting the IDs
             */
            public SingleDataSetObserver(long id, ListView l, Adapter a) {
                mCheckedId = id;
                mListView = l;
                mAdapter = a;
            }

            @Override
            public void onChanged() {
                // The filter may have changed which item is checked.  Find the
                // item that the ListView thinks is checked.
                int position = mListView.getCheckedItemPosition();
                long id = mAdapter.getItemId(position);
                if (mCheckedId != id) {
                    // Clear the ListView's idea of the checked item, since
                    // it is incorrect
                    mListView.clearChoices();
                    // Search for mCheckedId.  If it is in the filtered list,
                    // mark it as checked
                    int count = mAdapter.getCount();
                    for (int i = 0; i < count; i++) {
                        if (mAdapter.getItemId(i) == mCheckedId) {
                            mListView.setItemChecked(i, true);
                            break;
                        }
                    }
                }
            }
        }

        @Override
        public void run() {
            if (mWebViewCore == null
                    || getWebView().getWindowToken() == null
                    || getWebView().getViewRootImpl() == null) {
                // We've been detached and/or destroyed since this was posted
                return;
            }
            final ListView listView = (ListView) LayoutInflater.from(mContext)
                    .inflate(com.android.internal.R.layout.select_dialog, null);
            final MyArrayListAdapter adapter = new MyArrayListAdapter();
            AlertDialog.Builder b = new AlertDialog.Builder(mContext)
                    .setView(listView).setCancelable(true)
                    .setInverseBackgroundForced(true);

            if (mMultiple) {
                b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mWebViewCore.sendMessage(
                                EventHub.LISTBOX_CHOICES,
                                adapter.getCount(), 0,
                                listView.getCheckedItemPositions());
                    }});
                b.setNegativeButton(android.R.string.cancel,
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mWebViewCore.sendMessage(
                                EventHub.SINGLE_LISTBOX_CHOICE, -2, 0);
                }});
            }
            mListBoxDialog = b.create();
            listView.setAdapter(adapter);
            listView.setFocusableInTouchMode(true);
            // There is a bug (1250103) where the checks in a ListView with
            // multiple items selected are associated with the positions, not
            // the ids, so the items do not properly retain their checks when
            // filtered.  Do not allow filtering on multiple lists until
            // that bug is fixed.

            listView.setTextFilterEnabled(!mMultiple);
            if (mMultiple) {
                listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
                int length = mSelectedArray.length;
                for (int i = 0; i < length; i++) {
                    listView.setItemChecked(mSelectedArray[i], true);
                }
            } else {
                listView.setOnItemClickListener(new OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View v,
                            int position, long id) {
                        // Rather than sending the message right away, send it
                        // after the page regains focus.
                        mListBoxMessage = Message.obtain(null,
                                EventHub.SINGLE_LISTBOX_CHOICE, (int) id, 0);
                        if (mListBoxDialog != null) {
                            mListBoxDialog.dismiss();
                            mListBoxDialog = null;
                        }
                    }
                });
                if (mSelection != -1) {
                    listView.setSelection(mSelection);
                    listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
                    listView.setItemChecked(mSelection, true);
                    DataSetObserver observer = new SingleDataSetObserver(
                            adapter.getItemId(mSelection), listView, adapter);
                    adapter.registerDataSetObserver(observer);
                }
            }
            mListBoxDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                 if (mWebViewCore != null) {
                    mWebViewCore.sendMessage(
                                EventHub.SINGLE_LISTBOX_CHOICE, -2, 0);
                    }
                    mListBoxDialog = null;
                }
            });
            mListBoxDialog.show();
        }
    }

    private Message mListBoxMessage;

    /*
     * Request a dropdown menu for a listbox with multiple selection.
     *
     * @param array Labels for the listbox.
     * @param enabledArray  State for each element in the list.  See static
     *      integers in Container class.
     * @param selectedArray Which positions are initally selected.
     */
    void requestListBox(String[] array, int[] enabledArray, int[]
            selectedArray) {
        mPrivateHandler.post(
                new InvokeListBox(array, enabledArray, selectedArray));
    }

    /*
     * Request a dropdown menu for a listbox with single selection or a single
     * <select> element.
     *
     * @param array Labels for the listbox.
     * @param enabledArray  State for each element in the list.  See static
     *      integers in Container class.
     * @param selection Which position is initally selected.
     */
    void requestListBox(String[] array, int[] enabledArray, int selection) {
        mPrivateHandler.post(
                new InvokeListBox(array, enabledArray, selection));
    }

    private int getScaledMaxXScroll() {
        int width;
        if (mHeightCanMeasure == false) {
            width = getViewWidth() / 4;
        } else {
            Rect visRect = new Rect();
            calcOurVisibleRect(visRect);
            width = visRect.width() / 2;
        }
        // FIXME the divisor should be retrieved from somewhere
        return viewToContentX(width);
    }

    private int getScaledMaxYScroll() {
        int height;
        if (mHeightCanMeasure == false) {
            height = getViewHeight() / 4;
        } else {
            Rect visRect = new Rect();
            calcOurVisibleRect(visRect);
            height = visRect.height() / 2;
        }
        // FIXME the divisor should be retrieved from somewhere
        // the closest thing today is hard-coded into ScrollView.java
        // (from ScrollView.java, line 363)   int maxJump = height/2;
        return Math.round(height * mZoomManager.getInvScale());
    }

    /**
     * Called by JNI to invalidate view
     */
    private void viewInvalidate() {
        invalidate();
    }

    /**
     * Pass the key directly to the page.  This assumes that
     * nativePageShouldHandleShiftAndArrows() returned true.
     */
    private void letPageHandleNavKey(int keyCode, long time, boolean down, int metaState) {
        int keyEventAction;
        if (down) {
            keyEventAction = KeyEvent.ACTION_DOWN;
        } else {
            keyEventAction = KeyEvent.ACTION_UP;
        }

        KeyEvent event = new KeyEvent(time, time, keyEventAction, keyCode,
                1, (metaState & KeyEvent.META_SHIFT_ON)
                | (metaState & KeyEvent.META_ALT_ON)
                | (metaState & KeyEvent.META_SYM_ON)
                , KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0);
        sendKeyEvent(event);
    }

    private void sendKeyEvent(KeyEvent event) {
        int direction = 0;
        switch (event.getKeyCode()) {
        case KeyEvent.KEYCODE_DPAD_DOWN:
            direction = View.FOCUS_DOWN;
            break;
        case KeyEvent.KEYCODE_DPAD_UP:
            direction = View.FOCUS_UP;
            break;
        case KeyEvent.KEYCODE_DPAD_LEFT:
            direction = View.FOCUS_LEFT;
            break;
        case KeyEvent.KEYCODE_DPAD_RIGHT:
            direction = View.FOCUS_RIGHT;
            break;
        case KeyEvent.KEYCODE_TAB:
            direction = event.isShiftPressed() ? View.FOCUS_BACKWARD : View.FOCUS_FORWARD;
            break;
        }
        if (direction != 0 && mWebView.focusSearch(direction) == null) {
            // Can't take focus in that direction
            direction = 0;
        }
        int eventHubAction = EventHub.KEY_UP;
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            eventHubAction = EventHub.KEY_DOWN;
            int sound = keyCodeToSoundsEffect(event.getKeyCode());
            if (sound != 0) {
                mWebView.playSoundEffect(sound);
            }
        }
        sendBatchableInputMessage(eventHubAction, direction, 0, event);
    }

    /**
     * See {@link WebView#setBackgroundColor(int)}
     */
    @Override
    public void setBackgroundColor(int color) {
        mBackgroundColor = color;
        mWebViewCore.sendMessage(EventHub.SET_BACKGROUND_COLOR, color);
    }

    /**
     * Enable the communication b/t the webView and VideoViewProxy
     *
     * only used by the Browser
     */
    public void setHTML5VideoViewProxy(HTML5VideoViewProxy proxy) {
        mHTML5VideoViewProxy = proxy;
    }

    /**
     * Set the time to wait between passing touches to WebCore. See also the
     * TOUCH_SENT_INTERVAL member for further discussion.
     *
     * This is only used by the DRT test application.
     */
    public void setTouchInterval(int interval) {
        mCurrentTouchInterval = interval;
    }

    /**
     * Copy text into the clipboard. This is called indirectly from
     * WebViewCore.
     * @param text The text to put into the clipboard.
     */
    private void copyToClipboard(String text) {
        ClipboardManager cm = (ClipboardManager)mContext
                .getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText(getTitle(), text);
        cm.setPrimaryClip(clip);
    }

    /*package*/ void autoFillForm(int autoFillQueryId) {
        mPrivateHandler.obtainMessage(AUTOFILL_FORM, autoFillQueryId, 0)
            .sendToTarget();
    }

    /* package */ ViewManager getViewManager() {
        return mViewManager;
    }

    /** send content invalidate */
    protected void contentInvalidateAll() {
        if (mWebViewCore != null && !mBlockWebkitViewMessages) {
            mWebViewCore.sendMessage(EventHub.CONTENT_INVALIDATE_ALL);
        }
    }

    /** discard all textures from tiles. Used in Profiled WebView */
    public void discardAllTextures() {
        nativeDiscardAllTextures();
    }

    @Override
    public void setLayerType(int layerType, Paint paint) {
        updateHwAccelerated();
    }

    @Override
    public void preDispatchDraw(Canvas canvas) {
        // no-op for WebViewClassic.
    }

    private void updateHwAccelerated() {
        if (mNativeClass == 0) {
            return;
        }
        boolean hwAccelerated = false;
        if (mWebView.isHardwareAccelerated()
                && mWebView.getLayerType() != View.LAYER_TYPE_SOFTWARE) {
            hwAccelerated = true;
        }

        // result is of type LayerAndroid::InvalidateFlags, non zero means invalidate/redraw
        int result = nativeSetHwAccelerated(mNativeClass, hwAccelerated);
        if (mWebViewCore != null && !mBlockWebkitViewMessages && result != 0) {
            mWebViewCore.contentDraw();
        }
    }

    /**
     * Begin collecting per-tile profiling data
     *
     * only used by profiling tests
     */
    public void tileProfilingStart() {
        nativeTileProfilingStart();
    }
    /**
     * Return per-tile profiling data
     *
     * only used by profiling tests
     */
    public float tileProfilingStop() {
        return nativeTileProfilingStop();
    }

    /** only used by profiling tests */
    public void tileProfilingClear() {
        nativeTileProfilingClear();
    }
    /** only used by profiling tests */
    public int tileProfilingNumFrames() {
        return nativeTileProfilingNumFrames();
    }
    /** only used by profiling tests */
    public int tileProfilingNumTilesInFrame(int frame) {
        return nativeTileProfilingNumTilesInFrame(frame);
    }
    /** only used by profiling tests */
    public int tileProfilingGetInt(int frame, int tile, String key) {
        return nativeTileProfilingGetInt(frame, tile, key);
    }
    /** only used by profiling tests */
    public float tileProfilingGetFloat(int frame, int tile, String key) {
        return nativeTileProfilingGetFloat(frame, tile, key);
    }

    /**
     * Checks the focused content for an editable text field. This can be
     * text input or ContentEditable.
     * @return true if the focused item is an editable text field.
     */
    boolean focusCandidateIsEditableText() {
        if (mFocusedNode != null) {
            return mFocusedNode.mEditable;
        }
        return false;
    }

    // Called via JNI
    private void postInvalidate() {
        mWebView.postInvalidate();
    }

    // Note: must be called before first WebViewClassic is created.
    public static void setShouldMonitorWebCoreThread() {
        WebViewCore.setShouldMonitorWebCoreThread();
    }

    @Override
    public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
        int layer = getBaseLayer();
        if (layer != 0) {
            try {
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                ViewStateSerializer.dumpLayerHierarchy(layer, stream, level);
                stream.close();
                byte[] buf = stream.toByteArray();
                out.write(new String(buf, "ascii"));
            } catch (IOException e) {}
        }
    }

    @Override
    public View findHierarchyView(String className, int hashCode) {
        if (mNativeClass == 0) return null;
        Picture pic = new Picture();
        if (!nativeDumpLayerContentToPicture(mNativeClass, className, hashCode, pic)) {
            return null;
        }
        return new PictureWrapperView(getContext(), pic, mWebView);
    }

    private static class PictureWrapperView extends View {
        Picture mPicture;
        WebView mWebView;

        public PictureWrapperView(Context context, Picture picture, WebView parent) {
            super(context);
            mPicture = picture;
            mWebView = parent;
            setWillNotDraw(false);
            setRight(mPicture.getWidth());
            setBottom(mPicture.getHeight());
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawPicture(mPicture);
        }

        @Override
        public boolean post(Runnable action) {
            return mWebView.post(action);
        }
    }

    private native void     nativeCreate(int ptr, String drawableDir, boolean isHighEndGfx);
    private native void     nativeDebugDump();
    private static native void nativeDestroy(int ptr);

    private native void nativeDraw(Canvas canvas, RectF visibleRect,
            int color, int extra);
    private native void     nativeDumpDisplayTree(String urlOrNull);
    private native boolean  nativeEvaluateLayersAnimations(int nativeInstance);
    private native int      nativeCreateDrawGLFunction(int nativeInstance, Rect invScreenRect,
            Rect screenRect, RectF visibleContentRect, float scale, int extras);
    private native int      nativeGetDrawGLFunction(int nativeInstance);
    private native void     nativeUpdateDrawGLFunction(int nativeInstance, Rect invScreenRect,
            Rect screenRect, RectF visibleContentRect, float scale);
    private native String   nativeGetSelection();
    private native void     nativeSetHeightCanMeasure(boolean measure);
    private native boolean  nativeSetBaseLayer(int nativeInstance,
            int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout,
            int scrollingLayer);
    private native int      nativeGetBaseLayer(int nativeInstance);
    private native void     nativeCopyBaseContentToPicture(Picture pict);
    private native boolean     nativeDumpLayerContentToPicture(int nativeInstance,
            String className, int layerId, Picture pict);
    private native boolean  nativeHasContent();
    private native void     nativeStopGL(int ptr);
    private native void     nativeDiscardAllTextures();
    private native void     nativeTileProfilingStart();
    private native float    nativeTileProfilingStop();
    private native void     nativeTileProfilingClear();
    private native int      nativeTileProfilingNumFrames();
    private native int      nativeTileProfilingNumTilesInFrame(int frame);
    private native int      nativeTileProfilingGetInt(int frame, int tile, String key);
    private native float    nativeTileProfilingGetFloat(int frame, int tile, String key);

    private native void     nativeUseHardwareAccelSkia(boolean enabled);

    // Returns a pointer to the scrollable LayerAndroid at the given point.
    private native int      nativeScrollableLayer(int nativeInstance, int x, int y, Rect scrollRect,
            Rect scrollBounds);
    /**
     * Scroll the specified layer.
     * @param nativeInstance Native WebView instance
     * @param layer Id of the layer to scroll, as determined by nativeScrollableLayer.
     * @param newX Destination x position to which to scroll.
     * @param newY Destination y position to which to scroll.
     * @return True if the layer is successfully scrolled.
     */
    private native boolean  nativeScrollLayer(int nativeInstance, int layer, int newX, int newY);
    private native void     nativeSetIsScrolling(boolean isScrolling);
    private native int      nativeGetBackgroundColor(int nativeInstance);
    native boolean  nativeSetProperty(String key, String value);
    native String   nativeGetProperty(String key);
    /**
     * See {@link ComponentCallbacks2} for the trim levels and descriptions
     */
    private static native void     nativeOnTrimMemory(int level);
    private static native void nativeSetPauseDrawing(int instance, boolean pause);
    private static native void nativeSetTextSelection(int instance, int selection);
    private static native int nativeGetHandleLayerId(int instance, int handle,
            Point cursorLocation, QuadF textQuad);
    private static native void nativeMapLayerRect(int instance, int layerId,
            Rect rect);
    // Returns 1 if a layer sync is needed, else 0
    private static native int nativeSetHwAccelerated(int instance, boolean hwAccelerated);
    private static native void nativeFindMaxVisibleRect(int instance, int layerId,
            Rect visibleContentRect);
    private static native boolean nativeIsHandleLeft(int instance, int handleId);
    private static native boolean nativeIsPointVisible(int instance,
            int layerId, int contentX, int contentY);
}
