From 8efd38b61dac31564c8a53e1699e32c35c594ae6 Mon Sep 17 00:00:00 2001 From: lucaslin Date: Tue, 19 Mar 2019 19:15:54 +0800 Subject: [PATCH] Fix the problem of CaptivePortalLogin app cannot show SSL error page This commit is trying to fix the limitation of older design: 1.There is no guarantee that onReceivedSslError() will be called after onPageStarted(). So, onReceivedSslError() may compare the host of SSL error url with mHostName which is unset. 2.Some WIFI APs may redirect to the probing url(mUrl) along with special parameter first then redirect to the real log-in page, it will make onPageStarted get unexpected hostname. Above 2 situations will make captive portal app cannot show SSL error page and result in captive portal app is blank. The new design is trying to get the main frame url and compare it with SSL error url. If the SSL error url is equal to main frame url, then show the SSL error page. Bug: 123208856 Bug: 122991421 Test: build pass Change-Id: I27be7258436ccb833ff75ebcfed3af811467fa47 --- .../CaptivePortalLoginActivity.java | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index 2c9b6eb72b4da..9488afb446c46 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -53,6 +53,7 @@ import android.view.View; import android.webkit.CookieManager; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; +import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -408,8 +409,7 @@ public class CaptivePortalLoginActivity extends Activity { TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()); private int mPagesLoaded; - // the host of the page that this webview is currently loading. Can be null when undefined. - private String mHostname; + private String mMainFrameUrl; // If we haven't finished cleaning up the history, don't allow going back. public boolean allowBack() { @@ -435,7 +435,6 @@ public class CaptivePortalLoginActivity extends Activity { } final URL url = makeURL(urlString); Log.d(TAG, "onPageStarted: " + sanitizeURL(url)); - mHostname = host(url); // For internally generated pages, leave URL bar listing prior URL as this is the URL // the page refers to. if (!urlString.startsWith(INTERNAL_ASSETS)) { @@ -479,17 +478,28 @@ public class CaptivePortalLoginActivity extends Activity { return Integer.toString((int)dp) + "px"; } + // Check if webview is trying to load the main frame and record its url. + @Override + public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { + if (request.isForMainFrame()) { + mMainFrameUrl = request.getUrl().toString(); + } + return false; + } + // A web page consisting of a large broken lock icon to indicate SSL failure. @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { - final URL url = makeURL(error.getUrl()); - final String host = host(url); + final URL errorUrl = makeURL(error.getUrl()); + final URL mainFrameUrl = makeURL(mMainFrameUrl); Log.d(TAG, String.format("SSL error: %s, url: %s, certificate: %s", - sslErrorName(error), sanitizeURL(url), error.getCertificate())); - if (url == null || !Objects.equals(host, mHostname)) { - // Ignore ssl errors for resources coming from a different hostname than the page - // that we are currently loading, and only cancel the request. + sslErrorName(error), sanitizeURL(errorUrl), error.getCertificate())); + if (errorUrl == null + // Ignore SSL errors from resources by comparing the main frame url with SSL + // error url. + || !errorUrl.equals(mainFrameUrl)) { + Log.d(TAG, "onReceivedSslError: mMainFrameUrl = " + mMainFrameUrl); handler.cancel(); return; }