/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.webview.chromium;

import android.content.ComponentCallbacks2;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.http.SslCertificate;
import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.util.Base64;
import android.util.Log;
import android.view.HardwareCanvas;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.webkit.DownloadListener;
import android.webkit.FindActionModeCallback;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebViewProvider;
import android.widget.TextView;

import org.chromium.android_webview.AwBrowserContext;
import org.chromium.android_webview.AwContents;
import org.chromium.base.MemoryPressureListener;
import org.chromium.base.ThreadUtils;
import org.chromium.content.browser.LoadUrlParams;
import org.chromium.net.NetworkChangeNotifier;

import java.io.BufferedWriter;
import java.io.File;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/**
 * This class is the delegate to which WebViewProxy forwards all API calls.
 *
 * Most of the actual functionality is implemented by AwContents (or ContentViewCore within
 * it). This class also contains WebView-specific APIs that require the creation of other
 * adapters (otherwise org.chromium.content would depend on the webview.chromium package)
 * and a small set of no-op deprecated APIs.
 */
class WebViewChromium implements WebViewProvider,
          WebViewProvider.ScrollDelegate, WebViewProvider.ViewDelegate {

    private static final String TAG = WebViewChromium.class.getSimpleName();

    // The WebView that this WebViewChromium is the provider for.
    WebView mWebView;
    // Lets us access protected View-derived methods on the WebView instance we're backing.
    WebView.PrivateAccess mWebViewPrivate;
    // The client adapter class.
    private WebViewContentsClientAdapter mContentsClientAdapter;

    // Variables for functionality provided by this adapter ---------------------------------------
    // WebSettings adapter, lazily initialized in the getter
    private WebSettings mWebSettings;
    // The WebView wrapper for ContentViewCore and required browser compontents.
    private AwContents mAwContents;
    // Non-null if this webview is using the GL accelerated draw path.
    private DrawGLFunctor mGLfunctor;

    private AwBrowserContext mBrowserContext;

    private final WebView.HitTestResult mHitTestResult;

    private final int mAppTargetSdkVersion;

    public WebViewChromium(WebView webView, WebView.PrivateAccess webViewPrivate,
            AwBrowserContext browserContext) {
        checkThread();
        mWebView = webView;
        mWebViewPrivate = webViewPrivate;
        mHitTestResult = new WebView.HitTestResult();
        mBrowserContext = browserContext;
        mAppTargetSdkVersion = mWebView.getContext().getApplicationInfo().targetSdkVersion;
    }

    static void completeWindowCreation(WebView parent, WebView child) {
        AwContents parentContents = ((WebViewChromium) parent.getWebViewProvider()).mAwContents;
        AwContents childContents =
                child == null ? null : ((WebViewChromium) child.getWebViewProvider()).mAwContents;
        parentContents.supplyContentsForPopup(childContents);
    }

    // WebViewProvider methods --------------------------------------------------------------------

    @Override
    public void init(Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
        // BUG=6790250 |javaScriptInterfaces| was only ever used by the obsolete DumpRenderTree
        // so is ignored. TODO: remove it from WebViewProvider.
        final boolean isAccessFromFileURLsGrantedByDefault =
                 mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN;
        mContentsClientAdapter = new WebViewContentsClientAdapter(mWebView);
        mAwContents = new AwContents(mBrowserContext, mWebView, new InternalAccessAdapter(),
                mContentsClientAdapter, isAccessFromFileURLsGrantedByDefault);

        if (privateBrowsing) {
            final String msg = "Private browsing is not supported in WebView.";
            if (mAppTargetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) {
                throw new IllegalArgumentException(msg);
            } else {
                Log.w(TAG, msg);
                // Intentionally irreversibly disable the webview instance, so that private
                // user data cannot leak through misuse of a non-privateBrowing WebView instance.
                // Can't just null out mAwContents as we never null-check it before use.
                mAwContents.destroy();
                TextView warningLabel = new TextView(mWebView.getContext());
                warningLabel.setText(mWebView.getContext().getString(
                        com.android.internal.R.string.webviewchromium_private_browsing_warning));
                mWebView.addView(warningLabel);
            }
        }

    }

    private RuntimeException createThreadException() {
        return new IllegalStateException("Calling View methods on another thread than the UI " +
                "thread. PLEASE FILE A BUG! go/klp-webview-bug");
    }

    //  Intentionally not static, as no need to check thread on static methods
    private void checkThread() {
        if (!ThreadUtils.runningOnUiThread()) {
            final RuntimeException threadViolation = createThreadException();
            ThreadUtils.postOnUiThread(new Runnable() {
                @Override
                public void run() {
                    throw threadViolation;
                }
            });
            throw createThreadException();
        }
    }

    @Override
    public void setHorizontalScrollbarOverlay(boolean overlay) {
        checkThread();
        mAwContents.setHorizontalScrollbarOverlay(overlay);
    }

    @Override
    public void setVerticalScrollbarOverlay(boolean overlay) {
        checkThread();
        mAwContents.setVerticalScrollbarOverlay(overlay);
    }

    @Override
    public boolean overlayHorizontalScrollbar() {
        checkThread();
        return mAwContents.overlayHorizontalScrollbar();
    }

    @Override
    public boolean overlayVerticalScrollbar() {
        checkThread();
        return mAwContents.overlayVerticalScrollbar();
    }

    @Override
    public int getVisibleTitleHeight() {
        // This is deprecated in WebView and should always return 0.
        return 0;
    }

    @Override
    public SslCertificate getCertificate() {
        checkThread();
        return mAwContents.getCertificate();
    }

    @Override
    public void setCertificate(SslCertificate certificate) {
        checkThread();
        UnimplementedWebViewApi.invoke();
    }

    @Override
    public void savePassword(String host, String username, String password) {
        // This is a deprecated API: intentional no-op.
    }

    @Override
    public void setHttpAuthUsernamePassword(String host, String realm, String username,
                                            String password) {
        checkThread();
        mAwContents.setHttpAuthUsernamePassword(host, realm, username, password);
    }

    @Override
    public String[] getHttpAuthUsernamePassword(String host, String realm) {
        checkThread();
        return mAwContents.getHttpAuthUsernamePassword(host, realm);
    }

    @Override
    public void destroy() {
        checkThread();
        mAwContents.destroy();
        if (mGLfunctor != null) {
            mGLfunctor.destroy();
            mGLfunctor = null;
        }
    }

    @Override
    public void setNetworkAvailable(boolean networkUp) {
        checkThread();
        // Note that this purely toggles the JS navigator.online property.
        // It does not in affect chromium or network stack state in any way.
        mAwContents.setNetworkAvailable(networkUp);
    }

    @Override
    public WebBackForwardList saveState(Bundle outState) {
        checkThread();
        if (outState == null) return null;
        if (!mAwContents.saveState(outState)) return null;
        return copyBackForwardList();
    }

    @Override
    public boolean savePicture(Bundle b, File dest) {
        // Intentional no-op: hidden method on WebView.
        return false;
    }

    @Override
    public boolean restorePicture(Bundle b, File src) {
        // Intentional no-op: hidden method on WebView.
        return false;
    }

    @Override
    public WebBackForwardList restoreState(Bundle inState) {
        checkThread();
        if (inState == null) return null;
        if (!mAwContents.restoreState(inState)) return null;
        return copyBackForwardList();
    }

    @Override
    public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
        // TODO: We may actually want to do some sanity checks here (like filter about://chrome).

        // For backwards compatibility, apps targeting less than K will have JS URLs evaluated
        // directly and any result of the evaluation will not replace the current page content.
        // Matching Chrome behavior more closely; apps targetting >= K that load a JS URL will
        // have the result of that URL replace the content of the current page.
        final String JAVASCRIPT_SCHEME = "javascript:";
        if (mAppTargetSdkVersion < Build.VERSION_CODES.KEY_LIME_PIE &&
                url.startsWith(JAVASCRIPT_SCHEME)) {
            mAwContents.evaluateJavaScriptEvenIfNotYetNavigated(
                    url.substring(JAVASCRIPT_SCHEME.length()));
            return;
        }

        LoadUrlParams params = new LoadUrlParams(url);
        if (additionalHttpHeaders != null) params.setExtraHeaders(additionalHttpHeaders);
        loadUrlOnUiThread(params);
    }

    @Override
    public void loadUrl(String url) {
        loadUrl(url, null);
    }

    @Override
    public void postUrl(String url, byte[] postData) {
        LoadUrlParams params = LoadUrlParams.createLoadHttpPostParams(url, postData);
        Map<String,String> headers = new HashMap<String,String>();
        headers.put("Content-Type", "application/x-www-form-urlencoded");
        params.setExtraHeaders(headers);
        loadUrlOnUiThread(params);
    }

    private static boolean isBase64Encoded(String encoding) {
        return "base64".equals(encoding);
    }

    @Override
    public void loadData(String data, String mimeType, String encoding) {
        loadUrlOnUiThread(LoadUrlParams.createLoadDataParams(
                data, mimeType, isBase64Encoded(encoding)));
    }

    @Override
    public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding,
            String historyUrl) {
        LoadUrlParams loadUrlParams;

        if (baseUrl != null && baseUrl.startsWith("data:")) {
            // For backwards compatibility with WebViewClassic, we use the value of |encoding|
            // as the charset, as long as it's not "base64".
            boolean isBase64 = isBase64Encoded(encoding);
            loadUrlParams = LoadUrlParams.createLoadDataParamsWithBaseUrl(
                    data, mimeType, isBase64, baseUrl, historyUrl, isBase64 ? null : encoding);
        } else {
            if (baseUrl == null || baseUrl.length() == 0) baseUrl = "about:blank";
            // When loading data with a non-data: base URL, the classic WebView would effectively
            // "dump" that string of data into the WebView without going through regular URL
            // loading steps such as decoding URL-encoded entities. We achieve this same behavior by
            // base64 encoding the data that is passed here and then loading that as a data: URL.
            try {
                loadUrlParams = LoadUrlParams.createLoadDataParamsWithBaseUrl(
                        Base64.encodeToString(data.getBytes("utf-8"), Base64.DEFAULT), mimeType,
                        true, baseUrl, historyUrl, "utf-8");
            } catch (java.io.UnsupportedEncodingException e) {
                Log.wtf(TAG, "Unable to load data string " + data, e);
                return;
            }
        }
        loadUrlOnUiThread(loadUrlParams);
    }

    private void loadUrlOnUiThread(final LoadUrlParams loadUrlParams) {
        if (ThreadUtils.runningOnUiThread()) {
            mAwContents.loadUrl(loadUrlParams);
        } else {
            // Disallowed in WebView API for apps targetting a new SDK
            assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
            ThreadUtils.postOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mAwContents.loadUrl(loadUrlParams);
                }
            });
        }
    }

    public void evaluateJavaScript(String script, ValueCallback<String> resultCallback) {
        checkThread();
        mAwContents.evaluateJavaScript(script, resultCallback);
    }

    @Override
    public void saveWebArchive(String filename) {
        checkThread();
        saveWebArchive(filename, false, null);
    }

    @Override
    public void saveWebArchive(String basename, boolean autoname, ValueCallback<String> callback) {
        checkThread();
        mAwContents.saveWebArchive(basename, autoname, callback);
    }

    @Override
    public void stopLoading() {
        checkThread();
        mAwContents.stopLoading();
    }

    @Override
    public void reload() {
        checkThread();
        mAwContents.reload();
    }

    @Override
    public boolean canGoBack() {
        checkThread();
        return mAwContents.canGoBack();
    }

    @Override
    public void goBack() {
        checkThread();
        mAwContents.goBack();
    }

    @Override
    public boolean canGoForward() {
        checkThread();
        return mAwContents.canGoForward();
    }

    @Override
    public void goForward() {
        checkThread();
        mAwContents.goForward();
    }

    @Override
    public boolean canGoBackOrForward(int steps) {
        checkThread();
        return mAwContents.canGoBackOrForward(steps);
    }

    @Override
    public void goBackOrForward(int steps) {
        checkThread();
        mAwContents.goBackOrForward(steps);
    }

    @Override
    public boolean isPrivateBrowsingEnabled() {
        // Not supported in this WebView implementation.
        return false;
    }

    @Override
    public boolean pageUp(boolean top) {
        checkThread();
        return mAwContents.pageUp(top);
    }

    @Override
    public boolean pageDown(boolean bottom) {
        checkThread();
        return mAwContents.pageDown(bottom);
    }

    @Override
    public void clearView() {
        checkThread();
        UnimplementedWebViewApi.invoke();
    }

    @Override
    public Picture capturePicture() {
        checkThread();
        return mAwContents.capturePicture();
    }

    @Override
    public void exportToPdf(OutputStream stream, int width, int height,
            ValueCallback<Boolean> resultCallback) {
        checkThread();
        // TODO(sgurun) enable this only after upstream part lands
        //mAwContents.exportToPdf(stream, width, height, resultCallback);
    }

    @Override
    public float getScale() {
        checkThread();
        return mAwContents.getScale();
    }

    @Override
    public void setInitialScale(int scaleInPercent) {
        checkThread();
        mAwContents.getSettings().setInitialPageScale(scaleInPercent);
    }

    @Override
    public void invokeZoomPicker() {
        checkThread();
        mAwContents.invokeZoomPicker();
    }

    @Override
    public WebView.HitTestResult getHitTestResult() {
        checkThread();
        AwContents.HitTestData data = mAwContents.getLastHitTestResult();
        mHitTestResult.setType(data.hitTestResultType);
        mHitTestResult.setExtra(data.hitTestResultExtraData);
        return mHitTestResult;
    }

    @Override
    public void requestFocusNodeHref(Message hrefMsg) {
        checkThread();
        mAwContents.requestFocusNodeHref(hrefMsg);
    }

    @Override
    public void requestImageRef(Message msg) {
        checkThread();
        mAwContents.requestImageRef(msg);
    }

    @Override
    public String getUrl() {
        checkThread();
        String url =  mAwContents.getUrl();
        if (url == null || url.trim().isEmpty()) return null;
        return url;
    }

    @Override
    public String getOriginalUrl() {
        checkThread();
        String url =  mAwContents.getOriginalUrl();
        if (url == null || url.trim().isEmpty()) return null;
        return url;
    }

    @Override
    public String getTitle() {
        checkThread();
        return mAwContents.getTitle();
    }

    @Override
    public Bitmap getFavicon() {
        checkThread();
        return mAwContents.getFavicon();
    }

    @Override
    public String getTouchIconUrl() {
        // Intentional no-op: hidden method on WebView.
        return null;
    }

    @Override
    public int getProgress() {
        // No checkThread() because the value is cached java side (workaround for b/10533304).
        return mAwContents.getMostRecentProgress();
    }

    @Override
    public int getContentHeight() {
        checkThread();
        return mAwContents.getContentHeightCss();
    }

    @Override
    public int getContentWidth() {
        checkThread();
        return mAwContents.getContentWidthCss();
    }

    @Override
    public void pauseTimers() {
        checkThread();
        mAwContents.pauseTimers();
    }

    @Override
    public void resumeTimers() {
        checkThread();
        mAwContents.resumeTimers();
    }

    @Override
    public void onPause() {
        checkThread();
        mAwContents.onPause();
    }

    @Override
    public void onResume() {
        checkThread();
        mAwContents.onResume();
    }

    @Override
    public boolean isPaused() {
        checkThread();
        return mAwContents.isPaused();
    }

    @Override
    public void freeMemory() {
        checkThread();
        // This method is not intended to have any effect on release builds,
        // since memory is managed automatically by Chromium.
        // However, in debug builds, this method is exploited by our WebView
        // memory benchmarks to synthesize the memory pressure signal.
        if (Build.IS_DEBUGGABLE) {
            MemoryPressureListener.simulateMemoryPressureSignal(
                    ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
        }
    }

    @Override
    public void clearCache(boolean includeDiskFiles) {
        checkThread();
        mAwContents.clearCache(includeDiskFiles);
    }

    /**
     * This is a poorly named method, but we keep it for historical reasons.
     */
    @Override
    public void clearFormData() {
        checkThread();
        mAwContents.hideAutofillPopup();
    }

    @Override
    public void clearHistory() {
        checkThread();
        mAwContents.clearHistory();
    }

    @Override
    public void clearSslPreferences() {
        checkThread();
        mAwContents.clearSslPreferences();
    }

    @Override
    public WebBackForwardList copyBackForwardList() {
        checkThread();
        return new WebBackForwardListChromium(
                mAwContents.getNavigationHistory());
    }

    @Override
    public void setFindListener(WebView.FindListener listener) {
        checkThread();
        mContentsClientAdapter.setFindListener(listener);
    }

    @Override
    public void findNext(boolean forwards) {
        checkThread();
        mAwContents.findNext(forwards);
    }

    @Override
    public int findAll(String searchString) {
        checkThread();
        mAwContents.findAllAsync(searchString);
        return 0;
    }

    @Override
    public void findAllAsync(String searchString) {
        checkThread();
        mAwContents.findAllAsync(searchString);
    }

    @Override
    public boolean showFindDialog(String text, boolean showIme) {
        checkThread();
        if (mWebView.getParent() == null) {
            return false;
        }

        FindActionModeCallback findAction = new FindActionModeCallback(mWebView.getContext());
        if (findAction == null) {
            return false;
        }

        mWebView.startActionMode(findAction);
        findAction.setWebView(mWebView);
        if (showIme) {
            findAction.showSoftInput();
        }

        if (text != null) {
            findAction.setText(text);
            findAction.findAll();
        }

        return true;
    }

    @Override
    public void notifyFindDialogDismissed() {
        checkThread();
        clearMatches();
    }

    @Override
    public void clearMatches() {
        checkThread();
        mAwContents.clearMatches();
    }

    @Override
    public void documentHasImages(Message response) {
        checkThread();
        mAwContents.documentHasImages(response);
    }

    @Override
    public void setWebViewClient(WebViewClient client) {
        checkThread();
        mContentsClientAdapter.setWebViewClient(client);
    }

    @Override
    public void setDownloadListener(DownloadListener listener) {
        checkThread();
        mContentsClientAdapter.setDownloadListener(listener);
    }

    @Override
    public void setWebChromeClient(WebChromeClient client) {
        checkThread();
        mContentsClientAdapter.setWebChromeClient(client);
    }

    @Override
    public void setPictureListener(WebView.PictureListener listener) {
        checkThread();
        mContentsClientAdapter.setPictureListener(listener);
        mAwContents.enableOnNewPicture(listener != null,
                mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR2);
    }

    @Override
    public void addJavascriptInterface(Object obj, String interfaceName) {
        checkThread();
        Class<? extends Annotation> requiredAnnotation = null;
        if (mAppTargetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
           requiredAnnotation = JavascriptInterface.class;
        }
        mAwContents.addPossiblyUnsafeJavascriptInterface(obj, interfaceName, requiredAnnotation);
    }

    @Override
    public void removeJavascriptInterface(String interfaceName) {
        checkThread();
        mAwContents.removeJavascriptInterface(interfaceName);
    }

    @Override
    public WebSettings getSettings() {
        checkThread();
        if (mWebSettings == null) {
            mWebSettings = new ContentSettingsAdapter(mAwContents.getSettings());
        }
        return mWebSettings;
    }

    @Override
    public void setMapTrackballToArrowKeys(boolean setMap) {
        checkThread();
        // This is a deprecated API: intentional no-op.
    }

    @Override
    public void flingScroll(int vx, int vy) {
        checkThread();
        mAwContents.flingScroll(vx, vy);
    }

    @Override
    public View getZoomControls() {
        checkThread();
        // This was deprecated in 2009 and hidden in JB MR1, so just provide the minimum needed
        // to stop very out-dated applications from crashing.
        Log.w(TAG, "WebView doesn't support getZoomControls");
        return mAwContents.getSettings().supportZoom() ? new View(mWebView.getContext()) : null;
    }

    @Override
    public boolean canZoomIn() {
        checkThread();
        return mAwContents.canZoomIn();
    }

    @Override
    public boolean canZoomOut() {
        checkThread();
        return mAwContents.canZoomOut();
    }

    @Override
    public boolean zoomIn() {
        checkThread();
        return mAwContents.zoomIn();
    }

    @Override
    public boolean zoomOut() {
        checkThread();
        return mAwContents.zoomOut();
    }

    @Override
    public void dumpViewHierarchyWithProperties(BufferedWriter out, int level) {
        UnimplementedWebViewApi.invoke();
    }

    @Override
    public View findHierarchyView(String className, int hashCode) {
        UnimplementedWebViewApi.invoke();
        return null;
    }

    // WebViewProvider glue methods ---------------------------------------------------------------

    @Override
    // This needs to be kept thread safe!
    public WebViewProvider.ViewDelegate getViewDelegate() {
        return this;
    }

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


    // WebViewProvider.ViewDelegate implementation ------------------------------------------------

    // TODO: remove from WebViewProvider and use default implementation from
    // ViewGroup.
    // @Override
    public boolean shouldDelayChildPressedState() {
        checkThread();
        return true;
    }

//    @Override
    public AccessibilityNodeProvider getAccessibilityNodeProvider() {
        checkThread();
        return mAwContents.getAccessibilityNodeProvider();
    }

    @Override
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        checkThread();
        mAwContents.onInitializeAccessibilityNodeInfo(info);
    }

    @Override
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        checkThread();
        mAwContents.onInitializeAccessibilityEvent(event);
    }

    @Override
    public boolean performAccessibilityAction(int action, Bundle arguments) {
        checkThread();
        if (mAwContents.supportsAccessibilityAction(action)) {
            return mAwContents.performAccessibilityAction(action, arguments);
        }
        return mWebViewPrivate.super_performAccessibilityAction(action, arguments);
    }

    @Override
    public void setOverScrollMode(int mode) {
        checkThread();
        // This gets called from the android.view.View c'tor that WebView inherits from. This
        // causes the method to be called when mAwContents == null.
        // It's safe to ignore these calls however since AwContents will read the current value of
        // this setting when it's created.
        if (mAwContents != null) {
            mAwContents.setOverScrollMode(mode);
        }
    }

    @Override
    public void setScrollBarStyle(int style) {
        checkThread();
        mAwContents.setScrollBarStyle(style);
    }

    @Override
    public void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar,
                                        int l, int t, int r, int b) {
        checkThread();
        // WebViewClassic was overriding this method to handle rubberband over-scroll. Since
        // WebViewChromium doesn't support that the vanilla implementation of this method can be
        // used.
        mWebViewPrivate.super_onDrawVerticalScrollBar(canvas, scrollBar, l, t, r, b);
    }

    @Override
    public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        checkThread();
        mAwContents.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
    }

    @Override
    public void onWindowVisibilityChanged(int visibility) {
        checkThread();
        mAwContents.onWindowVisibilityChanged(visibility);
    }

    @Override
    public void onDraw(Canvas canvas) {
        checkThread();
        mAwContents.onDraw(canvas);
    }

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams layoutParams) {
        checkThread();
        // TODO: This is the minimum implementation for HTMLViewer
        // bringup. Likely will need to go up to ContentViewCore for
        // a complete implementation.
        mWebViewPrivate.super_setLayoutParams(layoutParams);
    }

    @Override
    public boolean performLongClick() {
        checkThread();
        return mWebViewPrivate.super_performLongClick();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        checkThread();
        mAwContents.onConfigurationChanged(newConfig);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        checkThread();
        return mAwContents.onCreateInputConnection(outAttrs);
    }

    @Override
    public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
        checkThread();
        UnimplementedWebViewApi.invoke();
        return false;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        checkThread();
        UnimplementedWebViewApi.invoke();
        return false;
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        checkThread();
        return mAwContents.onKeyUp(keyCode, event);
    }

    @Override
    public void onAttachedToWindow() {
        checkThread();
        mAwContents.onAttachedToWindow();
    }

    @Override
    public void onDetachedFromWindow() {
        checkThread();
        mAwContents.onDetachedFromWindow();
        if (mGLfunctor != null) {
            mGLfunctor.detach();
        }
    }

    @Override
    public void onVisibilityChanged(View changedView, int visibility) {
        checkThread();
        // The AwContents will find out the container view visibility before the first draw so we
        // can safely ignore onVisibilityChanged callbacks that happen before init().
        if (mAwContents != null) {
            mAwContents.onVisibilityChanged(changedView, visibility);
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        checkThread();
        mAwContents.onWindowFocusChanged(hasWindowFocus);
    }

    @Override
    public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        checkThread();
        mAwContents.onFocusChanged(focused, direction, previouslyFocusedRect);
    }

    @Override
    public boolean setFrame(int left, int top, int right, int bottom) {
        // TODO(joth): This is the minimum implementation for initial
        // bringup. Likely will need to go up to AwContents for a complete
        // implementation, e.g. setting the compositor visible region (to
        // avoid painting tiles that are offscreen due to the view's position).
        checkThread();
        return mWebViewPrivate.super_setFrame(left, top, right, bottom);
    }

    @Override
    public void onSizeChanged(int w, int h, int ow, int oh) {
        checkThread();
        mAwContents.onSizeChanged(w, h, ow, oh);
    }

    @Override
    public void onScrollChanged(int l, int t, int oldl, int oldt) {
        checkThread();
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        checkThread();
        return mAwContents.dispatchKeyEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        checkThread();
        return mAwContents.onTouchEvent(ev);
    }

    @Override
    public boolean onHoverEvent(MotionEvent event) {
        checkThread();
        return mAwContents.onHoverEvent(event);
    }

    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        checkThread();
        return mAwContents.onGenericMotionEvent(event);
    }

    @Override
    public boolean onTrackballEvent(MotionEvent ev) {
        checkThread();
        // Trackball event not handled, which eventually gets converted to DPAD keyevents
        return false;
    }

    @Override
    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
        checkThread();
        mAwContents.requestFocus();
        return mWebViewPrivate.super_requestFocus(direction, previouslyFocusedRect);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        checkThread();
        mAwContents.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
        checkThread();
        return mAwContents.requestChildRectangleOnScreen(child, rect, immediate);
    }

    @Override
    public void setBackgroundColor(final int color) {
        if (ThreadUtils.runningOnUiThread()) {
            mAwContents.setBackgroundColor(color);
        } else {
            // Disallowed in WebView API for apps targetting a new SDK
            assert mAppTargetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR2;
            ThreadUtils.postOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mAwContents.setBackgroundColor(color);
                }
            });
        }
    }

    @Override
    public void setLayerType(int layerType, Paint paint) {
        checkThread();
        UnimplementedWebViewApi.invoke();
    }

    @Override
    public void preDispatchDraw(Canvas canvas) {
        checkThread();
        // TODO(leandrogracia): remove this method from WebViewProvider if we think
        // we won't need it again.
    }

    // WebViewProvider.ScrollDelegate implementation ----------------------------------------------

    @Override
    public int computeHorizontalScrollRange() {
        checkThread();
        return mAwContents.computeHorizontalScrollRange();
    }

    @Override
    public int computeHorizontalScrollOffset() {
        checkThread();
        return mAwContents.computeHorizontalScrollOffset();
    }

    @Override
    public int computeVerticalScrollRange() {
        checkThread();
        return mAwContents.computeVerticalScrollRange();
    }

    @Override
    public int computeVerticalScrollOffset() {
        checkThread();
        return mAwContents.computeVerticalScrollOffset();
    }

    @Override
    public int computeVerticalScrollExtent() {
        checkThread();
        return mAwContents.computeVerticalScrollExtent();
    }

    @Override
    public void computeScroll() {
        checkThread();
        mAwContents.computeScroll();
    }

    // AwContents.InternalAccessDelegate implementation --------------------------------------
    private class InternalAccessAdapter implements AwContents.InternalAccessDelegate {
        @Override
        public boolean drawChild(Canvas arg0, View arg1, long arg2) {
            UnimplementedWebViewApi.invoke();
            return false;
        }

        @Override
        public boolean super_onKeyUp(int arg0, KeyEvent arg1) {
            UnimplementedWebViewApi.invoke();
            return false;
        }

        @Override
        public boolean super_dispatchKeyEventPreIme(KeyEvent arg0) {
            UnimplementedWebViewApi.invoke();
            return false;
        }

        @Override
        public boolean super_dispatchKeyEvent(KeyEvent event) {
            return mWebViewPrivate.super_dispatchKeyEvent(event);
        }

        @Override
        public boolean super_onGenericMotionEvent(MotionEvent arg0) {
            UnimplementedWebViewApi.invoke();
            return false;
        }

        @Override
        public void super_onConfigurationChanged(Configuration arg0) {
            UnimplementedWebViewApi.invoke();
        }

        @Override
        public int super_getScrollBarStyle() {
            return mWebViewPrivate.super_getScrollBarStyle();
        }

        @Override
        public boolean awakenScrollBars() {
            mWebViewPrivate.awakenScrollBars(0);
            // TODO: modify the WebView.PrivateAccess to provide a return value.
            return true;
        }

        @Override
        public boolean super_awakenScrollBars(int arg0, boolean arg1) {
            // TODO: need method on WebView.PrivateAccess?
            UnimplementedWebViewApi.invoke();
            return false;
        }

        @Override
        public void onScrollChanged(int l, int t, int oldl, int oldt) {
            mWebViewPrivate.setScrollXRaw(l);
            mWebViewPrivate.setScrollYRaw(t);
            mWebViewPrivate.onScrollChanged(l, t, oldl, oldt);
        }

        @Override
        public void overScrollBy(int deltaX, int deltaY,
            int scrollX, int scrollY,
            int scrollRangeX, int scrollRangeY,
            int maxOverScrollX, int maxOverScrollY,
            boolean isTouchEvent) {
            mWebViewPrivate.overScrollBy(deltaX, deltaY, scrollX, scrollY,
                    scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
        }

        @Override
        public void super_scrollTo(int scrollX, int scrollY) {
            mWebViewPrivate.super_scrollTo(scrollX, scrollY);
        }

        @Override
        public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
            mWebViewPrivate.setMeasuredDimension(measuredWidth, measuredHeight);
        }

        @Override
        public boolean requestDrawGL(Canvas canvas) {
            if (mGLfunctor == null) {
                mGLfunctor = new DrawGLFunctor(mAwContents.getAwDrawGLViewContext());
            }
            return mGLfunctor.requestDrawGL((HardwareCanvas)canvas, mWebView.getViewRootImpl());
        }
    }
}
