PageDialogsHandler.java revision 30c714c853a4239e72ab1e238ce2a92472d06ab0
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.text.format.DateFormat;
268233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.LayoutInflater;
278233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.view.View;
288233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.HttpAuthHandler;
298233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.SslErrorHandler;
308233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.webkit.WebView;
318233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.widget.LinearLayout;
328233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport android.widget.TextView;
338233facddcc51865d612a919d450db6954aa48e3Michael Kolb
348233facddcc51865d612a919d450db6954aa48e3Michael Kolbimport java.util.Date;
358233facddcc51865d612a919d450db6954aa48e3Michael Kolb
368233facddcc51865d612a919d450db6954aa48e3Michael Kolb/**
378233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Displays page info
388233facddcc51865d612a919d450db6954aa48e3Michael Kolb *
398233facddcc51865d612a919d450db6954aa48e3Michael Kolb */
408233facddcc51865d612a919d450db6954aa48e3Michael Kolbpublic class PageDialogsHandler {
418233facddcc51865d612a919d450db6954aa48e3Michael Kolb
428233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Context mContext;
438233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Controller mController;
448233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private boolean mPageInfoFromShowSSLCertificateOnError;
458233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Tab mPageInfoView;
468233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private AlertDialog mPageInfoDialog;
478233facddcc51865d612a919d450db6954aa48e3Michael Kolb
488233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // as SSLCertificateOnError has different style for landscape / portrait,
498233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // we have to re-open it when configuration changed
508233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private AlertDialog mSSLCertificateOnErrorDialog;
518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private WebView mSSLCertificateOnErrorView;
528233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private SslErrorHandler mSSLCertificateOnErrorHandler;
538233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private SslError mSSLCertificateOnErrorError;
548233facddcc51865d612a919d450db6954aa48e3Michael Kolb
558233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // as SSLCertificate has different style for landscape / portrait, we
568233facddcc51865d612a919d450db6954aa48e3Michael Kolb    // have to re-open it when configuration changed
578233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private AlertDialog mSSLCertificateDialog;
588233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private Tab mSSLCertificateView;
598233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private HttpAuthenticationDialog mHttpAuthenticationDialog;
608233facddcc51865d612a919d450db6954aa48e3Michael Kolb
618233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public PageDialogsHandler(Context context, Controller controller) {
628233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mContext = context;
638233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mController = controller;
648233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
658233facddcc51865d612a919d450db6954aa48e3Michael Kolb
668233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void onConfigurationChanged(Configuration config) {
678233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mPageInfoDialog != null) {
688233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mPageInfoDialog.dismiss();
698233facddcc51865d612a919d450db6954aa48e3Michael Kolb            showPageInfo(mPageInfoView, mPageInfoFromShowSSLCertificateOnError);
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();
778233facddcc51865d612a919d450db6954aa48e3Michael Kolb            showSSLCertificateOnError(mSSLCertificateOnErrorView, mSSLCertificateOnErrorHandler,
788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    mSSLCertificateOnErrorError);
798233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
808233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (mHttpAuthenticationDialog != null) {
818233facddcc51865d612a919d450db6954aa48e3Michael Kolb            mHttpAuthenticationDialog.reshow();
828233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
838233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
848233facddcc51865d612a919d450db6954aa48e3Michael Kolb
858233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
868233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays an http-authentication dialog.
878233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
888233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void showHttpAuthentication(final Tab tab, final HttpAuthHandler handler, String host, String realm) {
898233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog = new HttpAuthenticationDialog(mContext, host, realm);
908233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog.setOkListener(new HttpAuthenticationDialog.OkListener() {
918233facddcc51865d612a919d450db6954aa48e3Michael Kolb            public void onOk(String host, String realm, String username, String password) {
928233facddcc51865d612a919d450db6954aa48e3Michael Kolb                setHttpAuthUsernamePassword(host, realm, username, password);
938233facddcc51865d612a919d450db6954aa48e3Michael Kolb                handler.proceed(username, password);
948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mHttpAuthenticationDialog = null;
958233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
968233facddcc51865d612a919d450db6954aa48e3Michael Kolb        });
978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog.setCancelListener(new HttpAuthenticationDialog.CancelListener() {
988233facddcc51865d612a919d450db6954aa48e3Michael Kolb            public void onCancel() {
998233facddcc51865d612a919d450db6954aa48e3Michael Kolb                handler.cancel();
10030c714c853a4239e72ab1e238ce2a92472d06ab0John Reck                mController.onUpdatedLockIcon(tab);
1018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                mHttpAuthenticationDialog = null;
1028233facddcc51865d612a919d450db6954aa48e3Michael Kolb            }
1038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        });
1048233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mHttpAuthenticationDialog.show();
1058233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
1068233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1078233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
1088233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Set HTTP authentication password.
1098233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *
1108233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param host The host for the password
1118233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param realm The realm for the password
1128233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param username The username for the password. If it is null, it means
1138233facddcc51865d612a919d450db6954aa48e3Michael Kolb     *            password can't be saved.
1148233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param password The password
1158233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
1168233facddcc51865d612a919d450db6954aa48e3Michael Kolb    public void setHttpAuthUsernamePassword(String host, String realm,
1178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                            String username,
1188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                            String password) {
1198233facddcc51865d612a919d450db6954aa48e3Michael Kolb        WebView w = mController.getCurrentTopWebView();
1208233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (w != null) {
1218233facddcc51865d612a919d450db6954aa48e3Michael Kolb            w.setHttpAuthUsernamePassword(host, realm, username, password);
1228233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1238233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
1248233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1258233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
1268233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays a page-info dialog.
1278233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param tab The tab to show info about
1288233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param fromShowSSLCertificateOnError The flag that indicates whether
1298233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * this dialog was opened from the SSL-certificate-on-error dialog or
1308233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * not. This is important, since we need to know whether to return to
1318233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * the parent dialog or simply dismiss.
1328233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
1338233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void showPageInfo(final Tab tab,
1348233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final boolean fromShowSSLCertificateOnError) {
1358233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final LayoutInflater factory = LayoutInflater.from(mContext);
1368233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final View pageInfoView = factory.inflate(R.layout.page_info, null);
1388233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1398233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final WebView view = tab.getWebView();
1408233facddcc51865d612a919d450db6954aa48e3Michael Kolb
14130c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String url = tab.getUrl();
14230c714c853a4239e72ab1e238ce2a92472d06ab0John Reck        String title = tab.getTitle();
1438233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1448233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (url == null) {
1458233facddcc51865d612a919d450db6954aa48e3Michael Kolb            url = "";
1468233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1478233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (title == null) {
1488233facddcc51865d612a919d450db6954aa48e3Michael Kolb            title = "";
1498233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
1508233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1518233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
1528233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
1538233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1548233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageInfoView = tab;
1558233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError;
1568233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1578233facddcc51865d612a919d450db6954aa48e3Michael Kolb        AlertDialog.Builder alertDialogBuilder =
1588233facddcc51865d612a919d450db6954aa48e3Michael Kolb            new AlertDialog.Builder(mContext)
1598233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setTitle(R.string.page_info)
1608233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setIcon(android.R.drawable.ic_dialog_info)
1618233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setView(pageInfoView)
1628233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setPositiveButton(
1638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                R.string.ok,
1648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new DialogInterface.OnClickListener() {
1658233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    public void onClick(DialogInterface dialog,
1668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        int whichButton) {
1678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoDialog = null;
1688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoView = null;
1698233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        // if we came here from the SSL error dialog
1718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (fromShowSSLCertificateOnError) {
1728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // go back to the SSL error dialog
1738233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            showSSLCertificateOnError(
1748233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView,
1758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler,
1768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError);
1778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
1788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
1798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                })
1808233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setOnCancelListener(
1818233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new DialogInterface.OnCancelListener() {
1828233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    public void onCancel(DialogInterface dialog) {
1838233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoDialog = null;
1848233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoView = null;
1858233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1868233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        // if we came here from the SSL error dialog
1878233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (fromShowSSLCertificateOnError) {
1888233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // go back to the SSL error dialog
1898233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            showSSLCertificateOnError(
1908233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView,
1918233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler,
1928233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError);
1938233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
1948233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
1958233facddcc51865d612a919d450db6954aa48e3Michael Kolb                });
1968233facddcc51865d612a919d450db6954aa48e3Michael Kolb
1978233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // if we have a main top-level page SSL certificate set or a certificate
1988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // error
1998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (fromShowSSLCertificateOnError ||
2008233facddcc51865d612a919d450db6954aa48e3Michael Kolb                (view != null && view.getCertificate() != null)) {
2018233facddcc51865d612a919d450db6954aa48e3Michael Kolb            // add a 'View Certificate' button
2028233facddcc51865d612a919d450db6954aa48e3Michael Kolb            alertDialogBuilder.setNeutralButton(
2038233facddcc51865d612a919d450db6954aa48e3Michael Kolb                R.string.view_certificate,
2048233facddcc51865d612a919d450db6954aa48e3Michael Kolb                new DialogInterface.OnClickListener() {
2058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    public void onClick(DialogInterface dialog,
2068233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        int whichButton) {
2078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoDialog = null;
2088233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        mPageInfoView = null;
2098233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2108233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        // if we came here from the SSL error dialog
2118233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        if (fromShowSSLCertificateOnError) {
2128233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // go back to the SSL error dialog
2138233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            showSSLCertificateOnError(
2148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView,
2158233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler,
2168233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError);
2178233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        } else {
2188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // otherwise, display the top-most certificate from
2198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            // the chain
2208233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            if (view.getCertificate() != null) {
2218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                showSSLCertificate(tab);
2228233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
2238233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        }
2248233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    }
2258233facddcc51865d612a919d450db6954aa48e3Michael Kolb                });
2268233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2278233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2288233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mPageInfoDialog = alertDialogBuilder.show();
2298233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
2308233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2318233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
2328233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays the main top-level page SSL certificate dialog
2338233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * (accessible from the Page-Info dialog).
2348233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param tab The tab to show certificate for.
2358233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
2368233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private void showSSLCertificate(final Tab tab) {
2378233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final View certificateView =
2388233facddcc51865d612a919d450db6954aa48e3Michael Kolb                inflateCertificateView(tab.getWebView().getCertificate());
2398233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (certificateView == null) {
2408233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
2418233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2428233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2438233facddcc51865d612a919d450db6954aa48e3Michael Kolb        LayoutInflater factory = LayoutInflater.from(mContext);
2448233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2458233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final LinearLayout placeholder =
2468233facddcc51865d612a919d450db6954aa48e3Michael Kolb                (LinearLayout)certificateView.findViewById(R.id.placeholder);
2478233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2488233facddcc51865d612a919d450db6954aa48e3Michael Kolb        LinearLayout ll = (LinearLayout) factory.inflate(
2498233facddcc51865d612a919d450db6954aa48e3Michael Kolb            R.layout.ssl_success, placeholder);
2508233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ((TextView)ll.findViewById(R.id.success))
2518233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setText(R.string.ssl_certificate_is_valid);
2528233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2538233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateView = tab;
2548233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateDialog =
2558233facddcc51865d612a919d450db6954aa48e3Michael Kolb            new AlertDialog.Builder(mContext)
2568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setTitle(R.string.ssl_certificate).setIcon(
2578233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    R.drawable.ic_dialog_browser_certificate_secure)
2588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setView(certificateView)
2598233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setPositiveButton(R.string.ok,
2608233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnClickListener() {
2618233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onClick(DialogInterface dialog,
2628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    int whichButton) {
2638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateDialog = null;
2648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateView = null;
2658233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                showPageInfo(tab, false);
2678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
2688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
2698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setOnCancelListener(
2708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnCancelListener() {
2718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onCancel(DialogInterface dialog) {
2728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateDialog = null;
2738233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateView = null;
2748233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                showPageInfo(tab, false);
2768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
2778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
2788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .show();
2798233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
2808233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2818233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
2828233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Displays the SSL error certificate dialog.
2838233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param view The target web-view.
2848233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param handler The SSL error handler responsible for cancelling the
2858233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * connection that resulted in an SSL error or proceeding per user request.
2868233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param error The SSL error object.
2878233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
2888233facddcc51865d612a919d450db6954aa48e3Michael Kolb    void showSSLCertificateOnError(
2898233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final WebView view, final SslErrorHandler handler,
2908233facddcc51865d612a919d450db6954aa48e3Michael Kolb            final SslError error) {
2918233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2928233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final View certificateView =
2938233facddcc51865d612a919d450db6954aa48e3Michael Kolb            inflateCertificateView(error.getCertificate());
2948233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (certificateView == null) {
2958233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return;
2968233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
2978233facddcc51865d612a919d450db6954aa48e3Michael Kolb
2988233facddcc51865d612a919d450db6954aa48e3Michael Kolb        LayoutInflater factory = LayoutInflater.from(mContext);
2998233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3008233facddcc51865d612a919d450db6954aa48e3Michael Kolb        final LinearLayout placeholder =
3018233facddcc51865d612a919d450db6954aa48e3Michael Kolb                (LinearLayout)certificateView.findViewById(R.id.placeholder);
3028233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3038233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (error.hasError(SslError.SSL_UNTRUSTED)) {
3048233facddcc51865d612a919d450db6954aa48e3Michael Kolb            LinearLayout ll = (LinearLayout)factory
3058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .inflate(R.layout.ssl_warning, placeholder);
3068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView)ll.findViewById(R.id.warning))
3078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(R.string.ssl_untrusted);
3088233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
3098233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3108233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (error.hasError(SslError.SSL_IDMISMATCH)) {
3118233facddcc51865d612a919d450db6954aa48e3Michael Kolb            LinearLayout ll = (LinearLayout)factory
3128233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .inflate(R.layout.ssl_warning, placeholder);
3138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView)ll.findViewById(R.id.warning))
3148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(R.string.ssl_mismatch);
3158233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
3168233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3178233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (error.hasError(SslError.SSL_EXPIRED)) {
3188233facddcc51865d612a919d450db6954aa48e3Michael Kolb            LinearLayout ll = (LinearLayout)factory
3198233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .inflate(R.layout.ssl_warning, placeholder);
3208233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView)ll.findViewById(R.id.warning))
3218233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(R.string.ssl_expired);
3228233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
3238233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3248233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (error.hasError(SslError.SSL_NOTYETVALID)) {
3258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            LinearLayout ll = (LinearLayout)factory
3268233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .inflate(R.layout.ssl_warning, placeholder);
3278233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView)ll.findViewById(R.id.warning))
3288233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(R.string.ssl_not_yet_valid);
3298233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
3308233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3318233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateOnErrorHandler = handler;
3328233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateOnErrorView = view;
3338233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateOnErrorError = error;
3348233facddcc51865d612a919d450db6954aa48e3Michael Kolb        mSSLCertificateOnErrorDialog =
3358233facddcc51865d612a919d450db6954aa48e3Michael Kolb            new AlertDialog.Builder(mContext)
3368233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setTitle(R.string.ssl_certificate).setIcon(
3378233facddcc51865d612a919d450db6954aa48e3Michael Kolb                    R.drawable.ic_dialog_browser_certificate_partially_secure)
3388233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setView(certificateView)
3398233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setPositiveButton(R.string.ok,
3408233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnClickListener() {
3418233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onClick(DialogInterface dialog,
3428233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    int whichButton) {
3438233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorDialog = null;
3448233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView = null;
3458233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler = null;
3468233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError = null;
3478233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3488233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                view.getWebViewClient().onReceivedSslError(
3498233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                                view, handler, error);
3508233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
3518233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
3528233facddcc51865d612a919d450db6954aa48e3Michael Kolb                 .setNeutralButton(R.string.page_info_view,
3538233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnClickListener() {
3548233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onClick(DialogInterface dialog,
3558233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                    int whichButton) {
3568233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorDialog = null;
3578233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3588233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                // do not clear the dialog state: we will
3598233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                // need to show the dialog again once the
3608233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                // user is done exploring the page-info details
3618233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3628233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                showPageInfo(mController.getTabControl()
3638233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        .getTabFromView(view),
3648233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                        true);
3658233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
3668233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
3678233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setOnCancelListener(
3688233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        new DialogInterface.OnCancelListener() {
3698233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            public void onCancel(DialogInterface dialog) {
3708233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorDialog = null;
3718233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorView = null;
3728233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorHandler = null;
3738233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                mSSLCertificateOnErrorError = null;
3748233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3758233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                view.getWebViewClient().onReceivedSslError(
3768233facddcc51865d612a919d450db6954aa48e3Michael Kolb                                                view, handler, error);
3778233facddcc51865d612a919d450db6954aa48e3Michael Kolb                            }
3788233facddcc51865d612a919d450db6954aa48e3Michael Kolb                        })
3798233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .show();
3808233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
3818233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3828233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
3838233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Inflates the SSL certificate view (helper method).
3848233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @param certificate The SSL certificate.
3858233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @return The resultant certificate view with issued-to, issued-by,
3868233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * issued-on, expires-on, and possibly other fields set.
3878233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * If the input certificate is null, returns null.
3888233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
3898233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private View inflateCertificateView(SslCertificate certificate) {
3908233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (certificate == null) {
3918233facddcc51865d612a919d450db6954aa48e3Michael Kolb            return null;
3928233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
3938233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3948233facddcc51865d612a919d450db6954aa48e3Michael Kolb        LayoutInflater factory = LayoutInflater.from(mContext);
3958233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3968233facddcc51865d612a919d450db6954aa48e3Michael Kolb        View certificateView = factory.inflate(
3978233facddcc51865d612a919d450db6954aa48e3Michael Kolb            R.layout.ssl_certificate, null);
3988233facddcc51865d612a919d450db6954aa48e3Michael Kolb
3998233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // issued to:
4008233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SslCertificate.DName issuedTo = certificate.getIssuedTo();
4018233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (issuedTo != null) {
4028233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView) certificateView.findViewById(R.id.to_common))
4038233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(issuedTo.getCName());
4048233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView) certificateView.findViewById(R.id.to_org))
4058233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(issuedTo.getOName());
4068233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView) certificateView.findViewById(R.id.to_org_unit))
4078233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(issuedTo.getUName());
4088233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
4098233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4108233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // issued by:
4118233facddcc51865d612a919d450db6954aa48e3Michael Kolb        SslCertificate.DName issuedBy = certificate.getIssuedBy();
4128233facddcc51865d612a919d450db6954aa48e3Michael Kolb        if (issuedBy != null) {
4138233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView) certificateView.findViewById(R.id.by_common))
4148233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(issuedBy.getCName());
4158233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView) certificateView.findViewById(R.id.by_org))
4168233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(issuedBy.getOName());
4178233facddcc51865d612a919d450db6954aa48e3Michael Kolb            ((TextView) certificateView.findViewById(R.id.by_org_unit))
4188233facddcc51865d612a919d450db6954aa48e3Michael Kolb                .setText(issuedBy.getUName());
4198233facddcc51865d612a919d450db6954aa48e3Michael Kolb        }
4208233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4218233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // issued on:
4228233facddcc51865d612a919d450db6954aa48e3Michael Kolb        String issuedOn = formatCertificateDate(
4238233facddcc51865d612a919d450db6954aa48e3Michael Kolb            certificate.getValidNotBeforeDate());
4248233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ((TextView) certificateView.findViewById(R.id.issued_on))
4258233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setText(issuedOn);
4268233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4278233facddcc51865d612a919d450db6954aa48e3Michael Kolb        // expires on:
4288233facddcc51865d612a919d450db6954aa48e3Michael Kolb        String expiresOn = formatCertificateDate(
4298233facddcc51865d612a919d450db6954aa48e3Michael Kolb            certificate.getValidNotAfterDate());
4308233facddcc51865d612a919d450db6954aa48e3Michael Kolb        ((TextView) certificateView.findViewById(R.id.expires_on))
4318233facddcc51865d612a919d450db6954aa48e3Michael Kolb            .setText(expiresOn);
4328233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4338233facddcc51865d612a919d450db6954aa48e3Michael Kolb        return certificateView;
4348233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
4358233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4368233facddcc51865d612a919d450db6954aa48e3Michael Kolb    /**
4378233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * Formats the certificate date to a properly localized date string.
4388233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * @return Properly localized version of the certificate date string and
4398233facddcc51865d612a919d450db6954aa48e3Michael Kolb     * the "" if it fails to localize.
4408233facddcc51865d612a919d450db6954aa48e3Michael Kolb     */
4418233facddcc51865d612a919d450db6954aa48e3Michael Kolb    private String formatCertificateDate(Date certificateDate) {
4428233facddcc51865d612a919d450db6954aa48e3Michael Kolb      if (certificateDate == null) {
4438233facddcc51865d612a919d450db6954aa48e3Michael Kolb          return "";
4448233facddcc51865d612a919d450db6954aa48e3Michael Kolb      }
4458233facddcc51865d612a919d450db6954aa48e3Michael Kolb      String formattedDate = DateFormat.getDateFormat(mContext)
4468233facddcc51865d612a919d450db6954aa48e3Michael Kolb              .format(certificateDate);
4478233facddcc51865d612a919d450db6954aa48e3Michael Kolb      if (formattedDate == null) {
4488233facddcc51865d612a919d450db6954aa48e3Michael Kolb          return "";
4498233facddcc51865d612a919d450db6954aa48e3Michael Kolb      }
4508233facddcc51865d612a919d450db6954aa48e3Michael Kolb      return formattedDate;
4518233facddcc51865d612a919d450db6954aa48e3Michael Kolb    }
4528233facddcc51865d612a919d450db6954aa48e3Michael Kolb
4538233facddcc51865d612a919d450db6954aa48e3Michael Kolb}
454