17
17
import android .webkit .WebView ;
18
18
import android .webkit .WebViewClient ;
19
19
import androidx .annotation .NonNull ;
20
- import io . flutter . plugin . common . BinaryMessenger ;
20
+ import androidx . annotation . VisibleForTesting ;
21
21
import io .flutter .plugin .common .MethodCall ;
22
22
import io .flutter .plugin .common .MethodChannel ;
23
23
import io .flutter .plugin .common .MethodChannel .MethodCallHandler ;
28
28
import java .util .Map ;
29
29
30
30
public class FlutterWebView implements PlatformView , MethodCallHandler {
31
+
31
32
private static final String JS_CHANNEL_NAMES_FIELD = "javascriptChannelNames" ;
32
33
private final WebView webView ;
33
34
private final MethodChannel methodChannel ;
@@ -36,6 +37,7 @@ public class FlutterWebView implements PlatformView, MethodCallHandler {
36
37
37
38
// Verifies that a url opened by `Window.open` has a secure url.
38
39
private class FlutterWebChromeClient extends WebChromeClient {
40
+
39
41
@ Override
40
42
public boolean onCreateWindow (
41
43
final WebView view , boolean isDialog , boolean isUserGesture , Message resultMsg ) {
@@ -83,8 +85,7 @@ public void onProgressChanged(WebView view, int progress) {
83
85
@ SuppressWarnings ("unchecked" )
84
86
FlutterWebView (
85
87
final Context context ,
86
- BinaryMessenger messenger ,
87
- int id ,
88
+ MethodChannel methodChannel ,
88
89
Map <String , Object > params ,
89
90
View containerView ) {
90
91
@@ -93,37 +94,34 @@ public void onProgressChanged(WebView view, int progress) {
93
94
(DisplayManager ) context .getSystemService (Context .DISPLAY_SERVICE );
94
95
displayListenerProxy .onPreWebViewInitialization (displayManager );
95
96
96
- Boolean usesHybridComposition = (Boolean ) params .get ("usesHybridComposition" );
97
97
webView =
98
- (usesHybridComposition )
99
- ? new WebView (context )
100
- : new InputAwareWebView (context , containerView );
98
+ createWebView (
99
+ new WebViewBuilder (context , containerView ), params , new FlutterWebChromeClient ());
101
100
102
101
displayListenerProxy .onPostWebViewInitialization (displayManager );
103
102
104
103
platformThreadHandler = new Handler (context .getMainLooper ());
105
- // Allow local storage.
106
- webView .getSettings ().setDomStorageEnabled (true );
107
- webView .getSettings ().setJavaScriptCanOpenWindowsAutomatically (true );
108
-
109
- // Multi windows is set with FlutterWebChromeClient by default to handle internal bug: b/159892679.
110
- webView .getSettings ().setSupportMultipleWindows (true );
111
- webView .setWebChromeClient (new FlutterWebChromeClient ());
112
104
113
- methodChannel = new MethodChannel ( messenger , "plugins.flutter.io/webview_" + id ) ;
114
- methodChannel .setMethodCallHandler (this );
105
+ this . methodChannel = methodChannel ;
106
+ this . methodChannel .setMethodCallHandler (this );
115
107
116
108
flutterWebViewClient = new FlutterWebViewClient (methodChannel );
117
109
Map <String , Object > settings = (Map <String , Object >) params .get ("settings" );
118
- if (settings != null ) applySettings (settings );
110
+ if (settings != null ) {
111
+ applySettings (settings );
112
+ }
119
113
120
114
if (params .containsKey (JS_CHANNEL_NAMES_FIELD )) {
121
115
List <String > names = (List <String >) params .get (JS_CHANNEL_NAMES_FIELD );
122
- if (names != null ) registerJavaScriptChannelNames (names );
116
+ if (names != null ) {
117
+ registerJavaScriptChannelNames (names );
118
+ }
123
119
}
124
120
125
121
Integer autoMediaPlaybackPolicy = (Integer ) params .get ("autoMediaPlaybackPolicy" );
126
- if (autoMediaPlaybackPolicy != null ) updateAutoMediaPlaybackPolicy (autoMediaPlaybackPolicy );
122
+ if (autoMediaPlaybackPolicy != null ) {
123
+ updateAutoMediaPlaybackPolicy (autoMediaPlaybackPolicy );
124
+ }
127
125
if (params .containsKey ("userAgent" )) {
128
126
String userAgent = (String ) params .get ("userAgent" );
129
127
updateUserAgent (userAgent );
@@ -134,6 +132,44 @@ public void onProgressChanged(WebView view, int progress) {
134
132
}
135
133
}
136
134
135
+ /**
136
+ * Creates a {@link android.webkit.WebView} and configures it according to the supplied
137
+ * parameters.
138
+ *
139
+ * <p>The {@link WebView} is configured with the following predefined settings:
140
+ *
141
+ * <ul>
142
+ * <li>always enable the DOM storage API;
143
+ * <li>always allow JavaScript to automatically open windows;
144
+ * <li>always allow support for multiple windows;
145
+ * <li>always use the {@link FlutterWebChromeClient} as web Chrome client.
146
+ * </ul>
147
+ *
148
+ * <p><strong>Important:</strong> This method is visible for testing purposes only and should
149
+ * never be called from outside this class.
150
+ *
151
+ * @param webViewBuilder a {@link WebViewBuilder} which is responsible for building the {@link
152
+ * WebView}.
153
+ * @param params creation parameters received over the method channel.
154
+ * @param webChromeClient an implementation of WebChromeClient This value may be null.
155
+ * @return The new {@link android.webkit.WebView} object.
156
+ */
157
+ @ VisibleForTesting
158
+ static WebView createWebView (
159
+ WebViewBuilder webViewBuilder , Map <String , Object > params , WebChromeClient webChromeClient ) {
160
+ boolean usesHybridComposition = Boolean .TRUE .equals (params .get ("usesHybridComposition" ));
161
+ webViewBuilder
162
+ .setUsesHybridComposition (usesHybridComposition )
163
+ .setDomStorageEnabled (true ) // Always enable DOM storage API.
164
+ .setJavaScriptCanOpenWindowsAutomatically (
165
+ true ) // Always allow automatically opening of windows.
166
+ .setSupportMultipleWindows (true ) // Always support multiple windows.
167
+ .setWebChromeClient (
168
+ webChromeClient ); // Always use {@link FlutterWebChromeClient} as web Chrome client.
169
+
170
+ return webViewBuilder .build ();
171
+ }
172
+
137
173
@ Override
138
174
public View getView () {
139
175
return webView ;
@@ -369,7 +405,9 @@ private void applySettings(Map<String, Object> settings) {
369
405
switch (key ) {
370
406
case "jsMode" :
371
407
Integer mode = (Integer ) settings .get (key );
372
- if (mode != null ) updateJsMode (mode );
408
+ if (mode != null ) {
409
+ updateJsMode (mode );
410
+ }
373
411
break ;
374
412
case "hasNavigationDelegate" :
375
413
final boolean hasNavigationDelegate = (boolean ) settings .get (key );
0 commit comments