Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 2dd85ec

Browse files
[webview_flutter_android] Fixes bug where a AndroidNavigationDelegate was required to load a request (#6872)
* fix bug * comment * another test * fix spelling
1 parent 15cfe8a commit 2dd85ec

File tree

5 files changed

+57
-23
lines changed

5 files changed

+57
-23
lines changed

packages/webview_flutter/webview_flutter_android/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 3.1.1
2+
3+
* Fixes bug where a `AndroidNavigationDelegate` was required to load a request.
4+
15
## 3.1.0
26

37
* Adds support for selecting Hybrid Composition on versions 23+. Please use

packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientHostApiImpl.java

+14-7
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@ public class WebChromeClientHostApiImpl implements WebChromeClientHostApi {
2929
/**
3030
* Implementation of {@link WebChromeClient} that passes arguments of callback methods to Dart.
3131
*/
32-
public static class WebChromeClientImpl extends WebChromeClient {
32+
public static class WebChromeClientImpl extends SecureWebChromeClient {
3333
private final WebChromeClientFlutterApiImpl flutterApi;
34-
@Nullable private WebViewClient webViewClient;
3534

3635
/**
3736
* Creates a {@link WebChromeClient} that passes arguments of callbacks methods to Dart.
@@ -42,6 +41,19 @@ public WebChromeClientImpl(@NonNull WebChromeClientFlutterApiImpl flutterApi) {
4241
this.flutterApi = flutterApi;
4342
}
4443

44+
@Override
45+
public void onProgressChanged(WebView view, int progress) {
46+
flutterApi.onProgressChanged(this, view, (long) progress, reply -> {});
47+
}
48+
}
49+
50+
/**
51+
* Implementation of {@link WebChromeClient} that only allows secure urls when opening a new
52+
* window.
53+
*/
54+
public static class SecureWebChromeClient extends WebChromeClient {
55+
@Nullable private WebViewClient webViewClient;
56+
4557
@Override
4658
public boolean onCreateWindow(
4759
final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
@@ -105,11 +117,6 @@ public boolean shouldOverrideUrlLoading(WebView windowWebView, String url) {
105117
return true;
106118
}
107119

108-
@Override
109-
public void onProgressChanged(WebView view, int progress) {
110-
flutterApi.onProgressChanged(this, view, (long) progress, reply -> {});
111-
}
112-
113120
/**
114121
* Set the {@link WebViewClient} that calls to {@link WebChromeClient#onCreateWindow} are passed
115122
* to.

packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java

+19-15
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import io.flutter.plugin.common.BinaryMessenger;
1818
import io.flutter.plugin.platform.PlatformView;
1919
import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebViewHostApi;
20-
import io.flutter.plugins.webviewflutter.WebChromeClientHostApiImpl.WebChromeClientImpl;
2120
import java.util.Map;
2221
import java.util.Objects;
2322

@@ -80,7 +79,7 @@ public void setWebContentsDebuggingEnabled(boolean enabled) {
8079
/** Implementation of {@link WebView} that can be used as a Flutter {@link PlatformView}s. */
8180
public static class WebViewPlatformView extends WebView implements PlatformView {
8281
private WebViewClient currentWebViewClient;
83-
private WebChromeClientImpl currentWebChromeClient;
82+
private WebChromeClientHostApiImpl.SecureWebChromeClient currentWebChromeClient;
8483

8584
/**
8685
* Creates a {@link WebViewPlatformView}.
@@ -91,9 +90,7 @@ public WebViewPlatformView(
9190
Context context, BinaryMessenger binaryMessenger, InstanceManager instanceManager) {
9291
super(context);
9392
currentWebViewClient = new WebViewClient();
94-
currentWebChromeClient =
95-
new WebChromeClientImpl(
96-
new WebChromeClientFlutterApiImpl(binaryMessenger, instanceManager));
93+
currentWebChromeClient = new WebChromeClientHostApiImpl.SecureWebChromeClient();
9794

9895
setWebViewClient(currentWebViewClient);
9996
setWebChromeClient(currentWebChromeClient);
@@ -119,12 +116,21 @@ public void setWebViewClient(WebViewClient webViewClient) {
119116
@Override
120117
public void setWebChromeClient(WebChromeClient client) {
121118
super.setWebChromeClient(client);
122-
if (!(client instanceof WebChromeClientImpl)) {
123-
throw new AssertionError("Client must be a WebChromeClientImpl.");
119+
if (!(client instanceof WebChromeClientHostApiImpl.SecureWebChromeClient)) {
120+
throw new AssertionError("Client must be a SecureWebChromeClient.");
124121
}
125-
currentWebChromeClient = (WebChromeClientImpl) client;
122+
currentWebChromeClient = (WebChromeClientHostApiImpl.SecureWebChromeClient) client;
126123
currentWebChromeClient.setWebViewClient(currentWebViewClient);
127124
}
125+
126+
// When running unit tests, the parent `WebView` class is replaced by a stub that returns null
127+
// for every method. This is overridden so that this returns the current WebChromeClient during
128+
// unit tests. This should only remain overridden as long as `setWebChromeClient` is overridden.
129+
@Nullable
130+
@Override
131+
public WebChromeClient getWebChromeClient() {
132+
return currentWebChromeClient;
133+
}
128134
}
129135

130136
/**
@@ -135,7 +141,7 @@ public void setWebChromeClient(WebChromeClient client) {
135141
public static class InputAwareWebViewPlatformView extends InputAwareWebView
136142
implements PlatformView {
137143
private WebViewClient currentWebViewClient;
138-
private WebChromeClientImpl currentWebChromeClient;
144+
private WebChromeClientHostApiImpl.SecureWebChromeClient currentWebChromeClient;
139145

140146
/**
141147
* Creates a {@link InputAwareWebViewPlatformView}.
@@ -149,9 +155,7 @@ public InputAwareWebViewPlatformView(
149155
View containerView) {
150156
super(context, containerView);
151157
currentWebViewClient = new WebViewClient();
152-
currentWebChromeClient =
153-
new WebChromeClientImpl(
154-
new WebChromeClientFlutterApiImpl(binaryMessenger, instanceManager));
158+
currentWebChromeClient = new WebChromeClientHostApiImpl.SecureWebChromeClient();
155159

156160
setWebViewClient(currentWebViewClient);
157161
setWebChromeClient(currentWebChromeClient);
@@ -198,10 +202,10 @@ public void setWebViewClient(WebViewClient webViewClient) {
198202
@Override
199203
public void setWebChromeClient(WebChromeClient client) {
200204
super.setWebChromeClient(client);
201-
if (!(client instanceof WebChromeClientImpl)) {
202-
throw new AssertionError("Client must be a WebChromeClientImpl.");
205+
if (!(client instanceof WebChromeClientHostApiImpl.SecureWebChromeClient)) {
206+
throw new AssertionError("Client must be a SecureWebChromeClient.");
203207
}
204-
currentWebChromeClient = (WebChromeClientImpl) client;
208+
currentWebChromeClient = (WebChromeClientHostApiImpl.SecureWebChromeClient) client;
205209
currentWebChromeClient.setWebViewClient(currentWebViewClient);
206210
}
207211
}

packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java

+19
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package io.flutter.plugins.webviewflutter;
66

77
import static org.junit.Assert.assertEquals;
8+
import static org.junit.Assert.assertFalse;
9+
import static org.junit.Assert.assertTrue;
810
import static org.mockito.ArgumentMatchers.eq;
911
import static org.mockito.Mockito.mock;
1012
import static org.mockito.Mockito.verify;
@@ -18,6 +20,7 @@
1820
import io.flutter.plugin.common.BinaryMessenger;
1921
import io.flutter.plugins.webviewflutter.WebViewHostApiImpl.WebViewPlatformView;
2022
import java.util.HashMap;
23+
import java.util.Objects;
2124
import org.junit.After;
2225
import org.junit.Before;
2326
import org.junit.Rule;
@@ -262,4 +265,20 @@ public void setWebChromeClient() {
262265
testHostApiImpl.setWebChromeClient(0L, 1L);
263266
verify(mockWebView).setWebChromeClient(mockWebChromeClient);
264267
}
268+
269+
@Test
270+
public void defaultWebChromeClientIsSecureWebChromeClient() {
271+
final WebViewPlatformView webView = new WebViewPlatformView(mockContext, null, null);
272+
assertTrue(
273+
webView.getWebChromeClient() instanceof WebChromeClientHostApiImpl.SecureWebChromeClient);
274+
assertFalse(
275+
webView.getWebChromeClient() instanceof WebChromeClientHostApiImpl.WebChromeClientImpl);
276+
}
277+
278+
@Test
279+
public void defaultWebChromeClientDoesNotAttemptToCommunicateWithDart() {
280+
final WebViewPlatformView webView = new WebViewPlatformView(mockContext, null, null);
281+
// This shouldn't throw an Exception.
282+
Objects.requireNonNull(webView.getWebChromeClient()).onProgressChanged(webView, 0);
283+
}
265284
}

packages/webview_flutter/webview_flutter_android/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: webview_flutter_android
22
description: A Flutter plugin that provides a WebView widget on Android.
33
repository: https://github.com/flutter/plugins/tree/main/packages/webview_flutter/webview_flutter_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
5-
version: 3.1.0
5+
version: 3.1.1
66

77
environment:
88
sdk: ">=2.17.0 <3.0.0"

0 commit comments

Comments
 (0)