// 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 when the pinch gesture starts and
     * stops.
     */
    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();
    }

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

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

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

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

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

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

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