WebViewContentsClientAdapter.java revision 97a5fe19fb8224fd8ce867edf6692eceb5fd70d1
146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)/*
246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Copyright (C) 2012 The Android Open Source Project
346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *
446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License");
546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * you may not use this file except in compliance with the License.
646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * You may obtain a copy of the License at
746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *
846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *      http://www.apache.org/licenses/LICENSE-2.0
946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *
1046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software
1146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS,
1246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * See the License for the specific language governing permissions and
1446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * limitations under the License.
1546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */
1646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
1746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)package com.android.webview.chromium;
1846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
1946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.ActivityNotFoundException;
2046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.Context;
2146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.Intent;
2246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.graphics.Picture;
2346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Handler;
2446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Looper;
25251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liuimport android.os.Message;
2646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.provider.Browser;
2746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.util.Log;
2846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.KeyEvent;
2946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.ConsoleMessage;
304320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liuimport android.webkit.DownloadListener;
31885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsenimport android.webkit.GeolocationPermissions;
3246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.JsPromptResult;
3346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.JsResult;
3446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebChromeClient;
3546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebResourceResponse;
3646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebView;
3746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewClient;
3846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
3946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.AwContentsClient;
4046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.AwHttpAuthHandler;
4146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.InterceptedRequestData;
4246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.JsPromptResultReceiver;
4346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.JsResultReceiver;
4446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentView;
4546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentViewClient;
4646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
4746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.net.URISyntaxException;
4846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
4946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)/**
5046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * An adapter class that forwards the callbacks from {@link ContentViewClient}
5146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * to the appropriate {@link WebViewClient} or {@link WebChromeClient}.
5246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *
5346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * An instance of this class is associated with one {@link WebViewChromium}
5446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * instance. A WebViewChromium is a WebView implementation provider (that is
5546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * android.webkit.WebView delegates all functionality to it) and has exactly
5646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * one corresponding {@link ContentView} instance.
5746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *
5846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * A {@link ContentViewClient} may be shared between multiple {@link ContentView}s,
5946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * and hence multiple WebViews. Many WebViewClient methods pass the source
6046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * WebView as an argument. This means that we either need to pass the
6146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * corresponding ContentView to the corresponding ContentViewClient methods,
6246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * or use an instance of ContentViewClientAdapter per WebViewChromium, to
6346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * allow the source WebView to be injected by ContentViewClientAdapter. We
6446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * choose the latter, because it makes for a cleaner design.
6546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */
6646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)public class WebViewContentsClientAdapter extends AwContentsClient {
6746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private static final String TAG = "ContentViewClientAdapter";
6846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The WebView instance that this adapter is serving.
6946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private final WebView mWebView;
7046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The WebViewClient instance that was passed to WebView.setWebViewClient().
7146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebViewClient mWebViewClient;
7246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The WebViewClient instance that was passed to WebView.setContentViewClient().
7346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebChromeClient mWebChromeClient;
7446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The listener receiving find-in-page API results.
7546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebView.FindListener mFindListener;
7646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The listener receiving notifications of screen updates.
7746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebView.PictureListener mPictureListener;
7846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
794320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    private DownloadListener mDownloadListener;
804320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
819b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    private Handler mUiThreadHandler;
829b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
839b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    private static final int NEW_WEBVIEW_CREATED = 100;
849b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
8546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
8646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * Adapter constructor.
8746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     *
8846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @param webView the {@link WebView} instance that this adapter is serving.
8946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
9046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    WebViewContentsClientAdapter(WebView webView) {
9146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (webView == null) {
9246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            throw new IllegalArgumentException("webView can't be null");
9346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
9446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
9546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebView = webView;
9646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        setWebViewClient(null);
9746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        setWebChromeClient(null);
989b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
999b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch        mUiThreadHandler = new Handler() {
1009b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
1019b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch            @Override
1029b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch            public void handleMessage(Message msg) {
1039b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                switch(msg.what) {
1049b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                    case NEW_WEBVIEW_CREATED:
1051ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        WebView.WebViewTransport t = (WebView.WebViewTransport) msg.obj;
1061ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        WebView newWebView = t.getWebView();
1071ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        if (newWebView == null) {
1081ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                            throw new IllegalArgumentException(
1091ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "Must provide a new WebView for the new window.");
1101ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        }
1111ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        if (newWebView == mWebView) {
1121ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                            throw new IllegalArgumentException(
1131ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "Parent WebView cannot host it's own popup window. Please " +
1141ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "use WebSettings.setSupportMultipleWindows(false)");
1151ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        }
1161ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch
1171ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        if (newWebView.copyBackForwardList().getSize() != 0) {
1181ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                            throw new IllegalArgumentException(
1191ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "New WebView for popup window must not have been previously " +
1201ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "navigated.");
1211ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        }
1221ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch
1231ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        WebViewChromium.completeWindowCreation(mWebView, newWebView);
1249b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                        break;
1259b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                    default:
1269b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                        throw new IllegalStateException();
1279b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                }
1289b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch            }
1299b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch        };
1309b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
13146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
13246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
13346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // WebViewClassic is coded in such a way that even if a null WebViewClient is set,
13446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // certain actions take place.
13546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // We choose to replicate this behavior by using a NullWebViewClient implementation (also known
13646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // as the Null Object pattern) rather than duplicating the WebViewClassic approach in
13746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // ContentView.
13846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    static class NullWebViewClient extends WebViewClient {
13946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
14046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
14146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // TODO: Investigate more and add a test case.
14246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // This is a copy of what Clank does. The WebViewCore key handling code and Clank key
14346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // handling code differ enough that it's not trivial to figure out how keycodes are
14446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // being filtered.
14546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            int keyCode = event.getKeyCode();
14646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (keyCode == KeyEvent.KEYCODE_MENU ||
14746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_HOME ||
14846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_BACK ||
14946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_CALL ||
15046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_ENDCALL ||
15146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_POWER ||
15246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||
15346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_CAMERA ||
15446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_FOCUS ||
15546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
15646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_VOLUME_MUTE ||
15746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
15846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                return true;
15946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
16046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            return false;
16146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
16246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
16346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
16446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public boolean shouldOverrideUrlLoading(WebView view, String url) {
16546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            Intent intent;
16646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // Perform generic parsing of the URI to turn it into an Intent.
16746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            try {
16846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
16946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            } catch (URISyntaxException ex) {
17046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                Log.w(TAG, "Bad URI " + url + ": " + ex.getMessage());
17146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                return false;
17246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
17346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // Sanitize the Intent, ensuring web pages can not bypass browser
17446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // security (only access to BROWSABLE activities).
17546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            intent.addCategory(Intent.CATEGORY_BROWSABLE);
17646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            intent.setComponent(null);
17746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // Pass the package name as application ID so that the intent from the
17846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // same application can be opened in the same tab.
179fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu            intent.putExtra(Browser.EXTRA_APPLICATION_ID,
180fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu                    view.getContext().getPackageName());
18146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            try {
182fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu                view.getContext().startActivity(intent);
18346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            } catch (ActivityNotFoundException ex) {
18446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                Log.w(TAG, "No application can handle " + url);
18546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                return false;
18646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
18746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            return true;
18846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
18946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
19046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
19146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setWebViewClient(WebViewClient client) {
19246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (client != null) {
19346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mWebViewClient = client;
19446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        } else {
195fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu            mWebViewClient = new NullWebViewClient();
19646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
19746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
19846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
19946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setWebChromeClient(WebChromeClient client) {
20046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (client != null) {
20146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mWebChromeClient = client;
20246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        } else {
20346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // WebViewClassic doesn't implement any special behavior for a null WebChromeClient.
20446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mWebChromeClient = new WebChromeClient();
20546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
20646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
20746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
2084320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    void setDownloadListener(DownloadListener listener) {
2094320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu        mDownloadListener = listener;
2104320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    }
2114320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
21246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setFindListener(WebView.FindListener listener) {
21346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mFindListener = listener;
21446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
21546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
21646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setPictureListener(WebView.PictureListener listener) {
21746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mPictureListener = listener;
21846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
21946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
22046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
22146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //                        Adapter for WebContentsDelegate methods.
22246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
22346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
22446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
2255e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu     * @see AwContentsClient#doUpdateVisiteHistory(String, boolean)
2265e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu     */
2275e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    @Override
2285e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    public void doUpdateVisitedHistory(String url, boolean isReload) {
2295e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu        mWebViewClient.doUpdateVisitedHistory(mWebView, url, isReload);
2305e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    }
2315e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu
2325e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    /**
23346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onProgressChanged(int)
23446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
23546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
23646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onProgressChanged(int progress) {
23746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebChromeClient.onProgressChanged(mWebView, progress);
23846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
23946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
24046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
24146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#shouldInterceptRequest(java.lang.String)
24246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
24346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
24446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public InterceptedRequestData shouldInterceptRequest(String url) {
24546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        WebResourceResponse response = mWebViewClient.shouldInterceptRequest(mWebView, url);
24646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (response == null) return null;
24746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        return new InterceptedRequestData(
24846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                response.getMimeType(),
24946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                response.getEncoding(),
25046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                response.getData());
25146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
25246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
25346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
25446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#shouldIgnoreNavigation(java.lang.String)
25546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
25646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
25746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public boolean shouldIgnoreNavigation(String url) {
25846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)      return mWebViewClient.shouldOverrideUrlLoading(mWebView, url);
25946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
26046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
26146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
26246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onUnhandledKeyEvent(android.view.KeyEvent)
26346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
26446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
26546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onUnhandledKeyEvent(KeyEvent event) {
26646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onUnhandledKeyEvent(mWebView, event);
26746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
26846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
26946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
27046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onConsoleMessage(android.webkit.ConsoleMessage)
27146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
27246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
27346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
27446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        return mWebChromeClient.onConsoleMessage(consoleMessage);
27546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
27646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
27746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
27846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onFindResultReceived(int,int,boolean)
27946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
28046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
28146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
28246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            boolean isDoneCounting) {
28346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (mFindListener == null) return;
28446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);
28546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
28646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
2875ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil    /**
2885ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil     * @See AwContentsClient#onNewPicture(Picture)
2895ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil     */
2905ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil    public void onNewPicture(Picture picture) {
2915ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil        if (mPictureListener == null) return;
2925ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil        mPictureListener.onNewPicture(mWebView, picture);
2935ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil    }
2945ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil
29546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
29646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onLoadResource(String url) {
29746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onLoadResource(mWebView, url);
29846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
29946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
3009b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    @Override
3019b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    public boolean onCreateWindow(boolean isDialog, boolean isUserGesture) {
3029b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch        Message m = mUiThreadHandler.obtainMessage(
3039b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                NEW_WEBVIEW_CREATED, mWebView.new WebViewTransport());
3041ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch        return mWebChromeClient.onCreateWindow(mWebView, isDialog, isUserGesture, m);
3059b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    }
3069b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
307d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch    /**
308d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch     * @see AwContentsClient#onCloseWindow()
309d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch     */
310d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch    /* @Override */
311d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch    public void onCloseWindow() {
312d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch        mWebChromeClient.onCloseWindow(mWebView);
313d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch    }
314d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch
315d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch    /**
316d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch     * @see AwContentsClient#onRequestFocus()
317d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch     */
318d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch    /* @Override */
319d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch    public void onRequestFocus() {
320d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch        mWebChromeClient.onRequestFocus(mWebView);
321d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch    }
322d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch
32346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
32446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //                        Trivial Chrome -> WebViewClient mappings.
32546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
32646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
32746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
32846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onPageStarted(String)
32946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
33046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
33146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onPageStarted(String url) {
33246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        //TODO: Can't get the favicon till b/6094807 is fixed.
33346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onPageStarted(mWebView, url, null);
33446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
33546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
33646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
33746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onPageFinished(String)
33846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
33946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
34046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onPageFinished(String url) {
34146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onPageFinished(mWebView, url);
34246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
34346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // HACK: Fake a picture listener update, to allow CTS tests to progress.
34446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // TODO: Remove when we have real picture listener updates implemented.
34546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (mPictureListener != null) {
34646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
34746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                @Override
34846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                public void run() {
34946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    UnimplementedWebViewApi.invoke();
35046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    if (mPictureListener != null) {
35146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                        mPictureListener.onNewPicture(mWebView, new Picture());
35246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                    }
35346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                }
35446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }, 100);
35546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
35646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
35746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
35846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
35946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onReceivedError(int,String,String)
36046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
36146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
36246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onReceivedError(int errorCode, String description, String failingUrl) {
36346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onReceivedError(mWebView, errorCode, description, failingUrl);
36446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
36546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
36646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
36746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onUpdateTitle(String)
36846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
36946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
37046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onUpdateTitle(String title) {
37146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebChromeClient.onReceivedTitle(mWebView, title);
37246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
37346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
37446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
37546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
37646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#shouldOverrideKeyEvent(KeyEvent)
37746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
37846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
37946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public boolean shouldOverrideKeyEvent(KeyEvent event) {
380b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        // TODO(joth): The expression here is a workaround for http://b/7697782 :-
381b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        // 1. The check for system key should be made in AwContents or ContentViewCore,
382b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        //    before shouldOverrideKeyEvent() is called at all.
383b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        // 2. shouldOverrideKeyEvent() should be called in onKeyDown/onKeyUp, not from
384b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        //    dispatchKeyEvent().
385b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        return event.isSystem() ||
386b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon            mWebViewClient.shouldOverrideKeyEvent(mWebView, event);
38746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
38846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
38946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
39046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
39146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //                 More complicated mappings (including behavior choices)
39246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
39346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
39446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
39546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onTabCrash()
39646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
39746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
39846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onTabCrash() {
39946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // The WebViewClassic implementation used a single process, so any crash would
40046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // cause the application to terminate.  WebViewChromium should have the same
40146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // behavior as long as we run the renderer in-process. This needs to be revisited
40246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // if we change that decision.
40346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        Log.e(TAG, "Renderer crash reported.");
40446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebChromeClient.onCloseWindow(mWebView);
40546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
40646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
40746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
40846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //                                     The TODO section
40946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
41046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
41146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
41246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
41346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onImeEvent()
41446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
41546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
41646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onImeEvent() {
41746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
41846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
41946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
42046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onStartContentIntent(Context, String)
4213e9ca893bb8fb7e0038c04bd04ae78f40233db4fBo Liu     * Callback when detecting a click on a content link.
42246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
42346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
42446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onStartContentIntent(Context context, String contentUrl) {
4253e9ca893bb8fb7e0038c04bd04ae78f40233db4fBo Liu        mWebViewClient.shouldOverrideUrlLoading(mWebView, contentUrl);
42646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
42746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
42846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private static class SimpleJsResultReceiver implements JsResult.ResultReceiver {
42946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        private JsResultReceiver mChromeResultReceiver;
43046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
43146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public SimpleJsResultReceiver(JsResultReceiver receiver) {
43246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mChromeResultReceiver = receiver;
43346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
43446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
43546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
43646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public void onJsResultComplete(JsResult result) {
43746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (result.getResult()) {
43846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                mChromeResultReceiver.confirm();
43946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            } else {
44046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                mChromeResultReceiver.cancel();
44146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
44246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
44346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
44446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
44546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private static class JsPromptResultReceiverAdapter implements JsResult.ResultReceiver {
44646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        private JsPromptResultReceiver mChromeResultReceiver;
44746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        private JsPromptResult mPromptResult;
44846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
44946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public JsPromptResultReceiverAdapter(JsPromptResultReceiver receiver) {
45046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mChromeResultReceiver = receiver;
45146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // We hold onto the JsPromptResult here, just to avoid the need to downcast
45246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // in onJsResultComplete.
45346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mPromptResult = new JsPromptResult(this);
45446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
45546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
45646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public JsPromptResult getPromptResult() {
45746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            return mPromptResult;
45846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
45946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
46046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
46146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public void onJsResultComplete(JsResult result) {
46246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (result != mPromptResult) throw new RuntimeException("incorrect JsResult instance");
46346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (mPromptResult.getResult()) {
46446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                mChromeResultReceiver.confirm(mPromptResult.getStringResult());
46546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            } else {
46646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                mChromeResultReceiver.cancel();
46746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
46846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
46946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
47046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
47146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
472885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen    public void onGeolocationPermissionsShowPrompt(String origin,
473885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen            GeolocationPermissions.Callback callback) {
474885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen        mWebChromeClient.onGeolocationPermissionsShowPrompt(origin, callback);
475885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen    }
476885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen
477885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen    @Override
478885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen    public void onGeolocationPermissionsHidePrompt() {
479885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen        mWebChromeClient.onGeolocationPermissionsHidePrompt();
480885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen    }
481885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen
482885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsen    @Override
48346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsAlert(String url, String message, JsResultReceiver receiver) {
48446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        JsResult res = new JsResult(new SimpleJsResultReceiver(receiver));
48546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebChromeClient.onJsAlert(mWebView, url, message, res);
48646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // TODO: Handle the case of the client returning false;
48746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
48846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
48946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
49046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsBeforeUnload(String url, String message, JsResultReceiver receiver) {
49146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        JsResult res = new JsResult(new SimpleJsResultReceiver(receiver));
49246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebChromeClient.onJsBeforeUnload(mWebView, url, message, res);
49346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // TODO: Handle the case of the client returning false;
49446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
49546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
49646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
49746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsConfirm(String url, String message, JsResultReceiver receiver) {
49846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        JsResult res = new JsResult(new SimpleJsResultReceiver(receiver));
49946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebChromeClient.onJsConfirm(mWebView, url, message, res);
50046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // TODO: Handle the case of the client returning false;
50146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
50246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
50346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
50446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsPrompt(String url, String message, String defaultValue,
50546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            JsPromptResultReceiver receiver) {
50646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        JsPromptResult res = new JsPromptResultReceiverAdapter(receiver).getPromptResult();
50746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebChromeClient.onJsPrompt(mWebView, url, message, defaultValue, res);
50846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        // TODO: Handle the case of the client returning false;
50946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
51046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
51146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
51246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onReceivedHttpAuthRequest(AwHttpAuthHandler handler, String host, String realm) {
51346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onReceivedHttpAuthRequest(mWebView,
51446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                new AwHttpAuthHandlerAdapter(handler), host, realm);
51546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
51646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
517251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu    @Override
51897a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu    public void onReceivedLoginRequest(String realm, String account, String args) {
51997a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu        mWebViewClient.onReceivedLoginRequest(mWebView, realm, account, args);
52097a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu    }
52197a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu
52297a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu    @Override
523251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu    public void onFormResubmission(Message dontResend, Message resend) {
524251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu        mWebViewClient.onFormResubmission(mWebView, dontResend, resend);
525251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu    }
526251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu
5274320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    @Override
5284320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    public void onDownloadStart(String url,
5294320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                String userAgent,
5304320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                String contentDisposition,
5314320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                String mimeType,
5324320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                long contentLength) {
5334320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu        if (mDownloadListener != null) {
5344320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu            mDownloadListener.onDownloadStart(url,
5354320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              userAgent,
5364320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              contentDisposition,
5374320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              mimeType,
5384320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              contentLength);
5394320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu        }
5404320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    }
5414320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
5423c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung    @Override
5433c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung    public void onScaleChanged(float oldScale, float newScale) {
5443c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung        mWebViewClient.onScaleChanged(mWebView, oldScale, newScale);
5453c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung    }
5464320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
54746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private static class AwHttpAuthHandlerAdapter extends android.webkit.HttpAuthHandler {
54846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        private AwHttpAuthHandler mAwHandler;
54946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
55046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public AwHttpAuthHandlerAdapter(AwHttpAuthHandler awHandler) {
55146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mAwHandler = awHandler;
55246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
55346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
55446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
55546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public void proceed(String username, String password) {
55646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (username == null) {
55746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                username = "";
55846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
55946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
56046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (password == null) {
56146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                password = "";
56246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
56346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mAwHandler.proceed(username, password);
56446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
56546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
56646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
56746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public void cancel() {
56846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mAwHandler.cancel();
56946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
57046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
57146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
57246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public boolean useHttpAuthUsernamePassword() {
573d32343c77868461af07738ac7abd802000490d3dBen Murdoch            return mAwHandler.isFirstAttempt();
57446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
57546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
57646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)}
577