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