From 5d0431106e0682f001dd788d306c10a6b3309eeb Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Wed, 21 Jul 2021 19:38:59 +0200 Subject: [PATCH 1/7] Refactor for testability --- .../webview_flutter/android/build.gradle | 2 + .../webviewflutter/FlutterWebView.java | 73 ++++++-- ...actory.java => FlutterWebViewFactory.java} | 4 +- .../webviewflutter/WebViewBuilder.java | 161 ++++++++++++++++++ .../webviewflutter/WebViewFlutterPlugin.java | 4 +- .../webviewflutter/WebViewBuilderTest.java | 61 +++++++ 6 files changed, 286 insertions(+), 19 deletions(-) rename packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/{WebViewFactory.java => FlutterWebViewFactory.java} (86%) create mode 100644 packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java create mode 100644 packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java diff --git a/packages/webview_flutter/webview_flutter/android/build.gradle b/packages/webview_flutter/webview_flutter/android/build.gradle index 45f769b4bc59..41c702f9fc56 100644 --- a/packages/webview_flutter/webview_flutter/android/build.gradle +++ b/packages/webview_flutter/webview_flutter/android/build.gradle @@ -37,5 +37,7 @@ android { implementation 'androidx.annotation:annotation:1.0.0' implementation 'androidx.webkit:webkit:1.0.0' testImplementation 'junit:junit:4.12' + testImplementation 'org.mockito:mockito-inline:3.11.1' + testImplementation 'androidx.test:core:1.3.0' } } diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index ebc7c31987f4..bcd259bd46d0 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -17,6 +17,7 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -28,6 +29,7 @@ import java.util.Map; public class FlutterWebView implements PlatformView, MethodCallHandler { + private static final String JS_CHANNEL_NAMES_FIELD = "javascriptChannelNames"; private final WebView webView; private final MethodChannel methodChannel; @@ -36,6 +38,7 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { // Verifies that a url opened by `Window.open` has a secure url. private class FlutterWebChromeClient extends WebChromeClient { + @Override public boolean onCreateWindow( final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) { @@ -94,36 +97,32 @@ public void onProgressChanged(WebView view, int progress) { displayListenerProxy.onPreWebViewInitialization(displayManager); Boolean usesHybridComposition = (Boolean) params.get("usesHybridComposition"); - webView = - (usesHybridComposition) - ? new WebView(context) - : new InputAwareWebView(context, containerView); + webView = createWebView(context, params, containerView); displayListenerProxy.onPostWebViewInitialization(displayManager); platformThreadHandler = new Handler(context.getMainLooper()); - // Allow local storage. - webView.getSettings().setDomStorageEnabled(true); - webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); - - // Multi windows is set with FlutterWebChromeClient by default to handle internal bug: b/159892679. - webView.getSettings().setSupportMultipleWindows(true); - webView.setWebChromeClient(new FlutterWebChromeClient()); methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); methodChannel.setMethodCallHandler(this); flutterWebViewClient = new FlutterWebViewClient(methodChannel); Map settings = (Map) params.get("settings"); - if (settings != null) applySettings(settings); + if (settings != null) { + applySettings(settings); + } if (params.containsKey(JS_CHANNEL_NAMES_FIELD)) { List names = (List) params.get(JS_CHANNEL_NAMES_FIELD); - if (names != null) registerJavaScriptChannelNames(names); + if (names != null) { + registerJavaScriptChannelNames(names); + } } Integer autoMediaPlaybackPolicy = (Integer) params.get("autoMediaPlaybackPolicy"); - if (autoMediaPlaybackPolicy != null) updateAutoMediaPlaybackPolicy(autoMediaPlaybackPolicy); + if (autoMediaPlaybackPolicy != null) { + updateAutoMediaPlaybackPolicy(autoMediaPlaybackPolicy); + } if (params.containsKey("userAgent")) { String userAgent = (String) params.get("userAgent"); updateUserAgent(userAgent); @@ -134,6 +133,48 @@ public void onProgressChanged(WebView view, int progress) { } } + /** + * Creates a {@link android.webkit.WebView} and configures it according to the supplied + * parameters. + * + *

The {@link WebView} is configured with the following predefined settings: + *

    + *
  • always enable the DOM storage API;
  • + *
  • always allow JavaScript to automatically open windows;
  • + *
  • always allow support for multiple windows;
  • + *
  • always use the {@link FlutterWebChromeClient} as web Chrome client.
  • + *
+ *

+ * + *

+ * Important: + * This method is visible for testing purposes only and should never be called from outside this + * class. + *

+ * @param context an Activity Context to access application assets. This value cannot be + * null. + * @param params creation parameters received over the method channel. + * @param containerView must be supplied when the {@code useHybridComposition} parameter is set to + * {@code false}. Used to create an InputConnection on the WebView's + * dedicated input, or IME, thread (see also {@link InputAwareWebView}). + * @return The new {@link android.webkit.WebView} object. + */ + @VisibleForTesting + WebView createWebView( + Context context, + Map params, + View containerView + ) { + Boolean usesHybridComposition = (Boolean) params.get("usesHybridComposition"); + WebViewBuilder builder = new WebViewBuilder(context, usesHybridComposition, containerView) + .setDomStorageEnabled(true) // Always enable DOM storage API. + .setJavaScriptCanOpenWindowsAutomatically(true) // Always allow automatically opening of windows. + .setSupportMultipleWindows(true) // Always support multiple windows. + .setWebChromeClient(new FlutterWebChromeClient()); // Always use {@link FlutterWebChromeClient} as web Chrome client. + + return builder.build(); + } + @Override public View getView() { return webView; @@ -369,7 +410,9 @@ private void applySettings(Map settings) { switch (key) { case "jsMode": Integer mode = (Integer) settings.get(key); - if (mode != null) updateJsMode(mode); + if (mode != null) { + updateJsMode(mode); + } break; case "hasNavigationDelegate": final boolean hasNavigationDelegate = (boolean) settings.get(key); diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java similarity index 86% rename from packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java rename to packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java index 22de668e0126..6a1e61e2d800 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFactory.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java @@ -12,11 +12,11 @@ import io.flutter.plugin.platform.PlatformViewFactory; import java.util.Map; -public final class WebViewFactory extends PlatformViewFactory { +public final class FlutterWebViewFactory extends PlatformViewFactory { private final BinaryMessenger messenger; private final View containerView; - WebViewFactory(BinaryMessenger messenger, View containerView) { + FlutterWebViewFactory(BinaryMessenger messenger, View containerView) { super(StandardMessageCodec.INSTANCE); this.messenger = messenger; this.containerView = containerView; diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java new file mode 100644 index 000000000000..16bb0d0f7a93 --- /dev/null +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java @@ -0,0 +1,161 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter.plugins.webviewflutter; + +import android.content.Context; +import android.view.View; +import android.webkit.WebChromeClient; +import android.webkit.WebSettings; +import android.webkit.WebView; +import androidx.annotation.NonNull; + +/** + * Builder used to create {@link android.webkit.WebView} objects. + */ +public class WebViewBuilder { + + /** + * Factory used to create a new {@link android.webkit.WebView} instance. + */ + static class WebViewFactory { + + /** + * Creates a new {@link android.webkit.WebView} instance. + * + * @param context an Activity Context to access application assets. This value + * cannot be null. + * @param usesHybridComposition If {@code false} a {@link InputAwareWebView} instance is + * returned. + * @param containerView must be supplied when the {@code useHybridComposition} parameter + * is set to {@code false}. Used to create an InputConnection on + * the WebView's dedicated input, or IME, thread (see also {@link + * InputAwareWebView}) + * @return A new instance of the {@link android.webkit.WebView} object. + */ + WebView create(Context context, boolean usesHybridComposition, View containerView) { + return usesHybridComposition + ? new WebView(context) + : new InputAwareWebView(context, containerView); + } + } + + private final Context context; + private final View containerView; + private final boolean usesHybridComposition; + private final WebViewFactory webViewFactory; + + private boolean enableDomStorage; + private boolean javaScriptCanOpenWindowsAutomatically; + private boolean supportMultipleWindows; + private WebChromeClient webChromeClient; + + /** + * Constructs a new {@link WebViewBuilder} object. + * + * @param context an Activity Context to access application assets. This value + * cannot be null. + * @param usesHybridComposition if {@code false} a {@link InputAwareWebView} instance is returned. + * @param containerView must be supplied when the {@code useHybridComposition} parameter + * is set to {@code false}. Used to create an InputConnection on the + * WebView's dedicated input, or IME, thread (see also {@link + * InputAwareWebView}) + */ + public WebViewBuilder( + @NonNull final Context context, + boolean usesHybridComposition, + View containerView) { + this(context, usesHybridComposition, containerView, new WebViewFactory()); + } + + /** + * Constructs a new {@link WebViewBuilder} object with a custom implementation of the {@link + * WebViewFactory} object. + * + * @param context an Activity Context to access application assets. This value + * cannot be null. + * @param usesHybridComposition if {@code false} a {@link InputAwareWebView} instance is returned. + * @param containerView must be supplied when the {@code useHybridComposition} parameter + * is set to {@code false}. Used to create an InputConnection on the + * WebView's dedicated input, or IME, thread (see also {@link + * InputAwareWebView}) + * @param webViewFactory custom implementation of the {@link WebViewFactory} object. + */ + WebViewBuilder( + @NonNull final Context context, + boolean usesHybridComposition, + View containerView, + WebViewFactory webViewFactory + ) { + this.context = context; + this.usesHybridComposition = usesHybridComposition; + this.containerView = containerView; + this.webViewFactory = webViewFactory; + } + + /** + * Sets whether the DOM storage API is enabled. The default value is {@code false}. + * + * @param flag {@code true} is {@link android.webkit.WebView} should use the DOM storage API. + * @return This builder. This value cannot be {@code null}. + */ + public WebViewBuilder setDomStorageEnabled(boolean flag) { + this.enableDomStorage = flag; + return this; + } + + /** + * Sets whether JavaScript is allowed to open windows automatically. This applies to the + * JavaScript function {@code window.open()}. The default value is {@code false}. + * + * @param flag {@code true} if JavaScript is allowed to open windows automatically. + * @return This builder. This value cannot be {@code null}. + */ + public WebViewBuilder setJavaScriptCanOpenWindowsAutomatically(boolean flag) { + this.javaScriptCanOpenWindowsAutomatically = flag; + return this; + } + + /** + * Set whether the WebView supports multiple windows. If set to {@code true}, {@link + * WebChromeClient#onCreateWindow} must be implemented by the host application. The default is + * {@code false}. + * + * @param flag {@code true} if multiple windows are supported. + * @return This builder. This value cannot be {@code null}. + */ + public WebViewBuilder setSupportMultipleWindows(boolean flag) { + this.supportMultipleWindows = flag; + return this; + } + + /** + * Sets the chrome handler. This is an implementation of WebChromeClient for use in handling + * JavaScript dialogs, favicons, titles, and the progress. This will replace the current handler. + * + * @param webChromeClient an implementation of WebChromeClient This value may be null. + * @return This builder. This value cannot be {@code null}. + */ + public WebViewBuilder setWebChromeClient(WebChromeClient webChromeClient) { + this.webChromeClient = webChromeClient; + return this; + } + + /** + * Build the {@link android.webkit.WebView} using the current settings. + * + * @return The {@link android.webkit.WebView} using the current settings. + */ + public WebView build() { + WebView webView = webViewFactory.create(context, usesHybridComposition, containerView); + + WebSettings webSettings = webView.getSettings(); + webSettings.setDomStorageEnabled(enableDomStorage); + webSettings.setJavaScriptCanOpenWindowsAutomatically(javaScriptCanOpenWindowsAutomatically); + webSettings.setSupportMultipleWindows(supportMultipleWindows); + webView.setWebChromeClient(webChromeClient); + + return webView; + } +} diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java index dc329e2273d0..55d700eb9994 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java @@ -46,7 +46,7 @@ public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registra .platformViewRegistry() .registerViewFactory( "plugins.flutter.io/webview", - new WebViewFactory(registrar.messenger(), registrar.view())); + new FlutterWebViewFactory(registrar.messenger(), registrar.view())); new FlutterCookieManager(registrar.messenger()); } @@ -56,7 +56,7 @@ public void onAttachedToEngine(FlutterPluginBinding binding) { binding .getPlatformViewRegistry() .registerViewFactory( - "plugins.flutter.io/webview", new WebViewFactory(messenger, /*containerView=*/ null)); + "plugins.flutter.io/webview", new FlutterWebViewFactory(messenger, /*containerView=*/ null)); flutterCookieManager = new FlutterCookieManager(messenger); } diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java new file mode 100644 index 000000000000..2f10eb73734f --- /dev/null +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java @@ -0,0 +1,61 @@ +package io.flutter.plugins.webviewflutter; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.*; + +import android.content.Context; +import android.view.View; +import android.webkit.WebChromeClient; +import android.webkit.WebSettings; +import android.webkit.WebView; +import java.io.IOException; +import org.junit.Before; +import org.junit.Test; + +public class WebViewBuilderTest { + private Context mockContext; + private View mockContainerView; + + @Before + public void before() { + mockContext = mock(Context.class); + mockContainerView = mock(View.class); + } + + @Test + public void ctor_test() { + WebViewBuilder builder = + new WebViewBuilder(mockContext, false, mockContainerView); + + assertNotNull(builder); + } + + @Test + public void build_Should_set_values() throws IOException { + WebViewBuilder.WebViewFactory mockFactory = + mock(WebViewBuilder.WebViewFactory.class); + WebView mockWebView = mock(WebView.class); + WebSettings mockWebSettings = mock(WebSettings.class); + WebChromeClient mockWebChromeClient = mock(WebChromeClient.class); + + when(mockWebView.getSettings()).thenReturn(mockWebSettings); + + WebViewBuilder builder = + new WebViewBuilder(mockContext, false, mockContainerView, mockFactory) + .setDomStorageEnabled(true) + .setJavaScriptCanOpenWindowsAutomatically(true) + .setSupportMultipleWindows(true) + .setWebChromeClient(mockWebChromeClient); + + when(mockFactory.create(mockContext, false, mockContainerView)).thenReturn(mockWebView); + + WebView webView = builder.build(); + + assertNotNull(webView); + verify(mockWebSettings).setDomStorageEnabled(true); + verify(mockWebSettings).setJavaScriptCanOpenWindowsAutomatically(true); + verify(mockWebSettings).setSupportMultipleWindows(true); + verify(mockWebView).setWebChromeClient(mockWebChromeClient); + } +} From c026f9d4f13e5911bffa71e45cf116214504c37b Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 22 Jul 2021 08:56:47 +0200 Subject: [PATCH 2/7] Test FlutterWebView.createWebView method --- .../webviewflutter/FlutterWebView.java | 78 ++++++++++------- .../webviewflutter/WebViewBuilder.java | 83 +++++++------------ .../webviewflutter/FlutterWebViewTest.java | 55 ++++++++++++ .../webviewflutter/WebViewBuilderTest.java | 33 +++++--- 4 files changed, 158 insertions(+), 91 deletions(-) create mode 100644 packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index bcd259bd46d0..d6ddc84ad738 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -96,15 +96,15 @@ public void onProgressChanged(WebView view, int progress) { (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); displayListenerProxy.onPreWebViewInitialization(displayManager); - Boolean usesHybridComposition = (Boolean) params.get("usesHybridComposition"); - webView = createWebView(context, params, containerView); + webView = + createWebView( + new WebViewBuilder(context, containerView), params, new FlutterWebChromeClient()); displayListenerProxy.onPostWebViewInitialization(displayManager); platformThreadHandler = new Handler(context.getMainLooper()); - methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); - methodChannel.setMethodCallHandler(this); + methodChannel = createMethodChannel(messenger, id, this); flutterWebViewClient = new FlutterWebViewClient(methodChannel); Map settings = (Map) params.get("settings"); @@ -138,41 +138,61 @@ public void onProgressChanged(WebView view, int progress) { * parameters. * *

The {@link WebView} is configured with the following predefined settings: + * *

    - *
  • always enable the DOM storage API;
  • - *
  • always allow JavaScript to automatically open windows;
  • - *
  • always allow support for multiple windows;
  • - *
  • always use the {@link FlutterWebChromeClient} as web Chrome client.
  • + *
  • always enable the DOM storage API; + *
  • always allow JavaScript to automatically open windows; + *
  • always allow support for multiple windows; + *
  • always use the {@link FlutterWebChromeClient} as web Chrome client. *
- *

* - *

- * Important: - * This method is visible for testing purposes only and should never be called from outside this - * class. - *

- * @param context an Activity Context to access application assets. This value cannot be - * null. - * @param params creation parameters received over the method channel. - * @param containerView must be supplied when the {@code useHybridComposition} parameter is set to - * {@code false}. Used to create an InputConnection on the WebView's - * dedicated input, or IME, thread (see also {@link InputAwareWebView}). + *

Important: This method is visible for testing purposes only and should + * never be called from outside this class. + * + * @param webViewBuilder a {@link WebViewBuilder} which is responsible for building the {@link + * WebView}. + * @param params creation parameters received over the method channel. + * @param webChromeClient an implementation of WebChromeClient This value may be null. * @return The new {@link android.webkit.WebView} object. */ @VisibleForTesting - WebView createWebView( - Context context, - Map params, - View containerView - ) { + static WebView createWebView( + WebViewBuilder webViewBuilder, Map params, WebChromeClient webChromeClient) { Boolean usesHybridComposition = (Boolean) params.get("usesHybridComposition"); - WebViewBuilder builder = new WebViewBuilder(context, usesHybridComposition, containerView) + webViewBuilder + .setUsesHybridComposition(usesHybridComposition) .setDomStorageEnabled(true) // Always enable DOM storage API. - .setJavaScriptCanOpenWindowsAutomatically(true) // Always allow automatically opening of windows. + .setJavaScriptCanOpenWindowsAutomatically( + true) // Always allow automatically opening of windows. .setSupportMultipleWindows(true) // Always support multiple windows. - .setWebChromeClient(new FlutterWebChromeClient()); // Always use {@link FlutterWebChromeClient} as web Chrome client. + .setWebChromeClient( + webChromeClient); // Always use {@link FlutterWebChromeClient} as web Chrome client. + + return webViewBuilder.build(); + } + + /** + * Creates a {@link MethodChannel} used to handle communication with the Flutter application about + * the {@link FlutterWebView} instance. + * + *

Important: This method is visible for testing purposes only and should + * never be called from outside this class. + * + * @param messenger a {@link BinaryMessenger} to facilitate communication with Flutter. + * @param id an identifier used to create a unique channel name and identify communication with a + * particular {@link FlutterWebView} instance. + * @param handler a {@link MethodCallHandler} responsible for handling messages that arrive from + * the Flutter application. + * @return The {@link MethodChannel} configured using the supplied {@link BinaryMessenger} and + * {@link MethodCallHandler}. + */ + @VisibleForTesting + static MethodChannel createMethodChannel( + BinaryMessenger messenger, int id, MethodCallHandler handler) { + MethodChannel methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); + methodChannel.setMethodCallHandler(handler); - return builder.build(); + return methodChannel; } @Override diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java index 16bb0d0f7a93..40e3f003f717 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java @@ -11,30 +11,24 @@ import android.webkit.WebView; import androidx.annotation.NonNull; -/** - * Builder used to create {@link android.webkit.WebView} objects. - */ +/** Builder used to create {@link android.webkit.WebView} objects. */ public class WebViewBuilder { - /** - * Factory used to create a new {@link android.webkit.WebView} instance. - */ + /** Factory used to create a new {@link android.webkit.WebView} instance. */ static class WebViewFactory { /** * Creates a new {@link android.webkit.WebView} instance. * - * @param context an Activity Context to access application assets. This value - * cannot be null. + * @param context an Activity Context to access application assets. This value cannot be null. * @param usesHybridComposition If {@code false} a {@link InputAwareWebView} instance is - * returned. - * @param containerView must be supplied when the {@code useHybridComposition} parameter - * is set to {@code false}. Used to create an InputConnection on - * the WebView's dedicated input, or IME, thread (see also {@link - * InputAwareWebView}) + * returned. + * @param containerView must be supplied when the {@code useHybridComposition} parameter is set + * to {@code false}. Used to create an InputConnection on the WebView's dedicated input, or + * IME, thread (see also {@link InputAwareWebView}) * @return A new instance of the {@link android.webkit.WebView} object. */ - WebView create(Context context, boolean usesHybridComposition, View containerView) { + static WebView create(Context context, boolean usesHybridComposition, View containerView) { return usesHybridComposition ? new WebView(context) : new InputAwareWebView(context, containerView); @@ -43,55 +37,25 @@ WebView create(Context context, boolean usesHybridComposition, View containerVie private final Context context; private final View containerView; - private final boolean usesHybridComposition; - private final WebViewFactory webViewFactory; private boolean enableDomStorage; private boolean javaScriptCanOpenWindowsAutomatically; private boolean supportMultipleWindows; + private boolean usesHybridComposition; private WebChromeClient webChromeClient; - /** - * Constructs a new {@link WebViewBuilder} object. - * - * @param context an Activity Context to access application assets. This value - * cannot be null. - * @param usesHybridComposition if {@code false} a {@link InputAwareWebView} instance is returned. - * @param containerView must be supplied when the {@code useHybridComposition} parameter - * is set to {@code false}. Used to create an InputConnection on the - * WebView's dedicated input, or IME, thread (see also {@link - * InputAwareWebView}) - */ - public WebViewBuilder( - @NonNull final Context context, - boolean usesHybridComposition, - View containerView) { - this(context, usesHybridComposition, containerView, new WebViewFactory()); - } - /** * Constructs a new {@link WebViewBuilder} object with a custom implementation of the {@link * WebViewFactory} object. * - * @param context an Activity Context to access application assets. This value - * cannot be null. - * @param usesHybridComposition if {@code false} a {@link InputAwareWebView} instance is returned. - * @param containerView must be supplied when the {@code useHybridComposition} parameter - * is set to {@code false}. Used to create an InputConnection on the - * WebView's dedicated input, or IME, thread (see also {@link - * InputAwareWebView}) - * @param webViewFactory custom implementation of the {@link WebViewFactory} object. + * @param context an Activity Context to access application assets. This value cannot be null. + * @param containerView must be supplied when the {@code useHybridComposition} parameter is set to + * {@code false}. Used to create an InputConnection on the WebView's dedicated input, or IME, + * thread (see also {@link InputAwareWebView}) */ - WebViewBuilder( - @NonNull final Context context, - boolean usesHybridComposition, - View containerView, - WebViewFactory webViewFactory - ) { + WebViewBuilder(@NonNull final Context context, View containerView) { this.context = context; - this.usesHybridComposition = usesHybridComposition; this.containerView = containerView; - this.webViewFactory = webViewFactory; } /** @@ -118,7 +82,7 @@ public WebViewBuilder setJavaScriptCanOpenWindowsAutomatically(boolean flag) { } /** - * Set whether the WebView supports multiple windows. If set to {@code true}, {@link + * Sets whether the {@link WebView} supports multiple windows. If set to {@code true}, {@link * WebChromeClient#onCreateWindow} must be implemented by the host application. The default is * {@code false}. * @@ -130,6 +94,21 @@ public WebViewBuilder setSupportMultipleWindows(boolean flag) { return this; } + /** + * Sets whether the hybrid composition should be used. + * + *

If set to {@code true} a standard {@link WebView} is created. If set to {@code false} the + * {@link WebViewBuilder} will create a {@link InputAwareWebView} to workaround issues using the + * {@link WebView} on Android versions below N. + * + * @param flag {@code true} if uses hybrid composition. The default is {@code false}. + * @return This builder. This value cannot be {@code null} + */ + public WebViewBuilder setUsesHybridComposition(boolean flag) { + this.usesHybridComposition = flag; + return this; + } + /** * Sets the chrome handler. This is an implementation of WebChromeClient for use in handling * JavaScript dialogs, favicons, titles, and the progress. This will replace the current handler. @@ -148,7 +127,7 @@ public WebViewBuilder setWebChromeClient(WebChromeClient webChromeClient) { * @return The {@link android.webkit.WebView} using the current settings. */ public WebView build() { - WebView webView = webViewFactory.create(context, usesHybridComposition, containerView); + WebView webView = WebViewFactory.create(context, usesHybridComposition, containerView); WebSettings webSettings = webView.getSettings(); webSettings.setDomStorageEnabled(enableDomStorage); diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java new file mode 100644 index 000000000000..b2aa61c9379f --- /dev/null +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java @@ -0,0 +1,55 @@ +package io.flutter.plugins.webviewflutter; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; + +public class FlutterWebViewTest { + private WebChromeClient mockWebChromeClient; + private WebViewBuilder mockWebViewBuilder; + private WebView mockWebView; + + @Before + public void before() { + mockWebChromeClient = mock(WebChromeClient.class); + mockWebViewBuilder = mock(WebViewBuilder.class); + mockWebView = mock(WebView.class); + + when(mockWebViewBuilder.setDomStorageEnabled(anyBoolean())).thenReturn(mockWebViewBuilder); + when(mockWebViewBuilder.setJavaScriptCanOpenWindowsAutomatically(anyBoolean())).thenReturn(mockWebViewBuilder); + when(mockWebViewBuilder.setSupportMultipleWindows(anyBoolean())).thenReturn(mockWebViewBuilder); + when(mockWebViewBuilder.setUsesHybridComposition(anyBoolean())).thenReturn(mockWebViewBuilder); + when(mockWebViewBuilder.setWebChromeClient(any(WebChromeClient.class))).thenReturn(mockWebViewBuilder); + + when(mockWebViewBuilder.build()).thenReturn(mockWebView); + } + + @Test + public void createWebView_should_create_webview_with_default_configuration() { + FlutterWebView.createWebView( + mockWebViewBuilder, createParameterMap(false), mockWebChromeClient); + + verify(mockWebViewBuilder, times(1)).setDomStorageEnabled(true); + verify(mockWebViewBuilder, times(1)).setJavaScriptCanOpenWindowsAutomatically(true); + verify(mockWebViewBuilder, times(1)).setSupportMultipleWindows(true); + verify(mockWebViewBuilder, times(1)).setUsesHybridComposition(false); + verify(mockWebViewBuilder, times(1)).setWebChromeClient(mockWebChromeClient); + } + + private Map createParameterMap(boolean usesHybridComposition) { + Map params = new HashMap<>(); + params.put("usesHybridComposition", usesHybridComposition); + + return params; + } +} diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java index 2f10eb73734f..a3c60ac55c9b 100644 --- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java @@ -1,6 +1,5 @@ package io.flutter.plugins.webviewflutter; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.*; @@ -9,47 +8,61 @@ import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; +import io.flutter.plugins.webviewflutter.WebViewBuilder.WebViewFactory; import java.io.IOException; +import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.MockedStatic.Verification; public class WebViewBuilderTest { private Context mockContext; private View mockContainerView; + private WebView mockWebView; + private MockedStatic mockedStaticWebViewFactory; @Before public void before() { mockContext = mock(Context.class); mockContainerView = mock(View.class); + mockWebView = mock(WebView.class); + mockedStaticWebViewFactory = mockStatic(WebViewFactory.class); + + mockedStaticWebViewFactory.when(new Verification() { + @Override + public void apply() { + WebViewFactory.create(mockContext, false, mockContainerView); + } + }).thenReturn(mockWebView); + } + + @After + public void after() { + mockedStaticWebViewFactory.close(); } @Test public void ctor_test() { - WebViewBuilder builder = - new WebViewBuilder(mockContext, false, mockContainerView); + WebViewBuilder builder = new WebViewBuilder(mockContext, mockContainerView); assertNotNull(builder); } @Test - public void build_Should_set_values() throws IOException { - WebViewBuilder.WebViewFactory mockFactory = - mock(WebViewBuilder.WebViewFactory.class); - WebView mockWebView = mock(WebView.class); + public void build_should_set_values() throws IOException { WebSettings mockWebSettings = mock(WebSettings.class); WebChromeClient mockWebChromeClient = mock(WebChromeClient.class); when(mockWebView.getSettings()).thenReturn(mockWebSettings); WebViewBuilder builder = - new WebViewBuilder(mockContext, false, mockContainerView, mockFactory) + new WebViewBuilder(mockContext, mockContainerView) .setDomStorageEnabled(true) .setJavaScriptCanOpenWindowsAutomatically(true) .setSupportMultipleWindows(true) .setWebChromeClient(mockWebChromeClient); - when(mockFactory.create(mockContext, false, mockContainerView)).thenReturn(mockWebView); - WebView webView = builder.build(); assertNotNull(webView); From 9bce993f6dc1d795e2cf529f843208f55d2b69d6 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 22 Jul 2021 09:06:52 +0200 Subject: [PATCH 3/7] Fixed formatting --- .../webviewflutter/WebViewFlutterPlugin.java | 3 ++- .../webviewflutter/FlutterWebViewTest.java | 6 ++++-- .../webviewflutter/WebViewBuilderTest.java | 15 +++++++++------ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java index 55d700eb9994..268d35a1e04c 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterPlugin.java @@ -56,7 +56,8 @@ public void onAttachedToEngine(FlutterPluginBinding binding) { binding .getPlatformViewRegistry() .registerViewFactory( - "plugins.flutter.io/webview", new FlutterWebViewFactory(messenger, /*containerView=*/ null)); + "plugins.flutter.io/webview", + new FlutterWebViewFactory(messenger, /*containerView=*/ null)); flutterCookieManager = new FlutterCookieManager(messenger); } diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java index b2aa61c9379f..142af130b7ba 100644 --- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java @@ -26,10 +26,12 @@ public void before() { mockWebView = mock(WebView.class); when(mockWebViewBuilder.setDomStorageEnabled(anyBoolean())).thenReturn(mockWebViewBuilder); - when(mockWebViewBuilder.setJavaScriptCanOpenWindowsAutomatically(anyBoolean())).thenReturn(mockWebViewBuilder); + when(mockWebViewBuilder.setJavaScriptCanOpenWindowsAutomatically(anyBoolean())) + .thenReturn(mockWebViewBuilder); when(mockWebViewBuilder.setSupportMultipleWindows(anyBoolean())).thenReturn(mockWebViewBuilder); when(mockWebViewBuilder.setUsesHybridComposition(anyBoolean())).thenReturn(mockWebViewBuilder); - when(mockWebViewBuilder.setWebChromeClient(any(WebChromeClient.class))).thenReturn(mockWebViewBuilder); + when(mockWebViewBuilder.setWebChromeClient(any(WebChromeClient.class))) + .thenReturn(mockWebViewBuilder); when(mockWebViewBuilder.build()).thenReturn(mockWebView); } diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java index a3c60ac55c9b..659a5b530a76 100644 --- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java @@ -29,12 +29,15 @@ public void before() { mockWebView = mock(WebView.class); mockedStaticWebViewFactory = mockStatic(WebViewFactory.class); - mockedStaticWebViewFactory.when(new Verification() { - @Override - public void apply() { - WebViewFactory.create(mockContext, false, mockContainerView); - } - }).thenReturn(mockWebView); + mockedStaticWebViewFactory + .when( + new Verification() { + @Override + public void apply() { + WebViewFactory.create(mockContext, false, mockContainerView); + } + }) + .thenReturn(mockWebView); } @After From da1b1c3889aac1d8fb16a51b0551b071cab2f2a6 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 22 Jul 2021 09:10:18 +0200 Subject: [PATCH 4/7] Add missing license header --- .../io/flutter/plugins/webviewflutter/FlutterWebViewTest.java | 4 ++++ .../io/flutter/plugins/webviewflutter/WebViewBuilderTest.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java index 142af130b7ba..96cbdece387c 100644 --- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/FlutterWebViewTest.java @@ -1,3 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + package io.flutter.plugins.webviewflutter; import static org.mockito.ArgumentMatchers.any; diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java index 659a5b530a76..7a5eb47d69fe 100644 --- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java @@ -1,3 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + package io.flutter.plugins.webviewflutter; import static org.junit.Assert.assertNotNull; From 953189d4ef36206645bd29fc2e9ce30136970743 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 22 Jul 2021 12:10:17 +0200 Subject: [PATCH 5/7] Processed PR feedback --- .../webviewflutter/FlutterWebView.java | 32 +++---------------- .../webviewflutter/FlutterWebViewFactory.java | 4 ++- .../webviewflutter/WebViewBuilder.java | 3 +- .../webviewflutter/WebViewBuilderTest.java | 19 +++++++++++ 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index d6ddc84ad738..e5bab3e6ea46 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -86,8 +86,7 @@ public void onProgressChanged(WebView view, int progress) { @SuppressWarnings("unchecked") FlutterWebView( final Context context, - BinaryMessenger messenger, - int id, + MethodChannel methodChannel, Map params, View containerView) { @@ -104,7 +103,8 @@ public void onProgressChanged(WebView view, int progress) { platformThreadHandler = new Handler(context.getMainLooper()); - methodChannel = createMethodChannel(messenger, id, this); + this.methodChannel = methodChannel; + this.methodChannel.setMethodCallHandler(this); flutterWebViewClient = new FlutterWebViewClient(methodChannel); Map settings = (Map) params.get("settings"); @@ -158,7 +158,7 @@ public void onProgressChanged(WebView view, int progress) { @VisibleForTesting static WebView createWebView( WebViewBuilder webViewBuilder, Map params, WebChromeClient webChromeClient) { - Boolean usesHybridComposition = (Boolean) params.get("usesHybridComposition"); + boolean usesHybridComposition = Boolean.TRUE.equals(params.get("usesHybridComposition")); webViewBuilder .setUsesHybridComposition(usesHybridComposition) .setDomStorageEnabled(true) // Always enable DOM storage API. @@ -171,30 +171,6 @@ static WebView createWebView( return webViewBuilder.build(); } - /** - * Creates a {@link MethodChannel} used to handle communication with the Flutter application about - * the {@link FlutterWebView} instance. - * - *

Important: This method is visible for testing purposes only and should - * never be called from outside this class. - * - * @param messenger a {@link BinaryMessenger} to facilitate communication with Flutter. - * @param id an identifier used to create a unique channel name and identify communication with a - * particular {@link FlutterWebView} instance. - * @param handler a {@link MethodCallHandler} responsible for handling messages that arrive from - * the Flutter application. - * @return The {@link MethodChannel} configured using the supplied {@link BinaryMessenger} and - * {@link MethodCallHandler}. - */ - @VisibleForTesting - static MethodChannel createMethodChannel( - BinaryMessenger messenger, int id, MethodCallHandler handler) { - MethodChannel methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); - methodChannel.setMethodCallHandler(handler); - - return methodChannel; - } - @Override public View getView() { return webView; diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java index 6a1e61e2d800..8fe58104a0fb 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebViewFactory.java @@ -7,6 +7,7 @@ import android.content.Context; import android.view.View; import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.StandardMessageCodec; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; @@ -26,6 +27,7 @@ public final class FlutterWebViewFactory extends PlatformViewFactory { @Override public PlatformView create(Context context, int id, Object args) { Map params = (Map) args; - return new FlutterWebView(context, messenger, id, params, containerView); + MethodChannel methodChannel = new MethodChannel(messenger, "plugins.flutter.io/webview_" + id); + return new FlutterWebView(context, methodChannel, params, containerView); } } diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java index 40e3f003f717..6b8cc51febe8 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java @@ -10,6 +10,7 @@ import android.webkit.WebSettings; import android.webkit.WebView; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; /** Builder used to create {@link android.webkit.WebView} objects. */ public class WebViewBuilder { @@ -116,7 +117,7 @@ public WebViewBuilder setUsesHybridComposition(boolean flag) { * @param webChromeClient an implementation of WebChromeClient This value may be null. * @return This builder. This value cannot be {@code null}. */ - public WebViewBuilder setWebChromeClient(WebChromeClient webChromeClient) { + public WebViewBuilder setWebChromeClient(@Nullable WebChromeClient webChromeClient) { this.webChromeClient = webChromeClient; return this; } diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java index 7a5eb47d69fe..ea842588a427 100644 --- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java @@ -78,4 +78,23 @@ public void build_should_set_values() throws IOException { verify(mockWebSettings).setSupportMultipleWindows(true); verify(mockWebView).setWebChromeClient(mockWebChromeClient); } + + @Test + public void build_should_use_default_values() throws IOException { + WebSettings mockWebSettings = mock(WebSettings.class); + WebChromeClient mockWebChromeClient = mock(WebChromeClient.class); + + when(mockWebView.getSettings()).thenReturn(mockWebSettings); + + WebViewBuilder builder = + new WebViewBuilder(mockContext, mockContainerView); + + WebView webView = builder.build(); + + assertNotNull(webView); + verify(mockWebSettings).setDomStorageEnabled(false); + verify(mockWebSettings).setJavaScriptCanOpenWindowsAutomatically(false); + verify(mockWebSettings).setSupportMultipleWindows(false); + verify(mockWebView).setWebChromeClient(null); + } } From 2c15ee0262e558f3597b9656ef45e94a89fb0229 Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 22 Jul 2021 12:14:07 +0200 Subject: [PATCH 6/7] Fixed formatting --- .../io/flutter/plugins/webviewflutter/WebViewBuilderTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java index ea842588a427..48fbce231ed5 100644 --- a/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java +++ b/packages/webview_flutter/webview_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java @@ -86,8 +86,7 @@ public void build_should_use_default_values() throws IOException { when(mockWebView.getSettings()).thenReturn(mockWebSettings); - WebViewBuilder builder = - new WebViewBuilder(mockContext, mockContainerView); + WebViewBuilder builder = new WebViewBuilder(mockContext, mockContainerView); WebView webView = builder.build(); From b2b72a25f3b28e494de1098c5d055eb0d143e21d Mon Sep 17 00:00:00 2001 From: Maurits van Beusekom Date: Thu, 22 Jul 2021 12:18:14 +0200 Subject: [PATCH 7/7] Fixed formatting --- .../java/io/flutter/plugins/webviewflutter/FlutterWebView.java | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index e5bab3e6ea46..a3b681f27980 100644 --- a/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -18,7 +18,6 @@ import android.webkit.WebViewClient; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; -import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler;