// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.content.browser;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.provider.Settings;
import android.provider.Settings.Secure;
import android.text.Editable;
import android.util.Log;
import android.util.Pair;
import android.view.ActionMode;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsoluteLayout;
import android.widget.FrameLayout;

import com.google.common.annotations.VisibleForTesting;

import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.WeakContext;
import org.chromium.content.R;
import org.chromium.content.browser.ContentViewGestureHandler.MotionEventDelegate;
import org.chromium.content.browser.accessibility.AccessibilityInjector;
import org.chromium.content.browser.accessibility.BrowserAccessibilityManager;
import org.chromium.content.browser.input.AdapterInputConnection;
import org.chromium.content.browser.input.HandleView;
import org.chromium.content.browser.input.ImeAdapter;
import org.chromium.content.browser.input.ImeAdapter.AdapterInputConnectionFactory;
import org.chromium.content.browser.input.InputMethodManagerWrapper;
import org.chromium.content.browser.input.InsertionHandleController;
import org.chromium.content.browser.input.SelectPopupDialog;
import org.chromium.content.browser.input.SelectionHandleController;
import org.chromium.content.common.TraceEvent;
import org.chromium.ui.ViewAndroid;
import org.chromium.ui.ViewAndroidDelegate;
import org.chromium.ui.WindowAndroid;
import org.chromium.ui.gfx.DeviceDisplayInfo;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * Provides a Java-side 'wrapper' around a WebContent (native) instance.
 * Contains all the major functionality necessary to manage the lifecycle of a ContentView without
 * being tied to the view system.
 */
@JNINamespace("content")
    public class ContentViewCore implements MotionEventDelegate,
                                            NavigationClient,
                                            AccessibilityStateChangeListener {
    /**
     * Indicates that input events are batched together and delivered just before vsync.
     */
    public static final int INPUT_EVENTS_DELIVERED_AT_VSYNC = 1;

    /**
     * Opposite of INPUT_EVENTS_DELIVERED_AT_VSYNC.
     */
    public static final int INPUT_EVENTS_DELIVERED_IMMEDIATELY = 0;

    private static final String TAG = "ContentViewCore";

    // Used to represent gestures for long press and long tap.
    private static final int IS_LONG_PRESS = 1;
    private static final int IS_LONG_TAP = 2;

    // Length of the delay (in ms) before fading in handles after the last page movement.
    private static final int TEXT_HANDLE_FADE_IN_DELAY = 300;

    // If the embedder adds a JavaScript interface object that contains an indirect reference to
    // the ContentViewCore, then storing a strong ref to the interface object on the native
    // side would prevent garbage collection of the ContentViewCore (as that strong ref would
    // create a new GC root).
    // For that reason, we store only a weak reference to the interface object on the
    // native side. However we still need a strong reference on the Java side to
    // prevent garbage collection if the embedder doesn't maintain their own ref to the
    // interface object - the Java side ref won't create a new GC root.
    // This map stores those refernces. We put into the map on addJavaScriptInterface()
    // and remove from it in removeJavaScriptInterface().
    private final Map<String, Object> mJavaScriptInterfaces = new HashMap<String, Object>();

    // Additionally, we keep track of all Java bound JS objects that are in use on the
    // current page to ensure that they are not garbage collected until the page is
    // navigated. This includes interface objects that have been removed
    // via the removeJavaScriptInterface API and transient objects returned from methods
    // on the interface object. Note we use HashSet rather than Set as the native side
    // expects HashSet (no bindings for interfaces).
    private final HashSet<Object> mRetainedJavaScriptObjects = new HashSet<Object>();

    /**
     * Interface that consumers of {@link ContentViewCore} must implement to allow the proper
     * dispatching of view methods through the containing view.
     *
     * <p>
     * All methods with the "super_" prefix should be routed to the parent of the
     * implementing container view.
     */
    @SuppressWarnings("javadoc")
    public interface InternalAccessDelegate {
        /**
         * @see View#drawChild(Canvas, View, long)
         */
        boolean drawChild(Canvas canvas, View child, long drawingTime);

        /**
         * @see View#onKeyUp(keyCode, KeyEvent)
         */
        boolean super_onKeyUp(int keyCode, KeyEvent event);

        /**
         * @see View#dispatchKeyEventPreIme(KeyEvent)
         */
        boolean super_dispatchKeyEventPreIme(KeyEvent event);

        /**
         * @see View#dispatchKeyEvent(KeyEvent)
         */
        boolean super_dispatchKeyEvent(KeyEvent event);

        /**
         * @see View#onGenericMotionEvent(MotionEvent)
         */
        boolean super_onGenericMotionEvent(MotionEvent event);

        /**
         * @see View#onConfigurationChanged(Configuration)
         */
        void super_onConfigurationChanged(Configuration newConfig);

        /**
         * @see View#awakenScrollBars()
         */
        boolean awakenScrollBars();

        /**
         * @see View#awakenScrollBars(int, boolean)
         */
        boolean super_awakenScrollBars(int startDelay, boolean invalidate);
    }

    /**
     * An interface that allows the embedder to be notified of events and state changes related to
     * gesture processing.
     */
    public interface GestureStateListener {
        /**
         * Called when the pinch gesture starts.
         */
        void onPinchGestureStart();

        /**
         * Called when the pinch gesture ends.
         */
        void onPinchGestureEnd();

        /**
         * Called when the fling gesture is sent.
         */
        void onFlingStartGesture(int vx, int vy);

        /**
         * Called when the fling cancel gesture is sent.
         */
        void onFlingCancelGesture();

        /**
         * Called when a fling event was not handled by the renderer.
         */
        void onUnhandledFlingStartEvent();

        /**
         * Called to indicate that a scroll update gesture had been consumed by the page.
         * This callback is called whenever any layer is scrolled (like a frame or div). It is
         * not called when a JS touch handler consumes the event (preventDefault), it is not called
         * for JS-initiated scrolling.
         */
        void onScrollUpdateGestureConsumed();
    }

    /**
     * An interface for controlling visibility and state of embedder-provided zoom controls.
     */
    public interface ZoomControlsDelegate {
        /**
         * Called when it's reasonable to show zoom controls.
         */
        void invokeZoomPicker();

        /**
         * Called when zoom controls need to be hidden (e.g. when the view hides).
         */
        void dismissZoomPicker();

        /**
         * Called when page scale has been changed, so the controls can update their state.
         */
        void updateZoomControls();
    }

    /**
     * An interface that allows the embedder to be notified of changes to the parameters of the
     * currently displayed contents.
     * These notifications are consistent with respect to the UI thread (the size is the size of
     * the contents currently displayed on screen).
     */
    public interface UpdateFrameInfoListener {
        /**
         * Called each time any of the parameters are changed.
         *
         * @param pageScaleFactor The page scale.
         */
        void onFrameInfoUpdated(float pageScaleFactor);
    }

    private VSyncManager.Provider mVSyncProvider;
    private VSyncManager.Listener mVSyncListener;
    private int mVSyncSubscriberCount;
    private boolean mVSyncListenerRegistered;

    // To avoid IPC delay we use input events to directly trigger a vsync signal in the renderer.
    // When we do this, we also need to avoid sending the real vsync signal for the current
    // frame to avoid double-ticking. This flag is used to inhibit the next vsync notification.
    private boolean mDidSignalVSyncUsingInputEvent;

    public VSyncManager.Listener getVSyncListener(VSyncManager.Provider vsyncProvider) {
        if (mVSyncProvider != null && mVSyncListenerRegistered) {
            mVSyncProvider.unregisterVSyncListener(mVSyncListener);
            mVSyncListenerRegistered = false;
        }

        mVSyncProvider = vsyncProvider;
        mVSyncListener = new VSyncManager.Listener() {
            @Override
            public void updateVSync(long tickTimeMicros, long intervalMicros) {
                if (mNativeContentViewCore != 0) {
                    nativeUpdateVSyncParameters(mNativeContentViewCore, tickTimeMicros,
                            intervalMicros);
                }
            }

            @Override
            public void onVSync(long frameTimeMicros) {
                animateIfNecessary(frameTimeMicros);

                if (mDidSignalVSyncUsingInputEvent) {
                    TraceEvent.instant("ContentViewCore::onVSync ignored");
                    mDidSignalVSyncUsingInputEvent = false;
                    return;
                }
                if (mNativeContentViewCore != 0) {
                    nativeOnVSync(mNativeContentViewCore, frameTimeMicros);
                }
            }
        };

        if (mVSyncSubscriberCount > 0) {
            // setVSyncNotificationEnabled(true) is called before getVSyncListener.
            vsyncProvider.registerVSyncListener(mVSyncListener);
            mVSyncListenerRegistered = true;
        }

        return mVSyncListener;
    }

    @CalledByNative
    void setVSyncNotificationEnabled(boolean enabled) {
        if (!isVSyncNotificationEnabled() && enabled) {
            mDidSignalVSyncUsingInputEvent = false;
        }
        if (mVSyncProvider != null) {
            if (!mVSyncListenerRegistered && enabled) {
                mVSyncProvider.registerVSyncListener(mVSyncListener);
                mVSyncListenerRegistered = true;
            } else if (mVSyncSubscriberCount == 1 && !enabled) {
                assert mVSyncListenerRegistered;
                mVSyncProvider.unregisterVSyncListener(mVSyncListener);
                mVSyncListenerRegistered = false;
            }
        }
        mVSyncSubscriberCount += enabled ? 1 : -1;
        assert mVSyncSubscriberCount >= 0;
    }

    @CalledByNative
    private void resetVSyncNotification() {
        while (isVSyncNotificationEnabled()) setVSyncNotificationEnabled(false);
        mVSyncSubscriberCount = 0;
        mVSyncListenerRegistered = false;
        mNeedAnimate = false;
    }

    private boolean isVSyncNotificationEnabled() {
        return mVSyncProvider != null && mVSyncListenerRegistered;
    }

    @CalledByNative
    private void setNeedsAnimate() {
        if (!mNeedAnimate) {
            mNeedAnimate = true;
            setVSyncNotificationEnabled(true);
        }
    }

    private final Context mContext;
    private ViewGroup mContainerView;
    private InternalAccessDelegate mContainerViewInternals;
    private WebContentsObserverAndroid mWebContentsObserver;

    private ContentViewClient mContentViewClient;

    private ContentSettings mContentSettings;

    // Native pointer to C++ ContentViewCoreImpl object which will be set by nativeInit().
    private int mNativeContentViewCore = 0;

    private boolean mAttachedToWindow = false;

    // Pid of the renderer process backing this ContentViewCore.
    private int mPid = 0;

    private ContentViewGestureHandler mContentViewGestureHandler;
    private GestureStateListener mGestureStateListener;
    private ZoomManager mZoomManager;
    private ZoomControlsDelegate mZoomControlsDelegate;

    private PopupZoomer mPopupZoomer;

    private Runnable mFakeMouseMoveRunnable = null;

    // Only valid when focused on a text / password field.
    private ImeAdapter mImeAdapter;
    private ImeAdapter.AdapterInputConnectionFactory mAdapterInputConnectionFactory;
    private AdapterInputConnection mInputConnection;

    private SelectionHandleController mSelectionHandleController;
    private InsertionHandleController mInsertionHandleController;

    private Runnable mDeferredHandleFadeInRunnable;

    private PositionObserver mPositionObserver;
    private PositionObserver.Listener mPositionListener;

    // Size of the viewport in physical pixels as set from onSizeChanged.
    private int mViewportWidthPix;
    private int mViewportHeightPix;
    private int mPhysicalBackingWidthPix;
    private int mPhysicalBackingHeightPix;
    private int mOverdrawBottomHeightPix;
    private int mViewportSizeOffsetWidthPix;
    private int mViewportSizeOffsetHeightPix;

    // Cached copy of all positions and scales as reported by the renderer.
    private final RenderCoordinates mRenderCoordinates;

    private final RenderCoordinates.NormalizedPoint mStartHandlePoint;
    private final RenderCoordinates.NormalizedPoint mEndHandlePoint;
    private final RenderCoordinates.NormalizedPoint mInsertionHandlePoint;

    // Tracks whether a selection is currently active.  When applied to selected text, indicates
    // whether the last selected text is still highlighted.
    private boolean mHasSelection;
    private String mLastSelectedText;
    private boolean mSelectionEditable;
    private ActionMode mActionMode;
    private boolean mUnselectAllOnActionModeDismiss;

    // Delegate that will handle GET downloads, and be notified of completion of POST downloads.
    private ContentViewDownloadDelegate mDownloadDelegate;

    // The AccessibilityInjector that handles loading Accessibility scripts into the web page.
    private AccessibilityInjector mAccessibilityInjector;

    // Whether native accessibility, i.e. without any script injection, is allowed.
    private boolean mNativeAccessibilityAllowed;

    // Whether native accessibility, i.e. without any script injection, has been enabled.
    private boolean mNativeAccessibilityEnabled;

    // Handles native accessibility, i.e. without any script injection.
    private BrowserAccessibilityManager mBrowserAccessibilityManager;

    // System accessibility service.
    private final AccessibilityManager mAccessibilityManager;

    // Allows us to dynamically respond when the accessibility script injection flag changes.
    private ContentObserver mAccessibilityScriptInjectionObserver;

    // Temporary notification to tell onSizeChanged to focus a form element,
    // because the OSK was just brought up.
    private boolean mUnfocusOnNextSizeChanged = false;
    private final Rect mFocusPreOSKViewportRect = new Rect();

    private boolean mNeedUpdateOrientationChanged;

    // Used to keep track of whether we should try to undo the last zoom-to-textfield operation.
    private boolean mScrolledAndZoomedFocusedEditableNode = false;

    // Whether we use hardware-accelerated drawing.
    private boolean mHardwareAccelerated = false;

    // Whether we received a new frame since consumePendingRendererFrame() was last called.
    private boolean mPendingRendererFrame = false;

    // Whether we should animate at the next vsync tick.
    private boolean mNeedAnimate = false;

    private ViewAndroid mViewAndroid;


    /**
     * Constructs a new ContentViewCore. Embedders must call initialize() after constructing
     * a ContentViewCore and before using it.
     *
     * @param context The context used to create this.
     */
    public ContentViewCore(Context context) {
        mContext = context;

        WeakContext.initializeWeakContext(context);
        HeapStatsLogger.init(mContext.getApplicationContext());
        mAdapterInputConnectionFactory = new AdapterInputConnectionFactory();

        mRenderCoordinates = new RenderCoordinates();
        mRenderCoordinates.setDeviceScaleFactor(
                getContext().getResources().getDisplayMetrics().density);
        mStartHandlePoint = mRenderCoordinates.createNormalizedPoint();
        mEndHandlePoint = mRenderCoordinates.createNormalizedPoint();
        mInsertionHandlePoint = mRenderCoordinates.createNormalizedPoint();
        mAccessibilityManager = (AccessibilityManager)
                getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
    }

    /**
     * @return The context used for creating this ContentViewCore.
     */
    @CalledByNative
    public Context getContext() {
        return mContext;
    }

    /**
     * @return The ViewGroup that all view actions of this ContentViewCore should interact with.
     */
    public ViewGroup getContainerView() {
        return mContainerView;
    }

    /**
     * Specifies how much smaller the WebKit layout size should be relative to the size of this
     * view.
     * @param offsetXPix The X amount in pixels to shrink the viewport by.
     * @param offsetYPix The Y amount in pixels to shrink the viewport by.
     */
    public void setViewportSizeOffset(int offsetXPix, int offsetYPix) {
        if (offsetXPix != mViewportSizeOffsetWidthPix ||
                offsetYPix != mViewportSizeOffsetHeightPix) {
            mViewportSizeOffsetWidthPix = offsetXPix;
            mViewportSizeOffsetHeightPix = offsetYPix;
            if (mNativeContentViewCore != 0) nativeWasResized(mNativeContentViewCore);
        }
    }

    /**
     * Returns a delegate that can be used to add and remove views from the ContainerView.
     *
     * NOTE: Use with care, as not all ContentViewCore users setup their ContainerView in the same
     * way. In particular, the Android WebView has limitations on what implementation details can
     * be provided via a child view, as they are visible in the API and could introduce
     * compatibility breaks with existing applications. If in doubt, contact the
     * android_webview/OWNERS
     *
     * @return A ViewAndroidDelegate that can be used to add and remove views.
     */
    @VisibleForTesting
    public ViewAndroidDelegate getViewAndroidDelegate() {
        return new ViewAndroidDelegate() {
            @Override
            public View acquireAnchorView() {
                View anchorView = new View(getContext());
                mContainerView.addView(anchorView);
                return anchorView;
            }

            @Override
            @SuppressWarnings("deprecation")  // AbsoluteLayout.LayoutParams
            public void setAnchorViewPosition(
                    View view, float x, float y, float width, float height) {
                assert(view.getParent() == mContainerView);

                float scale = (float) DeviceDisplayInfo.create(getContext()).getDIPScale();

                // The anchor view should not go outside the bounds of the ContainerView.
                int leftMargin = Math.round(x * scale);
                int topMargin = Math.round(mRenderCoordinates.getContentOffsetYPix() + y * scale);
                int scaledWidth = Math.round(width * scale);
                // ContentViewCore currently only supports these two container view types.
                if (mContainerView instanceof FrameLayout) {
                    if (scaledWidth + leftMargin > mContainerView.getWidth()) {
                        scaledWidth = mContainerView.getWidth() - leftMargin;
                    }
                    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                        scaledWidth, Math.round(height * scale));
                    lp.leftMargin = leftMargin;
                    lp.topMargin = topMargin;
                    view.setLayoutParams(lp);
                } else if (mContainerView instanceof AbsoluteLayout) {
                    // This fixes the offset due to a difference in
                    // scrolling model of WebView vs. Chrome.
                    // TODO(sgurun) fix this to use mContainerView.getScroll[X/Y]()
                    // as it naturally accounts for scroll differences between
                    // these models.
                    leftMargin += mRenderCoordinates.getScrollXPixInt();
                    topMargin += mRenderCoordinates.getScrollYPixInt();

                    android.widget.AbsoluteLayout.LayoutParams lp =
                            new android.widget.AbsoluteLayout.LayoutParams(
                                scaledWidth, (int)(height * scale), leftMargin, topMargin);
                    view.setLayoutParams(lp);
                } else {
                    Log.e(TAG, "Unknown layout " + mContainerView.getClass().getName());
                }
            }

            @Override
            public void releaseAnchorView(View anchorView) {
                mContainerView.removeView(anchorView);
            }
        };
    }

    @VisibleForTesting
    public ImeAdapter getImeAdapterForTest() {
        return mImeAdapter;
    }

    @VisibleForTesting
    public void setAdapterInputConnectionFactory(AdapterInputConnectionFactory factory) {
        mAdapterInputConnectionFactory = factory;
    }

    @VisibleForTesting
    public AdapterInputConnection getInputConnectionForTest() {
        return mInputConnection;
    }

    private ImeAdapter createImeAdapter(Context context) {
        return new ImeAdapter(new InputMethodManagerWrapper(context),
                new ImeAdapter.ImeAdapterDelegate() {
                    @Override
                    public void onImeEvent(boolean isFinish) {
                        getContentViewClient().onImeEvent();
                        if (!isFinish) {
                            hideHandles();
                            undoScrollFocusedEditableNodeIntoViewIfNeeded(false);
                        }
                    }

                    @Override
                    public void onSetFieldValue() {
                        scrollFocusedEditableNodeIntoView();
                    }

                    @Override
                    public void onDismissInput() {
                        getContentViewClient().onImeStateChangeRequested(false);
                    }

                    @Override
                    public View getAttachedView() {
                        return mContainerView;
                    }

                    @Override
                    public ResultReceiver getNewShowKeyboardReceiver() {
                        return new ResultReceiver(new Handler()) {
                            @Override
                            public void onReceiveResult(int resultCode, Bundle resultData) {
                                getContentViewClient().onImeStateChangeRequested(
                                        resultCode == InputMethodManager.RESULT_SHOWN ||
                                        resultCode == InputMethodManager.RESULT_UNCHANGED_SHOWN);
                                if (resultCode == InputMethodManager.RESULT_SHOWN) {
                                    // If OSK is newly shown, delay the form focus until
                                    // the onSizeChanged (in order to adjust relative to the
                                    // new size).
                                    // TODO(jdduke): We should not assume that onSizeChanged will
                                    // always be called, crbug.com/294908.
                                    getContainerView().getWindowVisibleDisplayFrame(
                                            mFocusPreOSKViewportRect);
                                } else if (resultCode ==
                                        InputMethodManager.RESULT_UNCHANGED_SHOWN) {
                                    // If the OSK was already there, focus the form immediately.
                                    scrollFocusedEditableNodeIntoView();
                                } else {
                                    undoScrollFocusedEditableNodeIntoViewIfNeeded(false);
                                }
                            }
                        };
                    }
                }
        );
    }

    /**
     * Returns true if the given Activity has hardware acceleration enabled
     * in its manifest, or in its foreground window.
     *
     * TODO(husky): Remove when initialize() is refactored (see TODO there)
     * TODO(dtrainor) This is still used by other classes.  Make sure to pull some version of this
     * out before removing it.
     */
    public static boolean hasHardwareAcceleration(Activity activity) {
        // Has HW acceleration been enabled manually in the current window?
        Window window = activity.getWindow();
        if (window != null) {
            if ((window.getAttributes().flags
                    & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
                return true;
            }
        }

        // Has HW acceleration been enabled in the manifest?
        try {
            ActivityInfo info = activity.getPackageManager().getActivityInfo(
                    activity.getComponentName(), 0);
            if ((info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
                return true;
            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.e("Chrome", "getActivityInfo(self) should not fail");
        }

        return false;
    }

    /**
     * Returns true if the given Context is a HW-accelerated Activity.
     *
     * TODO(husky): Remove when initialize() is refactored (see TODO there)
     */
    private static boolean hasHardwareAcceleration(Context context) {
        if (context instanceof Activity) {
            return hasHardwareAcceleration((Activity) context);
        }
        return false;
    }

    /**
     *
     * @param containerView The view that will act as a container for all views created by this.
     * @param internalDispatcher Handles dispatching all hidden or super methods to the
     *                           containerView.
     * @param nativeWebContents A pointer to the native web contents.
     * @param windowAndroid An instance of the WindowAndroid.
     */
    // Perform important post-construction set up of the ContentViewCore.
    // We do not require the containing view in the constructor to allow embedders to create a
    // ContentViewCore without having fully created its containing view. The containing view
    // is a vital component of the ContentViewCore, so embedders must exercise caution in what
    // they do with the ContentViewCore before calling initialize().
    // We supply the nativeWebContents pointer here rather than in the constructor to allow us
    // to set the private browsing mode at a later point for the WebView implementation.
    // Note that the caller remains the owner of the nativeWebContents and is responsible for
    // deleting it after destroying the ContentViewCore.
    public void initialize(ViewGroup containerView, InternalAccessDelegate internalDispatcher,
            int nativeWebContents, WindowAndroid windowAndroid,
            int inputEventDeliveryMode) {
        // Check whether to use hardware acceleration. This is a bit hacky, and
        // only works if the Context is actually an Activity (as it is in the
        // Chrome application).
        //
        // What we're doing here is checking whether the app has *requested*
        // hardware acceleration by setting the appropriate flags. This does not
        // necessarily mean we're going to *get* hardware acceleration -- that's
        // up to the Android framework.
        //
        // TODO(husky): Once the native code has been updated so that the
        // HW acceleration flag can be set dynamically (Grace is doing this),
        // move this check into onAttachedToWindow(), where we can test for
        // HW support directly.
        mHardwareAccelerated = hasHardwareAcceleration(mContext);

        mContainerView = containerView;
        mPositionObserver = new ViewPositionObserver(mContainerView);
        mPositionListener = new PositionObserver.Listener() {
            @Override
            public void onPositionChanged(int x, int y) {
                if (isSelectionHandleShowing() || isInsertionHandleShowing()) {
                    temporarilyHideTextHandles();
                }
            }
        };

        int windowNativePointer = windowAndroid != null ? windowAndroid.getNativePointer() : 0;

        int viewAndroidNativePointer = 0;
        if (windowNativePointer != 0) {
            mViewAndroid = new ViewAndroid(windowAndroid, getViewAndroidDelegate());
            viewAndroidNativePointer = mViewAndroid.getNativePointer();
        }

        mNativeContentViewCore = nativeInit(mHardwareAccelerated,
                nativeWebContents, viewAndroidNativePointer, windowNativePointer);
        mContentSettings = new ContentSettings(this, mNativeContentViewCore);
        initializeContainerView(internalDispatcher, inputEventDeliveryMode);

        mAccessibilityInjector = AccessibilityInjector.newInstance(this);

        String contentDescription = "Web View";
        if (R.string.accessibility_content_view == 0) {
            Log.w(TAG, "Setting contentDescription to 'Web View' as no value was specified.");
        } else {
            contentDescription = mContext.getResources().getString(
                    R.string.accessibility_content_view);
        }
        mContainerView.setContentDescription(contentDescription);
        mWebContentsObserver = new WebContentsObserverAndroid(this) {
            @Override
            public void didStartLoading(String url) {
                hidePopupDialog();
                resetGestureDetectors();
            }
        };

        mPid = nativeGetCurrentRenderProcessId(mNativeContentViewCore);
    }

    @CalledByNative
    void onNativeContentViewCoreDestroyed(int nativeContentViewCore) {
        assert nativeContentViewCore == mNativeContentViewCore;
        mNativeContentViewCore = 0;
    }

    /**
     * Initializes the View that will contain all Views created by the ContentViewCore.
     *
     * @param internalDispatcher Handles dispatching all hidden or super methods to the
     *                           containerView.
     */
    private void initializeContainerView(InternalAccessDelegate internalDispatcher,
            int inputEventDeliveryMode) {
        TraceEvent.begin();
        mContainerViewInternals = internalDispatcher;

        mContainerView.setWillNotDraw(false);
        mContainerView.setClickable(true);

        mZoomManager = new ZoomManager(mContext, this);
        mContentViewGestureHandler = new ContentViewGestureHandler(mContext, this, mZoomManager,
                inputEventDeliveryMode);
        mZoomControlsDelegate = new ZoomControlsDelegate() {
            @Override
            public void invokeZoomPicker() {}
            @Override
            public void dismissZoomPicker() {}
            @Override
            public void updateZoomControls() {}
        };

        mRenderCoordinates.reset();

        initPopupZoomer(mContext);
        mImeAdapter = createImeAdapter(mContext);
        TraceEvent.end();
    }

    private void initPopupZoomer(Context context){
        mPopupZoomer = new PopupZoomer(context);
        mPopupZoomer.setOnVisibilityChangedListener(new PopupZoomer.OnVisibilityChangedListener() {
            @Override
            public void onPopupZoomerShown(final PopupZoomer zoomer) {
                mContainerView.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mContainerView.indexOfChild(zoomer) == -1) {
                            mContainerView.addView(zoomer);
                        } else {
                            assert false : "PopupZoomer should never be shown without being hidden";
                        }
                    }
                });
            }

            @Override
            public void onPopupZoomerHidden(final PopupZoomer zoomer) {
                mContainerView.post(new Runnable() {
                    @Override
                    public void run() {
                        if (mContainerView.indexOfChild(zoomer) != -1) {
                            mContainerView.removeView(zoomer);
                            mContainerView.invalidate();
                        } else {
                            assert false : "PopupZoomer should never be hidden without being shown";
                        }
                    }
                });
            }
        });
        // TODO(yongsheng): LONG_TAP is not enabled in PopupZoomer. So need to dispatch a LONG_TAP
        // gesture if a user completes a tap on PopupZoomer UI after a LONG_PRESS gesture.
        PopupZoomer.OnTapListener listener = new PopupZoomer.OnTapListener() {
            @Override
            public boolean onSingleTap(View v, MotionEvent e) {
                mContainerView.requestFocus();
                if (mNativeContentViewCore != 0) {
                    nativeSingleTap(mNativeContentViewCore, e.getEventTime(),
                            e.getX(), e.getY(), true);
                }
                return true;
            }

            @Override
            public boolean onLongPress(View v, MotionEvent e) {
                if (mNativeContentViewCore != 0) {
                    nativeLongPress(mNativeContentViewCore, e.getEventTime(),
                            e.getX(), e.getY(), true);
                }
                return true;
            }
        };
        mPopupZoomer.setOnTapListener(listener);
    }

    /**
     * Destroy the internal state of the ContentView. This method may only be
     * called after the ContentView has been removed from the view system. No
     * other methods may be called on this ContentView after this method has
     * been called.
     */
    public void destroy() {
        if (mNativeContentViewCore != 0) {
            nativeOnJavaContentViewCoreDestroyed(mNativeContentViewCore);
        }
        resetVSyncNotification();
        mVSyncProvider = null;
        if (mViewAndroid != null) mViewAndroid.destroy();
        mNativeContentViewCore = 0;
        mContentSettings = null;
        mJavaScriptInterfaces.clear();
        mRetainedJavaScriptObjects.clear();
        unregisterAccessibilityContentObserver();
    }

    private void unregisterAccessibilityContentObserver() {
        if (mAccessibilityScriptInjectionObserver == null) {
            return;
        }
        getContext().getContentResolver().unregisterContentObserver(
                mAccessibilityScriptInjectionObserver);
        mAccessibilityScriptInjectionObserver = null;
    }

    /**
     * Returns true initially, false after destroy() has been called.
     * It is illegal to call any other public method after destroy().
     */
    public boolean isAlive() {
        return mNativeContentViewCore != 0;
    }

    /**
     * This is only useful for passing over JNI to native code that requires ContentViewCore*.
     * @return native ContentViewCore pointer.
     */
    @CalledByNative
    public int getNativeContentViewCore() {
        return mNativeContentViewCore;
    }

    /**
     * For internal use. Throws IllegalStateException if mNativeContentView is 0.
     * Use this to ensure we get a useful Java stack trace, rather than a native
     * crash dump, from use-after-destroy bugs in Java code.
     */
    void checkIsAlive() throws IllegalStateException {
        if (!isAlive()) {
            throw new IllegalStateException("ContentView used after destroy() was called");
        }
    }

    public void setContentViewClient(ContentViewClient client) {
        if (client == null) {
            throw new IllegalArgumentException("The client can't be null.");
        }
        mContentViewClient = client;
    }

    ContentViewClient getContentViewClient() {
        if (mContentViewClient == null) {
            // We use the Null Object pattern to avoid having to perform a null check in this class.
            // We create it lazily because most of the time a client will be set almost immediately
            // after ContentView is created.
            mContentViewClient = new ContentViewClient();
            // We don't set the native ContentViewClient pointer here on purpose. The native
            // implementation doesn't mind a null delegate and using one is better than passing a
            // Null Object, since we cut down on the number of JNI calls.
        }
        return mContentViewClient;
    }

    public int getBackgroundColor() {
        if (mNativeContentViewCore != 0) {
            return nativeGetBackgroundColor(mNativeContentViewCore);
        }
        return Color.WHITE;
    }

    @CalledByNative
    private void onBackgroundColorChanged(int color) {
        getContentViewClient().onBackgroundColorChanged(color);
    }

    /**
     * Load url without fixing up the url string. Consumers of ContentView are responsible for
     * ensuring the URL passed in is properly formatted (i.e. the scheme has been added if left
     * off during user input).
     *
     * @param params Parameters for this load.
     */
    public void loadUrl(LoadUrlParams params) {
        if (mNativeContentViewCore == 0) return;

        nativeLoadUrl(mNativeContentViewCore,
                params.mUrl,
                params.mLoadUrlType,
                params.mTransitionType,
                params.mUaOverrideOption,
                params.getExtraHeadersString(),
                params.mPostData,
                params.mBaseUrlForDataUrl,
                params.mVirtualUrlForDataUrl,
                params.mCanLoadLocalResources);
    }

    /**
     * Stops loading the current web contents.
     */
    public void stopLoading() {
        if (mNativeContentViewCore != 0) nativeStopLoading(mNativeContentViewCore);
    }

    /**
     * Get the URL of the current page.
     *
     * @return The URL of the current page.
     */
    public String getUrl() {
        if (mNativeContentViewCore != 0) return nativeGetURL(mNativeContentViewCore);
        return null;
    }

    /**
     * Get the title of the current page.
     *
     * @return The title of the current page.
     */
    public String getTitle() {
        if (mNativeContentViewCore != 0) return nativeGetTitle(mNativeContentViewCore);
        return null;
    }

    /**
     * Shows an interstitial page driven by the passed in delegate.
     *
     * @param url The URL being blocked by the interstitial.
     * @param delegate The delegate handling the interstitial.
     */
    @VisibleForTesting
    public void showInterstitialPage(
            String url, InterstitialPageDelegateAndroid delegate) {
        if (mNativeContentViewCore == 0) return;
        nativeShowInterstitialPage(mNativeContentViewCore, url, delegate.getNative());
    }

    /**
     * @return Whether the page is currently showing an interstitial, such as a bad HTTPS page.
     */
    public boolean isShowingInterstitialPage() {
        return mNativeContentViewCore == 0 ?
                false : nativeIsShowingInterstitialPage(mNativeContentViewCore);
    }

    /**
     * Mark any new frames that have arrived since this function was last called as non-pending.
     *
     * @return Whether there was a pending frame from the renderer.
     */
    public boolean consumePendingRendererFrame() {
        boolean hadPendingFrame = mPendingRendererFrame;
        mPendingRendererFrame = false;
        return hadPendingFrame;
    }

    /**
     * @return Viewport width in physical pixels as set from onSizeChanged.
     */
    @CalledByNative
    public int getViewportWidthPix() { return mViewportWidthPix; }

    /**
     * @return Viewport height in physical pixels as set from onSizeChanged.
     */
    @CalledByNative
    public int getViewportHeightPix() { return mViewportHeightPix; }

    /**
     * @return Width of underlying physical surface.
     */
    @CalledByNative
    public int getPhysicalBackingWidthPix() { return mPhysicalBackingWidthPix; }

    /**
     * @return Height of underlying physical surface.
     */
    @CalledByNative
    public int getPhysicalBackingHeightPix() { return mPhysicalBackingHeightPix; }

    /**
     * @return Amount the output surface extends past the bottom of the window viewport.
     */
    @CalledByNative
    public int getOverdrawBottomHeightPix() { return mOverdrawBottomHeightPix; }

    /**
     * @return The amount to shrink the viewport relative to {@link #getViewportWidthPix()}.
     */
    @CalledByNative
    public int getViewportSizeOffsetWidthPix() { return mViewportSizeOffsetWidthPix; }

    /**
     * @return The amount to shrink the viewport relative to {@link #getViewportHeightPix()}.
     */
    @CalledByNative
    public int getViewportSizeOffsetHeightPix() { return mViewportSizeOffsetHeightPix; }

    /**
     * @see android.webkit.WebView#getContentHeight()
     */
    public float getContentHeightCss() {
        return mRenderCoordinates.getContentHeightCss();
    }

    /**
     * @see android.webkit.WebView#getContentWidth()
     */
    public float getContentWidthCss() {
        return mRenderCoordinates.getContentWidthCss();
    }

    public Bitmap getBitmap() {
        return getBitmap(getViewportWidthPix(), getViewportHeightPix());
    }

    public Bitmap getBitmap(int width, int height) {
        if (width == 0 || height == 0
                || getViewportWidthPix() == 0 || getViewportHeightPix() == 0) {
            return null;
        }

        Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        if (mNativeContentViewCore != 0 &&
                nativePopulateBitmapFromCompositor(mNativeContentViewCore, b)) {
            // If we successfully grabbed a bitmap, check if we have to draw the Android overlay
            // components as well.
            if (mContainerView.getChildCount() > 0) {
                Canvas c = new Canvas(b);
                c.scale(width / (float) getViewportWidthPix(),
                        height / (float) getViewportHeightPix());
                mContainerView.draw(c);
            }
            return b;
        }

        return null;
    }

    /**
     * Generates a bitmap of the content that is performance optimized based on capture time.
     *
     * <p>
     * To have a consistent capture time across devices, we will scale down the captured bitmap
     * where necessary to reduce the time to generate the bitmap.
     *
     * @param width The width of the content to be captured.
     * @param height The height of the content to be captured.
     * @return A pair of the generated bitmap, and the scale that needs to be applied to return the
     *         bitmap to it's original size (i.e. if the bitmap is scaled down 50%, this
     *         will be 2).
     */
    public Pair<Bitmap, Float> getScaledPerformanceOptimizedBitmap(int width, int height) {
        float scale = 1f;
        // On tablets, always scale down to MDPI for performance reasons.
        if (DeviceUtils.isTablet(getContext())) {
            scale = getContext().getResources().getDisplayMetrics().density;
        }
        return Pair.create(
                getBitmap((int) (width / scale), (int) (height / scale)),
                scale);
    }

    /**
     * @return Whether the current WebContents has a previous navigation entry.
     */
    public boolean canGoBack() {
        return mNativeContentViewCore != 0 && nativeCanGoBack(mNativeContentViewCore);
    }

    /**
     * @return Whether the current WebContents has a navigation entry after the current one.
     */
    public boolean canGoForward() {
        return mNativeContentViewCore != 0 && nativeCanGoForward(mNativeContentViewCore);
    }

    /**
     * @param offset The offset into the navigation history.
     * @return Whether we can move in history by given offset
     */
    public boolean canGoToOffset(int offset) {
        return mNativeContentViewCore != 0 && nativeCanGoToOffset(mNativeContentViewCore, offset);
    }

    /**
     * Navigates to the specified offset from the "current entry". Does nothing if the offset is out
     * of bounds.
     * @param offset The offset into the navigation history.
     */
    public void goToOffset(int offset) {
        if (mNativeContentViewCore != 0) nativeGoToOffset(mNativeContentViewCore, offset);
    }

    @Override
    public void goToNavigationIndex(int index) {
        if (mNativeContentViewCore != 0) nativeGoToNavigationIndex(mNativeContentViewCore, index);
    }

    /**
     * Goes to the navigation entry before the current one.
     */
    public void goBack() {
        if (mNativeContentViewCore != 0) nativeGoBack(mNativeContentViewCore);
    }

    /**
     * Goes to the navigation entry following the current one.
     */
    public void goForward() {
        if (mNativeContentViewCore != 0) nativeGoForward(mNativeContentViewCore);
    }

    /**
     * Reload the current page.
     */
    public void reload() {
        mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
        if (mNativeContentViewCore != 0) nativeReload(mNativeContentViewCore);
    }

    /**
     * Cancel the pending reload.
     */
    public void cancelPendingReload() {
        if (mNativeContentViewCore != 0) nativeCancelPendingReload(mNativeContentViewCore);
    }

    /**
     * Continue the pending reload.
     */
    public void continuePendingReload() {
        if (mNativeContentViewCore != 0) nativeContinuePendingReload(mNativeContentViewCore);
    }

    /**
     * Clears the ContentViewCore's page history in both the backwards and
     * forwards directions.
     */
    public void clearHistory() {
        if (mNativeContentViewCore != 0) nativeClearHistory(mNativeContentViewCore);
    }

    /**
     * @return The selected text (empty if no text selected).
     */
    public String getSelectedText() {
        return mHasSelection ? mLastSelectedText : "";
    }

    /**
     * @return Whether the current selection is editable (false if no text selected).
     */
    public boolean isSelectionEditable() {
        return mHasSelection ? mSelectionEditable : false;
    }

    // End FrameLayout overrides.

    /**
     * @see View#onTouchEvent(MotionEvent)
     */
    public boolean onTouchEvent(MotionEvent event) {
        undoScrollFocusedEditableNodeIntoViewIfNeeded(false);
        return mContentViewGestureHandler.onTouchEvent(event);
    }

    /**
     * @return ContentViewGestureHandler for all MotionEvent and gesture related calls.
     */
    ContentViewGestureHandler getContentViewGestureHandler() {
        return mContentViewGestureHandler;
    }

    @Override
    public boolean sendTouchEvent(long timeMs, int action, TouchPoint[] pts) {
        if (mNativeContentViewCore != 0) {
            return nativeSendTouchEvent(mNativeContentViewCore, timeMs, action, pts);
        }
        return false;
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void hasTouchEventHandlers(boolean hasTouchHandlers) {
        mContentViewGestureHandler.hasTouchEventHandlers(hasTouchHandlers);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void confirmTouchEvent(int ackResult) {
        mContentViewGestureHandler.confirmTouchEvent(ackResult);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void unhandledFlingStartEvent() {
        if (mGestureStateListener != null) {
            mGestureStateListener.onUnhandledFlingStartEvent();
        }
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void onScrollUpdateGestureConsumed() {
        if (mGestureStateListener != null) {
            mGestureStateListener.onScrollUpdateGestureConsumed();
        }
    }

    @Override
    public boolean sendGesture(int type, long timeMs, int x, int y, boolean lastInputEventForVSync,
                               Bundle b) {
        if (offerGestureToEmbedder(type)) return false;
        if (mNativeContentViewCore == 0) return false;
        updateTextHandlesForGesture(type);
        updateGestureStateListener(type, b);
        if (lastInputEventForVSync && isVSyncNotificationEnabled()) {
            assert type == ContentViewGestureHandler.GESTURE_SCROLL_BY ||
                    type == ContentViewGestureHandler.GESTURE_PINCH_BY;
            mDidSignalVSyncUsingInputEvent = true;
        }
        switch (type) {
            case ContentViewGestureHandler.GESTURE_SHOW_PRESSED_STATE:
                nativeShowPressState(mNativeContentViewCore, timeMs, x, y);
                return true;
            case ContentViewGestureHandler.GESTURE_SHOW_PRESS_CANCEL:
                nativeShowPressCancel(mNativeContentViewCore, timeMs, x, y);
                return true;
            case ContentViewGestureHandler.GESTURE_DOUBLE_TAP:
                nativeDoubleTap(mNativeContentViewCore, timeMs, x, y);
                return true;
            case ContentViewGestureHandler.GESTURE_SINGLE_TAP_UP:
                nativeSingleTap(mNativeContentViewCore, timeMs, x, y, false);
                return true;
            case ContentViewGestureHandler.GESTURE_SINGLE_TAP_CONFIRMED:
                handleTapOrPress(timeMs, x, y, 0,
                        b.getBoolean(ContentViewGestureHandler.SHOW_PRESS, false));
                return true;
            case ContentViewGestureHandler.GESTURE_SINGLE_TAP_UNCONFIRMED:
                nativeSingleTapUnconfirmed(mNativeContentViewCore, timeMs, x, y);
                return true;
            case ContentViewGestureHandler.GESTURE_LONG_PRESS:
                handleTapOrPress(timeMs, x, y, IS_LONG_PRESS, false);
                return true;
            case ContentViewGestureHandler.GESTURE_LONG_TAP:
                handleTapOrPress(timeMs, x, y, IS_LONG_TAP, false);
                return true;
            case ContentViewGestureHandler.GESTURE_SCROLL_START:
                nativeScrollBegin(mNativeContentViewCore, timeMs, x, y);
                return true;
            case ContentViewGestureHandler.GESTURE_SCROLL_BY: {
                int dx = b.getInt(ContentViewGestureHandler.DISTANCE_X);
                int dy = b.getInt(ContentViewGestureHandler.DISTANCE_Y);
                nativeScrollBy(mNativeContentViewCore, timeMs, x, y, dx, dy,
                        lastInputEventForVSync);
                return true;
            }
            case ContentViewGestureHandler.GESTURE_SCROLL_END:
                nativeScrollEnd(mNativeContentViewCore, timeMs);
                return true;
            case ContentViewGestureHandler.GESTURE_FLING_START:
                nativeFlingStart(mNativeContentViewCore, timeMs, x, y,
                        b.getInt(ContentViewGestureHandler.VELOCITY_X, 0),
                        b.getInt(ContentViewGestureHandler.VELOCITY_Y, 0));
                return true;
            case ContentViewGestureHandler.GESTURE_FLING_CANCEL:
                nativeFlingCancel(mNativeContentViewCore, timeMs);
                return true;
            case ContentViewGestureHandler.GESTURE_PINCH_BEGIN:
                nativePinchBegin(mNativeContentViewCore, timeMs, x, y);
                return true;
            case ContentViewGestureHandler.GESTURE_PINCH_BY:
                nativePinchBy(mNativeContentViewCore, timeMs, x, y,
                        b.getFloat(ContentViewGestureHandler.DELTA, 0),
                        lastInputEventForVSync);
                return true;
            case ContentViewGestureHandler.GESTURE_PINCH_END:
                nativePinchEnd(mNativeContentViewCore, timeMs);
                return true;
            default:
                return false;
        }
    }

    public void setGestureStateListener(GestureStateListener pinchGestureStateListener) {
        mGestureStateListener = pinchGestureStateListener;
    }

    void updateGestureStateListener(int gestureType, Bundle b) {
        if (mGestureStateListener == null) return;

        switch (gestureType) {
            case ContentViewGestureHandler.GESTURE_PINCH_BEGIN:
                mGestureStateListener.onPinchGestureStart();
                break;
            case ContentViewGestureHandler.GESTURE_PINCH_END:
                mGestureStateListener.onPinchGestureEnd();
                break;
            case ContentViewGestureHandler.GESTURE_FLING_START:
                mGestureStateListener.onFlingStartGesture(
                        b.getInt(ContentViewGestureHandler.VELOCITY_X, 0),
                        b.getInt(ContentViewGestureHandler.VELOCITY_Y, 0));
                break;
            case ContentViewGestureHandler.GESTURE_FLING_CANCEL:
                mGestureStateListener.onFlingCancelGesture();
                break;
            default:
                break;
        }
    }

    public interface JavaScriptCallback {
        void handleJavaScriptResult(String jsonResult);
    }

    /**
     * Injects the passed Javascript code in the current page and evaluates it.
     * If a result is required, pass in a callback.
     * Used in automation tests.
     *
     * @param script The Javascript to execute.
     * @param callback The callback to be fired off when a result is ready. The script's
     *                 result will be json encoded and passed as the parameter, and the call
     *                 will be made on the main thread.
     *                 If no result is required, pass null.
     */
    public void evaluateJavaScript(String script, JavaScriptCallback callback) {
        if (mNativeContentViewCore == 0) return;
        nativeEvaluateJavaScript(mNativeContentViewCore, script, callback, false);
    }

    /**
     * Injects the passed Javascript code in the current page and evaluates it.
     * If there is no page existing, a new one will be created.
     *
     * @param script The Javascript to execute.
     */
    public void evaluateJavaScriptEvenIfNotYetNavigated(String script) {
        if (mNativeContentViewCore == 0) return;
        nativeEvaluateJavaScript(mNativeContentViewCore, script, null, true);
    }

    /**
     * This method should be called when the containing activity is paused.
     */
    public void onActivityPause() {
        TraceEvent.begin();
        hidePopupDialog();
        nativeOnHide(mNativeContentViewCore);
        TraceEvent.end();
    }

    /**
     * This method should be called when the containing activity is resumed.
     */
    public void onActivityResume() {
        nativeOnShow(mNativeContentViewCore);
        setAccessibilityState(mAccessibilityManager.isEnabled());
    }

    /**
     * To be called when the ContentView is shown.
     */
    public void onShow() {
        nativeOnShow(mNativeContentViewCore);
        setAccessibilityState(mAccessibilityManager.isEnabled());
    }

    /**
     * To be called when the ContentView is hidden.
     */
    public void onHide() {
        hidePopupDialog();
        setInjectedAccessibility(false);
        nativeOnHide(mNativeContentViewCore);
    }

    /**
     * Return the ContentSettings object used to retrieve the settings for this
     * ContentViewCore. For modifications, ChromeNativePreferences is to be used.
     * @return A ContentSettings object that can be used to retrieve this
     *         ContentViewCore's settings.
     */
    public ContentSettings getContentSettings() {
        return mContentSettings;
    }

    @Override
    public boolean didUIStealScroll(float x, float y) {
        return getContentViewClient().shouldOverrideScroll(
                x, y, computeHorizontalScrollOffset(), computeVerticalScrollOffset());
    }

    @Override
    public boolean hasFixedPageScale() {
        return mRenderCoordinates.hasFixedPageScale();
    }

    private void hidePopupDialog() {
        SelectPopupDialog.hide(this);
        hideHandles();
        hideSelectActionBar();
    }

    void hideSelectActionBar() {
        if (mActionMode != null) {
            mActionMode.finish();
            mActionMode = null;
        }
    }

    public boolean isSelectActionBarShowing() {
        return mActionMode != null;
    }

    private void resetGestureDetectors() {
        mContentViewGestureHandler.resetGestureHandlers();
    }

    /**
     * @see View#onAttachedToWindow()
     */
    @SuppressWarnings("javadoc")
    public void onAttachedToWindow() {
        mAttachedToWindow = true;
        if (mNativeContentViewCore != 0) {
            assert mPid == nativeGetCurrentRenderProcessId(mNativeContentViewCore);
            ChildProcessLauncher.bindAsHighPriority(mPid);
            // Normally the initial binding is removed in onRenderProcessSwap(), but it is possible
            // to construct WebContents and spawn the renderer before passing it to ContentViewCore.
            // In this case there will be no onRenderProcessSwap() call and the initial binding will
            // be removed here.
            ChildProcessLauncher.removeInitialBinding(mPid);
        }
        setAccessibilityState(mAccessibilityManager.isEnabled());
    }

    /**
     * @see View#onDetachedFromWindow()
     */
    @SuppressWarnings("javadoc")
    public void onDetachedFromWindow() {
        mAttachedToWindow = false;
        if (mNativeContentViewCore != 0) {
            assert mPid == nativeGetCurrentRenderProcessId(mNativeContentViewCore);
            ChildProcessLauncher.unbindAsHighPriority(mPid);
        }
        setInjectedAccessibility(false);
        hidePopupDialog();
        mZoomControlsDelegate.dismissZoomPicker();
        unregisterAccessibilityContentObserver();
    }

    /**
     * @see View#onVisibilityChanged(android.view.View, int)
     */
    public void onVisibilityChanged(View changedView, int visibility) {
        if (visibility != View.VISIBLE) {
            mZoomControlsDelegate.dismissZoomPicker();
        }
    }

    /**
     * @see View#onCreateInputConnection(EditorInfo)
     */
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        if (!mImeAdapter.hasTextInputType()) {
            // Although onCheckIsTextEditor will return false in this case, the EditorInfo
            // is still used by the InputMethodService. Need to make sure the IME doesn't
            // enter fullscreen mode.
            outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
        }
        mInputConnection =
                mAdapterInputConnectionFactory.get(mContainerView, mImeAdapter, outAttrs);
        return mInputConnection;
    }

    public Editable getEditableForTest() {
        return mInputConnection.getEditable();
    }

    /**
     * @see View#onCheckIsTextEditor()
     */
    public boolean onCheckIsTextEditor() {
        return mImeAdapter.hasTextInputType();
    }

    /**
     * @see View#onConfigurationChanged(Configuration)
     */
    @SuppressWarnings("javadoc")
    public void onConfigurationChanged(Configuration newConfig) {
        TraceEvent.begin();

        if (newConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
            mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore),
                    ImeAdapter.getTextInputTypeNone(),
                    AdapterInputConnection.INVALID_SELECTION,
                    AdapterInputConnection.INVALID_SELECTION);
            InputMethodManager manager = (InputMethodManager)
                    getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            manager.restartInput(mContainerView);
        }
        mContainerViewInternals.super_onConfigurationChanged(newConfig);
        mNeedUpdateOrientationChanged = true;
        TraceEvent.end();
    }

    /**
     * @see View#onSizeChanged(int, int, int, int)
     */
    @SuppressWarnings("javadoc")
    public void onSizeChanged(int wPix, int hPix, int owPix, int ohPix) {
        if (getViewportWidthPix() == wPix && getViewportHeightPix() == hPix) return;

        mViewportWidthPix = wPix;
        mViewportHeightPix = hPix;
        if (mNativeContentViewCore != 0) {
            nativeWasResized(mNativeContentViewCore);
        }

        updateAfterSizeChanged();
    }

    /**
     * Called when the underlying surface the compositor draws to changes size.
     * This may be larger than the viewport size.
     */
    public void onPhysicalBackingSizeChanged(int wPix, int hPix) {
        if (mPhysicalBackingWidthPix == wPix && mPhysicalBackingHeightPix == hPix) return;

        mPhysicalBackingWidthPix = wPix;
        mPhysicalBackingHeightPix = hPix;

        if (mNativeContentViewCore != 0) {
            nativeWasResized(mNativeContentViewCore);
        }
    }

    /**
     * Called when the amount the surface is overdrawing off the bottom has changed.
     * @param overdrawHeightPix The overdraw height.
     */
    public void onOverdrawBottomHeightChanged(int overdrawHeightPix) {
        if (mOverdrawBottomHeightPix == overdrawHeightPix) return;

        mOverdrawBottomHeightPix = overdrawHeightPix;

        if (mNativeContentViewCore != 0) {
            nativeWasResized(mNativeContentViewCore);
        }
    }

    private void updateAfterSizeChanged() {
        mPopupZoomer.hide(false);

        // Execute a delayed form focus operation because the OSK was brought
        // up earlier.
        if (!mFocusPreOSKViewportRect.isEmpty()) {
            Rect rect = new Rect();
            getContainerView().getWindowVisibleDisplayFrame(rect);
            if (!rect.equals(mFocusPreOSKViewportRect)) {
                // Only assume the OSK triggered the onSizeChanged if width was preserved.
                if (rect.width() == mFocusPreOSKViewportRect.width()) {
                    scrollFocusedEditableNodeIntoView();
                }
                mFocusPreOSKViewportRect.setEmpty();
            }
        } else if (mUnfocusOnNextSizeChanged) {
            undoScrollFocusedEditableNodeIntoViewIfNeeded(true);
            mUnfocusOnNextSizeChanged = false;
        }

        if (mNeedUpdateOrientationChanged) {
            sendOrientationChangeEvent();
            mNeedUpdateOrientationChanged = false;
        }
    }

    private void scrollFocusedEditableNodeIntoView() {
        if (mNativeContentViewCore != 0) {
            Runnable scrollTask = new Runnable() {
                @Override
                public void run() {
                    if (mNativeContentViewCore != 0) {
                        nativeScrollFocusedEditableNodeIntoView(mNativeContentViewCore);
                    }
                }
            };

            scrollTask.run();

            // The native side keeps track of whether the zoom and scroll actually occurred. It is
            // more efficient to do it this way and sometimes fire an unnecessary message rather
            // than synchronize with the renderer and always have an additional message.
            mScrolledAndZoomedFocusedEditableNode = true;
        }
    }

    private void undoScrollFocusedEditableNodeIntoViewIfNeeded(boolean backButtonPressed) {
        // The only call to this function that matters is the first call after the
        // scrollFocusedEditableNodeIntoView function call.
        // If the first call to this function is a result of a back button press we want to undo the
        // preceding scroll. If the call is a result of some other action we don't want to perform
        // an undo.
        // All subsequent calls are ignored since only the scroll function sets
        // mScrolledAndZoomedFocusedEditableNode to true.
        if (mScrolledAndZoomedFocusedEditableNode && backButtonPressed &&
                mNativeContentViewCore != 0) {
            Runnable scrollTask = new Runnable() {
                @Override
                public void run() {
                    if (mNativeContentViewCore != 0) {
                        nativeUndoScrollFocusedEditableNodeIntoView(mNativeContentViewCore);
                    }
                }
            };

            scrollTask.run();
        }
        mScrolledAndZoomedFocusedEditableNode = false;
    }

    /**
     * @see View#onWindowFocusChanged(boolean)
     */
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        if (!hasWindowFocus) {
            mContentViewGestureHandler.onWindowFocusLost();
        }
    }

    public void onFocusChanged(boolean gainFocus) {
        if (!gainFocus) getContentViewClient().onImeStateChangeRequested(false);
        if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus);
    }

    /**
     * @see View#onKeyUp(int, KeyEvent)
     */
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (mPopupZoomer.isShowing() && keyCode == KeyEvent.KEYCODE_BACK) {
            mPopupZoomer.hide(true);
            return true;
        }
        return mContainerViewInternals.super_onKeyUp(keyCode, event);
    }

    /**
     * @see View#dispatchKeyEventPreIme(KeyEvent)
     */
    public boolean dispatchKeyEventPreIme(KeyEvent event) {
        try {
            TraceEvent.begin();
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && mImeAdapter.isActive()) {
                mUnfocusOnNextSizeChanged = true;
            } else {
                undoScrollFocusedEditableNodeIntoViewIfNeeded(false);
            }
            return mContainerViewInternals.super_dispatchKeyEventPreIme(event);
        } finally {
            TraceEvent.end();
        }
    }

    /**
     * @see View#dispatchKeyEvent(KeyEvent)
     */
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (getContentViewClient().shouldOverrideKeyEvent(event)) {
            return mContainerViewInternals.super_dispatchKeyEvent(event);
        }

        if (mImeAdapter.dispatchKeyEvent(event)) return true;

        return mContainerViewInternals.super_dispatchKeyEvent(event);
    }

    /**
     * @see View#onHoverEvent(MotionEvent)
     * Mouse move events are sent on hover enter, hover move and hover exit.
     * They are sent on hover exit because sometimes it acts as both a hover
     * move and hover exit.
     */
    public boolean onHoverEvent(MotionEvent event) {
        TraceEvent.begin("onHoverEvent");
        mContainerView.removeCallbacks(mFakeMouseMoveRunnable);
        if (mBrowserAccessibilityManager != null) {
            return mBrowserAccessibilityManager.onHoverEvent(event);
        }
        if (mNativeContentViewCore != 0) {
            nativeSendMouseMoveEvent(mNativeContentViewCore, event.getEventTime(),
                    event.getX(), event.getY());
        }
        TraceEvent.end("onHoverEvent");
        return true;
    }

    /**
     * @see View#onGenericMotionEvent(MotionEvent)
     */
    public boolean onGenericMotionEvent(MotionEvent event) {
        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_SCROLL:
                    nativeSendMouseWheelEvent(mNativeContentViewCore, event.getEventTime(),
                            event.getX(), event.getY(),
                            event.getAxisValue(MotionEvent.AXIS_VSCROLL));

                    mContainerView.removeCallbacks(mFakeMouseMoveRunnable);
                    // Send a delayed onMouseMove event so that we end
                    // up hovering over the right position after the scroll.
                    final MotionEvent eventFakeMouseMove = MotionEvent.obtain(event);
                    mFakeMouseMoveRunnable = new Runnable() {
                          @Override
                          public void run() {
                              onHoverEvent(eventFakeMouseMove);
                          }
                    };
                    mContainerView.postDelayed(mFakeMouseMoveRunnable, 250);
                    return true;
            }
        }
        return mContainerViewInternals.super_onGenericMotionEvent(event);
    }

    /**
     * @see View#scrollBy(int, int)
     * Currently the ContentView scrolling happens in the native side. In
     * the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo()
     * are overridden, so that View's mScrollX and mScrollY will be unchanged at
     * (0, 0). This is critical for drawing ContentView correctly.
     */
    public void scrollBy(int xPix, int yPix) {
        if (mNativeContentViewCore != 0) {
            nativeScrollBy(mNativeContentViewCore,
                    System.currentTimeMillis(), 0, 0, xPix, yPix, false);
        }
    }

    /**
     * @see View#scrollTo(int, int)
     */
    public void scrollTo(int xPix, int yPix) {
        if (mNativeContentViewCore == 0) return;
        final float xCurrentPix = mRenderCoordinates.getScrollXPix();
        final float yCurrentPix = mRenderCoordinates.getScrollYPix();
        final float dxPix = xPix - xCurrentPix;
        final float dyPix = yPix - yCurrentPix;
        if (dxPix != 0 || dyPix != 0) {
            long time = System.currentTimeMillis();
            nativeScrollBegin(mNativeContentViewCore, time, xCurrentPix, yCurrentPix);
            nativeScrollBy(mNativeContentViewCore,
                    time, xCurrentPix, yCurrentPix, dxPix, dyPix, false);
            nativeScrollEnd(mNativeContentViewCore, time);
        }
    }

    // NOTE: this can go away once ContentView.getScrollX() reports correct values.
    //       see: b/6029133
    public int getNativeScrollXForTest() {
        return mRenderCoordinates.getScrollXPixInt();
    }

    // NOTE: this can go away once ContentView.getScrollY() reports correct values.
    //       see: b/6029133
    public int getNativeScrollYForTest() {
        return mRenderCoordinates.getScrollYPixInt();
    }

    /**
     * @see View#computeHorizontalScrollExtent()
     */
    @SuppressWarnings("javadoc")
    public int computeHorizontalScrollExtent() {
        return mRenderCoordinates.getLastFrameViewportWidthPixInt();
    }

    /**
     * @see View#computeHorizontalScrollOffset()
     */
    @SuppressWarnings("javadoc")
    public int computeHorizontalScrollOffset() {
        return mRenderCoordinates.getScrollXPixInt();
    }

    /**
     * @see View#computeHorizontalScrollRange()
     */
    @SuppressWarnings("javadoc")
    public int computeHorizontalScrollRange() {
        return mRenderCoordinates.getContentWidthPixInt();
    }

    /**
     * @see View#computeVerticalScrollExtent()
     */
    @SuppressWarnings("javadoc")
    public int computeVerticalScrollExtent() {
        return mRenderCoordinates.getLastFrameViewportHeightPixInt();
    }

    /**
     * @see View#computeVerticalScrollOffset()
     */
    @SuppressWarnings("javadoc")
    public int computeVerticalScrollOffset() {
        return mRenderCoordinates.getScrollYPixInt();
    }

    /**
     * @see View#computeVerticalScrollRange()
     */
    @SuppressWarnings("javadoc")
    public int computeVerticalScrollRange() {
        return mRenderCoordinates.getContentHeightPixInt();
    }

    // End FrameLayout overrides.

    /**
     * @see View#awakenScrollBars(int, boolean)
     */
    @SuppressWarnings("javadoc")
    public boolean awakenScrollBars(int startDelay, boolean invalidate) {
        // For the default implementation of ContentView which draws the scrollBars on the native
        // side, calling this function may get us into a bad state where we keep drawing the
        // scrollBars, so disable it by always returning false.
        if (mContainerView.getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) {
            return false;
        } else {
            return mContainerViewInternals.super_awakenScrollBars(startDelay, invalidate);
        }
    }

    /**
     * Called by native side when the corresponding renderer crashes. Note that if a renderer is
     * shared between tabs, this might be called multiple times while the tab is crashed. This is
     * because the tabs sharing a renderer also share RenderProcessHost. When one of those tabs
     * reloads and a new renderer is created for the shared RenderProcessHost, all tabs are notified
     * in onRenderProcessSwap(), not only the one that reloads. If this renderer dies, all the other
     * dead tabs are notified again.
     * @param alreadyCrashed true iff this tab is already in crashed state but the shared renderer
     *                       resurrected and died again since the last time this was called.
     */
    @SuppressWarnings("unused")
    @CalledByNative
    private void onTabCrash(boolean alreadyCrashed) {
        assert mPid != 0;
        if (!alreadyCrashed) {
            getContentViewClient().onRendererCrash(ChildProcessLauncher.isOomProtected(mPid));
        }
        mPid = 0;
    }

    private void handleTapOrPress(
            long timeMs, float xPix, float yPix, int isLongPressOrTap, boolean showPress) {
        if (mContainerView.isFocusable() && mContainerView.isFocusableInTouchMode()
                && !mContainerView.isFocused())  {
            mContainerView.requestFocus();
        }

        if (!mPopupZoomer.isShowing()) mPopupZoomer.setLastTouch(xPix, yPix);

        if (isLongPressOrTap == IS_LONG_PRESS) {
            getInsertionHandleController().allowAutomaticShowing();
            getSelectionHandleController().allowAutomaticShowing();
            if (mNativeContentViewCore != 0) {
                nativeLongPress(mNativeContentViewCore, timeMs, xPix, yPix, false);
            }
        } else if (isLongPressOrTap == IS_LONG_TAP) {
            getInsertionHandleController().allowAutomaticShowing();
            getSelectionHandleController().allowAutomaticShowing();
            if (mNativeContentViewCore != 0) {
                nativeLongTap(mNativeContentViewCore, timeMs, xPix, yPix, false);
            }
        } else {
            if (!showPress && mNativeContentViewCore != 0) {
                nativeShowPressState(mNativeContentViewCore, timeMs, xPix, yPix);
            }
            if (mSelectionEditable) getInsertionHandleController().allowAutomaticShowing();
            if (mNativeContentViewCore != 0) {
                nativeSingleTap(mNativeContentViewCore, timeMs, xPix, yPix, false);
            }
        }
    }

    public void setZoomControlsDelegate(ZoomControlsDelegate zoomControlsDelegate) {
        mZoomControlsDelegate = zoomControlsDelegate;
    }

    public void updateMultiTouchZoomSupport(boolean supportsMultiTouchZoom) {
        mZoomManager.updateMultiTouchSupport(supportsMultiTouchZoom);
    }

    public void updateDoubleTapDragSupport(boolean supportsDoubleTapDrag) {
        mContentViewGestureHandler.updateDoubleTapDragSupport(supportsDoubleTapDrag);
    }

    public void selectPopupMenuItems(int[] indices) {
        if (mNativeContentViewCore != 0) {
            nativeSelectPopupMenuItems(mNativeContentViewCore, indices);
        }
    }

    /**
     * Get the screen orientation from the OS and push it to WebKit.
     *
     * TODO(husky): Add a hook for mock orientations.
     *
     * TODO(husky): Currently each new tab starts with an orientation of 0 until you actually
     * rotate the device. This is wrong if you actually started in landscape mode. To fix this, we
     * need to push the correct orientation, but only after WebKit's Frame object has been fully
     * initialized. Need to find a good time to do that. onPageFinished() would probably work but
     * it isn't implemented yet.
     */
    private void sendOrientationChangeEvent() {
        if (mNativeContentViewCore == 0) return;

        WindowManager windowManager =
                (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        switch (windowManager.getDefaultDisplay().getRotation()) {
            case Surface.ROTATION_90:
                nativeSendOrientationChangeEvent(mNativeContentViewCore, 90);
                break;
            case Surface.ROTATION_180:
                nativeSendOrientationChangeEvent(mNativeContentViewCore, 180);
                break;
            case Surface.ROTATION_270:
                nativeSendOrientationChangeEvent(mNativeContentViewCore, -90);
                break;
            case Surface.ROTATION_0:
                nativeSendOrientationChangeEvent(mNativeContentViewCore, 0);
                break;
            default:
                Log.w(TAG, "Unknown rotation!");
                break;
        }
    }

    /**
     * Register the delegate to be used when content can not be handled by
     * the rendering engine, and should be downloaded instead. This will replace
     * the current delegate, if any.
     * @param delegate An implementation of ContentViewDownloadDelegate.
     */
    public void setDownloadDelegate(ContentViewDownloadDelegate delegate) {
        mDownloadDelegate = delegate;
    }

    // Called by DownloadController.
    ContentViewDownloadDelegate getDownloadDelegate() {
        return mDownloadDelegate;
    }

    private SelectionHandleController getSelectionHandleController() {
        if (mSelectionHandleController == null) {
            mSelectionHandleController = new SelectionHandleController(
                    getContainerView(), mPositionObserver) {
                @Override
                public void selectBetweenCoordinates(int x1, int y1, int x2, int y2) {
                    if (mNativeContentViewCore != 0 && !(x1 == x2 && y1 == y2)) {
                        nativeSelectBetweenCoordinates(mNativeContentViewCore,
                                x1, y1 - mRenderCoordinates.getContentOffsetYPix(),
                                x2, y2 - mRenderCoordinates.getContentOffsetYPix());
                    }
                }

                @Override
                public void showHandles(int startDir, int endDir) {
                    super.showHandles(startDir, endDir);
                    showSelectActionBar();
                }

            };

            mSelectionHandleController.hideAndDisallowAutomaticShowing();
        }

        return mSelectionHandleController;
    }

    private InsertionHandleController getInsertionHandleController() {
        if (mInsertionHandleController == null) {
            mInsertionHandleController = new InsertionHandleController(
                    getContainerView(), mPositionObserver) {
                private static final int AVERAGE_LINE_HEIGHT = 14;

                @Override
                public void setCursorPosition(int x, int y) {
                    if (mNativeContentViewCore != 0) {
                        nativeMoveCaret(mNativeContentViewCore,
                                x, y - mRenderCoordinates.getContentOffsetYPix());
                    }
                }

                @Override
                public void paste() {
                    mImeAdapter.paste();
                    hideHandles();
                }

                @Override
                public int getLineHeight() {
                    return (int) Math.ceil(
                            mRenderCoordinates.fromLocalCssToPix(AVERAGE_LINE_HEIGHT));
                }

                @Override
                public void showHandle() {
                    super.showHandle();
                }
            };

            mInsertionHandleController.hideAndDisallowAutomaticShowing();
        }

        return mInsertionHandleController;
    }

    @VisibleForTesting
    public InsertionHandleController getInsertionHandleControllerForTest() {
        return mInsertionHandleController;
    }

    @VisibleForTesting
    public SelectionHandleController getSelectionHandleControllerForTest() {
        return mSelectionHandleController;
    }

    private void updateHandleScreenPositions() {
        if (isSelectionHandleShowing()) {
            mSelectionHandleController.setStartHandlePosition(
                    mStartHandlePoint.getXPix(), mStartHandlePoint.getYPix());
            mSelectionHandleController.setEndHandlePosition(
                    mEndHandlePoint.getXPix(), mEndHandlePoint.getYPix());
        }

        if (isInsertionHandleShowing()) {
            mInsertionHandleController.setHandlePosition(
                    mInsertionHandlePoint.getXPix(), mInsertionHandlePoint.getYPix());
        }
    }

    private void hideHandles() {
        if (mSelectionHandleController != null) {
            mSelectionHandleController.hideAndDisallowAutomaticShowing();
        }
        if (mInsertionHandleController != null) {
            mInsertionHandleController.hideAndDisallowAutomaticShowing();
        }
        mPositionObserver.removeListener(mPositionListener);
    }

    private void showSelectActionBar() {
        if (mActionMode != null) {
            mActionMode.invalidate();
            return;
        }

        // Start a new action mode with a SelectActionModeCallback.
        SelectActionModeCallback.ActionHandler actionHandler =
                new SelectActionModeCallback.ActionHandler() {
            @Override
            public boolean selectAll() {
                return mImeAdapter.selectAll();
            }

            @Override
            public boolean cut() {
                return mImeAdapter.cut();
            }

            @Override
            public boolean copy() {
                return mImeAdapter.copy();
            }

            @Override
            public boolean paste() {
                return mImeAdapter.paste();
            }

            @Override
            public boolean isSelectionEditable() {
                return mSelectionEditable;
            }

            @Override
            public String getSelectedText() {
                return ContentViewCore.this.getSelectedText();
            }

            @Override
            public void onDestroyActionMode() {
                mActionMode = null;
                if (mUnselectAllOnActionModeDismiss) mImeAdapter.unselect();
                getContentViewClient().onContextualActionBarHidden();
            }
        };
        mActionMode = null;
        // On ICS, startActionMode throws an NPE when getParent() is null.
        if (mContainerView.getParent() != null) {
            mActionMode = mContainerView.startActionMode(
                    getContentViewClient().getSelectActionModeCallback(getContext(), actionHandler,
                            nativeIsIncognito(mNativeContentViewCore)));
        }
        mUnselectAllOnActionModeDismiss = true;
        if (mActionMode == null) {
            // There is no ActionMode, so remove the selection.
            mImeAdapter.unselect();
        } else {
            getContentViewClient().onContextualActionBarShown();
        }
    }

    public boolean getUseDesktopUserAgent() {
        if (mNativeContentViewCore != 0) {
            return nativeGetUseDesktopUserAgent(mNativeContentViewCore);
        }
        return false;
    }

    /**
     * Set whether or not we're using a desktop user agent for the currently loaded page.
     * @param override If true, use a desktop user agent.  Use a mobile one otherwise.
     * @param reloadOnChange Reload the page if the UA has changed.
     */
    public void setUseDesktopUserAgent(boolean override, boolean reloadOnChange) {
        if (mNativeContentViewCore != 0) {
            nativeSetUseDesktopUserAgent(mNativeContentViewCore, override, reloadOnChange);
        }
    }

    public void clearSslPreferences() {
        nativeClearSslPreferences(mNativeContentViewCore);
    }

    /**
     * @return Whether the native ContentView has crashed.
     */
    public boolean isCrashed() {
        if (mNativeContentViewCore == 0) return false;
        return nativeCrashed(mNativeContentViewCore);
    }

    private boolean isSelectionHandleShowing() {
        return mSelectionHandleController != null && mSelectionHandleController.isShowing();
    }

    private boolean isInsertionHandleShowing() {
        return mInsertionHandleController != null && mInsertionHandleController.isShowing();
    }

    private void updateTextHandlesForGesture(int type) {
        switch(type) {
            case ContentViewGestureHandler.GESTURE_DOUBLE_TAP:
            case ContentViewGestureHandler.GESTURE_SCROLL_START:
            case ContentViewGestureHandler.GESTURE_FLING_START:
            case ContentViewGestureHandler.GESTURE_PINCH_BEGIN:
                temporarilyHideTextHandles();
                break;

            default:
                break;
        }
    }

    // Makes the insertion/selection handles invisible. They will fade back in shortly after the
    // last call to scheduleTextHandleFadeIn (or temporarilyHideTextHandles).
    private void temporarilyHideTextHandles() {
        if (isSelectionHandleShowing() && !mSelectionHandleController.isDragging()) {
            mSelectionHandleController.setHandleVisibility(HandleView.INVISIBLE);
        }
        if (isInsertionHandleShowing() && !mInsertionHandleController.isDragging()) {
            mInsertionHandleController.setHandleVisibility(HandleView.INVISIBLE);
        }
        scheduleTextHandleFadeIn();
    }

    private boolean allowTextHandleFadeIn() {
        if (mContentViewGestureHandler.isNativeScrolling() ||
                mContentViewGestureHandler.isNativePinching()) {
            return false;
        }

        if (mPopupZoomer.isShowing()) return false;

        return true;
    }

    // Cancels any pending fade in and schedules a new one.
    private void scheduleTextHandleFadeIn() {
        if (!isInsertionHandleShowing() && !isSelectionHandleShowing()) return;

        if (mDeferredHandleFadeInRunnable == null) {
            mDeferredHandleFadeInRunnable = new Runnable() {
                @Override
                public void run() {
                    if (!allowTextHandleFadeIn()) {
                        // Delay fade in until it is allowed.
                        scheduleTextHandleFadeIn();
                    } else {
                        if (isSelectionHandleShowing()) {
                            mSelectionHandleController.beginHandleFadeIn();
                        }
                        if (isInsertionHandleShowing()) {
                            mInsertionHandleController.beginHandleFadeIn();
                        }
                    }
                }
            };
        }

        mContainerView.removeCallbacks(mDeferredHandleFadeInRunnable);
        mContainerView.postDelayed(mDeferredHandleFadeInRunnable, TEXT_HANDLE_FADE_IN_DELAY);
    }

    /**
     * Shows the IME if the focused widget could accept text input.
     */
    public void showImeIfNeeded() {
        if (mNativeContentViewCore != 0) nativeShowImeIfNeeded(mNativeContentViewCore);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void updateFrameInfo(
            float scrollOffsetX, float scrollOffsetY,
            float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor,
            float contentWidth, float contentHeight,
            float viewportWidth, float viewportHeight,
            float controlsOffsetYCss, float contentOffsetYCss,
            float overdrawBottomHeightCss) {
        TraceEvent.instant("ContentViewCore:updateFrameInfo");
        // Adjust contentWidth/Height to be always at least as big as
        // the actual viewport (as set by onSizeChanged).
        contentWidth = Math.max(contentWidth,
                mRenderCoordinates.fromPixToLocalCss(mViewportWidthPix));
        contentHeight = Math.max(contentHeight,
                mRenderCoordinates.fromPixToLocalCss(mViewportHeightPix));

        final float contentOffsetYPix = mRenderCoordinates.fromDipToPix(contentOffsetYCss);

        final boolean contentSizeChanged =
                contentWidth != mRenderCoordinates.getContentWidthCss()
                || contentHeight != mRenderCoordinates.getContentHeightCss();
        final boolean scaleLimitsChanged =
                minPageScaleFactor != mRenderCoordinates.getMinPageScaleFactor()
                || maxPageScaleFactor != mRenderCoordinates.getMaxPageScaleFactor();
        final boolean pageScaleChanged =
                pageScaleFactor != mRenderCoordinates.getPageScaleFactor();
        final boolean scrollChanged =
                pageScaleChanged
                || scrollOffsetX != mRenderCoordinates.getScrollX()
                || scrollOffsetY != mRenderCoordinates.getScrollY();
        final boolean contentOffsetChanged =
                contentOffsetYPix != mRenderCoordinates.getContentOffsetYPix();

        final boolean needHidePopupZoomer = contentSizeChanged || scrollChanged;
        final boolean needUpdateZoomControls = scaleLimitsChanged || scrollChanged;
        final boolean needTemporarilyHideHandles = scrollChanged;

        if (needHidePopupZoomer) mPopupZoomer.hide(true);

        mRenderCoordinates.updateFrameInfo(
                scrollOffsetX, scrollOffsetY,
                contentWidth, contentHeight,
                viewportWidth, viewportHeight,
                pageScaleFactor, minPageScaleFactor, maxPageScaleFactor,
                contentOffsetYPix);

        if (needTemporarilyHideHandles) temporarilyHideTextHandles();
        if (needUpdateZoomControls) mZoomControlsDelegate.updateZoomControls();
        if (contentOffsetChanged) updateHandleScreenPositions();

        // Update offsets for fullscreen.
        final float deviceScale = mRenderCoordinates.getDeviceScaleFactor();
        final float controlsOffsetPix = controlsOffsetYCss * deviceScale;
        final float overdrawBottomHeightPix = overdrawBottomHeightCss * deviceScale;
        getContentViewClient().onOffsetsForFullscreenChanged(
                controlsOffsetPix, contentOffsetYPix, overdrawBottomHeightPix);

        mPendingRendererFrame = true;
        if (mBrowserAccessibilityManager != null) {
            mBrowserAccessibilityManager.notifyFrameInfoInitialized();
        }

        // Update geometry for external video surface.
        getContentViewClient().onGeometryChanged(-1, null);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void updateImeAdapter(int nativeImeAdapterAndroid, int textInputType,
            String text, int selectionStart, int selectionEnd,
            int compositionStart, int compositionEnd, boolean showImeIfNeeded) {
        TraceEvent.begin();
        mSelectionEditable = (textInputType != ImeAdapter.getTextInputTypeNone());

        if (mActionMode != null) mActionMode.invalidate();

        mImeAdapter.attachAndShowIfNeeded(nativeImeAdapterAndroid, textInputType,
                selectionStart, selectionEnd, showImeIfNeeded);

        if (mInputConnection != null) {
            mInputConnection.setEditableText(text, selectionStart, selectionEnd,
                    compositionStart, compositionEnd);
        }
        TraceEvent.end();
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void processImeBatchStateAck(boolean isBegin) {
        if (mInputConnection == null) return;
        mInputConnection.setIgnoreTextInputStateUpdates(isBegin);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void setTitle(String title) {
        getContentViewClient().onUpdateTitle(title);
    }

    /**
     * Called (from native) when the <select> popup needs to be shown.
     * @param items           Items to show.
     * @param enabled         POPUP_ITEM_TYPEs for items.
     * @param multiple        Whether the popup menu should support multi-select.
     * @param selectedIndices Indices of selected items.
     */
    @SuppressWarnings("unused")
    @CalledByNative
    private void showSelectPopup(String[] items, int[] enabled, boolean multiple,
            int[] selectedIndices) {
        SelectPopupDialog.show(this, items, enabled, multiple, selectedIndices);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void showDisambiguationPopup(Rect targetRect, Bitmap zoomedBitmap) {
        mPopupZoomer.setBitmap(zoomedBitmap);
        mPopupZoomer.show(targetRect);
        temporarilyHideTextHandles();
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private SmoothScroller createSmoothScroller(boolean scrollDown, int mouseEventX,
            int mouseEventY) {
        return new SmoothScroller(this, scrollDown, mouseEventX, mouseEventY);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void onSelectionChanged(String text) {
        mLastSelectedText = text;
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void onSelectionBoundsChanged(Rect anchorRectDip, int anchorDir, Rect focusRectDip,
            int focusDir, boolean isAnchorFirst) {
        // All coordinates are in DIP.
        int x1 = anchorRectDip.left;
        int y1 = anchorRectDip.bottom;
        int x2 = focusRectDip.left;
        int y2 = focusRectDip.bottom;

        if (x1 != x2 || y1 != y2 ||
                (mSelectionHandleController != null && mSelectionHandleController.isDragging())) {
            if (mInsertionHandleController != null) {
                mInsertionHandleController.hide();
            }
            if (isAnchorFirst) {
                mStartHandlePoint.setLocalDip(x1, y1);
                mEndHandlePoint.setLocalDip(x2, y2);
            } else {
                mStartHandlePoint.setLocalDip(x2, y2);
                mEndHandlePoint.setLocalDip(x1, y1);
            }

            boolean wereSelectionHandlesShowing = getSelectionHandleController().isShowing();

            getSelectionHandleController().onSelectionChanged(anchorDir, focusDir);
            updateHandleScreenPositions();
            mHasSelection = true;

            if (!wereSelectionHandlesShowing && getSelectionHandleController().isShowing()) {
                // TODO(cjhopman): Remove this when there is a better signal that long press caused
                // a selection. See http://crbug.com/150151.
                mContainerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
            }

        } else {
            mUnselectAllOnActionModeDismiss = false;
            hideSelectActionBar();
            if (x1 != 0 && y1 != 0 && mSelectionEditable) {
                // Selection is a caret, and a text field is focused.
                if (mSelectionHandleController != null) {
                    mSelectionHandleController.hide();
                }
                mInsertionHandlePoint.setLocalDip(x1, y1);

                getInsertionHandleController().onCursorPositionChanged();
                updateHandleScreenPositions();
                InputMethodManager manager = (InputMethodManager)
                        getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                if (manager.isWatchingCursor(mContainerView)) {
                    final int xPix = (int) mInsertionHandlePoint.getXPix();
                    final int yPix = (int) mInsertionHandlePoint.getYPix();
                    manager.updateCursor(mContainerView, xPix, yPix, xPix, yPix);
                }
            } else {
                // Deselection
                if (mSelectionHandleController != null) {
                    mSelectionHandleController.hideAndDisallowAutomaticShowing();
                }
                if (mInsertionHandleController != null) {
                    mInsertionHandleController.hideAndDisallowAutomaticShowing();
                }
            }
            mHasSelection = false;
        }
        if (isSelectionHandleShowing() || isInsertionHandleShowing()) {
            mPositionObserver.addListener(mPositionListener);
        }
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private static void onEvaluateJavaScriptResult(
            String jsonResult, JavaScriptCallback callback) {
        callback.handleJavaScriptResult(jsonResult);
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void showPastePopup(int xDip, int yDip) {
        mInsertionHandlePoint.setLocalDip(xDip, yDip);
        getInsertionHandleController().showHandle();
        updateHandleScreenPositions();
        getInsertionHandleController().showHandleWithPastePopup();
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void onRenderProcessSwap(int oldPid, int newPid) {
        assert mPid == oldPid || mPid == newPid;
        if (mAttachedToWindow && oldPid != newPid) {
            ChildProcessLauncher.unbindAsHighPriority(oldPid);
            ChildProcessLauncher.bindAsHighPriority(newPid);
        }

        // We want to remove the initial binding even if the ContentView is not attached, so that
        // renderers for ContentViews loading in background do not retain the high priority.
        ChildProcessLauncher.removeInitialBinding(newPid);
        mPid = newPid;
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void onWebContentsConnected() {
        attachImeAdapter();
    }

    @SuppressWarnings("unused")
    @CalledByNative
    private void onWebContentsSwapped() {
        attachImeAdapter();
    }

    /**
     * Attaches the native ImeAdapter object to the java ImeAdapter to allow communication via JNI.
     */
    public void attachImeAdapter() {
        if (mImeAdapter != null && mNativeContentViewCore != 0) {
            mImeAdapter.attach(nativeGetNativeImeAdapter(mNativeContentViewCore));
        }
    }

    /**
     * @return Whether a reload happens when this ContentView is activated.
     */
    public boolean needsReload() {
        return mNativeContentViewCore != 0 && nativeNeedsReload(mNativeContentViewCore);
    }

    /**
     * @see View#hasFocus()
     */
    @CalledByNative
    public boolean hasFocus() {
        return mContainerView.hasFocus();
    }

    /**
     * Simulate a pinch zoom gesture.
     *
     * @param delta the factor by which the current page scale should be multiplied by.
     *
     * @return whether the gesture was sent.
     */
    public boolean pinchByDelta(float delta) {
        if (mNativeContentViewCore == 0) {
            return false;
        }

        long timeMs = System.currentTimeMillis();
        int xPix = getViewportWidthPix() / 2;
        int yPix = getViewportHeightPix() / 2;

        getContentViewGestureHandler().pinchBegin(timeMs, xPix, yPix);
        getContentViewGestureHandler().pinchBy(timeMs, xPix, yPix, delta);
        getContentViewGestureHandler().pinchEnd(timeMs);

        return true;
    }

    /**
     * Invokes the graphical zoom picker widget for this ContentView.
     */
    @Override
    public void invokeZoomPicker() {
        mZoomControlsDelegate.invokeZoomPicker();
    }

    /**
     * This will mimic {@link #addPossiblyUnsafeJavascriptInterface(Object, String, Class)}
     * and automatically pass in {@link JavascriptInterface} as the required annotation.
     *
     * @param object The Java object to inject into the ContentViewCore's JavaScript context.  Null
     *               values are ignored.
     * @param name   The name used to expose the instance in JavaScript.
     */
    public void addJavascriptInterface(Object object, String name) {
        addPossiblyUnsafeJavascriptInterface(object, name, JavascriptInterface.class);
    }

    /**
     * This method injects the supplied Java object into the ContentViewCore.
     * The object is injected into the JavaScript context of the main frame,
     * using the supplied name. This allows the Java object to be accessed from
     * JavaScript. Note that that injected objects will not appear in
     * JavaScript until the page is next (re)loaded. For example:
     * <pre> view.addJavascriptInterface(new Object(), "injectedObject");
     * view.loadData("<!DOCTYPE html><title></title>", "text/html", null);
     * view.loadUrl("javascript:alert(injectedObject.toString())");</pre>
     * <p><strong>IMPORTANT:</strong>
     * <ul>
     * <li> addJavascriptInterface() can be used to allow JavaScript to control
     * the host application. This is a powerful feature, but also presents a
     * security risk. Use of this method in a ContentViewCore containing
     * untrusted content could allow an attacker to manipulate the host
     * application in unintended ways, executing Java code with the permissions
     * of the host application. Use extreme care when using this method in a
     * ContentViewCore which could contain untrusted content. Particular care
     * should be taken to avoid unintentional access to inherited methods, such
     * as {@link Object#getClass()}. To prevent access to inherited methods,
     * pass an annotation for {@code requiredAnnotation}.  This will ensure
     * that only methods with {@code requiredAnnotation} are exposed to the
     * Javascript layer.  {@code requiredAnnotation} will be passed to all
     * subsequently injected Java objects if any methods return an object.  This
     * means the same restrictions (or lack thereof) will apply.  Alternatively,
     * {@link #addJavascriptInterface(Object, String)} can be called, which
     * automatically uses the {@link JavascriptInterface} annotation.
     * <li> JavaScript interacts with Java objects on a private, background
     * thread of the ContentViewCore. Care is therefore required to maintain
     * thread safety.</li>
     * </ul></p>
     *
     * @param object             The Java object to inject into the
     *                           ContentViewCore's JavaScript context. Null
     *                           values are ignored.
     * @param name               The name used to expose the instance in
     *                           JavaScript.
     * @param requiredAnnotation Restrict exposed methods to ones with this
     *                           annotation.  If {@code null} all methods are
     *                           exposed.
     *
     */
    public void addPossiblyUnsafeJavascriptInterface(Object object, String name,
            Class<? extends Annotation> requiredAnnotation) {
        if (mNativeContentViewCore != 0 && object != null) {
            mJavaScriptInterfaces.put(name, object);
            nativeAddJavascriptInterface(mNativeContentViewCore, object, name, requiredAnnotation,
                    mRetainedJavaScriptObjects);
        }
    }

    /**
     * Removes a previously added JavaScript interface with the given name.
     *
     * @param name The name of the interface to remove.
     */
    public void removeJavascriptInterface(String name) {
        mJavaScriptInterfaces.remove(name);
        if (mNativeContentViewCore != 0) {
            nativeRemoveJavascriptInterface(mNativeContentViewCore, name);
        }
    }

    /**
     * Return the current scale of the ContentView.
     * @return The current page scale factor.
     */
    public float getScale() {
        return mRenderCoordinates.getPageScaleFactor();
    }

    /**
     * If the view is ready to draw contents to the screen. In hardware mode,
     * the initialization of the surface texture may not occur until after the
     * view has been added to the layout. This method will return {@code true}
     * once the texture is actually ready.
     */
    public boolean isReady() {
        return nativeIsRenderWidgetHostViewReady(mNativeContentViewCore);
    }

    @CalledByNative
    private void startContentIntent(String contentUrl) {
        getContentViewClient().onStartContentIntent(getContext(), contentUrl);
    }

    @Override
    public void onAccessibilityStateChanged(boolean enabled) {
        setAccessibilityState(enabled);
    }

    /**
     * Determines whether or not this ContentViewCore can handle this accessibility action.
     * @param action The action to perform.
     * @return Whether or not this action is supported.
     */
    public boolean supportsAccessibilityAction(int action) {
        return mAccessibilityInjector.supportsAccessibilityAction(action);
    }

    /**
     * Attempts to perform an accessibility action on the web content.  If the accessibility action
     * cannot be processed, it returns {@code null}, allowing the caller to know to call the
     * super {@link View#performAccessibilityAction(int, Bundle)} method and use that return value.
     * Otherwise the return value from this method should be used.
     * @param action The action to perform.
     * @param arguments Optional action arguments.
     * @return Whether the action was performed or {@code null} if the call should be delegated to
     *         the super {@link View} class.
     */
    public boolean performAccessibilityAction(int action, Bundle arguments) {
        if (mAccessibilityInjector.supportsAccessibilityAction(action)) {
            return mAccessibilityInjector.performAccessibilityAction(action, arguments);
        }

        return false;
    }

    /**
     * Set the BrowserAccessibilityManager, used for native accessibility
     * (not script injection). This is only set when system accessibility
     * has been enabled.
     * @param manager The new BrowserAccessibilityManager.
     */
    public void setBrowserAccessibilityManager(BrowserAccessibilityManager manager) {
        mBrowserAccessibilityManager = manager;
    }

    /**
     * Get the BrowserAccessibilityManager, used for native accessibility
     * (not script injection). This will return null when system accessibility
     * is not enabled.
     * @return This view's BrowserAccessibilityManager.
     */
    public BrowserAccessibilityManager getBrowserAccessibilityManager() {
        return mBrowserAccessibilityManager;
    }

    /**
     * If native accessibility (not script injection) is enabled, and if this is
     * running on JellyBean or later, returns an AccessibilityNodeProvider that
     * implements native accessibility for this view. Returns null otherwise.
     * Lazily initializes native accessibility here if it's allowed.
     * @return The AccessibilityNodeProvider, if available, or null otherwise.
     */
    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
        if (mBrowserAccessibilityManager != null) {
            return mBrowserAccessibilityManager.getAccessibilityNodeProvider();
        }

        if (mNativeAccessibilityAllowed &&
                !mNativeAccessibilityEnabled &&
                mNativeContentViewCore != 0 &&
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mNativeAccessibilityEnabled = true;
            nativeSetAccessibilityEnabled(mNativeContentViewCore, true);
        }

        return null;
    }

    /**
     * @see View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
     */
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        // Note: this is only used by the script-injecting accessibility code.
        mAccessibilityInjector.onInitializeAccessibilityNodeInfo(info);
    }

    /**
     * @see View#onInitializeAccessibilityEvent(AccessibilityEvent)
     */
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        // Note: this is only used by the script-injecting accessibility code.
        event.setClassName(this.getClass().getName());

        // Identify where the top-left of the screen currently points to.
        event.setScrollX(mRenderCoordinates.getScrollXPixInt());
        event.setScrollY(mRenderCoordinates.getScrollYPixInt());

        // The maximum scroll values are determined by taking the content dimensions and
        // subtracting off the actual dimensions of the ChromeView.
        int maxScrollXPix = Math.max(0, mRenderCoordinates.getMaxHorizontalScrollPixInt());
        int maxScrollYPix = Math.max(0, mRenderCoordinates.getMaxVerticalScrollPixInt());
        event.setScrollable(maxScrollXPix > 0 || maxScrollYPix > 0);

        // Setting the maximum scroll values requires API level 15 or higher.
        final int SDK_VERSION_REQUIRED_TO_SET_SCROLL = 15;
        if (Build.VERSION.SDK_INT >= SDK_VERSION_REQUIRED_TO_SET_SCROLL) {
            event.setMaxScrollX(maxScrollXPix);
            event.setMaxScrollY(maxScrollYPix);
        }
    }

    /**
     * Returns whether accessibility script injection is enabled on the device
     */
    public boolean isDeviceAccessibilityScriptInjectionEnabled() {
        try {
            if (!mContentSettings.getJavaScriptEnabled()) {
                return false;
            }

            int result = getContext().checkCallingOrSelfPermission(
                    android.Manifest.permission.INTERNET);
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }

            Field field = Settings.Secure.class.getField("ACCESSIBILITY_SCRIPT_INJECTION");
            field.setAccessible(true);
            String accessibilityScriptInjection = (String) field.get(null);
            ContentResolver contentResolver = getContext().getContentResolver();

            if (mAccessibilityScriptInjectionObserver == null) {
                ContentObserver contentObserver = new ContentObserver(new Handler()) {
                    public void onChange(boolean selfChange, Uri uri) {
                        setAccessibilityState(mAccessibilityManager.isEnabled());
                    }
                };
                contentResolver.registerContentObserver(
                    Settings.Secure.getUriFor(accessibilityScriptInjection),
                    false,
                    contentObserver);
                mAccessibilityScriptInjectionObserver = contentObserver;
            }

            return Settings.Secure.getInt(contentResolver, accessibilityScriptInjection, 0) == 1;
        } catch (NoSuchFieldException e) {
        } catch (IllegalAccessException e) {
        }
        return false;
    }

    /**
     * Returns whether or not accessibility injection is being used.
     */
    public boolean isInjectingAccessibilityScript() {
        return mAccessibilityInjector.accessibilityIsAvailable();
    }

    /**
     * Turns browser accessibility on or off.
     * If |state| is |false|, this turns off both native and injected accessibility.
     * Otherwise, if accessibility script injection is enabled, this will enable the injected
     * accessibility scripts. Native accessibility is enabled on demand.
     */
    public void setAccessibilityState(boolean state) {
        if (!state) {
            setInjectedAccessibility(false);
            mNativeAccessibilityAllowed = false;
        } else {
            boolean useScriptInjection = isDeviceAccessibilityScriptInjectionEnabled();
            setInjectedAccessibility(useScriptInjection);
            mNativeAccessibilityAllowed = !useScriptInjection;
        }
    }

    /**
     * Enable or disable injected accessibility features
     */
    public void setInjectedAccessibility(boolean enabled) {
        mAccessibilityInjector.addOrRemoveAccessibilityApisIfNecessary();
        mAccessibilityInjector.setScriptEnabled(enabled);
    }

    /**
     * Stop any TTS notifications that are currently going on.
     */
    public void stopCurrentAccessibilityNotifications() {
        mAccessibilityInjector.onPageLostFocus();
    }

    /**
     * Inform WebKit that Fullscreen mode has been exited by the user.
     */
    public void exitFullscreen() {
        nativeExitFullscreen(mNativeContentViewCore);
    }

    /**
     * Changes whether hiding the top controls is enabled.
     *
     * @param enableHiding Whether hiding the top controls should be enabled or not.
     * @param enableShowing Whether showing the top controls should be enabled or not.
     * @param animate Whether the transition should be animated or not.
     */
    public void updateTopControlsState(boolean enableHiding, boolean enableShowing,
            boolean animate) {
        nativeUpdateTopControlsState(mNativeContentViewCore, enableHiding, enableShowing, animate);
    }

    /**
     * Callback factory method for nativeGetNavigationHistory().
     */
    @CalledByNative
    private void addToNavigationHistory(Object history, int index, String url, String virtualUrl,
            String originalUrl, String title, Bitmap favicon) {
        NavigationEntry entry = new NavigationEntry(
                index, url, virtualUrl, originalUrl, title, favicon);
        ((NavigationHistory) history).addEntry(entry);
    }

    /**
     * Get a copy of the navigation history of the view.
     */
    public NavigationHistory getNavigationHistory() {
        NavigationHistory history = new NavigationHistory();
        if (mNativeContentViewCore != 0) {
            int currentIndex = nativeGetNavigationHistory(mNativeContentViewCore, history);
            history.setCurrentEntryIndex(currentIndex);
        }
        return history;
    }

    @Override
    public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit) {
        NavigationHistory history = new NavigationHistory();
        if (mNativeContentViewCore != 0) {
            nativeGetDirectedNavigationHistory(mNativeContentViewCore, history, isForward, itemLimit);
        }
        return history;
    }

    /**
     * @return The original request URL for the current navigation entry, or null if there is no
     *         current entry.
     */
    public String getOriginalUrlForActiveNavigationEntry() {
        if (mNativeContentViewCore != 0) {
            return nativeGetOriginalUrlForActiveNavigationEntry(mNativeContentViewCore);
        }
        return "";
    }

    /**
     * @return The cached copy of render positions and scales.
     */
    public RenderCoordinates getRenderCoordinates() {
        return mRenderCoordinates;
    }

    @CalledByNative
    private static Rect createRect(int x, int y, int right, int bottom) {
        return new Rect(x, y, right, bottom);
    }

    public void attachExternalVideoSurface(int playerId, Surface surface) {
        if (mNativeContentViewCore != 0) {
            nativeAttachExternalVideoSurface(mNativeContentViewCore, playerId, surface);
        }
    }

    public void detachExternalVideoSurface(int playerId) {
        if (mNativeContentViewCore != 0) {
            nativeDetachExternalVideoSurface(mNativeContentViewCore, playerId);
        }
    }

    private boolean onAnimate(long frameTimeMicros) {
        if (mNativeContentViewCore == 0) return false;
        return nativeOnAnimate(mNativeContentViewCore, frameTimeMicros);
    }

    private void animateIfNecessary(long frameTimeMicros) {
        if (mNeedAnimate) {
            mNeedAnimate = onAnimate(frameTimeMicros);
            if (!mNeedAnimate) setVSyncNotificationEnabled(false);
        }
    }

    @CalledByNative
    private void notifyExternalSurface(
            int playerId, boolean isRequest, float x, float y, float width, float height) {
        if (isRequest) getContentViewClient().onExternalVideoSurfaceRequested(playerId);
        getContentViewClient().onGeometryChanged(playerId, new RectF(x, y, x + width, y + height));
    }

    /**
     * Offer a subset of gesture events to the embedding View,
     * primarily for WebView compatibility.
     *
     * @param type The type of the event.
     *
     * @return true if the embedder handled the event.
     */
    private boolean offerGestureToEmbedder(int type) {
        if (type == ContentViewGestureHandler.GESTURE_LONG_PRESS) {
            return mContainerView.performLongClick();
        }
        return false;
    }

    private native int nativeInit(boolean hardwareAccelerated, int webContentsPtr,
            int viewAndroidPtr, int windowAndroidPtr);

    @CalledByNative
    private ContentVideoViewClient getContentVideoViewClient() {
        return mContentViewClient.getContentVideoViewClient();
    }

    @CalledByNative
    private boolean shouldBlockMediaRequest(String url) {
        return mContentViewClient.shouldBlockMediaRequest(url);
    }

    private native void nativeOnJavaContentViewCoreDestroyed(int nativeContentViewCoreImpl);

    private native void nativeLoadUrl(
            int nativeContentViewCoreImpl,
            String url,
            int loadUrlType,
            int transitionType,
            int uaOverrideOption,
            String extraHeaders,
            byte[] postData,
            String baseUrlForDataUrl,
            String virtualUrlForDataUrl,
            boolean canLoadLocalResources);

    private native String nativeGetURL(int nativeContentViewCoreImpl);

    private native String nativeGetTitle(int nativeContentViewCoreImpl);

    private native void nativeShowInterstitialPage(
            int nativeContentViewCoreImpl, String url, int nativeInterstitialPageDelegateAndroid);
    private native boolean nativeIsShowingInterstitialPage(int nativeContentViewCoreImpl);

    private native boolean nativeIsIncognito(int nativeContentViewCoreImpl);

    // Returns true if the native side crashed so that java side can draw a sad tab.
    private native boolean nativeCrashed(int nativeContentViewCoreImpl);

    private native void nativeSetFocus(int nativeContentViewCoreImpl, boolean focused);

    private native void nativeSendOrientationChangeEvent(
            int nativeContentViewCoreImpl, int orientation);

    // All touch events (including flings, scrolls etc) accept coordinates in physical pixels.
    private native boolean nativeSendTouchEvent(
            int nativeContentViewCoreImpl, long timeMs, int action, TouchPoint[] pts);

    private native int nativeSendMouseMoveEvent(
            int nativeContentViewCoreImpl, long timeMs, float x, float y);

    private native int nativeSendMouseWheelEvent(
            int nativeContentViewCoreImpl, long timeMs, float x, float y, float verticalAxis);

    private native void nativeScrollBegin(
            int nativeContentViewCoreImpl, long timeMs, float x, float y);

    private native void nativeScrollEnd(int nativeContentViewCoreImpl, long timeMs);

    private native void nativeScrollBy(
            int nativeContentViewCoreImpl, long timeMs, float x, float y,
            float deltaX, float deltaY, boolean lastInputEventForVSync);

    private native void nativeFlingStart(
            int nativeContentViewCoreImpl, long timeMs, float x, float y, float vx, float vy);

    private native void nativeFlingCancel(int nativeContentViewCoreImpl, long timeMs);

    private native void nativeSingleTap(
            int nativeContentViewCoreImpl, long timeMs, float x, float y, boolean linkPreviewTap);

    private native void nativeSingleTapUnconfirmed(
            int nativeContentViewCoreImpl, long timeMs, float x, float y);

    private native void nativeShowPressState(
            int nativeContentViewCoreImpl, long timeMs, float x, float y);

    private native void nativeShowPressCancel(
            int nativeContentViewCoreImpl, long timeMs, float x, float y);

    private native void nativeDoubleTap(
            int nativeContentViewCoreImpl, long timeMs, float x, float y);

    private native void nativeLongPress(
            int nativeContentViewCoreImpl, long timeMs, float x, float y, boolean linkPreviewTap);

    private native void nativeLongTap(
            int nativeContentViewCoreImpl, long timeMs, float x, float y, boolean linkPreviewTap);

    private native void nativePinchBegin(
            int nativeContentViewCoreImpl, long timeMs, float x, float y);

    private native void nativePinchEnd(int nativeContentViewCoreImpl, long timeMs);

    private native void nativePinchBy(int nativeContentViewCoreImpl, long timeMs,
            float anchorX, float anchorY, float deltaScale, boolean lastInputEventForVSync);

    private native void nativeSelectBetweenCoordinates(
            int nativeContentViewCoreImpl, float x1, float y1, float x2, float y2);

    private native void nativeMoveCaret(int nativeContentViewCoreImpl, float x, float y);

    private native boolean nativeCanGoBack(int nativeContentViewCoreImpl);
    private native boolean nativeCanGoForward(int nativeContentViewCoreImpl);
    private native boolean nativeCanGoToOffset(int nativeContentViewCoreImpl, int offset);
    private native void nativeGoBack(int nativeContentViewCoreImpl);
    private native void nativeGoForward(int nativeContentViewCoreImpl);
    private native void nativeGoToOffset(int nativeContentViewCoreImpl, int offset);
    private native void nativeGoToNavigationIndex(int nativeContentViewCoreImpl, int index);

    private native void nativeStopLoading(int nativeContentViewCoreImpl);

    private native void nativeReload(int nativeContentViewCoreImpl);

    private native void nativeCancelPendingReload(int nativeContentViewCoreImpl);

    private native void nativeContinuePendingReload(int nativeContentViewCoreImpl);

    private native void nativeSelectPopupMenuItems(int nativeContentViewCoreImpl, int[] indices);

    private native void nativeScrollFocusedEditableNodeIntoView(int nativeContentViewCoreImpl);
    private native void nativeUndoScrollFocusedEditableNodeIntoView(int nativeContentViewCoreImpl);
    private native boolean nativeNeedsReload(int nativeContentViewCoreImpl);

    private native void nativeClearHistory(int nativeContentViewCoreImpl);

    private native void nativeEvaluateJavaScript(int nativeContentViewCoreImpl,
            String script, JavaScriptCallback callback, boolean startRenderer);

    private native int nativeGetNativeImeAdapter(int nativeContentViewCoreImpl);

    private native int nativeGetCurrentRenderProcessId(int nativeContentViewCoreImpl);

    private native int nativeGetBackgroundColor(int nativeContentViewCoreImpl);

    private native void nativeOnShow(int nativeContentViewCoreImpl);
    private native void nativeOnHide(int nativeContentViewCoreImpl);

    private native void nativeSetUseDesktopUserAgent(int nativeContentViewCoreImpl,
            boolean enabled, boolean reloadOnChange);
    private native boolean nativeGetUseDesktopUserAgent(int nativeContentViewCoreImpl);

    private native void nativeClearSslPreferences(int nativeContentViewCoreImpl);

    private native void nativeAddJavascriptInterface(int nativeContentViewCoreImpl, Object object,
            String name, Class requiredAnnotation, HashSet<Object> retainedObjectSet);

    private native void nativeRemoveJavascriptInterface(int nativeContentViewCoreImpl, String name);

    private native int nativeGetNavigationHistory(int nativeContentViewCoreImpl, Object context);
    private native void nativeGetDirectedNavigationHistory(int nativeContentViewCoreImpl,
            Object context, boolean isForward, int maxEntries);
    private native String nativeGetOriginalUrlForActiveNavigationEntry(
            int nativeContentViewCoreImpl);

    private native void nativeUpdateVSyncParameters(int nativeContentViewCoreImpl,
            long timebaseMicros, long intervalMicros);

    private native void nativeOnVSync(int nativeContentViewCoreImpl, long frameTimeMicros);

    private native boolean nativeOnAnimate(int nativeContentViewCoreImpl, long frameTimeMicros);

    private native boolean nativePopulateBitmapFromCompositor(int nativeContentViewCoreImpl,
            Bitmap bitmap);

    private native void nativeWasResized(int nativeContentViewCoreImpl);

    private native boolean nativeIsRenderWidgetHostViewReady(int nativeContentViewCoreImpl);

    private native void nativeExitFullscreen(int nativeContentViewCoreImpl);
    private native void nativeUpdateTopControlsState(int nativeContentViewCoreImpl,
            boolean enableHiding, boolean enableShowing, boolean animate);

    private native void nativeShowImeIfNeeded(int nativeContentViewCoreImpl);

    private native void nativeAttachExternalVideoSurface(
            int nativeContentViewCoreImpl, int playerId, Surface surface);

    private native void nativeDetachExternalVideoSurface(
            int nativeContentViewCoreImpl, int playerId);

    private native void nativeSetAccessibilityEnabled(
            int nativeContentViewCoreImpl, boolean enabled);
}
