PageDialogsHandler.java revision 08a6f0ce422a7cc35a9a27a0823b1ad604d70f48
18233facddcc51865d612a919d450db6954aa48e3Michael Kolb/*
28233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Copyright (C) 2010 The Android Open Source Project
38233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
48233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
58233facddcc51865d612a919d450db6954aa48e3Michael Kolb * you may not use this file except in compliance with the License.
68233facddcc51865d612a919d450db6954aa48e3Michael Kolb * You may obtain a copy of the License at
78233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
88233facddcc51865d612a919d450db6954aa48e3Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
98233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
108233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Unless required by applicable law or agreed to in writing, software
118233facddcc51865d612a919d450db6954aa48e3Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
128233facddcc51865d612a919d450db6954aa48e3Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138233facddcc51865d612a919d450db6954aa48e3Michael Kolb * See the License for the specific language governing permissions and
148233facddcc51865d612a919d450db6954aa48e3Michael Kolb * limitations under the License.
158233facddcc51865d612a919d450db6954aa48e3Michael Kolb */
168233facddcc51865d612a919d450db6954aa48e3Michael Kolb
178233facddcc51865d612a919d450db6954aa48e3Michael Kolbpackage com.android.browser;
188233facddcc51865d612a919d450db6954aa48e3Michael Kolb
198233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.app.AlertDialog;
208233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.Context;
218233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.DialogInterface;
228233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.content.res.Configuration;
238233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.net.http.SslCertificate;
248233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.net.http.SslError;
258233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.LayoutInflater;
268233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.View;
278233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.HttpAuthHandler;
288233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.SslErrorHandler;
298233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.WebView;
308233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.widget.LinearLayout;
318233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.widget.TextView;
328233facddcc51865d612a919d450db6954aa48e3Michael Kolb
338233facddcc51865d612a919d450db6954aa48e3Michael Kolb/**
348233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Displays page info
358233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
368233facddcc51865d612a919d450db6954aa48e3Michael Kolb */
378233facddcc51865d612a919d450db6954aa48e3Michael Kolbpublic class PageDialogsHandler {
388233facddcc51865d612a919d450db6954aa48e3Michael Kolb
398233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Context mContext;
408233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Controller mController;
418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mPageInfoFromShowSSLCertificateOnError;
42ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu    private String mUrlCertificateOnError;
438233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Tab mPageInfoView;
448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private AlertDialog mPageInfoDialog;
458233facddcc51865d612a919d450db6954aa48e3Michael Kolb
468233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // as SSLCertificateOnError has different style for landscape / portrait,
478233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // we have to re-open it when configuration changed
488233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private AlertDialog mSSLCertificateOnErrorDialog;
498233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private WebView mSSLCertificateOnErrorView;
508233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private SslErrorHandler mSSLCertificateOnErrorHandler;
518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private SslError mSSLCertificateOnErrorError;
528233facddcc51865d612a919d450db6954aa48e3Michael Kolb
538233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // as SSLCertificate has different style for landscape / portrait, we
548233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // have to re-open it when configuration changed
558233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private AlertDialog mSSLCertificateDialog;
568233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Tab mSSLCertificateView;
578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private HttpAuthenticationDialog mHttpAuthenticationDialog;
588233facddcc51865d612a919d450db6954aa48e3Michael Kolb
598233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public PageDialogsHandler(Context context, Controller controller) {
608233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mContext = context;
618233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mController = controller;
628233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
638233facddcc51865d612a919d450db6954aa48e3Michael Kolb
648233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onConfigurationChanged(Configuration config) {
658233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mPageInfoDialog != null) {
668233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mPageInfoDialog.dismiss();
67ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu            showPageInfo(mPageInfoView,
68ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                         mPageInfoFromShowSSLCertificateOnError,
69ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                         mUrlCertificateOnError);
708233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
718233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mSSLCertificateDialog != null) {
728233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mSSLCertificateDialog.dismiss();
738233facddcc51865d612a919d450db6954aa48e3Michael Kolb            showSSLCertificate(mSSLCertificateView);
748233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
758233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mSSLCertificateOnErrorDialog != null) {
768233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mSSLCertificateOnErrorDialog.dismiss();
77ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu            showSSLCertificateOnError(mSSLCertificateOnErrorView,
78ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                                      mSSLCertificateOnErrorHandler,
79ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                                      mSSLCertificateOnErrorError);
808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
818233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mHttpAuthenticationDialog != null) {
828233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mHttpAuthenticationDialog.reshow();
838233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
848233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
858233facddcc51865d612a919d450db6954aa48e3Michael Kolb
868233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
878233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays an http-authentication dialog.
888233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void showHttpAuthentication(final Tab tab, final HttpAuthHandler handler, String host, String realm) {
908233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog = new HttpAuthenticationDialog(mContext, host, realm);
918233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog.setOkListener(new HttpAuthenticationDialog.OkListener() {
928233facddcc51865d612a919d450db6954aa48e3Michael Kolb            public void onOk(String host, String realm, String username, String password) {
938233facddcc51865d612a919d450db6954aa48e3Michael Kolb                setHttpAuthUsernamePassword(host, realm, username, password);
948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                handler.proceed(username, password);
958233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mHttpAuthenticationDialog = null;
968233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        });
988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog.setCancelListener(new HttpAuthenticationDialog.CancelListener() {
998233facddcc51865d612a919d450db6954aa48e3Michael Kolb            public void onCancel() {
1008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                handler.cancel();
1012466effd6ef97aa17396c214d51f9f19a4760260Steve Block                mController.onUpdatedSecurityState(tab);
1028233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mHttpAuthenticationDialog = null;
1038233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
1048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        });
1058233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog.show();
1068233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
1078233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1088233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
1098233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Set HTTP authentication password.
1108233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *
1118233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param host The host for the password
1128233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param realm The realm for the password
1138233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param username The username for the password. If it is null, it means
1148233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *            password can't be saved.
1158233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param password The password
1168233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
1178233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void setHttpAuthUsernamePassword(String host, String realm,
1188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                            String username,
1198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                            String password) {
1208233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebView w = mController.getCurrentTopWebView();
1218233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (w != null) {
1228233facddcc51865d612a919d450db6954aa48e3Michael Kolb            w.setHttpAuthUsernamePassword(host, realm, username, password);
1238233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1248233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
1258233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1268233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
1278233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays a page-info dialog.
1288233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param tab The tab to show info about
1298233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param fromShowSSLCertificateOnError The flag that indicates whether
1308233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * this dialog was opened from the SSL-certificate-on-error dialog or
1318233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * not. This is important, since we need to know whether to return to
1328233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * the parent dialog or simply dismiss.
133ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu     * @param urlCertificateOnError The URL that invokes SSLCertificateError.
134ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu     * Null when fromShowSSLCertificateOnError is false.
1358233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
1368233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void showPageInfo(final Tab tab,
137ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu            final boolean fromShowSSLCertificateOnError,
138ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu            final String urlCertificateOnError) {
1398233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final LayoutInflater factory = LayoutInflater.from(mContext);
1408233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1418233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final View pageInfoView = factory.inflate(R.layout.page_info, null);
1428233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final WebView view = tab.getWebView();
1448233facddcc51865d612a919d450db6954aa48e3Michael Kolb
145ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu        String url = fromShowSSLCertificateOnError ? urlCertificateOnError : tab.getUrl();
14630c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String title = tab.getTitle();
1478233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1488233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (url == null) {
1498233facddcc51865d612a919d450db6954aa48e3Michael Kolb            url = "";
1508233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1518233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (title == null) {
1528233facddcc51865d612a919d450db6954aa48e3Michael Kolb            title = "";
1538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1548233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1558233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
1568233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
1578233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1588233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageInfoView = tab;
1598233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
160ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu        mUrlCertificateOnError = urlCertificateOnError;
1618233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1628233facddcc51865d612a919d450db6954aa48e3Michael Kolb        AlertDialog.Builder alertDialogBuilder =
1638233facddcc51865d612a919d450db6954aa48e3Michael Kolb            new AlertDialog.Builder(mContext)
1648233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setTitle(R.string.page_info)
1658233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setIcon(android.R.drawable.ic_dialog_info)
1668233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setView(pageInfoView)
1678233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setPositiveButton(
1688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                R.string.ok,
1698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new DialogInterface.OnClickListener() {
1708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    public void onClick(DialogInterface dialog,
1718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        int whichButton) {
1728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoDialog = null;
1738233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoView = null;
1748233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        // if we came here from the SSL error dialog
1768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (fromShowSSLCertificateOnError) {
1778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // go back to the SSL error dialog
1788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            showSSLCertificateOnError(
1798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView,
1808233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler,
1818233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError);
1828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
1838233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
1848233facddcc51865d612a919d450db6954aa48e3Michael Kolb                })
1858233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setOnCancelListener(
1868233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new DialogInterface.OnCancelListener() {
1878233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    public void onCancel(DialogInterface dialog) {
1888233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoDialog = null;
1898233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoView = null;
1908233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1918233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        // if we came here from the SSL error dialog
1928233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (fromShowSSLCertificateOnError) {
1938233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // go back to the SSL error dialog
1948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            showSSLCertificateOnError(
1958233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView,
1968233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler,
1978233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError);
1988233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
1998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
2008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                });
2018233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2028233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // if we have a main top-level page SSL certificate set or a certificate
2038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // error
2048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (fromShowSSLCertificateOnError ||
2058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                (view != null && view.getCertificate() != null)) {
2068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // add a 'View Certificate' button
2078233facddcc51865d612a919d450db6954aa48e3Michael Kolb            alertDialogBuilder.setNeutralButton(
2088233facddcc51865d612a919d450db6954aa48e3Michael Kolb                R.string.view_certificate,
2098233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new DialogInterface.OnClickListener() {
2108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    public void onClick(DialogInterface dialog,
2118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        int whichButton) {
2128233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoDialog = null;
2138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoView = null;
2148233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2158233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        // if we came here from the SSL error dialog
2168233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (fromShowSSLCertificateOnError) {
2178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // go back to the SSL error dialog
2188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            showSSLCertificateOnError(
2198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView,
2208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler,
2218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError);
2228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        } else {
2238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // otherwise, display the top-most certificate from
2248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // the chain
225cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                            showSSLCertificate(tab);
2268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
2278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
2288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                });
2298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2308233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageInfoDialog = alertDialogBuilder.show();
2328233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
2338233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2348233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
2358233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays the main top-level page SSL certificate dialog
2368233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * (accessible from the Page-Info dialog).
2378233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param tab The tab to show certificate for.
2388233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
2398233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void showSSLCertificate(final Tab tab) {
240873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom
241873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom        SslCertificate cert = tab.getWebView().getCertificate();
242873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom        if (cert == null) {
2438233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
2448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2458233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2468233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateView = tab;
24708a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block        mSSLCertificateDialog = createSslCertificateDialog(cert, tab.getSslCertificateError())
2488233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setPositiveButton(R.string.ok,
2498233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnClickListener() {
2508233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onClick(DialogInterface dialog,
2518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    int whichButton) {
2528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateDialog = null;
2538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateView = null;
2548233facddcc51865d612a919d450db6954aa48e3Michael Kolb
255ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                                showPageInfo(tab, false, null);
2568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
2578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
2588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setOnCancelListener(
2598233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnCancelListener() {
2608233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onCancel(DialogInterface dialog) {
2618233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateDialog = null;
2628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateView = null;
2638233facddcc51865d612a919d450db6954aa48e3Michael Kolb
264ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                                showPageInfo(tab, false, null);
2658233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
2668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
2678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .show();
2688233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
2698233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2708233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
2718233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays the SSL error certificate dialog.
2728233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param view The target web-view.
2738233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param handler The SSL error handler responsible for cancelling the
2748233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * connection that resulted in an SSL error or proceeding per user request.
2758233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param error The SSL error object.
2768233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
2778233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void showSSLCertificateOnError(
2788233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final WebView view, final SslErrorHandler handler,
2798233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final SslError error) {
2808233facddcc51865d612a919d450db6954aa48e3Michael Kolb
281873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom        SslCertificate cert = error.getCertificate();
282873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom        if (cert == null) {
2838233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
2848233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2858233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2868233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateOnErrorHandler = handler;
2878233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateOnErrorView = view;
2888233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateOnErrorError = error;
289cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        mSSLCertificateOnErrorDialog = createSslCertificateDialog(cert, error)
2908233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setPositiveButton(R.string.ok,
2918233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnClickListener() {
2928233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onClick(DialogInterface dialog,
2938233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    int whichButton) {
2948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorDialog = null;
2958233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView = null;
2968233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler = null;
2978233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError = null;
2988233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                view.getWebViewClient().onReceivedSslError(
3008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                                view, handler, error);
3018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
3028233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
3038233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 .setNeutralButton(R.string.page_info_view,
3048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnClickListener() {
3058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onClick(DialogInterface dialog,
3068233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    int whichButton) {
3078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorDialog = null;
3088233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3098233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                // do not clear the dialog state: we will
3108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                // need to show the dialog again once the
3118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                // user is done exploring the page-info details
3128233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                showPageInfo(mController.getTabControl()
3148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        .getTabFromView(view),
315ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                                        true,
316ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu                                        error.getUrl());
3178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
3188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
3198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setOnCancelListener(
3208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnCancelListener() {
3218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onCancel(DialogInterface dialog) {
3228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorDialog = null;
3238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView = null;
3248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler = null;
3258233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError = null;
3268233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3278233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                view.getWebViewClient().onReceivedSslError(
3288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                                view, handler, error);
3298233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
3308233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
3318233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .show();
3328233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
333cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block
334cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block    /*
335cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block     * Creates an AlertDialog to display the given certificate. If error is
336cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block     * null, text is added to state that the certificae is valid and the icon
337cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block     * is set accordingly. If error is non-null, it must relate to the supplied
338cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block     * certificate. In this case, error is used to add text describing the
339cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block     * problems with the certificate and a different icon is used.
340cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block     */
341cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block    private AlertDialog.Builder createSslCertificateDialog(SslCertificate certificate,
342cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            SslError error) {
343cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        View certificateView = certificate.inflateCertificateView(mContext);
344cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        final LinearLayout placeholder =
345cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                (LinearLayout)certificateView.findViewById(com.android.internal.R.id.placeholder);
346cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block
347cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        LayoutInflater factory = LayoutInflater.from(mContext);
348cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        int iconId;
349cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block
350cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        if (error == null) {
351cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            iconId = R.drawable.ic_dialog_browser_certificate_secure;
352cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            LinearLayout table = (LinearLayout)factory.inflate(R.layout.ssl_success, placeholder);
353cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            TextView successString = (TextView)table.findViewById(R.id.success);
354cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            successString.setText(com.android.internal.R.string.ssl_certificate_is_valid);
355cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        } else {
356cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            iconId = R.drawable.ic_dialog_browser_certificate_partially_secure;
357cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            if (error.hasError(SslError.SSL_UNTRUSTED)) {
358cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                addError(factory, placeholder, R.string.ssl_untrusted);
359cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            }
360cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            if (error.hasError(SslError.SSL_IDMISMATCH)) {
361cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                addError(factory, placeholder, R.string.ssl_mismatch);
362cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            }
363cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            if (error.hasError(SslError.SSL_EXPIRED)) {
364cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                addError(factory, placeholder, R.string.ssl_expired);
365cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            }
366cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            if (error.hasError(SslError.SSL_NOTYETVALID)) {
367cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                addError(factory, placeholder, R.string.ssl_not_yet_valid);
368cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            }
369cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            if (error.hasError(SslError.SSL_DATE_INVALID)) {
370cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                addError(factory, placeholder, R.string.ssl_date_invalid);
371cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            }
372cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            if (error.hasError(SslError.SSL_INVALID)) {
373cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                addError(factory, placeholder, R.string.ssl_invalid);
374cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            }
375cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            // The SslError should always have at least one type of error and we
376cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            // should explicitly handle every type of error it supports. We
377cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            // therefore expect the condition below to never be hit. We use it
378cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            // as as safety net in case a new error type is added to SslError
379cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            // without the logic above being updated accordingly.
380cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            if (placeholder.getChildCount() == 0) {
381cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                addError(factory, placeholder, R.string.ssl_unknown);
382cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block            }
383cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        }
384cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block
385cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        return new AlertDialog.Builder(mContext)
386cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                .setTitle(com.android.internal.R.string.ssl_certificate)
387cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                .setIcon(iconId)
388cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                .setView(certificateView);
389cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block    }
390cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block
391cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block    private void addError(LayoutInflater inflater, LinearLayout parent, int error) {
392cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        TextView textView = (TextView) inflater.inflate(R.layout.ssl_warning,
393cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block                parent, false);
394cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        textView.setText(error);
395cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block        parent.addView(textView);
396cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block    }
3978233facddcc51865d612a919d450db6954aa48e3Michael Kolb}
398