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) { 139d5cb4fa9f12b690dffdac98f17f0679b81571f07Michael Kolb if (tab == null) return; 1408233facddcc51865d612a919d450db6954aa48e3Michael Kolb final LayoutInflater factory = LayoutInflater.from(mContext); 1418233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1428233facddcc51865d612a919d450db6954aa48e3Michael Kolb final View pageInfoView = factory.inflate(R.layout.page_info, null); 1438233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1448233facddcc51865d612a919d450db6954aa48e3Michael Kolb final WebView view = tab.getWebView(); 1458233facddcc51865d612a919d450db6954aa48e3Michael Kolb 146ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu String url = fromShowSSLCertificateOnError ? urlCertificateOnError : tab.getUrl(); 14730c714c853a4239e72ab1e238ce2a92472d06ab0John Reck String title = tab.getTitle(); 1488233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1498233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (url == null) { 1508233facddcc51865d612a919d450db6954aa48e3Michael Kolb url = ""; 1518233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1528233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (title == null) { 1538233facddcc51865d612a919d450db6954aa48e3Michael Kolb title = ""; 1548233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1558233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1568233facddcc51865d612a919d450db6954aa48e3Michael Kolb ((TextView) pageInfoView.findViewById(R.id.address)).setText(url); 1578233facddcc51865d612a919d450db6954aa48e3Michael Kolb ((TextView) pageInfoView.findViewById(R.id.title)).setText(title); 1588233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1598233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoView = tab; 1608233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoFromShowSSLCertificateOnError = fromShowSSLCertificateOnError; 161ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu mUrlCertificateOnError = urlCertificateOnError; 1628233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1638233facddcc51865d612a919d450db6954aa48e3Michael Kolb AlertDialog.Builder alertDialogBuilder = 1648233facddcc51865d612a919d450db6954aa48e3Michael Kolb new AlertDialog.Builder(mContext) 1658233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setTitle(R.string.page_info) 1668233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setIcon(android.R.drawable.ic_dialog_info) 1678233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setView(pageInfoView) 1688233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setPositiveButton( 1698233facddcc51865d612a919d450db6954aa48e3Michael Kolb R.string.ok, 1708233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnClickListener() { 1718233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onClick(DialogInterface dialog, 1728233facddcc51865d612a919d450db6954aa48e3Michael Kolb int whichButton) { 1738233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoDialog = null; 1748233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoView = null; 1758233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1768233facddcc51865d612a919d450db6954aa48e3Michael Kolb // if we came here from the SSL error dialog 1778233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (fromShowSSLCertificateOnError) { 1788233facddcc51865d612a919d450db6954aa48e3Michael Kolb // go back to the SSL error dialog 1798233facddcc51865d612a919d450db6954aa48e3Michael Kolb showSSLCertificateOnError( 1808233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorView, 1818233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorHandler, 1828233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorError); 1838233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1848233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 1858233facddcc51865d612a919d450db6954aa48e3Michael Kolb }) 1868233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setOnCancelListener( 1878233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnCancelListener() { 1888233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onCancel(DialogInterface dialog) { 1898233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoDialog = null; 1908233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoView = null; 1918233facddcc51865d612a919d450db6954aa48e3Michael Kolb 1928233facddcc51865d612a919d450db6954aa48e3Michael Kolb // if we came here from the SSL error dialog 1938233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (fromShowSSLCertificateOnError) { 1948233facddcc51865d612a919d450db6954aa48e3Michael Kolb // go back to the SSL error dialog 1958233facddcc51865d612a919d450db6954aa48e3Michael Kolb showSSLCertificateOnError( 1968233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorView, 1978233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorHandler, 1988233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorError); 1998233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2008233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2018233facddcc51865d612a919d450db6954aa48e3Michael Kolb }); 2028233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2038233facddcc51865d612a919d450db6954aa48e3Michael Kolb // if we have a main top-level page SSL certificate set or a certificate 2048233facddcc51865d612a919d450db6954aa48e3Michael Kolb // error 2058233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (fromShowSSLCertificateOnError || 2068233facddcc51865d612a919d450db6954aa48e3Michael Kolb (view != null && view.getCertificate() != null)) { 2078233facddcc51865d612a919d450db6954aa48e3Michael Kolb // add a 'View Certificate' button 2088233facddcc51865d612a919d450db6954aa48e3Michael Kolb alertDialogBuilder.setNeutralButton( 2098233facddcc51865d612a919d450db6954aa48e3Michael Kolb R.string.view_certificate, 2108233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnClickListener() { 2118233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onClick(DialogInterface dialog, 2128233facddcc51865d612a919d450db6954aa48e3Michael Kolb int whichButton) { 2138233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoDialog = null; 2148233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoView = null; 2158233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2168233facddcc51865d612a919d450db6954aa48e3Michael Kolb // if we came here from the SSL error dialog 2178233facddcc51865d612a919d450db6954aa48e3Michael Kolb if (fromShowSSLCertificateOnError) { 2188233facddcc51865d612a919d450db6954aa48e3Michael Kolb // go back to the SSL error dialog 2198233facddcc51865d612a919d450db6954aa48e3Michael Kolb showSSLCertificateOnError( 2208233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorView, 2218233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorHandler, 2228233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorError); 2238233facddcc51865d612a919d450db6954aa48e3Michael Kolb } else { 2248233facddcc51865d612a919d450db6954aa48e3Michael Kolb // otherwise, display the top-most certificate from 2258233facddcc51865d612a919d450db6954aa48e3Michael Kolb // the chain 226cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block showSSLCertificate(tab); 2278233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2288233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2298233facddcc51865d612a919d450db6954aa48e3Michael Kolb }); 2308233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2318233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2328233facddcc51865d612a919d450db6954aa48e3Michael Kolb mPageInfoDialog = alertDialogBuilder.show(); 2338233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2348233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2358233facddcc51865d612a919d450db6954aa48e3Michael Kolb /** 2368233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Displays the main top-level page SSL certificate dialog 2378233facddcc51865d612a919d450db6954aa48e3Michael Kolb * (accessible from the Page-Info dialog). 2388233facddcc51865d612a919d450db6954aa48e3Michael Kolb * @param tab The tab to show certificate for. 2398233facddcc51865d612a919d450db6954aa48e3Michael Kolb */ 2408233facddcc51865d612a919d450db6954aa48e3Michael Kolb private void showSSLCertificate(final Tab tab) { 241873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom 242873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom SslCertificate cert = tab.getWebView().getCertificate(); 243873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom if (cert == null) { 2448233facddcc51865d612a919d450db6954aa48e3Michael Kolb return; 2458233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2468233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2478233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateView = tab; 24808a6f0ce422a7cc35a9a27a0823b1ad604d70f48Steve Block mSSLCertificateDialog = createSslCertificateDialog(cert, tab.getSslCertificateError()) 2498233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setPositiveButton(R.string.ok, 2508233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnClickListener() { 2518233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onClick(DialogInterface dialog, 2528233facddcc51865d612a919d450db6954aa48e3Michael Kolb int whichButton) { 2538233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateDialog = null; 2548233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateView = null; 2558233facddcc51865d612a919d450db6954aa48e3Michael Kolb 256ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu showPageInfo(tab, false, null); 2578233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2588233facddcc51865d612a919d450db6954aa48e3Michael Kolb }) 2598233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setOnCancelListener( 2608233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnCancelListener() { 2618233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onCancel(DialogInterface dialog) { 2628233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateDialog = null; 2638233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateView = null; 2648233facddcc51865d612a919d450db6954aa48e3Michael Kolb 265ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu showPageInfo(tab, false, null); 2668233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2678233facddcc51865d612a919d450db6954aa48e3Michael Kolb }) 2688233facddcc51865d612a919d450db6954aa48e3Michael Kolb .show(); 2698233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2708233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2718233facddcc51865d612a919d450db6954aa48e3Michael Kolb /** 2728233facddcc51865d612a919d450db6954aa48e3Michael Kolb * Displays the SSL error certificate dialog. 2738233facddcc51865d612a919d450db6954aa48e3Michael Kolb * @param view The target web-view. 2748233facddcc51865d612a919d450db6954aa48e3Michael Kolb * @param handler The SSL error handler responsible for cancelling the 2758233facddcc51865d612a919d450db6954aa48e3Michael Kolb * connection that resulted in an SSL error or proceeding per user request. 2768233facddcc51865d612a919d450db6954aa48e3Michael Kolb * @param error The SSL error object. 2778233facddcc51865d612a919d450db6954aa48e3Michael Kolb */ 2788233facddcc51865d612a919d450db6954aa48e3Michael Kolb void showSSLCertificateOnError( 2798233facddcc51865d612a919d450db6954aa48e3Michael Kolb final WebView view, final SslErrorHandler handler, 2808233facddcc51865d612a919d450db6954aa48e3Michael Kolb final SslError error) { 2818233facddcc51865d612a919d450db6954aa48e3Michael Kolb 282873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom SslCertificate cert = error.getCertificate(); 283873034cdbf67b7f0b555d7e15490d7466d49dd60Brian Carlstrom if (cert == null) { 2848233facddcc51865d612a919d450db6954aa48e3Michael Kolb return; 2858233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 2868233facddcc51865d612a919d450db6954aa48e3Michael Kolb 2878233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorHandler = handler; 2888233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorView = view; 2898233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorError = error; 290cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block mSSLCertificateOnErrorDialog = createSslCertificateDialog(cert, error) 2918233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setPositiveButton(R.string.ok, 2928233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnClickListener() { 2938233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onClick(DialogInterface dialog, 2948233facddcc51865d612a919d450db6954aa48e3Michael Kolb int whichButton) { 2958233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorDialog = null; 2968233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorView = null; 2978233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorHandler = null; 2988233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorError = null; 2998233facddcc51865d612a919d450db6954aa48e3Michael Kolb 300e1d6dfca80e4627a0c7fe46e38f904179c3edab3Jonathan Dixon ((BrowserWebView) view).getWebViewClient(). 3014d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon onReceivedSslError(view, handler, error); 3028233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3038233facddcc51865d612a919d450db6954aa48e3Michael Kolb }) 3048233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setNeutralButton(R.string.page_info_view, 3058233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnClickListener() { 3068233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onClick(DialogInterface dialog, 3078233facddcc51865d612a919d450db6954aa48e3Michael Kolb int whichButton) { 3088233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorDialog = null; 3098233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3108233facddcc51865d612a919d450db6954aa48e3Michael Kolb // do not clear the dialog state: we will 3118233facddcc51865d612a919d450db6954aa48e3Michael Kolb // need to show the dialog again once the 3128233facddcc51865d612a919d450db6954aa48e3Michael Kolb // user is done exploring the page-info details 3138233facddcc51865d612a919d450db6954aa48e3Michael Kolb 3148233facddcc51865d612a919d450db6954aa48e3Michael Kolb showPageInfo(mController.getTabControl() 3158233facddcc51865d612a919d450db6954aa48e3Michael Kolb .getTabFromView(view), 316ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu true, 317ae0c0411bb502976c6374e30c5d1aa4271a64dafHuahui Wu error.getUrl()); 3188233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3198233facddcc51865d612a919d450db6954aa48e3Michael Kolb }) 3208233facddcc51865d612a919d450db6954aa48e3Michael Kolb .setOnCancelListener( 3218233facddcc51865d612a919d450db6954aa48e3Michael Kolb new DialogInterface.OnCancelListener() { 3228233facddcc51865d612a919d450db6954aa48e3Michael Kolb public void onCancel(DialogInterface dialog) { 3238233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorDialog = null; 3248233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorView = null; 3258233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorHandler = null; 3268233facddcc51865d612a919d450db6954aa48e3Michael Kolb mSSLCertificateOnErrorError = null; 3278233facddcc51865d612a919d450db6954aa48e3Michael Kolb 328e1d6dfca80e4627a0c7fe46e38f904179c3edab3Jonathan Dixon ((BrowserWebView) view).getWebViewClient(). 3294d2fcaba7fb8eb1723943ac9a10e76d509330bd1Jonathan Dixon onReceivedSslError(view, handler, error); 3308233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 3318233facddcc51865d612a919d450db6954aa48e3Michael Kolb }) 3328233facddcc51865d612a919d450db6954aa48e3Michael Kolb .show(); 3338233facddcc51865d612a919d450db6954aa48e3Michael Kolb } 334cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block 335cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block /* 336cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block * Creates an AlertDialog to display the given certificate. If error is 337cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block * null, text is added to state that the certificae is valid and the icon 338cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block * is set accordingly. If error is non-null, it must relate to the supplied 339cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block * certificate. In this case, error is used to add text describing the 340cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block * problems with the certificate and a different icon is used. 341cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block */ 342cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block private AlertDialog.Builder createSslCertificateDialog(SslCertificate certificate, 343cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block SslError error) { 344cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block View certificateView = certificate.inflateCertificateView(mContext); 345cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block final LinearLayout placeholder = 346cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block (LinearLayout)certificateView.findViewById(com.android.internal.R.id.placeholder); 347cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block 348cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block LayoutInflater factory = LayoutInflater.from(mContext); 349cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block int iconId; 350cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block 351cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (error == null) { 352cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block iconId = R.drawable.ic_dialog_browser_certificate_secure; 353cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block LinearLayout table = (LinearLayout)factory.inflate(R.layout.ssl_success, placeholder); 354cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block TextView successString = (TextView)table.findViewById(R.id.success); 355cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block successString.setText(com.android.internal.R.string.ssl_certificate_is_valid); 356cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } else { 357cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block iconId = R.drawable.ic_dialog_browser_certificate_partially_secure; 358cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (error.hasError(SslError.SSL_UNTRUSTED)) { 359cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block addError(factory, placeholder, R.string.ssl_untrusted); 360cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 361cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (error.hasError(SslError.SSL_IDMISMATCH)) { 362cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block addError(factory, placeholder, R.string.ssl_mismatch); 363cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 364cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (error.hasError(SslError.SSL_EXPIRED)) { 365cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block addError(factory, placeholder, R.string.ssl_expired); 366cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 367cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (error.hasError(SslError.SSL_NOTYETVALID)) { 368cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block addError(factory, placeholder, R.string.ssl_not_yet_valid); 369cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 370cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (error.hasError(SslError.SSL_DATE_INVALID)) { 371cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block addError(factory, placeholder, R.string.ssl_date_invalid); 372cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 373cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (error.hasError(SslError.SSL_INVALID)) { 374cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block addError(factory, placeholder, R.string.ssl_invalid); 375cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 376cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block // The SslError should always have at least one type of error and we 377cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block // should explicitly handle every type of error it supports. We 378cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block // therefore expect the condition below to never be hit. We use it 379cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block // as as safety net in case a new error type is added to SslError 380cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block // without the logic above being updated accordingly. 381cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block if (placeholder.getChildCount() == 0) { 382cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block addError(factory, placeholder, R.string.ssl_unknown); 383cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 384cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 385cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block 386cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block return new AlertDialog.Builder(mContext) 387cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block .setTitle(com.android.internal.R.string.ssl_certificate) 388cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block .setIcon(iconId) 389cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block .setView(certificateView); 390cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 391cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block 392cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block private void addError(LayoutInflater inflater, LinearLayout parent, int error) { 393cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block TextView textView = (TextView) inflater.inflate(R.layout.ssl_warning, 394cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block parent, false); 395cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block textView.setText(error); 396cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block parent.addView(textView); 397cbc67a01ccfe9cc5ce441f02a8c0dc475340830eSteve Block } 3988233facddcc51865d612a919d450db6954aa48e3Michael Kolb} 399