diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index fe285b8f5867..b5502ecd2577 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.1.1 + +* Fixes bug where a `AndroidNavigationDelegate` was required to load a request. + ## 3.1.0 * Adds support for selecting Hybrid Composition on versions 23+. Please use diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java index 7b5241ed4d33..3fa4a2f9c298 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java @@ -29,9 +29,8 @@ public class WebChromeClientHostApiImpl implements WebChromeClientHostApi { /** * Implementation of {@link WebChromeClient} that passes arguments of callback methods to Dart. */ - public static class WebChromeClientImpl extends WebChromeClient { + public static class WebChromeClientImpl extends SecureWebChromeClient { private final WebChromeClientFlutterApiImpl flutterApi; - @Nullable private WebViewClient webViewClient; /** * Creates a {@link WebChromeClient} that passes arguments of callbacks methods to Dart. @@ -42,6 +41,19 @@ public WebChromeClientImpl(@NonNull WebChromeClientFlutterApiImpl flutterApi) { this.flutterApi = flutterApi; } + @Override + public void onProgressChanged(WebView view, int progress) { + flutterApi.onProgressChanged(this, view, (long) progress, reply -> {}); + } + } + + /** + * Implementation of {@link WebChromeClient} that only allows secure urls when opening a new + * window. + */ + public static class SecureWebChromeClient extends WebChromeClient { + @Nullable private WebViewClient webViewClient; + @Override public boolean onCreateWindow( final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { @@ -105,11 +117,6 @@ public boolean shouldOverrideUrlLoading(WebView windowWebView, String url) { return true; } - @Override - public void onProgressChanged(WebView view, int progress) { - flutterApi.onProgressChanged(this, view, (long) progress, reply -> {}); - } - /** * Set the {@link WebViewClient} that calls to {@link WebChromeClient#onCreateWindow} are passed * to. diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java index 2fd990535b29..0a044cc5ab7e 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java @@ -17,7 +17,6 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebViewHostApi; -import io.flutter.plugins.webviewflutter.WebChromeClientHostApiImpl.WebChromeClientImpl; import java.util.Map; import java.util.Objects; @@ -80,7 +79,7 @@ public void setWebContentsDebuggingEnabled(boolean enabled) { /** Implementation of {@link WebView} that can be used as a Flutter {@link PlatformView}s. */ public static class WebViewPlatformView extends WebView implements PlatformView { private WebViewClient currentWebViewClient; - private WebChromeClientImpl currentWebChromeClient; + private WebChromeClientHostApiImpl.SecureWebChromeClient currentWebChromeClient; /** * Creates a {@link WebViewPlatformView}. @@ -91,9 +90,7 @@ public WebViewPlatformView( Context context, BinaryMessenger binaryMessenger, InstanceManager instanceManager) { super(context); currentWebViewClient = new WebViewClient(); - currentWebChromeClient = - new WebChromeClientImpl( - new WebChromeClientFlutterApiImpl(binaryMessenger, instanceManager)); + currentWebChromeClient = new WebChromeClientHostApiImpl.SecureWebChromeClient(); setWebViewClient(currentWebViewClient); setWebChromeClient(currentWebChromeClient); @@ -119,12 +116,21 @@ public void setWebViewClient(WebViewClient webViewClient) { @Override public void setWebChromeClient(WebChromeClient client) { super.setWebChromeClient(client); - if (!(client instanceof WebChromeClientImpl)) { - throw new AssertionError("Client must be a WebChromeClientImpl."); + if (!(client instanceof WebChromeClientHostApiImpl.SecureWebChromeClient)) { + throw new AssertionError("Client must be a SecureWebChromeClient."); } - currentWebChromeClient = (WebChromeClientImpl) client; + currentWebChromeClient = (WebChromeClientHostApiImpl.SecureWebChromeClient) client; currentWebChromeClient.setWebViewClient(currentWebViewClient); } + + // When running unit tests, the parent `WebView` class is replaced by a stub that returns null + // for every method. This is overridden so that this returns the current WebChromeClient during + // unit tests. This should only remain overridden as long as `setWebChromeClient` is overridden. + @Nullable + @Override + public WebChromeClient getWebChromeClient() { + return currentWebChromeClient; + } } /** @@ -135,7 +141,7 @@ public void setWebChromeClient(WebChromeClient client) { public static class InputAwareWebViewPlatformView extends InputAwareWebView implements PlatformView { private WebViewClient currentWebViewClient; - private WebChromeClientImpl currentWebChromeClient; + private WebChromeClientHostApiImpl.SecureWebChromeClient currentWebChromeClient; /** * Creates a {@link InputAwareWebViewPlatformView}. @@ -149,9 +155,7 @@ public InputAwareWebViewPlatformView( View containerView) { super(context, containerView); currentWebViewClient = new WebViewClient(); - currentWebChromeClient = - new WebChromeClientImpl( - new WebChromeClientFlutterApiImpl(binaryMessenger, instanceManager)); + currentWebChromeClient = new WebChromeClientHostApiImpl.SecureWebChromeClient(); setWebViewClient(currentWebViewClient); setWebChromeClient(currentWebChromeClient); @@ -198,10 +202,10 @@ public void setWebViewClient(WebViewClient webViewClient) { @Override public void setWebChromeClient(WebChromeClient client) { super.setWebChromeClient(client); - if (!(client instanceof WebChromeClientImpl)) { - throw new AssertionError("Client must be a WebChromeClientImpl."); + if (!(client instanceof WebChromeClientHostApiImpl.SecureWebChromeClient)) { + throw new AssertionError("Client must be a SecureWebChromeClient."); } - currentWebChromeClient = (WebChromeClientImpl) client; + currentWebChromeClient = (WebChromeClientHostApiImpl.SecureWebChromeClient) client; currentWebChromeClient.setWebViewClient(currentWebViewClient); } } diff --git a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java index ecaab779c16a..c49d6c5d1142 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java @@ -5,6 +5,8 @@ package io.flutter.plugins.webviewflutter; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -18,6 +20,7 @@ import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugins.webviewflutter.WebViewHostApiImpl.WebViewPlatformView; import java.util.HashMap; +import java.util.Objects; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -262,4 +265,20 @@ public void setWebChromeClient() { testHostApiImpl.setWebChromeClient(0L, 1L); verify(mockWebView).setWebChromeClient(mockWebChromeClient); } + + @Test + public void defaultWebChromeClientIsSecureWebChromeClient() { + final WebViewPlatformView webView = new WebViewPlatformView(mockContext, null, null); + assertTrue( + webView.getWebChromeClient() instanceof WebChromeClientHostApiImpl.SecureWebChromeClient); + assertFalse( + webView.getWebChromeClient() instanceof WebChromeClientHostApiImpl.WebChromeClientImpl); + } + + @Test + public void defaultWebChromeClientDoesNotAttemptToCommunicateWithDart() { + final WebViewPlatformView webView = new WebViewPlatformView(mockContext, null, null); + // This shouldn't throw an Exception. + Objects.requireNonNull(webView.getWebChromeClient()).onProgressChanged(webView, 0); + } } diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index cf6939ae1c55..72bc2e43414a 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_android description: A Flutter plugin that provides a WebView widget on Android. repository: https://github.com/flutter/plugins/tree/main/packages/webview_flutter/webview_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 3.1.0 +version: 3.1.1 environment: sdk: ">=2.17.0 <3.0.0"