This repository was archived by the owner on Feb 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[webview_flutter] Refactored creation of Android WebView for testability. #4178
Merged
fluttergithubbot
merged 7 commits into
flutter:master
from
Baseflow:webview/android_webview_builder
Jul 22, 2021
Merged
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
5d04311
Refactor for testability
mvanbeusekom c026f9d
Test FlutterWebView.createWebView method
mvanbeusekom 9bce993
Fixed formatting
mvanbeusekom da1b1c3
Add missing license header
mvanbeusekom 953189d
Processed PR feedback
mvanbeusekom 2c15ee0
Fixed formatting
mvanbeusekom b2b72a2
Fixed formatting
mvanbeusekom File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Refactor for testability
- Loading branch information
commit 5d0431106e0682f001dd788d306c10a6b3309eeb
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
161 changes: 161 additions & 0 deletions
161
...bview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewBuilder.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) { | ||
mvanbeusekom marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
...w_flutter/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewBuilderTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.