WebViewContentsClientAdapter.java revision 8e97d006ca9d9ccf17428980786953b2cac3c933
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;
221e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdochimport android.graphics.Bitmap;
23780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)import android.graphics.BitmapFactory;
24780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)import android.graphics.Canvas;
25780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)import android.graphics.Color;
2646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.graphics.Picture;
277da9c0c080655cfd18bb4ab0937d89be4c2ca659Marcin Kosibaimport android.net.http.ErrorStrings;
2862c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurunimport android.net.http.SslError;
2948c8233468f8c735d8504c8410b86cc373d679edJonathan Dixonimport android.net.Uri;
3048c8233468f8c735d8504c8410b86cc373d679edJonathan Dixonimport android.os.Build;
3146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Handler;
3246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Looper;
33251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liuimport android.os.Message;
3446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.provider.Browser;
3546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.util.Log;
3646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.view.KeyEvent;
37e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liuimport android.view.View;
3806b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurunimport android.webkit.ClientCertRequest;
3946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.ConsoleMessage;
404320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liuimport android.webkit.DownloadListener;
41885c764368483b3082be2eccfab3c8a9f72f95b1Kristian Monsenimport android.webkit.GeolocationPermissions;
426832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsenimport android.webkit.JsDialogHelper;
4346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.JsPromptResult;
4446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.JsResult;
45750453815989696ae449df0e58556cd16ebe63c0Tao Baiimport android.webkit.PermissionRequest;
4662c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurunimport android.webkit.SslErrorHandler;
47809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liuimport android.webkit.ValueCallback;
4846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebChromeClient;
49e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liuimport android.webkit.WebChromeClient.CustomViewCallback;
5046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebResourceResponse;
51c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosibaimport android.webkit.WebResourceRequest;
5246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebView;
5346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.webkit.WebViewClient;
5446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
5546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.AwContentsClient;
5606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurunimport org.chromium.android_webview.AwContentsClientBridge;
5746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.AwHttpAuthHandler;
58017554f2c30b84041e3e47a921fd94c80425699aMarcin Kosibaimport org.chromium.android_webview.AwWebResourceResponse;
5946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.JsPromptResultReceiver;
6046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.android_webview.JsResultReceiver;
61750453815989696ae449df0e58556cd16ebe63c0Tao Baiimport org.chromium.android_webview.permission.AwPermissionRequest;
62fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdochimport org.chromium.base.ThreadUtils;
6354b3666a044d576394424822704d21dace02dc7cMarcin Kosibaimport org.chromium.base.TraceEvent;
6446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentView;
6546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import org.chromium.content.browser.ContentViewClient;
6646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
67b6e8dc172dcd850cf57321a9c574b184275c85fbTao Baiimport java.lang.ref.WeakReference;
6846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.net.URISyntaxException;
6906b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurunimport java.security.Principal;
7006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurunimport java.security.PrivateKey;
7106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurunimport java.security.cert.X509Certificate;
72c0bac61af98d8597256114c3366cd23051ed2674Tao Baiimport java.util.ArrayList;
734054cf14197579550220ccb28ee43d63f3df3937Marcin Kosibaimport java.util.HashMap;
74c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosibaimport java.util.Map;
75b6e8dc172dcd850cf57321a9c574b184275c85fbTao Baiimport java.util.WeakHashMap;
7648c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon
7746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)/**
7846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * An adapter class that forwards the callbacks from {@link ContentViewClient}
7946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * to the appropriate {@link WebViewClient} or {@link WebChromeClient}.
8046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *
8146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * An instance of this class is associated with one {@link WebViewChromium}
8246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * instance. A WebViewChromium is a WebView implementation provider (that is
8346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * android.webkit.WebView delegates all functionality to it) and has exactly
8446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * one corresponding {@link ContentView} instance.
8546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) *
8646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * A {@link ContentViewClient} may be shared between multiple {@link ContentView}s,
8746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * and hence multiple WebViews. Many WebViewClient methods pass the source
8846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * WebView as an argument. This means that we either need to pass the
8946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * corresponding ContentView to the corresponding ContentViewClient methods,
9046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * or use an instance of ContentViewClientAdapter per WebViewChromium, to
9146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * allow the source WebView to be injected by ContentViewClientAdapter. We
9246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * choose the latter, because it makes for a cleaner design.
9346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */
9446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)public class WebViewContentsClientAdapter extends AwContentsClient {
95a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon    // TAG is chosen for consistency with classic webview tracing.
96a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon    private static final String TAG = "WebViewCallback";
97a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon    // Enables API callback tracing
98a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon    private static final boolean TRACE = android.webkit.DebugFlags.TRACE_CALLBACK;
9946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The WebView instance that this adapter is serving.
10046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private final WebView mWebView;
10146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The WebViewClient instance that was passed to WebView.setWebViewClient().
10246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebViewClient mWebViewClient;
10333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen    // The WebChromeClient instance that was passed to WebView.setContentViewClient().
10446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebChromeClient mWebChromeClient;
10546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The listener receiving find-in-page API results.
10646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebView.FindListener mFindListener;
10746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // The listener receiving notifications of screen updates.
10846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private WebView.PictureListener mPictureListener;
10946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
1104320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    private DownloadListener mDownloadListener;
1114320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
1129b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    private Handler mUiThreadHandler;
1139b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
1149b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    private static final int NEW_WEBVIEW_CREATED = 100;
1159b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
116b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai    private WeakHashMap<AwPermissionRequest, WeakReference<PermissionRequestAdapter>>
117b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            mOngoingPermissionRequests;
11846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
11946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * Adapter constructor.
12046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     *
12146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @param webView the {@link WebView} instance that this adapter is serving.
12246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
12346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    WebViewContentsClientAdapter(WebView webView) {
12446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (webView == null) {
12546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            throw new IllegalArgumentException("webView can't be null");
12646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
12746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
12846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebView = webView;
12946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        setWebViewClient(null);
1309b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
1319b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch        mUiThreadHandler = new Handler() {
1329b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
1339b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch            @Override
1349b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch            public void handleMessage(Message msg) {
1359b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                switch(msg.what) {
1369b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                    case NEW_WEBVIEW_CREATED:
1371ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        WebView.WebViewTransport t = (WebView.WebViewTransport) msg.obj;
1381ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        WebView newWebView = t.getWebView();
1391ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        if (newWebView == mWebView) {
1401ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                            throw new IllegalArgumentException(
1411ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "Parent WebView cannot host it's own popup window. Please " +
1421ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "use WebSettings.setSupportMultipleWindows(false)");
1431ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        }
1441ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch
145bbfef40e5fc625f4821f012fae7f16468b7308cfJonathan Dixon                        if (newWebView != null && newWebView.copyBackForwardList().getSize() != 0) {
1461ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                            throw new IllegalArgumentException(
1471ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "New WebView for popup window must not have been previously " +
1481ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                                    "navigated.");
1491ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        }
1501ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch
1511ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch                        WebViewChromium.completeWindowCreation(mWebView, newWebView);
1529b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                        break;
1539b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                    default:
1549b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                        throw new IllegalStateException();
1559b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                }
1569b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch            }
1579b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch        };
1589b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
15946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
16046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
16146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // WebViewClassic is coded in such a way that even if a null WebViewClient is set,
16246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // certain actions take place.
16346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // We choose to replicate this behavior by using a NullWebViewClient implementation (also known
16446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // as the Null Object pattern) rather than duplicating the WebViewClassic approach in
16546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    // ContentView.
16646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    static class NullWebViewClient extends WebViewClient {
16746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
16846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
16946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // TODO: Investigate more and add a test case.
170924278d1f98b209b04bd699494d269d363d1aaa4Primiano Tucci            // This is reflecting Clank's behavior.
17146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            int keyCode = event.getKeyCode();
172924278d1f98b209b04bd699494d269d363d1aaa4Primiano Tucci            return !ContentViewClient.shouldPropagateKey(keyCode);
17346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
17446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
17546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
17646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public boolean shouldOverrideUrlLoading(WebView view, String url) {
17746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            Intent intent;
17846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // Perform generic parsing of the URI to turn it into an Intent.
17946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            try {
18046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
18146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            } catch (URISyntaxException ex) {
18246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                Log.w(TAG, "Bad URI " + url + ": " + ex.getMessage());
18346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                return false;
18446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
18546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // Sanitize the Intent, ensuring web pages can not bypass browser
18646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // security (only access to BROWSABLE activities).
18746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            intent.addCategory(Intent.CATEGORY_BROWSABLE);
18846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            intent.setComponent(null);
18940dc0636706dd146d31f6d09882b5846ae7947ebMarcin Kosiba            Intent selector = intent.getSelector();
19040dc0636706dd146d31f6d09882b5846ae7947ebMarcin Kosiba            if (selector != null) {
19140dc0636706dd146d31f6d09882b5846ae7947ebMarcin Kosiba                selector.addCategory(Intent.CATEGORY_BROWSABLE);
19240dc0636706dd146d31f6d09882b5846ae7947ebMarcin Kosiba                selector.setComponent(null);
19340dc0636706dd146d31f6d09882b5846ae7947ebMarcin Kosiba            }
19446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // Pass the package name as application ID so that the intent from the
19546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            // same application can be opened in the same tab.
196fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu            intent.putExtra(Browser.EXTRA_APPLICATION_ID,
197fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu                    view.getContext().getPackageName());
19846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            try {
199fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu                view.getContext().startActivity(intent);
20046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            } catch (ActivityNotFoundException ex) {
20146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                Log.w(TAG, "No application can handle " + url);
20246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                return false;
20346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
20446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            return true;
20546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
20646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
20746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
20846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setWebViewClient(WebViewClient client) {
20946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (client != null) {
21046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mWebViewClient = client;
21146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        } else {
212fe742c86d6f6e12bd339c9c2efd947d55c910e2dBo Liu            mWebViewClient = new NullWebViewClient();
21346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
21446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
21546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
21646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setWebChromeClient(WebChromeClient client) {
21733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        mWebChromeClient = client;
21846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
21946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
2204320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    void setDownloadListener(DownloadListener listener) {
2214320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu        mDownloadListener = listener;
2224320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    }
2234320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
22446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setFindListener(WebView.FindListener listener) {
22546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mFindListener = listener;
22646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
22746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
22846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    void setPictureListener(WebView.PictureListener listener) {
22946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mPictureListener = listener;
23046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
23146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
23246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
233245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon    //                        Adapter for all the methods.
23446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    //--------------------------------------------------------------------------------------------
23546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
23646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
237809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu     * @see AwContentsClient#getVisitedHistory
238809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu     */
239809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu    @Override
240809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu    public void getVisitedHistory(ValueCallback<String[]> callback) {
241245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
24233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
243a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "getVisitedHistory");
24433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.getVisitedHistory(callback);
24533e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
246245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
247809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu    }
248809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu
249809cfd05f0ac95dda1a754b0a3b6283112f12defBo Liu    /**
2505e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu     * @see AwContentsClient#doUpdateVisiteHistory(String, boolean)
2515e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu     */
2525e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    @Override
2535e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    public void doUpdateVisitedHistory(String url, boolean isReload) {
254245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
255a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "doUpdateVisitedHistory=" + url + " reload=" + isReload);
2565e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu        mWebViewClient.doUpdateVisitedHistory(mWebView, url, isReload);
257245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
2585e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    }
2595e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu
2605e59ff9ab94d503528ef61ccd1c71adb887b5e01Bo Liu    /**
26146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onProgressChanged(int)
26246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
26346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
26446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onProgressChanged(int progress) {
265245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
26633e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
267a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onProgressChanged=" + progress);
26833e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onProgressChanged(mWebView, progress);
26933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
270245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
27146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
27246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
273c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba    private static class WebResourceRequestImpl implements WebResourceRequest {
274c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        private final ShouldInterceptRequestParams mParams;
275c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba
276c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        public WebResourceRequestImpl(ShouldInterceptRequestParams params) {
277c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba            mParams = params;
278c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        }
279c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba
280c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        @Override
281c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        public Uri getUrl() {
282c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba            return Uri.parse(mParams.url);
283c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        }
284c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba
285c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        @Override
286c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        public boolean isForMainFrame() {
287c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba            return mParams.isMainFrame;
288c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        }
289c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba
290c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        @Override
291c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        public boolean hasUserGestureInsecure() {
292c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba            return mParams.hasUserGesture;
293c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        }
294c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba
295c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        @Override
296c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        public String getMethod() {
297c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba            return mParams.method;
298c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        }
299c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba
300c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        @Override
301c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        public Map<String, String> getRequestHeaders() {
302c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba            return mParams.requestHeaders;
303c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        }
304c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba    }
305c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba
30646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
30746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#shouldInterceptRequest(java.lang.String)
30846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
30946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
310017554f2c30b84041e3e47a921fd94c80425699aMarcin Kosiba    public AwWebResourceResponse shouldInterceptRequest(ShouldInterceptRequestParams params) {
311245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
312017554f2c30b84041e3e47a921fd94c80425699aMarcin Kosiba        if (TRACE) Log.d(TAG, "shouldInterceptRequest=" + params.url);
313c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba        WebResourceResponse response = mWebViewClient.shouldInterceptRequest(mWebView,
314c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba                new WebResourceRequestImpl(params));
315245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
31646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (response == null) return null;
3174054cf14197579550220ccb28ee43d63f3df3937Marcin Kosiba
3184054cf14197579550220ccb28ee43d63f3df3937Marcin Kosiba        // AwWebResourceResponse should support null headers. b/16332774.
3194054cf14197579550220ccb28ee43d63f3df3937Marcin Kosiba        Map<String, String> responseHeaders = response.getResponseHeaders();
3204054cf14197579550220ccb28ee43d63f3df3937Marcin Kosiba        if (responseHeaders == null)
3214054cf14197579550220ccb28ee43d63f3df3937Marcin Kosiba            responseHeaders = new HashMap<String, String>();
3224054cf14197579550220ccb28ee43d63f3df3937Marcin Kosiba
323017554f2c30b84041e3e47a921fd94c80425699aMarcin Kosiba        return new AwWebResourceResponse(
32446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                response.getMimeType(),
32546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                response.getEncoding(),
326c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba                response.getData(),
327c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba                response.getStatusCode(),
328c5faabbe90f772416a710e94d790817a9c2523c5Marcin Kosiba                response.getReasonPhrase(),
3294054cf14197579550220ccb28ee43d63f3df3937Marcin Kosiba                responseHeaders);
33046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
33146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
33246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
333f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon     * @see AwContentsClient#shouldOverrideUrlLoading(java.lang.String)
33446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
335245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon    @Override
336f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon    public boolean shouldOverrideUrlLoading(String url) {
337245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
338a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "shouldOverrideUrlLoading=" + url);
339245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        boolean result = mWebViewClient.shouldOverrideUrlLoading(mWebView, url);
340245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
341245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        return result;
34246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
34346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
34446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
34546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onUnhandledKeyEvent(android.view.KeyEvent)
34646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
34746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
34846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onUnhandledKeyEvent(KeyEvent event) {
349245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
350a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onUnhandledKeyEvent");
35146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onUnhandledKeyEvent(mWebView, event);
352245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
35346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
35446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
35546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
35646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onConsoleMessage(android.webkit.ConsoleMessage)
35746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
35846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
35946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
360245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
36133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        boolean result;
36233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
363f8f270cb5b54adc9546566b283b83df911fc516fKristian Monsen            if (TRACE) Log.d(TAG, "onConsoleMessage: " + consoleMessage.message());
36433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            result = mWebChromeClient.onConsoleMessage(consoleMessage);
365cd7ea20fdcedc8cf0a8beb9e3a0f3ec2e7955a29Kristian Monsen            String message = consoleMessage.message();
366cd7ea20fdcedc8cf0a8beb9e3a0f3ec2e7955a29Kristian Monsen            if (result && message != null && message.startsWith("[blocked]")) {
367cd7ea20fdcedc8cf0a8beb9e3a0f3ec2e7955a29Kristian Monsen                Log.e(TAG, "Blocked URL: " + message);
368cd7ea20fdcedc8cf0a8beb9e3a0f3ec2e7955a29Kristian Monsen            }
36933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        } else {
37033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            result = false;
37133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
372245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
373245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        return result;
37446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
37546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
37646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
37746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see AwContentsClient#onFindResultReceived(int,int,boolean)
37846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
37946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
38046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
38146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            boolean isDoneCounting) {
38246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        if (mFindListener == null) return;
383245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
384a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onFindResultReceived");
38546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);
386245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
38746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
38846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
3895ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil    /**
3905ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil     * @See AwContentsClient#onNewPicture(Picture)
3915ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil     */
3929c5a40623b62737244deb2d04a98830d7ffa8404Leandro Gracia Gil    @Override
3935ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil    public void onNewPicture(Picture picture) {
3945ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil        if (mPictureListener == null) return;
395245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
396a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onNewPicture");
3975ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil        mPictureListener.onNewPicture(mWebView, picture);
398245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
3995ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil    }
4005ca5f5c6e538735aa0d0c840eb745cdc4e4a34bbLeandro Gracia Gil
40146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
40246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onLoadResource(String url) {
403245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
404a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onLoadResource=" + url);
40546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onLoadResource(mWebView, url);
406245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
40746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
40846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
4099b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    @Override
4109b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    public boolean onCreateWindow(boolean isDialog, boolean isUserGesture) {
4119b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch        Message m = mUiThreadHandler.obtainMessage(
4129b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch                NEW_WEBVIEW_CREATED, mWebView.new WebViewTransport());
413245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
41433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        boolean result;
41533e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
416a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onCreateWindow");
41733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            result = mWebChromeClient.onCreateWindow(mWebView, isDialog, isUserGesture, m);
41833e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        } else {
41933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            result = false;
42033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
421245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
422245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        return result;
4239b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch    }
4249b5e2bd7d0951a560aa848ff5e74b45560fee045Ben Murdoch
425d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch    /**
426d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch     * @see AwContentsClient#onCloseWindow()
427d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch     */
428245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon    @Override
429d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch    public void onCloseWindow() {
430245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
43133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
432a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onCloseWindow");
43333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onCloseWindow(mWebView);
43433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
435245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
436d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch    }
437d988b42ca3f28aea23dc968b2f7ed79dae868fc6Ben Murdoch
438d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch    /**
439d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch     * @see AwContentsClient#onRequestFocus()
440d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch     */
441245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon    @Override
442d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch    public void onRequestFocus() {
443245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
44433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
445a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onRequestFocus");
44633e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onRequestFocus(mWebView);
44733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
448245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
449d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch    }
450d7fde5118cb6e238163c9755ab581b82eea47dbaBen Murdoch
4511e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch    /**
452690b7c64c2aaae62680d137fca34c7fac5176ed2Selim Gurun     * @see AwContentsClient#onReceivedTouchIconUrl(String url, boolean precomposed)
453690b7c64c2aaae62680d137fca34c7fac5176ed2Selim Gurun     */
454690b7c64c2aaae62680d137fca34c7fac5176ed2Selim Gurun    @Override
455690b7c64c2aaae62680d137fca34c7fac5176ed2Selim Gurun    public void onReceivedTouchIconUrl(String url, boolean precomposed) {
456245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
45733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
458a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onReceivedTouchIconUrl=" + url);
45933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onReceivedTouchIconUrl(mWebView, url, precomposed);
46033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
461245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
462690b7c64c2aaae62680d137fca34c7fac5176ed2Selim Gurun    }
463690b7c64c2aaae62680d137fca34c7fac5176ed2Selim Gurun
464690b7c64c2aaae62680d137fca34c7fac5176ed2Selim Gurun    /**
4651e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch     * @see AwContentsClient#onReceivedIcon(Bitmap bitmap)
4661e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch     */
4671e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch    @Override
4681e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch    public void onReceivedIcon(Bitmap bitmap) {
469245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
47033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
471a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onReceivedIcon");
47233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onReceivedIcon(mWebView, bitmap);
47333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
474245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
4751e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch    }
4761e2928bab700c1a4c5a99d4e8c87e259866beb1dBen Murdoch
47746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
47846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onPageStarted(String)
47946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
48046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
48146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onPageStarted(String url) {
482245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
483a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onPageStarted=" + url);
484f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon        mWebViewClient.onPageStarted(mWebView, url, mWebView.getFavicon());
485245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
48646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
48746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
48846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
48946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onPageFinished(String)
49046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
49146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
49246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onPageFinished(String url) {
493245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
494a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onPageFinished=" + url);
49546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onPageFinished(mWebView, url);
496245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
497e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch
498e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // See b/8208948
499e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // This fakes an onNewPicture callback after onPageFinished to allow
500e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // CTS tests to run in an un-flaky manner. This is required as the
501e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // path for sending Picture updates in Chromium are decoupled from the
502e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // page loading callbacks, i.e. the Chrome compositor may draw our
503e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // content and send the Picture before onPageStarted or onPageFinished
504e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // are invoked. The CTS harness discards any pictures it receives before
505e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // onPageStarted is invoked, so in the case we get the Picture before that and
506e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // no further updates after onPageStarted, we'll fail the test by timing
507e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // out waiting for a Picture.
508e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // To ensure backwards compatibility, we need to defer sending Picture updates
509e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // until onPageFinished has been invoked. This work is being done
510e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        // upstream, and we can revert this hack when it lands.
511e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        if (mPictureListener != null) {
512fa14014161c4f0bc0e99d926cacb7071b8d903efBen Murdoch            ThreadUtils.postOnUiThreadDelayed(new Runnable() {
513e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch                @Override
514e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch                public void run() {
515e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch                    UnimplementedWebViewApi.invoke();
516e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch                    if (mPictureListener != null) {
517a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon                        if (TRACE) Log.d(TAG, "onPageFinished-fake");
51819b22dbf30aec2f35bfbdbc80f9fa01e98d563e8Ben Murdoch                        mPictureListener.onNewPicture(mWebView, new Picture());
519e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch                    }
520e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch                }
521e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch            }, 100);
522e51e2365d481a173bd2275e2b3f8d62f0d99898dBen Murdoch        }
52346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
52446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
52546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
52646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onReceivedError(int,String,String)
52746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
52846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
52946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onReceivedError(int errorCode, String description, String failingUrl) {
5307da9c0c080655cfd18bb4ab0937d89be4c2ca659Marcin Kosiba        if (description == null || description.isEmpty()) {
5317da9c0c080655cfd18bb4ab0937d89be4c2ca659Marcin Kosiba            // ErrorStrings is @hidden, so we can't do this in AwContents.
5327da9c0c080655cfd18bb4ab0937d89be4c2ca659Marcin Kosiba            // Normally the net/ layer will set a valid description, but for synthesized callbacks
5337da9c0c080655cfd18bb4ab0937d89be4c2ca659Marcin Kosiba            // (like in the case for intercepted requests) AwContents will pass in null.
5347da9c0c080655cfd18bb4ab0937d89be4c2ca659Marcin Kosiba            description = ErrorStrings.getString(errorCode, mWebView.getContext());
5357da9c0c080655cfd18bb4ab0937d89be4c2ca659Marcin Kosiba        }
536245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
537a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onReceivedError=" + failingUrl);
53846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onReceivedError(mWebView, errorCode, description, failingUrl);
539245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
540f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon    }
541f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon
54246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
543f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon     * @see ContentViewClient#onReceivedTitle(String)
54446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
545245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon    @Override
546f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon    public void onReceivedTitle(String title) {
547245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
54833e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
549a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onReceivedTitle");
55033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onReceivedTitle(mWebView, title);
55133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
552245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
55346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
55446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
55546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
55646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
55746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#shouldOverrideKeyEvent(KeyEvent)
55846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
55946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
56046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public boolean shouldOverrideKeyEvent(KeyEvent event) {
561924278d1f98b209b04bd699494d269d363d1aaa4Primiano Tucci        // The check below is reflecting Clank's behavior and is a workaround for http://b/7697782.
562924278d1f98b209b04bd699494d269d363d1aaa4Primiano Tucci        // 1. The check for system key should be made in AwContents or ContentViewCore, before
563924278d1f98b209b04bd699494d269d363d1aaa4Primiano Tucci        //    shouldOverrideKeyEvent() is called at all.
564b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        // 2. shouldOverrideKeyEvent() should be called in onKeyDown/onKeyUp, not from
565b5d9eb0196b542499722ffcc8ede41c0eae53516Jonathan Dixon        //    dispatchKeyEvent().
566924278d1f98b209b04bd699494d269d363d1aaa4Primiano Tucci        if (!ContentViewClient.shouldPropagateKey(event.getKeyCode())) return true;
567245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
568a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "shouldOverrideKeyEvent");
569245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        boolean result = mWebViewClient.shouldOverrideKeyEvent(mWebView, event);
570245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
571245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        return result;
57246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
57346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
57446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
57546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    /**
57646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     * @see ContentViewClient#onStartContentIntent(Context, String)
5773e9ca893bb8fb7e0038c04bd04ae78f40233db4fBo Liu     * Callback when detecting a click on a content link.
57846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)     */
579f909ca91bfefe7344f9a0e2c684150df1376d9a4Jonathan Dixon    // TODO: Delete this method when removed from base class.
58046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onStartContentIntent(Context context, String contentUrl) {
581245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
582a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "shouldOverrideUrlLoading=" + contentUrl);
5833e9ca893bb8fb7e0038c04bd04ae78f40233db4fBo Liu        mWebViewClient.shouldOverrideUrlLoading(mWebView, contentUrl);
584245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
58546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
58646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
5876832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen    @Override
5886832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen    public void onGeolocationPermissionsShowPrompt(String origin,
5896832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen            GeolocationPermissions.Callback callback) {
590245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
59133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
592a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onGeolocationPermissionsShowPrompt");
59333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onGeolocationPermissionsShowPrompt(origin, callback);
59433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
595245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
5966832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen    }
59746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
5986832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen    @Override
5996832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen    public void onGeolocationPermissionsHidePrompt() {
600245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
60133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
602a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onGeolocationPermissionsHidePrompt");
60333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onGeolocationPermissionsHidePrompt();
60433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
605245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
60646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
60746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
608750453815989696ae449df0e58556cd16ebe63c0Tao Bai    @Override
609750453815989696ae449df0e58556cd16ebe63c0Tao Bai    public void onPermissionRequest(AwPermissionRequest permissionRequest) {
610750453815989696ae449df0e58556cd16ebe63c0Tao Bai        TraceEvent.begin();
611750453815989696ae449df0e58556cd16ebe63c0Tao Bai        if (mWebChromeClient != null) {
612750453815989696ae449df0e58556cd16ebe63c0Tao Bai            if (TRACE) Log.d(TAG, "onPermissionRequest");
613b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            if (mOngoingPermissionRequests == null) {
614b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai                mOngoingPermissionRequests =
615b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai                    new WeakHashMap<AwPermissionRequest, WeakReference<PermissionRequestAdapter>>();
616b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            }
617b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            PermissionRequestAdapter adapter = new PermissionRequestAdapter(permissionRequest);
618b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            mOngoingPermissionRequests.put(
619b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai                    permissionRequest, new WeakReference<PermissionRequestAdapter>(adapter));
620b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            mWebChromeClient.onPermissionRequest(adapter);
621750453815989696ae449df0e58556cd16ebe63c0Tao Bai        } else {
622750453815989696ae449df0e58556cd16ebe63c0Tao Bai            // By default, we deny the permission.
623750453815989696ae449df0e58556cd16ebe63c0Tao Bai            permissionRequest.deny();
624750453815989696ae449df0e58556cd16ebe63c0Tao Bai        }
625750453815989696ae449df0e58556cd16ebe63c0Tao Bai        TraceEvent.end();
626750453815989696ae449df0e58556cd16ebe63c0Tao Bai    }
627750453815989696ae449df0e58556cd16ebe63c0Tao Bai
628750453815989696ae449df0e58556cd16ebe63c0Tao Bai    @Override
629750453815989696ae449df0e58556cd16ebe63c0Tao Bai    public void onPermissionRequestCanceled(AwPermissionRequest permissionRequest) {
630750453815989696ae449df0e58556cd16ebe63c0Tao Bai        TraceEvent.begin();
631b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai        if (mWebChromeClient != null && mOngoingPermissionRequests != null) {
632750453815989696ae449df0e58556cd16ebe63c0Tao Bai            if (TRACE) Log.d(TAG, "onPermissionRequestCanceled");
633b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            WeakReference<PermissionRequestAdapter> weakRef =
634b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai                    mOngoingPermissionRequests.get(permissionRequest);
635b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            // We don't hold strong reference to PermissionRequestAdpater and don't expect the
636b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            // user only holds weak reference to it either, if so, user has no way to call
637b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            // grant()/deny(), and no need to be notified the cancellation of request.
638b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            if (weakRef != null) {
639b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai                PermissionRequestAdapter adapter = weakRef.get();
640b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai                if (adapter != null) mWebChromeClient.onPermissionRequestCanceled(adapter);
641b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai            }
642750453815989696ae449df0e58556cd16ebe63c0Tao Bai        }
643750453815989696ae449df0e58556cd16ebe63c0Tao Bai        TraceEvent.end();
644750453815989696ae449df0e58556cd16ebe63c0Tao Bai    }
645750453815989696ae449df0e58556cd16ebe63c0Tao Bai
64646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private static class JsPromptResultReceiverAdapter implements JsResult.ResultReceiver {
6476832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        private JsPromptResultReceiver mChromePromptResultReceiver;
6486832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        private JsResultReceiver mChromeResultReceiver;
6496832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        // We hold onto the JsPromptResult here, just to avoid the need to downcast
6506832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        // in onJsResultComplete.
6516832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        private final JsPromptResult mPromptResult = new JsPromptResult(this);
65246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
65346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public JsPromptResultReceiverAdapter(JsPromptResultReceiver receiver) {
6546832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen            mChromePromptResultReceiver = receiver;
6556832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        }
6566832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen
6576832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        public JsPromptResultReceiverAdapter(JsResultReceiver receiver) {
65846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mChromeResultReceiver = receiver;
65946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
66046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
66146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public JsPromptResult getPromptResult() {
66246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            return mPromptResult;
66346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
66446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
66546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
66646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public void onJsResultComplete(JsResult result) {
6676832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen            if (mChromePromptResultReceiver != null) {
6686832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                if (mPromptResult.getResult()) {
6696832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                    mChromePromptResultReceiver.confirm(mPromptResult.getStringResult());
6706832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                } else {
6716832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                    mChromePromptResultReceiver.cancel();
6726832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                }
67346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            } else {
6746832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                if (mPromptResult.getResult()) {
6756832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                    mChromeResultReceiver.confirm();
6766832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                } else {
6776832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                    mChromeResultReceiver.cancel();
6786832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen                }
67946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
68046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
68146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
68246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
68346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
68446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsAlert(String url, String message, JsResultReceiver receiver) {
685245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
68633e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
68733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            final JsPromptResult res =
68833e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                    new JsPromptResultReceiverAdapter(receiver).getPromptResult();
689a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onJsAlert");
69033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            if (!mWebChromeClient.onJsAlert(mWebView, url, message, res)) {
69133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                new JsDialogHelper(res, JsDialogHelper.ALERT, null, message, url)
69233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                        .showDialog(mWebView.getContext());
69333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            }
6943e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen        } else {
6953e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen            receiver.cancel();
6966832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        }
697245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
69846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
69946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
70046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
70146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsBeforeUnload(String url, String message, JsResultReceiver receiver) {
702245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
70333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
70433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            final JsPromptResult res =
70533e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                    new JsPromptResultReceiverAdapter(receiver).getPromptResult();
706a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onJsBeforeUnload");
70733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            if (!mWebChromeClient.onJsBeforeUnload(mWebView, url, message, res)) {
70833e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                new JsDialogHelper(res, JsDialogHelper.UNLOAD, null, message, url)
70933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                        .showDialog(mWebView.getContext());
71033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            }
7113e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen        } else {
7123e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen            receiver.cancel();
7136832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        }
714245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
71546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
71646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
71746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
71846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsConfirm(String url, String message, JsResultReceiver receiver) {
719245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
72033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
72133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            final JsPromptResult res =
72233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                    new JsPromptResultReceiverAdapter(receiver).getPromptResult();
723a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onJsConfirm");
72433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            if (!mWebChromeClient.onJsConfirm(mWebView, url, message, res)) {
72533e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                new JsDialogHelper(res, JsDialogHelper.CONFIRM, null, message, url)
72633e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                        .showDialog(mWebView.getContext());
72733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            }
7283e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen        } else {
7293e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen            receiver.cancel();
7306832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        }
731245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
73246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
73346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
73446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
73546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void handleJsPrompt(String url, String message, String defaultValue,
73646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            JsPromptResultReceiver receiver) {
737245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
73833e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
73933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            final JsPromptResult res =
74033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                    new JsPromptResultReceiverAdapter(receiver).getPromptResult();
741a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onJsPrompt");
74233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            if (!mWebChromeClient.onJsPrompt(mWebView, url, message, defaultValue, res)) {
74333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                new JsDialogHelper(res, JsDialogHelper.PROMPT, defaultValue, message, url)
74433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen                        .showDialog(mWebView.getContext());
74533e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            }
7463e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen        } else {
7473e4e8cf37dfb631bbdf1aa5b04410bf038065fe6Kristian Monsen            receiver.cancel();
7486832aa63c94ee9ea1ebbee7e7e40b7d2dda0e820Kristian Monsen        }
749245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
75046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
75146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
75246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    @Override
75346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    public void onReceivedHttpAuthRequest(AwHttpAuthHandler handler, String host, String realm) {
754245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
755a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onReceivedHttpAuthRequest=" + host);
75646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        mWebViewClient.onReceivedHttpAuthRequest(mWebView,
75746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                new AwHttpAuthHandlerAdapter(handler), host, realm);
758245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
75946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
76046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
761251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu    @Override
762a4ff082306972f691e0b53ae30f1fa3203bd5189Selim Gurun    public void onReceivedSslError(final ValueCallback<Boolean> callback, SslError error) {
76362c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun        SslErrorHandler handler = new SslErrorHandler() {
76462c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun            @Override
76562c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun            public void proceed() {
766413084d3ad5ebedb497b42aa931bcce7caa36268Selim Gurun                callback.onReceiveValue(true);
76762c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun            }
76862c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun            @Override
76962c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun            public void cancel() {
770413084d3ad5ebedb497b42aa931bcce7caa36268Selim Gurun                callback.onReceiveValue(false);
77162c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun            }
77262c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun        };
773245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
774a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onReceivedSslError");
77562c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun        mWebViewClient.onReceivedSslError(mWebView, handler, error);
776245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
77762c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun    }
77862c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun
779a83766bebe5b32a442a51b1f757abb943b2fec4bSelim Gurun    private static class ClientCertRequestImpl extends ClientCertRequest {
78006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
78106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        final private AwContentsClientBridge.ClientCertificateRequestCallback mCallback;
78206b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        final private String[] mKeyTypes;
78306b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        final private Principal[] mPrincipals;
78406b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        final private String mHost;
78506b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        final private int mPort;
78606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
78706b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public ClientCertRequestImpl(
78806b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun                AwContentsClientBridge.ClientCertificateRequestCallback callback,
78906b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun                String[] keyTypes, Principal[] principals, String host, int port) {
79006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mCallback = callback;
79106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mKeyTypes = keyTypes;
79206b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mPrincipals = principals;
79306b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mHost = host;
79406b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mPort = port;
79506b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
79606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
79706b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        @Override
79806b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public String[] getKeyTypes() {
79906b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            // This is already a copy of native argument, so return directly.
80006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            return mKeyTypes;
80106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
80206b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
80306b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        @Override
80406b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public Principal[] getPrincipals() {
80506b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            // This is already a copy of native argument, so return directly.
80606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            return mPrincipals;
80706b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
80806b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
80906b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        @Override
81006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public String getHost() {
81106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            return mHost;
81206b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
81306b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
81406b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        @Override
81506b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public int getPort() {
81606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            return mPort;
81706b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
81806b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
81906b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        @Override
82006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public void proceed(final PrivateKey privateKey, final X509Certificate[] chain) {
82106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mCallback.proceed(privateKey, chain);
82206b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
82306b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
82406b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        @Override
82506b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public void ignore() {
82606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mCallback.ignore();
82706b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
82806b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
82906b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        @Override
83006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        public void cancel() {
83106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            mCallback.cancel();
83206b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        }
83306b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun    }
83406b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
83506b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun    @Override
83606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun    public void onReceivedClientCertRequest(
83706b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            AwContentsClientBridge.ClientCertificateRequestCallback callback,
83806b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            String[] keyTypes, Principal[] principals, String host, int port) {
83906b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        if (TRACE) Log.d(TAG, "onReceivedClientCertRequest");
84006b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        TraceEvent.begin();
84106b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        final ClientCertRequestImpl request = new ClientCertRequestImpl(callback,
84206b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun            keyTypes, principals, host, port);
84306b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        mWebViewClient.onReceivedClientCertRequest(mWebView, request);
84406b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun        TraceEvent.end();
84506b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun    }
84606b29e22754df5cc9c951dc94f60541b4e1a6221Selim Gurun
84762c1f9e94fbc64193ded0449b96dd2a44f810061Selim Gurun    @Override
84897a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu    public void onReceivedLoginRequest(String realm, String account, String args) {
849245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
850a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onReceivedLoginRequest=" + realm);
85197a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu        mWebViewClient.onReceivedLoginRequest(mWebView, realm, account, args);
852245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
85397a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu    }
85497a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu
85597a5fe19fb8224fd8ce867edf6692eceb5fd70d1Bo Liu    @Override
856251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu    public void onFormResubmission(Message dontResend, Message resend) {
857245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
858a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, "onFormResubmission");
859251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu        mWebViewClient.onFormResubmission(mWebView, dontResend, resend);
860245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
861251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu    }
862251a1c8d0a987b0df24e19904d0c0ef492304286Bo Liu
8634320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    @Override
8644320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    public void onDownloadStart(String url,
8654320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                String userAgent,
8664320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                String contentDisposition,
8674320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                String mimeType,
8684320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                long contentLength) {
8694320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu        if (mDownloadListener != null) {
870245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon            TraceEvent.begin();
871a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onDownloadStart");
8724320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu            mDownloadListener.onDownloadStart(url,
8734320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              userAgent,
8744320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              contentDisposition,
8754320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              mimeType,
8764320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu                                              contentLength);
877245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon            TraceEvent.end();
8784320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu        }
8794320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu    }
8804320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
8813c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung    @Override
88248c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon    public void showFileChooser(final ValueCallback<String[]> uploadFileCallback,
88348c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            final AwContentsClient.FileChooserParams fileChooserParams) {
88448c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        if (mWebChromeClient == null) {
88548c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            uploadFileCallback.onReceiveValue(null);
88648c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            return;
88748c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        }
88848c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        TraceEvent.begin();
8898e97d006ca9d9ccf17428980786953b2cac3c933Selim Gurun        FileChooserParamsAdapter adapter = new FileChooserParamsAdapter(
8908e97d006ca9d9ccf17428980786953b2cac3c933Selim Gurun                fileChooserParams, mWebView.getContext());
89148c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        if (TRACE) Log.d(TAG, "showFileChooser");
892e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun        ValueCallback<Uri[]> callbackAdapter = new ValueCallback<Uri[]>() {
893e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun            private boolean mCompleted;
894e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun            @Override
895e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun            public void onReceiveValue(Uri[] uriList) {
896e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                if (mCompleted) {
897e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                    throw new IllegalStateException("showFileChooser result was already called");
898e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                }
899e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                mCompleted = true;
900e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                String s[] = null;
901e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                if (uriList != null) {
902e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                    s = new String[uriList.length];
903e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                    for(int i = 0; i < uriList.length; i++) {
904e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                        s[i] = uriList[i].toString();
905e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                    }
906e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                }
907e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                uploadFileCallback.onReceiveValue(s);
908e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun            }
909e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun        };
9108e97d006ca9d9ccf17428980786953b2cac3c933Selim Gurun        if (mWebChromeClient.onShowFileChooser(mWebView, callbackAdapter, adapter)) {
91148c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            return;
91248c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        }
91348c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        if (mWebView.getContext().getApplicationInfo().targetSdkVersion >
914e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                Build.VERSION_CODES.KITKAT) {
91548c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            uploadFileCallback.onReceiveValue(null);
91648c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            return;
91748c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        }
91848c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        ValueCallback<Uri> innerCallback = new ValueCallback<Uri>() {
919e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun            private boolean mCompleted;
92048c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            @Override
92148c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            public void onReceiveValue(Uri uri) {
922e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                if (mCompleted) {
923e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                    throw new IllegalStateException("showFileChooser result was already called");
924e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                }
925e37101b580615162e33ff59e7e8dac72427b00deSelim Gurun                mCompleted = true;
92648c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon                uploadFileCallback.onReceiveValue(
92748c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon                        uri == null ? null : new String[] { uri.toString() });
92848c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon            }
92948c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        };
93048c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        if (TRACE) Log.d(TAG, "openFileChooser");
93148c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        mWebChromeClient.openFileChooser(innerCallback, fileChooserParams.acceptTypes,
93248c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon                fileChooserParams.capture ? "*" : "");
93348c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon        TraceEvent.end();
93448c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon    }
93548c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon
93648c8233468f8c735d8504c8410b86cc373d679edJonathan Dixon    @Override
9373520eb778d668dc76ca4541c69abd568b9d02691Mikhail Naganov    public void onScaleChangedScaled(float oldScale, float newScale) {
938245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
939a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon        if (TRACE) Log.d(TAG, " onScaleChangedScaled");
9403c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung        mWebViewClient.onScaleChanged(mWebView, oldScale, newScale);
941245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
9423c4cc4ad5269837048ffabfa3e749a30b6d17e25Alan Leung    }
9434320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu
9442729ce59ec2479c72f2422f49c2f0f0a121ee5b4Tao Bai    @Override
945bbe58198e8cce0c35c42809aebc965aa2b476e1cTao Bai    public void onShowCustomView(View view, CustomViewCallback cb) {
946245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
94733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
948a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onShowCustomView");
94933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onShowCustomView(view, cb);
95033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
951245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
952e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu    }
953e98a8a77d3f27ef6f5d34a17c845b66b1998fc06Bo Liu
9542729ce59ec2479c72f2422f49c2f0f0a121ee5b4Tao Bai    @Override
955782fea892aaa4a0867547697d49f6a1dd265d437Tao Bai    public void onHideCustomView() {
956245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
95733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
958a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "onHideCustomView");
95933e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            mWebChromeClient.onHideCustomView();
96033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
961245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
962782fea892aaa4a0867547697d49f6a1dd265d437Tao Bai    }
963782fea892aaa4a0867547697d49f6a1dd265d437Tao Bai
964782fea892aaa4a0867547697d49f6a1dd265d437Tao Bai    @Override
9652729ce59ec2479c72f2422f49c2f0f0a121ee5b4Tao Bai    protected View getVideoLoadingProgressView() {
966245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
96733e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        View result;
96833e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
969a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "getVideoLoadingProgressView");
97033e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            result = mWebChromeClient.getVideoLoadingProgressView();
97133e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        } else {
97233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            result = null;
97333e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
974245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
975245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        return result;
9762729ce59ec2479c72f2422f49c2f0f0a121ee5b4Tao Bai    }
9772729ce59ec2479c72f2422f49c2f0f0a121ee5b4Tao Bai
978be2a57c401cf1bb65d541b0bef30d71962d22488Tao Bai    @Override
979be2a57c401cf1bb65d541b0bef30d71962d22488Tao Bai    public Bitmap getDefaultVideoPoster() {
980245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.begin();
981780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)        Bitmap result = null;
98233e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        if (mWebChromeClient != null) {
983a66d54c9f62ace5182635c4bf74449fb62f9d464Jonathan Dixon            if (TRACE) Log.d(TAG, "getDefaultVideoPoster");
98433e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen            result = mWebChromeClient.getDefaultVideoPoster();
985780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)        }
986780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)        if (result == null) {
987780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)            // The ic_media_video_poster icon is transparent so we need to draw it on a gray
988780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)            // background.
989780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)            Bitmap poster = BitmapFactory.decodeResource(
990780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)                    mWebView.getContext().getResources(),
991780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)                    com.android.internal.R.drawable.ic_media_video_poster);
992780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)            result = Bitmap.createBitmap(poster.getWidth(), poster.getHeight(), poster.getConfig());
993780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)            result.eraseColor(Color.GRAY);
994780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)            Canvas canvas = new Canvas(result);
995780460e70baa6eeb9dd596248384c6dd6a05673fTorne (Richard Coles)            canvas.drawBitmap(poster, 0f, 0f, null);
99633e0aee95766f7091948865f4753eae3ed6f6306Kristian Monsen        }
997245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        TraceEvent.end();
998245b3a6a2a7850a46536a423594286e04e702006Jonathan Dixon        return result;
999be2a57c401cf1bb65d541b0bef30d71962d22488Tao Bai    }
1000be2a57c401cf1bb65d541b0bef30d71962d22488Tao Bai
1001750453815989696ae449df0e58556cd16ebe63c0Tao Bai    // TODO: Move to upstream.
100246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    private static class AwHttpAuthHandlerAdapter extends android.webkit.HttpAuthHandler {
100346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        private AwHttpAuthHandler mAwHandler;
100446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
100546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public AwHttpAuthHandlerAdapter(AwHttpAuthHandler awHandler) {
100646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mAwHandler = awHandler;
100746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
100846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
100946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
101046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public void proceed(String username, String password) {
101146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (username == null) {
101246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                username = "";
101346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
101446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
101546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            if (password == null) {
101646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)                password = "";
101746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            }
101846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mAwHandler.proceed(username, password);
101946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
102046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
102146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
102246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public void cancel() {
102346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)            mAwHandler.cancel();
102446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
102546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)
102646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        @Override
102746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        public boolean useHttpAuthUsernamePassword() {
1028d32343c77868461af07738ac7abd802000490d3dBen Murdoch            return mAwHandler.isFirstAttempt();
102946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)        }
103046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)    }
1031750453815989696ae449df0e58556cd16ebe63c0Tao Bai
1032750453815989696ae449df0e58556cd16ebe63c0Tao Bai    // TODO: Move to the upstream once the PermissionRequest is part of SDK.
1033c0bac61af98d8597256114c3366cd23051ed2674Tao Bai    public static class PermissionRequestAdapter extends PermissionRequest {
1034c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        // TODO: Move the below definitions to AwPermissionRequest.
1035c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        private static long BITMASK_RESOURCE_VIDEO_CAPTURE = 1 << 1;
1036c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        private static long BITMASK_RESOURCE_AUDIO_CAPTURE = 1 << 2;
1037c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        private static long BITMASK_RESOURCE_PROTECTED_MEDIA_ID = 1 << 3;
1038c0bac61af98d8597256114c3366cd23051ed2674Tao Bai
1039c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        public static long toAwPermissionResources(String[] resources) {
1040c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            long result = 0;
1041c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            for (String resource : resources) {
1042c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                if (resource.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE))
1043c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                    result |= BITMASK_RESOURCE_VIDEO_CAPTURE;
1044c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                else if (resource.equals(PermissionRequest.RESOURCE_AUDIO_CAPTURE))
1045c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                    result |= BITMASK_RESOURCE_AUDIO_CAPTURE;
1046c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                else if (resource.equals(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID))
1047c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                    result |= BITMASK_RESOURCE_PROTECTED_MEDIA_ID;
1048c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            }
1049c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            return result;
1050c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        }
1051c0bac61af98d8597256114c3366cd23051ed2674Tao Bai
1052c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        private static String[] toPermissionResources(long resources) {
1053c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            ArrayList<String> result = new ArrayList<String>();
1054c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            if ((resources & BITMASK_RESOURCE_VIDEO_CAPTURE) != 0)
1055c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                result.add(PermissionRequest.RESOURCE_VIDEO_CAPTURE);
1056c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            if ((resources & BITMASK_RESOURCE_AUDIO_CAPTURE) != 0)
1057c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                result.add(PermissionRequest.RESOURCE_AUDIO_CAPTURE);
1058c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            if ((resources & BITMASK_RESOURCE_PROTECTED_MEDIA_ID) != 0)
1059c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                result.add(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID);
1060c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            String[] resource_array = new String[result.size()];
1061c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            return result.toArray(resource_array);
1062c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        }
1063c0bac61af98d8597256114c3366cd23051ed2674Tao Bai
1064750453815989696ae449df0e58556cd16ebe63c0Tao Bai        private AwPermissionRequest mAwPermissionRequest;
1065c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        private String[] mResources;
1066750453815989696ae449df0e58556cd16ebe63c0Tao Bai
1067b6e8dc172dcd850cf57321a9c574b184275c85fbTao Bai        public PermissionRequestAdapter(AwPermissionRequest awPermissionRequest) {
1068750453815989696ae449df0e58556cd16ebe63c0Tao Bai            assert awPermissionRequest != null;
1069750453815989696ae449df0e58556cd16ebe63c0Tao Bai            mAwPermissionRequest = awPermissionRequest;
1070750453815989696ae449df0e58556cd16ebe63c0Tao Bai        }
1071750453815989696ae449df0e58556cd16ebe63c0Tao Bai
1072750453815989696ae449df0e58556cd16ebe63c0Tao Bai        @Override
1073750453815989696ae449df0e58556cd16ebe63c0Tao Bai        public Uri getOrigin() {
1074750453815989696ae449df0e58556cd16ebe63c0Tao Bai            return mAwPermissionRequest.getOrigin();
1075750453815989696ae449df0e58556cd16ebe63c0Tao Bai        }
1076750453815989696ae449df0e58556cd16ebe63c0Tao Bai
1077750453815989696ae449df0e58556cd16ebe63c0Tao Bai        @Override
1078c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        public String[] getResources() {
1079c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            synchronized (this) {
1080c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                if (mResources == null) {
1081c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                    mResources = toPermissionResources(mAwPermissionRequest.getResources());
1082c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                }
1083c0bac61af98d8597256114c3366cd23051ed2674Tao Bai                return mResources;
1084c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            }
1085750453815989696ae449df0e58556cd16ebe63c0Tao Bai        }
1086750453815989696ae449df0e58556cd16ebe63c0Tao Bai
1087750453815989696ae449df0e58556cd16ebe63c0Tao Bai        @Override
1088c0bac61af98d8597256114c3366cd23051ed2674Tao Bai        public void grant(String[] resources) {
1089c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            long requestedResource = mAwPermissionRequest.getResources();
1090c0bac61af98d8597256114c3366cd23051ed2674Tao Bai            if ((requestedResource & toAwPermissionResources(resources)) == requestedResource)
1091750453815989696ae449df0e58556cd16ebe63c0Tao Bai                mAwPermissionRequest.grant();
1092750453815989696ae449df0e58556cd16ebe63c0Tao Bai            else
1093750453815989696ae449df0e58556cd16ebe63c0Tao Bai                mAwPermissionRequest.deny();
1094750453815989696ae449df0e58556cd16ebe63c0Tao Bai        }
1095750453815989696ae449df0e58556cd16ebe63c0Tao Bai
1096750453815989696ae449df0e58556cd16ebe63c0Tao Bai        @Override
1097750453815989696ae449df0e58556cd16ebe63c0Tao Bai        public void deny() {
1098750453815989696ae449df0e58556cd16ebe63c0Tao Bai            mAwPermissionRequest.deny();
1099750453815989696ae449df0e58556cd16ebe63c0Tao Bai        }
1100750453815989696ae449df0e58556cd16ebe63c0Tao Bai
1101750453815989696ae449df0e58556cd16ebe63c0Tao Bai    }
110246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)}
1103