From 953e220652bd78c123cc179806b81cddb1d67ead Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 26 Jul 2019 13:09:54 +0200 Subject: [PATCH 01/20] Flutter implementation - Added userAgent field to WebView - Added userAgent getter to WebViewController - Updated CreationParams and WebViewSettings - Added MethodChannel for 'getUserAgent' --- .../lib/platform_interface.dart | 25 +++++++++++++++-- .../lib/src/webview_method_channel.dart | 7 +++++ .../webview_flutter/lib/webview_flutter.dart | 28 ++++++++++++++++++- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index bfb5b6255421..b708c3fba5b6 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -152,6 +152,11 @@ abstract class WebViewPlatformController { throw UnimplementedError( "WebView removeJavascriptChannels is not implemented on the current platform"); } + + Future getUserAgent() { + throw UnimplementedError( + "WebView getUserAgent is not implemented on the current platform"); + } } /// Settings for configuring a WebViewPlatform. @@ -163,6 +168,7 @@ class WebSettings { this.javascriptMode, this.hasNavigationDelegate, this.debuggingEnabled, + this.userAgent, }); /// The JavaScript execution mode to be used by the webview. @@ -176,16 +182,24 @@ class WebSettings { /// See also: [WebView.debuggingEnabled]. final bool debuggingEnabled; + /// The User Agent used for all following requests + /// + /// See also [WebView.userAgent] + final String userAgent; + @override String toString() { - return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled)'; + return 'WebSettings(javascriptMode: $javascriptMode, hasNavigationDelegate: $hasNavigationDelegate, debuggingEnabled: $debuggingEnabled, userAgent: $userAgent,)'; } } /// Configuration to use when creating a new [WebViewPlatformController]. class CreationParams { CreationParams( - {this.initialUrl, this.webSettings, this.javascriptChannelNames}); + {this.initialUrl, + this.webSettings, + this.javascriptChannelNames, + this.userAgent}); /// The initialUrl to load in the webview. /// @@ -210,9 +224,14 @@ class CreationParams { // to PlatformWebView. final Set javascriptChannelNames; + /// The User Agent used for all following requests + /// + /// When null, the default User Agent of the Android/iOS WebView is used + final String userAgent; + @override String toString() { - return '$runtimeType(initialUrl: $initialUrl, settings: $webSettings, javascriptChannelNames: $javascriptChannelNames)'; + return '$runtimeType(initialUrl: $initialUrl, settings: $webSettings, javascriptChannelNames: $javascriptChannelNames, UserAgent: $userAgent)'; } } diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index ce9988743853..c5bdd1827236 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -103,6 +103,11 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { 'removeJavascriptChannels', javascriptChannelNames.toList()); } + @override + Future getUserAgent() { + return _channel.invokeMethod('getUserAgent'); + } + /// Method channel mplementation for [WebViewPlatform.clearCookies]. static Future clearCookies() { return _cookieManagerChannel @@ -122,6 +127,7 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); + _addIfNonNull('userAgent', settings.userAgent); return map; } @@ -135,6 +141,7 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { 'initialUrl': creationParams.initialUrl, 'settings': _webSettingsToMap(creationParams.webSettings), 'javascriptChannelNames': creationParams.javascriptChannelNames.toList(), + 'userAgent': creationParams.userAgent, }; } } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 3c0175e2f22b..47accb803ce5 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -121,6 +121,7 @@ class WebView extends StatefulWidget { this.gestureRecognizers, this.onPageFinished, this.debuggingEnabled = false, + this.userAgent, }) : assert(javascriptMode != null), super(key: key); @@ -255,6 +256,18 @@ class WebView extends StatefulWidget { /// By default `debuggingEnabled` is false. final bool debuggingEnabled; + /// The User_Agent used for WebView requests. + /// + /// By default `userAgent` is null. + /// If the `userAgent` is null, the default User Agent from the Android / iOS WebView is used. + /// WebView User Agent for Android (https://developer.chrome.com/multidevice/user-agent) + /// + /// When the WebView is rebuild with a new User Agent, the page reloads and the request uses the new User Agent. + /// + /// When [WebViewController.goBack] is called after changing the User Agent, the old User Agent is used. + /// Only after reloading the Page you went back to,the request uses the new User Agent. + final String userAgent; + @override State createState() => _WebViewState(); } @@ -317,6 +330,7 @@ CreationParams _creationParamsfromWidget(WebView widget) { initialUrl: widget.initialUrl, webSettings: _webSettingsFromWidget(widget), javascriptChannelNames: _extractChannelNames(widget.javascriptChannels), + userAgent: widget.userAgent, ); } @@ -325,6 +339,7 @@ WebSettings _webSettingsFromWidget(WebView widget) { javascriptMode: widget.javascriptMode, hasNavigationDelegate: widget.navigationDelegate != null, debuggingEnabled: widget.debuggingEnabled, + userAgent: widget.userAgent, ); } @@ -337,9 +352,11 @@ WebSettings _clearUnchangedWebSettings( assert(newValue.javascriptMode != null); assert(newValue.hasNavigationDelegate != null); assert(newValue.debuggingEnabled != null); + assert(newValue.userAgent != null); JavascriptMode javascriptMode; bool hasNavigationDelegate; bool debuggingEnabled; + String userAgent; if (currentValue.javascriptMode != newValue.javascriptMode) { javascriptMode = newValue.javascriptMode; } @@ -349,11 +366,15 @@ WebSettings _clearUnchangedWebSettings( if (currentValue.debuggingEnabled != newValue.debuggingEnabled) { debuggingEnabled = newValue.debuggingEnabled; } + if (currentValue.userAgent != newValue.userAgent) { + userAgent = newValue.userAgent; + } return WebSettings( javascriptMode: javascriptMode, hasNavigationDelegate: hasNavigationDelegate, - debuggingEnabled: debuggingEnabled); + debuggingEnabled: debuggingEnabled, + userAgent: userAgent); } Set _extractChannelNames(Set channels) { @@ -568,6 +589,11 @@ class WebViewController { // ignore: strong_mode_implicit_dynamic_method return _webViewPlatformController.evaluateJavascript(javascriptString); } + + /// Returns the User Agent value that will be used for subsequent HTTP requests. + Future getUserAgent() async { + return _webViewPlatformController.getUserAgent(); + } } /// Manages cookies pertaining to all [WebView]s. From 9478588f3fccda1f9eb0d7230b26e4854b8f115e Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 26 Jul 2019 13:19:01 +0200 Subject: [PATCH 02/20] Added Android implementation + updated example - added updateUserAgent Method - added getUserAgent Method - userAgent gets set in flutter example --- .../webviewflutter/FlutterWebView.java | 20 +++++++++++++++++++ .../webview_flutter/example/lib/main.dart | 1 + 2 files changed, 21 insertions(+) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 838987714d31..41bf9cf1affb 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -55,6 +55,11 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { String url = (String) params.get("initialUrl"); webView.loadUrl(url); } + + if (params.containsKey("userAgent")) { + String userAgent = (String) params.get("userAgent"); + updateUserAgent(userAgent); + } } @Override @@ -121,6 +126,9 @@ public void onMethodCall(MethodCall methodCall, Result result) { case "clearCache": clearCache(result); break; + case "getUserAgent": + getUserAgent(methodCall, result); + break; default: result.notImplemented(); } @@ -232,6 +240,9 @@ private void applySettings(Map settings) { webView.setWebContentsDebuggingEnabled(debuggingEnabled); break; + case "userAgent": + updateUserAgent((String) settings.get(key)); + break; default: throw new IllegalArgumentException("Unknown WebView setting: " + key); } @@ -258,6 +269,15 @@ private void registerJavaScriptChannelNames(List channelNames) { } } + private void getUserAgent(MethodCall methodCall, Result result) { + String userAgent = webView.getSettings().getUserAgentString(); + result.success(userAgent); + } + + private void updateUserAgent(String userAgent) { + webView.getSettings().setUserAgentString(userAgent); + } + @Override public void dispose() { methodChannel.setMethodCallHandler(null); diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 5f3e0f8ff4fa..17ac5c8fda09 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -53,6 +53,7 @@ class _WebViewExampleState extends State { onWebViewCreated: (WebViewController webViewController) { _controller.complete(webViewController); }, + userAgent: 'Flutter_Custom_Agent', // TODO(iskakaushik): Remove this when collection literals makes it to stable. // ignore: prefer_collection_literals javascriptChannels: [ From 45e915dbc9af4cab11e4f470a4c3e3940b3f2fe5 Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 26 Jul 2019 13:23:05 +0200 Subject: [PATCH 03/20] iOS implementation - added onGetUserAgent Method - added updateUserAgent Method - updated applySettings Method --- .../ios/Classes/FlutterWebView.m | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index c56d5c7dbcc3..9f29215f928c 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -114,6 +114,8 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self onRemoveJavaScriptChannels:call result:result]; } else if ([[call method] isEqualToString:@"clearCache"]) { [self clearCache:result]; + } else if ([[call method] isEqualToString:@"getUserAgent"]) { + [self onGetUserAgent:call result:result]; } else { result(FlutterMethodNotImplemented); } @@ -246,6 +248,9 @@ - (NSString*)applySettings:(NSDictionary*)settings { _navigationDelegate.hasDartNavigationDelegate = [hasDartNavigationDelegate boolValue]; } else if ([key isEqualToString:@"debuggingEnabled"]) { // no-op debugging is always enabled on iOS. + } else if ([key isEqualToString:@"userAgent"]) { + NSString* userAgent = settings[key]; + [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; } else { [unknownKeys addObject:key]; } @@ -321,4 +326,28 @@ - (void)registerJavaScriptChannels:(NSSet*)channelNames } } +- (void)onGetUserAgent:(FlutterMethodCall*)call result:(FlutterResult)result { + [_webView evaluateJavaScript:@"navigator.userAgent" + completionHandler:^(NSString* userAgent, NSError* error) { + if (error) { + result([FlutterError + errorWithCode:@"userAgent_failed" + message:@"Failed to get UserAgent" + details:[NSString stringWithFormat: + @"webview_flutter: failed evaluating JavaScript: %@", + [error localizedDescription]]]); + } else { + result(userAgent); + } + }]; +} + +- (void)updateUserAgent:(NSString*)userAgent { + if (@available(iOS 9.0, *)) { + [_webView setCustomUserAgent:userAgent]; + } else { + NSLog(@"Updating UserAgent is not supported for Flutter WebViews prior to iOS 9."); + } +} + @end From ae81a986d769090849503a5c25cdc515e6dd9ac5 Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 26 Jul 2019 13:59:30 +0200 Subject: [PATCH 04/20] Added Widget Test --- .../example/test_driver/webview.dart | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/webview_flutter/example/test_driver/webview.dart b/packages/webview_flutter/example/test_driver/webview.dart index 7a290a05bd5b..8bc68121fee2 100644 --- a/packages/webview_flutter/example/test_driver/webview.dart +++ b/packages/webview_flutter/example/test_driver/webview.dart @@ -132,6 +132,49 @@ void main() { await controller.evaluateJavascript('Echo.postMessage("hello");'); expect(messagesReceived, equals(['hello'])); }); + + test('userAgent', () async { + final Completer controllerCompleter1 = + Completer(); + await pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: GlobalKey(), + initialUrl: 'https://flutter.dev/', + javascriptMode: JavascriptMode.unrestricted, + userAgent: 'Custom_User_Agent1', + onWebViewCreated: (WebViewController controller) { + controllerCompleter1.complete(controller); + }, + ), + ), + ); + final WebViewController controller1 = await controllerCompleter1.future; + final String customUserAgent1 = await controller1.getUserAgent(); + expect(customUserAgent1, 'Custom_User_Agent1'); + + // rebuilds a WebView with a different user agent. + final Completer controllerCompleter2 = + Completer(); + await pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: GlobalKey(), + initialUrl: 'https://flutter.dev/', + javascriptMode: JavascriptMode.unrestricted, + userAgent: 'Custom_User_Agent2', + onWebViewCreated: (WebViewController controller) { + controllerCompleter2.complete(controller); + }, + ), + ), + ); + final WebViewController controller2 = await controllerCompleter2.future; + final String customUserAgent2 = await controller2.getUserAgent(); + expect(customUserAgent2, 'Custom_User_Agent2'); + }); } Future pumpWidget(Widget widget) { From de27c9035408992e9454c3689f3b2468a63a8d0f Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 26 Jul 2019 15:48:40 +0200 Subject: [PATCH 05/20] Added unit tests for User Agent - added tests for get/set User Agent - allow currentValue.userAgent/newValue.userAgent to be null in _clearUnchangedWebSettings --- .../webview_flutter/lib/webview_flutter.dart | 3 +- .../test/webview_flutter_test.dart | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 47accb803ce5..42cc15d0eea1 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -343,7 +343,7 @@ WebSettings _webSettingsFromWidget(WebView widget) { ); } -// This method assumes that no fields in `currentValue` are null. +// This method assumes that no fields, except userAgent (see WebView.userAgent), in `currentValue` are null. WebSettings _clearUnchangedWebSettings( WebSettings currentValue, WebSettings newValue) { assert(currentValue.javascriptMode != null); @@ -352,7 +352,6 @@ WebSettings _clearUnchangedWebSettings( assert(newValue.javascriptMode != null); assert(newValue.hasNavigationDelegate != null); assert(newValue.debuggingEnabled != null); - assert(newValue.userAgent != null); JavascriptMode javascriptMode; bool hasNavigationDelegate; bool debuggingEnabled; diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index d451a86b19c8..a6d96a19202a 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -807,6 +807,41 @@ void main() { expect(platform.lastRequestHeaders, headers); }); }); + testWidgets('Set UserAgent', (WidgetTester tester) async { + await tester.pumpWidget(const WebView( + initialUrl: 'https://youtube.com', + javascriptMode: JavascriptMode.unrestricted, + )); + + final FakePlatformWebView platformWebView = + fakePlatformViewsController.lastCreatedView; + + expect(platformWebView.userAgent, isNull); + + await tester.pumpWidget(const WebView( + initialUrl: 'https://youtube.com', + javascriptMode: JavascriptMode.unrestricted, + userAgent: 'UA', + )); + + expect(platformWebView.userAgent, 'UA'); + }); + + testWidgets('Get UserAgent', (WidgetTester tester) async { + WebViewController controller; + await tester.pumpWidget( + WebView( + initialUrl: 'https://youtube.com', + javascriptMode: JavascriptMode.unrestricted, + userAgent: 'UA', + onWebViewCreated: (WebViewController webViewController) { + controller = webViewController; + }, + ), + ); + expect(controller, isNotNull); + expect(await controller.getUserAgent(), 'UA'); + }); } class FakePlatformWebView { @@ -826,7 +861,7 @@ class FakePlatformWebView { hasNavigationDelegate = params['settings']['hasNavigationDelegate'] ?? false; debuggingEnabled = params['settings']['debuggingEnabled']; - + userAgent = params['settings']['userAgent']; channel = MethodChannel( 'plugins.flutter.io/webview_$id', const StandardMethodCodec()); channel.setMockMethodCallHandler(onMethodCall); @@ -845,6 +880,7 @@ class FakePlatformWebView { bool hasNavigationDelegate; bool debuggingEnabled; + String userAgent; Future onMethodCall(MethodCall call) { switch (call.method) { @@ -862,6 +898,9 @@ class FakePlatformWebView { if (call.arguments['debuggingEnabled'] != null) { debuggingEnabled = call.arguments['debuggingEnabled']; } + if (call.arguments['userAgent'] != null) { + userAgent = call.arguments['userAgent']; + } break; case 'canGoBack': return Future.sync(() => currentPosition > 0); @@ -898,6 +937,8 @@ class FakePlatformWebView { case 'clearCache': hasCache = false; return Future.sync(() {}); + case 'getUserAgent': + return Future.value(userAgent); } return Future.sync(() {}); } @@ -1092,7 +1133,8 @@ class MatchesWebSettings extends Matcher { return _webSettings.javascriptMode == webSettings.javascriptMode && _webSettings.hasNavigationDelegate == webSettings.hasNavigationDelegate && - _webSettings.debuggingEnabled == webSettings.debuggingEnabled; + _webSettings.debuggingEnabled == webSettings.debuggingEnabled && + _webSettings.userAgent == webSettings.userAgent; } } From cbcc808e42c6855a9c35020835bd61bbec4e74b5 Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Sat, 27 Jul 2019 14:19:46 +0200 Subject: [PATCH 06/20] Updated CHANGELOG.md --- packages/webview_flutter/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 7904efa1998a..816ac119cfd4 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.11 + +* Add an optional `userAgent` property to set a custom User Agent. + Add `getUserAgent` to WebViewController. + ## 0.3.10+3 * Don't log an unknown setting key error for 'debuggingEnabled' on iOS. From d54e0bcc8d556d07399aa023770c61c201fadc51 Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Sat, 27 Jul 2019 15:47:51 +0200 Subject: [PATCH 07/20] Fixed format error in FlutterwebView.m --- .../ios/Classes/FlutterWebView.m | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 9f29215f928c..a0ae992b3941 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -327,19 +327,20 @@ - (void)registerJavaScriptChannels:(NSSet*)channelNames } - (void)onGetUserAgent:(FlutterMethodCall*)call result:(FlutterResult)result { - [_webView evaluateJavaScript:@"navigator.userAgent" - completionHandler:^(NSString* userAgent, NSError* error) { - if (error) { - result([FlutterError - errorWithCode:@"userAgent_failed" - message:@"Failed to get UserAgent" - details:[NSString stringWithFormat: - @"webview_flutter: failed evaluating JavaScript: %@", - [error localizedDescription]]]); - } else { - result(userAgent); - } - }]; + [_webView + evaluateJavaScript:@"navigator.userAgent" + completionHandler:^(NSString* userAgent, NSError* error) { + if (error) { + result([FlutterError + errorWithCode:@"userAgent_failed" + message:@"Failed to get UserAgent" + details:[NSString stringWithFormat: + @"webview_flutter: failed evaluating JavaScript: %@", + [error localizedDescription]]]); + } else { + result(userAgent); + } + }]; } - (void)updateUserAgent:(NSString*)userAgent { From 86d44caef2db5e6b3b9fb29a0c375d43ba6b669e Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Sat, 27 Jul 2019 18:49:00 +0200 Subject: [PATCH 08/20] Fixed another format error --- .../webview_flutter/ios/Classes/FlutterWebView.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index a0ae992b3941..9b9b6edf1310 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -249,8 +249,8 @@ - (NSString*)applySettings:(NSDictionary*)settings { } else if ([key isEqualToString:@"debuggingEnabled"]) { // no-op debugging is always enabled on iOS. } else if ([key isEqualToString:@"userAgent"]) { - NSString* userAgent = settings[key]; - [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; + NSString* userAgent = settings[key]; + [self updateUserAgent:[userAgent isEqual:[NSNull null]] ? nil : userAgent]; } else { [unknownKeys addObject:key]; } @@ -344,11 +344,11 @@ - (void)onGetUserAgent:(FlutterMethodCall*)call result:(FlutterResult)result { } - (void)updateUserAgent:(NSString*)userAgent { - if (@available(iOS 9.0, *)) { - [_webView setCustomUserAgent:userAgent]; - } else { - NSLog(@"Updating UserAgent is not supported for Flutter WebViews prior to iOS 9."); - } + if (@available(iOS 9.0, *)) { + [_webView setCustomUserAgent:userAgent]; + } else { + NSLog(@"Updating UserAgent is not supported for Flutter WebViews prior to iOS 9."); + } } @end From 7b26a413c58b18323cebf6cee4538ae338e0e170 Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Mon, 5 Aug 2019 10:35:16 +0200 Subject: [PATCH 09/20] Changed files according to pull request review - Updated Dartdoc comments - Changed tests to reuse one globalkey - Added test for rebuilding the webView with no user agent after setting the user agent --- .../example/test_driver/webview.dart | 65 ++++++++++++++++--- .../lib/platform_interface.dart | 7 +- .../lib/src/webview_method_channel.dart | 2 +- .../webview_flutter/lib/webview_flutter.dart | 16 +++-- 4 files changed, 69 insertions(+), 21 deletions(-) diff --git a/packages/webview_flutter/example/test_driver/webview.dart b/packages/webview_flutter/example/test_driver/webview.dart index 8bc68121fee2..679efe659925 100644 --- a/packages/webview_flutter/example/test_driver/webview.dart +++ b/packages/webview_flutter/example/test_driver/webview.dart @@ -133,14 +133,15 @@ void main() { expect(messagesReceived, equals(['hello'])); }); - test('userAgent', () async { + test('set custom userAgent', () async { final Completer controllerCompleter1 = Completer(); + final GlobalKey _globalKey = GlobalKey(); await pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( - key: GlobalKey(), + key: _globalKey, initialUrl: 'https://flutter.dev/', javascriptMode: JavascriptMode.unrestricted, userAgent: 'Custom_User_Agent1', @@ -153,27 +154,71 @@ void main() { final WebViewController controller1 = await controllerCompleter1.future; final String customUserAgent1 = await controller1.getUserAgent(); expect(customUserAgent1, 'Custom_User_Agent1'); + // rebuild the WebView with a different user agent. + await pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: _globalKey, + initialUrl: 'https://flutter.dev/', + javascriptMode: JavascriptMode.unrestricted, + userAgent: 'Custom_User_Agent2', + ), + ), + ); - // rebuilds a WebView with a different user agent. - final Completer controllerCompleter2 = + final String customUserAgent2 = await controller1.getUserAgent(); + expect(customUserAgent2, 'Custom_User_Agent2'); + }); + + test('use default platform userAgent after webView is rebuilt', () async { + final Completer controllerCompleter = Completer(); + final GlobalKey _globalKey = GlobalKey(); + // Build the webView with no user agent to get the default platform user agent. await pumpWidget( Directionality( textDirection: TextDirection.ltr, child: WebView( - key: GlobalKey(), + key: _globalKey, initialUrl: 'https://flutter.dev/', javascriptMode: JavascriptMode.unrestricted, - userAgent: 'Custom_User_Agent2', onWebViewCreated: (WebViewController controller) { - controllerCompleter2.complete(controller); + controllerCompleter.complete(controller); }, ), ), ); - final WebViewController controller2 = await controllerCompleter2.future; - final String customUserAgent2 = await controller2.getUserAgent(); - expect(customUserAgent2, 'Custom_User_Agent2'); + final WebViewController controller = await controllerCompleter.future; + final String defaultPlatformUserAgent = await controller.getUserAgent(); + // rebuild the WebView with a custom user agent. + await pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: _globalKey, + initialUrl: 'https://flutter.dev/', + javascriptMode: JavascriptMode.unrestricted, + userAgent: 'Custom_User_Agent', + ), + ), + ); + final String customUserAgent = await controller.getUserAgent(); + expect(customUserAgent, 'Custom_User_Agent'); + // rebuilds the WebView with no user agent. + await pumpWidget( + Directionality( + textDirection: TextDirection.ltr, + child: WebView( + key: _globalKey, + initialUrl: 'https://flutter.dev/', + javascriptMode: JavascriptMode.unrestricted, + ), + ), + ); + + final String customUserAgent2 = await controller.getUserAgent(); + expect(customUserAgent2, defaultPlatformUserAgent); }); } diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index b708c3fba5b6..2f8fb62ad930 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -153,6 +153,7 @@ abstract class WebViewPlatformController { "WebView removeJavascriptChannels is not implemented on the current platform"); } + /// Returns the current user agent used for the HTTP User-Agent: request header. Future getUserAgent() { throw UnimplementedError( "WebView getUserAgent is not implemented on the current platform"); @@ -182,7 +183,7 @@ class WebSettings { /// See also: [WebView.debuggingEnabled]. final bool debuggingEnabled; - /// The User Agent used for all following requests + /// The value used for the HTTP User-Agent: request header. /// /// See also [WebView.userAgent] final String userAgent; @@ -224,9 +225,9 @@ class CreationParams { // to PlatformWebView. final Set javascriptChannelNames; - /// The User Agent used for all following requests + /// The value used for the HTTP User-Agent: request header. /// - /// When null, the default User Agent of the Android/iOS WebView is used + /// When null the platform's webview default is used for the User-Agent header. final String userAgent; @override diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index c5bdd1827236..56ec71994f9e 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -127,7 +127,7 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); - _addIfNonNull('userAgent', settings.userAgent); + map['userAgent'] = settings.userAgent; return map; } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 42cc15d0eea1..58132315f06e 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -256,16 +256,18 @@ class WebView extends StatefulWidget { /// By default `debuggingEnabled` is false. final bool debuggingEnabled; - /// The User_Agent used for WebView requests. + /// The value used for the HTTP User-Agent: request header. /// - /// By default `userAgent` is null. - /// If the `userAgent` is null, the default User Agent from the Android / iOS WebView is used. - /// WebView User Agent for Android (https://developer.chrome.com/multidevice/user-agent) + /// Updating UserAgent is not supported for Flutter WebViews prior to iOS 9. + /// + /// When null the platform's webview default is used for the User-Agent header. + /// Webview user agent for Android (https://developer.chrome.com/multidevice/user-agent) /// - /// When the WebView is rebuild with a new User Agent, the page reloads and the request uses the new User Agent. + /// When the [WebView] is rebuilt with a new user agent, the page reloads and the request uses the new User Agent. /// - /// When [WebViewController.goBack] is called after changing the User Agent, the old User Agent is used. - /// Only after reloading the Page you went back to,the request uses the new User Agent. + /// When [WebViewController.goBack] is called after changing userAgent the previous userAgent value is used until the page is reloaded. + /// + /// By default `userAgent` is null. final String userAgent; @override From 7fed0321b657b3ff4414002bfb2d471a12f9f62b Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Mon, 5 Aug 2019 11:04:23 +0200 Subject: [PATCH 10/20] Minor changes - Added comment to _webSettingsToMap regarding nullability of user agent - Changed handling of null user agent in FakePlatformWebView according to changes in WebviewMethodChannel --- packages/webview_flutter/lib/src/webview_method_channel.dart | 1 + packages/webview_flutter/test/webview_flutter_test.dart | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index 56ec71994f9e..33e48ae9029f 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -127,6 +127,7 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); + // always add the user agent, as null is a valid value for the user agent. See [WebView.userAgent] map['userAgent'] = settings.userAgent; return map; } diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index a6d96a19202a..e6f7b9933877 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -898,9 +898,7 @@ class FakePlatformWebView { if (call.arguments['debuggingEnabled'] != null) { debuggingEnabled = call.arguments['debuggingEnabled']; } - if (call.arguments['userAgent'] != null) { - userAgent = call.arguments['userAgent']; - } + userAgent = call.arguments['userAgent']; break; case 'canGoBack': return Future.sync(() => currentPosition > 0); From c5cc6a711a943ea149c536c8591f959e90f805cf Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Mon, 5 Aug 2019 11:15:29 +0200 Subject: [PATCH 11/20] Updated dartdoc for WebView.userAgent --- packages/webview_flutter/lib/webview_flutter.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 58132315f06e..e0a3652a90c3 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -258,8 +258,6 @@ class WebView extends StatefulWidget { /// The value used for the HTTP User-Agent: request header. /// - /// Updating UserAgent is not supported for Flutter WebViews prior to iOS 9. - /// /// When null the platform's webview default is used for the User-Agent header. /// Webview user agent for Android (https://developer.chrome.com/multidevice/user-agent) /// @@ -267,6 +265,8 @@ class WebView extends StatefulWidget { /// /// When [WebViewController.goBack] is called after changing userAgent the previous userAgent value is used until the page is reloaded. /// + /// Updating UserAgent is not supported for Flutter WebViews prior to iOS 9. + /// /// By default `userAgent` is null. final String userAgent; From 79761515b33c3e96234e7b0555651c74f971adee Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Wed, 14 Aug 2019 11:11:43 -0700 Subject: [PATCH 12/20] Use a WebSetting type to allow representing absence of a null value. --- .../lib/platform_interface.dart | 64 +++++++++++++++++-- .../lib/src/webview_method_channel.dart | 11 +++- .../webview_flutter/lib/webview_flutter.dart | 9 ++- .../test/webview_flutter_test.dart | 1 + 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index 8b9ea5ceabd8..ac1330ec524b 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -160,17 +160,66 @@ abstract class WebViewPlatformController { } } +/// A single setting for configuring a WebViewPlatform which may be absent. +class WebSetting { + /// Constructs an absent setting instance. + /// + /// The [isPresent] field for the instance will be false. + /// + /// Accessing [value] for an absent instance will throw. + WebSetting.absent() + : _value = null, + isPresent = false; + + /// Constructs a setting of the given `value`. + /// + /// The [isPresent] field for the instance will be true. + WebSetting.of(T value) + : _value = value, + isPresent = true; + + final T _value; + + /// The setting's value. + /// + /// Throws if [WebSetting.isPresent] is false. + T get value { + if (!isPresent) { + throw StateError('Cannot access a value of an absent WebSetting'); + } + assert(isPresent); + return _value; + } + + /// True when this web setting instance contains a value. + /// + /// When false the [WebSetting.value] getter throws. + final bool isPresent; + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) return false; + final WebSetting typedOther = other; + return typedOther.isPresent == isPresent && typedOther._value == _value; + } + + @override + int get hashCode => hashValues(_value, isPresent); +} + /// Settings for configuring a WebViewPlatform. /// /// Initial settings are passed as part of [CreationParams], settings updates are sent with /// [WebViewPlatform#updateSettings]. +/// +/// The `userAgent` parameter must not be null. class WebSettings { WebSettings({ this.javascriptMode, this.hasNavigationDelegate, this.debuggingEnabled, - this.userAgent, - }); + @required this.userAgent, + }) : assert(userAgent != null); /// The JavaScript execution mode to be used by the webview. final JavascriptMode javascriptMode; @@ -183,10 +232,15 @@ class WebSettings { /// See also: [WebView.debuggingEnabled]. final bool debuggingEnabled; - /// The value used for the HTTP User-Agent: request header. + /// The value used for the HTTP `User-Agent:` request header. /// - /// See also [WebView.userAgent] - final String userAgent; + /// If [userAgent.value] is null the platform's default user agent should be used. + /// + /// An absent value ([userAgent.isPresent] is false) represents no change to this setting from the + /// last time it was set. + /// + /// See also [WebView.userAgent]. + final WebSetting userAgent; @override String toString() { diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index 1b8fb5de26b4..eff948625480 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -108,7 +108,6 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { return _channel.invokeMethod('getUserAgent'); } - /// Method channel mplementation for [WebViewPlatform.clearCookies]. /// Method channel implementation for [WebViewPlatform.clearCookies]. static Future clearCookies() { return _cookieManagerChannel @@ -125,11 +124,17 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { map[key] = value; } + void _addSettingIfPresent(String key, WebSetting setting) { + if (!setting.isPresent) { + return; + } + map[key] = setting.value; + } + _addIfNonNull('jsMode', settings.javascriptMode?.index); _addIfNonNull('hasNavigationDelegate', settings.hasNavigationDelegate); _addIfNonNull('debuggingEnabled', settings.debuggingEnabled); - // always add the user agent, as null is a valid value for the user agent. See [WebView.userAgent] - map['userAgent'] = settings.userAgent; + _addSettingIfPresent('userAgent', settings.userAgent); return map; } diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index 486a9b40b9ba..b257dc9915f2 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -372,23 +372,26 @@ WebSettings _webSettingsFromWidget(WebView widget) { javascriptMode: widget.javascriptMode, hasNavigationDelegate: widget.navigationDelegate != null, debuggingEnabled: widget.debuggingEnabled, - userAgent: widget.userAgent, + userAgent: WebSetting.of(widget.userAgent), ); } -// This method assumes that no fields, except userAgent (see WebView.userAgent), in `currentValue` are null. +// This method assumes that no fields in `currentValue` are null. WebSettings _clearUnchangedWebSettings( WebSettings currentValue, WebSettings newValue) { assert(currentValue.javascriptMode != null); assert(currentValue.hasNavigationDelegate != null); assert(currentValue.debuggingEnabled != null); + assert(currentValue.userAgent.isPresent); assert(newValue.javascriptMode != null); assert(newValue.hasNavigationDelegate != null); assert(newValue.debuggingEnabled != null); + assert(newValue.userAgent.isPresent); + JavascriptMode javascriptMode; bool hasNavigationDelegate; bool debuggingEnabled; - String userAgent; + WebSetting userAgent = WebSetting.absent(); if (currentValue.javascriptMode != newValue.javascriptMode) { javascriptMode = newValue.javascriptMode; } diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index e6f7b9933877..069aede4de45 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -776,6 +776,7 @@ void main() { javascriptMode: JavascriptMode.disabled, hasNavigationDelegate: false, debuggingEnabled: false, + userAgent: WebSetting.of(null), ), // TODO(iskakaushik): Remove this when collection literals makes it to stable. // ignore: prefer_collection_literals From 4c0d2f30258d6eacc0900756209c4a3f9f38a13c Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Wed, 14 Aug 2019 12:25:06 -0700 Subject: [PATCH 13/20] review fixes --- .../flutter/plugins/webviewflutter/FlutterWebView.java | 9 ++++----- packages/webview_flutter/example/lib/main.dart | 1 - packages/webview_flutter/lib/platform_interface.dart | 2 +- packages/webview_flutter/lib/webview_flutter.dart | 8 ++++---- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 27ba2db33cce..4dfcda0f4e7b 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -60,15 +60,14 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { } updateAutoMediaPlaybackPolicy((Integer) params.get("autoMediaPlaybackPolicy")); - if (params.containsKey("initialUrl")) { - String url = (String) params.get("initialUrl"); - webView.loadUrl(url); - } - if (params.containsKey("userAgent")) { String userAgent = (String) params.get("userAgent"); updateUserAgent(userAgent); } + if (params.containsKey("initialUrl")) { + String url = (String) params.get("initialUrl"); + webView.loadUrl(url); + } } @Override diff --git a/packages/webview_flutter/example/lib/main.dart b/packages/webview_flutter/example/lib/main.dart index 17ac5c8fda09..5f3e0f8ff4fa 100644 --- a/packages/webview_flutter/example/lib/main.dart +++ b/packages/webview_flutter/example/lib/main.dart @@ -53,7 +53,6 @@ class _WebViewExampleState extends State { onWebViewCreated: (WebViewController webViewController) { _controller.complete(webViewController); }, - userAgent: 'Flutter_Custom_Agent', // TODO(iskakaushik): Remove this when collection literals makes it to stable. // ignore: prefer_collection_literals javascriptChannels: [ diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index ac1330ec524b..6b6c518a0689 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -153,7 +153,7 @@ abstract class WebViewPlatformController { "WebView removeJavascriptChannels is not implemented on the current platform"); } - /// Returns the current user agent used for the HTTP User-Agent: request header. + /// Returns the value used for the HTTP User-Agent: request header in subsequent HTTP requests. Future getUserAgent() { throw UnimplementedError( "WebView getUserAgent is not implemented on the current platform"); diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index b257dc9915f2..e0345e0c5c5a 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -281,13 +281,13 @@ class WebView extends StatefulWidget { /// The value used for the HTTP User-Agent: request header. /// /// When null the platform's webview default is used for the User-Agent header. - /// Webview user agent for Android (https://developer.chrome.com/multidevice/user-agent) /// - /// When the [WebView] is rebuilt with a new user agent, the page reloads and the request uses the new User Agent. + /// When the [WebView] is rebuilt with a different `userAgent`, the page reloads and the request uses the new User Agent. /// - /// When [WebViewController.goBack] is called after changing userAgent the previous userAgent value is used until the page is reloaded. + /// When [WebViewController.goBack] is called after changing `userAgent` the previous `userAgent` value is used until the page is reloaded. /// - /// Updating UserAgent is not supported for Flutter WebViews prior to iOS 9. + /// This field is ignored on iOS versions prior to 9 as the platform does not support a custom + /// user agent. /// /// By default `userAgent` is null. final String userAgent; From 5be86ef99d408342bf2290f46181f99116f630b3 Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Wed, 14 Aug 2019 12:27:13 -0700 Subject: [PATCH 14/20] bump version --- packages/webview_flutter/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml index d2f6aa0e81e1..6c668033548b 100644 --- a/packages/webview_flutter/pubspec.yaml +++ b/packages/webview_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: webview_flutter description: A Flutter plugin that provides a WebView widget on Android and iOS. -version: 0.3.11+3 +version: 0.3.12 author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter From bf8b74cc16ab2e50e87b2f320199553eac7263cc Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Wed, 14 Aug 2019 13:53:50 -0700 Subject: [PATCH 15/20] remove extra blank line from changelog --- packages/webview_flutter/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index e8fc547e8c82..d45e0f4e6f6f 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -35,7 +35,6 @@ * Add keyboard text to README. - ## 0.3.10+3 * Don't log an unknown setting key error for 'debuggingEnabled' on iOS. From ebe699d5e15ed47667c9c42edade0cf37f1a9d9e Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Thu, 15 Aug 2019 12:05:42 +0200 Subject: [PATCH 16/20] Removed getUserAgent - Renoved functions involved in getting the user agent - Updated tests to inject javascript to get the current user agent - updated changelog --- packages/webview_flutter/CHANGELOG.md | 1 - .../webviewflutter/FlutterWebView.java | 195 +++++++++--------- .../example/test_driver/webview.dart | 20 +- .../ios/Classes/FlutterWebView.m | 19 -- .../lib/platform_interface.dart | 6 - .../lib/src/webview_method_channel.dart | 5 - .../webview_flutter/lib/webview_flutter.dart | 5 - .../test/webview_flutter_test.dart | 18 -- 8 files changed, 107 insertions(+), 162 deletions(-) diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md index 3da7921d2609..15b4a63dd81b 100644 --- a/packages/webview_flutter/CHANGELOG.md +++ b/packages/webview_flutter/CHANGELOG.md @@ -1,7 +1,6 @@ ## 0.3.12 * Add an optional `userAgent` property to set a custom User Agent. -* Add `getUserAgent` to WebViewController. ## 0.3.11+3 diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 4dfcda0f4e7b..fb18036d2abb 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -31,16 +31,11 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @SuppressWarnings("unchecked") - FlutterWebView( - final Context context, - BinaryMessenger messenger, - int id, - Map params, + FlutterWebView(final Context context, BinaryMessenger messenger, int id, Map params, final View containerView) { DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy(); - DisplayManager displayManager = - (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); displayListenerProxy.onPreWebViewInitialization(displayManager); webView = new InputAwareWebView(context, containerView); displayListenerProxy.onPostWebViewInitialization(displayManager); @@ -76,21 +71,29 @@ public View getView() { } // @Override - // This is overriding a method that hasn't rolled into stable Flutter yet. Including the - // annotation would cause compile time failures in versions of Flutter too old to include the new - // method. However leaving it raw like this means that the method will be ignored in old versions + // This is overriding a method that hasn't rolled into stable Flutter yet. + // Including the + // annotation would cause compile time failures in versions of Flutter too old + // to include the new + // method. However leaving it raw like this means that the method will be + // ignored in old versions // of Flutter but used as an override anyway wherever it's actually defined. - // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable. + // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to + // stable. public void onInputConnectionUnlocked() { webView.unlockInputConnection(); } // @Override - // This is overriding a method that hasn't rolled into stable Flutter yet. Including the - // annotation would cause compile time failures in versions of Flutter too old to include the new - // method. However leaving it raw like this means that the method will be ignored in old versions + // This is overriding a method that hasn't rolled into stable Flutter yet. + // Including the + // annotation would cause compile time failures in versions of Flutter too old + // to include the new + // method. However leaving it raw like this means that the method will be + // ignored in old versions // of Flutter but used as an override anyway wherever it's actually defined. - // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable. + // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to + // stable. public void onInputConnectionLocked() { webView.lockInputConnection(); } @@ -98,47 +101,44 @@ public void onInputConnectionLocked() { @Override public void onMethodCall(MethodCall methodCall, Result result) { switch (methodCall.method) { - case "loadUrl": - loadUrl(methodCall, result); - break; - case "updateSettings": - updateSettings(methodCall, result); - break; - case "canGoBack": - canGoBack(result); - break; - case "canGoForward": - canGoForward(result); - break; - case "goBack": - goBack(result); - break; - case "goForward": - goForward(result); - break; - case "reload": - reload(result); - break; - case "currentUrl": - currentUrl(result); - break; - case "evaluateJavascript": - evaluateJavaScript(methodCall, result); - break; - case "addJavascriptChannels": - addJavaScriptChannels(methodCall, result); - break; - case "removeJavascriptChannels": - removeJavaScriptChannels(methodCall, result); - break; - case "clearCache": - clearCache(result); - break; - case "getUserAgent": - getUserAgent(methodCall, result); - break; - default: - result.notImplemented(); + case "loadUrl": + loadUrl(methodCall, result); + break; + case "updateSettings": + updateSettings(methodCall, result); + break; + case "canGoBack": + canGoBack(result); + break; + case "canGoForward": + canGoForward(result); + break; + case "goBack": + goBack(result); + break; + case "goForward": + goForward(result); + break; + case "reload": + reload(result); + break; + case "currentUrl": + currentUrl(result); + break; + case "evaluateJavascript": + evaluateJavaScript(methodCall, result); + break; + case "addJavascriptChannels": + addJavaScriptChannels(methodCall, result); + break; + case "removeJavascriptChannels": + removeJavaScriptChannels(methodCall, result); + break; + case "clearCache": + clearCache(result); + break; + default: + result.notImplemented(); } } @@ -197,14 +197,12 @@ private void evaluateJavaScript(MethodCall methodCall, final Result result) { if (jsString == null) { throw new UnsupportedOperationException("JavaScript string cannot be null"); } - webView.evaluateJavascript( - jsString, - new android.webkit.ValueCallback() { - @Override - public void onReceiveValue(String value) { - result.success(value); - } - }); + webView.evaluateJavascript(jsString, new android.webkit.ValueCallback() { + @Override + public void onReceiveValue(String value) { + result.success(value); + } + }); } @SuppressWarnings("unchecked") @@ -232,46 +230,46 @@ private void clearCache(Result result) { private void applySettings(Map settings) { for (String key : settings.keySet()) { switch (key) { - case "jsMode": - updateJsMode((Integer) settings.get(key)); - break; - case "hasNavigationDelegate": - final boolean hasNavigationDelegate = (boolean) settings.get(key); - - final WebViewClient webViewClient = - flutterWebViewClient.createWebViewClient(hasNavigationDelegate); - - webView.setWebViewClient(webViewClient); - break; - case "debuggingEnabled": - final boolean debuggingEnabled = (boolean) settings.get(key); - - webView.setWebContentsDebuggingEnabled(debuggingEnabled); - break; - case "userAgent": - updateUserAgent((String) settings.get(key)); - break; - default: - throw new IllegalArgumentException("Unknown WebView setting: " + key); + case "jsMode": + updateJsMode((Integer) settings.get(key)); + break; + case "hasNavigationDelegate": + final boolean hasNavigationDelegate = (boolean) settings.get(key); + + final WebViewClient webViewClient = flutterWebViewClient.createWebViewClient(hasNavigationDelegate); + + webView.setWebViewClient(webViewClient); + break; + case "debuggingEnabled": + final boolean debuggingEnabled = (boolean) settings.get(key); + + webView.setWebContentsDebuggingEnabled(debuggingEnabled); + break; + case "userAgent": + updateUserAgent((String) settings.get(key)); + break; + default: + throw new IllegalArgumentException("Unknown WebView setting: " + key); } } } private void updateJsMode(int mode) { switch (mode) { - case 0: // disabled - webView.getSettings().setJavaScriptEnabled(false); - break; - case 1: // unrestricted - webView.getSettings().setJavaScriptEnabled(true); - break; - default: - throw new IllegalArgumentException("Trying to set unknown JavaScript mode: " + mode); + case 0: // disabled + webView.getSettings().setJavaScriptEnabled(false); + break; + case 1: // unrestricted + webView.getSettings().setJavaScriptEnabled(true); + break; + default: + throw new IllegalArgumentException("Trying to set unknown JavaScript mode: " + mode); } } private void updateAutoMediaPlaybackPolicy(int mode) { - // This is the index of the AutoMediaPlaybackPolicy enum, index 1 is always_allow, for all + // This is the index of the AutoMediaPlaybackPolicy enum, index 1 is + // always_allow, for all // other values we require a user gesture. boolean requireUserGesture = mode != 1; webView.getSettings().setMediaPlaybackRequiresUserGesture(requireUserGesture); @@ -279,16 +277,11 @@ private void updateAutoMediaPlaybackPolicy(int mode) { private void registerJavaScriptChannelNames(List channelNames) { for (String channelName : channelNames) { - webView.addJavascriptInterface( - new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName); + webView.addJavascriptInterface(new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), + channelName); } } - private void getUserAgent(MethodCall methodCall, Result result) { - String userAgent = webView.getSettings().getUserAgentString(); - result.success(userAgent); - } - private void updateUserAgent(String userAgent) { webView.getSettings().setUserAgentString(userAgent); } diff --git a/packages/webview_flutter/example/test_driver/webview.dart b/packages/webview_flutter/example/test_driver/webview.dart index d347d0e8b737..e16bd1753665 100644 --- a/packages/webview_flutter/example/test_driver/webview.dart +++ b/packages/webview_flutter/example/test_driver/webview.dart @@ -241,7 +241,7 @@ void main() { ), ); final WebViewController controller1 = await controllerCompleter1.future; - final String customUserAgent1 = await controller1.getUserAgent(); + final String customUserAgent1 = await _getUserAgent(controller1); expect(customUserAgent1, 'Custom_User_Agent1'); // rebuild the WebView with a different user agent. await pumpWidget( @@ -256,7 +256,7 @@ void main() { ), ); - final String customUserAgent2 = await controller1.getUserAgent(); + final String customUserAgent2 = await _getUserAgent(controller1); expect(customUserAgent2, 'Custom_User_Agent2'); }); @@ -279,7 +279,7 @@ void main() { ), ); final WebViewController controller = await controllerCompleter.future; - final String defaultPlatformUserAgent = await controller.getUserAgent(); + final String defaultPlatformUserAgent = await _getUserAgent(controller); // rebuild the WebView with a custom user agent. await pumpWidget( Directionality( @@ -288,12 +288,12 @@ void main() { key: _globalKey, initialUrl: 'https://flutter.dev/', javascriptMode: JavascriptMode.unrestricted, - userAgent: 'Custom_User_Agent', + userAgent: 'Custom"_User_"Agent', ), ), ); - final String customUserAgent = await controller.getUserAgent(); - expect(customUserAgent, 'Custom_User_Agent'); + final String customUserAgent = await _getUserAgent(controller); + expect(customUserAgent, 'Custom"_User_"Agent'); // rebuilds the WebView with no user agent. await pumpWidget( Directionality( @@ -306,7 +306,7 @@ void main() { ), ); - final String customUserAgent2 = await controller.getUserAgent(); + final String customUserAgent2 = await _getUserAgent(controller); expect(customUserAgent2, defaultPlatformUserAgent); }); @@ -472,3 +472,9 @@ String _webviewBool(bool value) { } return value ? 'true' : 'false'; } + +/// Returns the value used for the HTTP User-Agent: request header in subsequent HTTP requests. +Future _getUserAgent(WebViewController controller) async { + return await controller.evaluateJavascript('navigator.userAgent;') + ..toString(); +} diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m index 3a9f69be548c..653355b01dfa 100644 --- a/packages/webview_flutter/ios/Classes/FlutterWebView.m +++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m @@ -118,8 +118,6 @@ - (void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { [self onRemoveJavaScriptChannels:call result:result]; } else if ([[call method] isEqualToString:@"clearCache"]) { [self clearCache:result]; - } else if ([[call method] isEqualToString:@"getUserAgent"]) { - [self onGetUserAgent:call result:result]; } else { result(FlutterMethodNotImplemented); } @@ -354,23 +352,6 @@ - (void)registerJavaScriptChannels:(NSSet*)channelNames } } -- (void)onGetUserAgent:(FlutterMethodCall*)call result:(FlutterResult)result { - [_webView - evaluateJavaScript:@"navigator.userAgent" - completionHandler:^(NSString* userAgent, NSError* error) { - if (error) { - result([FlutterError - errorWithCode:@"userAgent_failed" - message:@"Failed to get UserAgent" - details:[NSString stringWithFormat: - @"webview_flutter: failed evaluating JavaScript: %@", - [error localizedDescription]]]); - } else { - result(userAgent); - } - }]; -} - - (void)updateUserAgent:(NSString*)userAgent { if (@available(iOS 9.0, *)) { [_webView setCustomUserAgent:userAgent]; diff --git a/packages/webview_flutter/lib/platform_interface.dart b/packages/webview_flutter/lib/platform_interface.dart index 6b6c518a0689..061b3aa55e66 100644 --- a/packages/webview_flutter/lib/platform_interface.dart +++ b/packages/webview_flutter/lib/platform_interface.dart @@ -152,12 +152,6 @@ abstract class WebViewPlatformController { throw UnimplementedError( "WebView removeJavascriptChannels is not implemented on the current platform"); } - - /// Returns the value used for the HTTP User-Agent: request header in subsequent HTTP requests. - Future getUserAgent() { - throw UnimplementedError( - "WebView getUserAgent is not implemented on the current platform"); - } } /// A single setting for configuring a WebViewPlatform which may be absent. diff --git a/packages/webview_flutter/lib/src/webview_method_channel.dart b/packages/webview_flutter/lib/src/webview_method_channel.dart index eff948625480..f34000569551 100644 --- a/packages/webview_flutter/lib/src/webview_method_channel.dart +++ b/packages/webview_flutter/lib/src/webview_method_channel.dart @@ -103,11 +103,6 @@ class MethodChannelWebViewPlatform implements WebViewPlatformController { 'removeJavascriptChannels', javascriptChannelNames.toList()); } - @override - Future getUserAgent() { - return _channel.invokeMethod('getUserAgent'); - } - /// Method channel implementation for [WebViewPlatform.clearCookies]. static Future clearCookies() { return _cookieManagerChannel diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart index e0345e0c5c5a..97b7786de9a6 100644 --- a/packages/webview_flutter/lib/webview_flutter.dart +++ b/packages/webview_flutter/lib/webview_flutter.dart @@ -625,11 +625,6 @@ class WebViewController { // ignore: strong_mode_implicit_dynamic_method return _webViewPlatformController.evaluateJavascript(javascriptString); } - - /// Returns the User Agent value that will be used for subsequent HTTP requests. - Future getUserAgent() async { - return _webViewPlatformController.getUserAgent(); - } } /// Manages cookies pertaining to all [WebView]s. diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart index 069aede4de45..6907436b24a2 100644 --- a/packages/webview_flutter/test/webview_flutter_test.dart +++ b/packages/webview_flutter/test/webview_flutter_test.dart @@ -827,22 +827,6 @@ void main() { expect(platformWebView.userAgent, 'UA'); }); - - testWidgets('Get UserAgent', (WidgetTester tester) async { - WebViewController controller; - await tester.pumpWidget( - WebView( - initialUrl: 'https://youtube.com', - javascriptMode: JavascriptMode.unrestricted, - userAgent: 'UA', - onWebViewCreated: (WebViewController webViewController) { - controller = webViewController; - }, - ), - ); - expect(controller, isNotNull); - expect(await controller.getUserAgent(), 'UA'); - }); } class FakePlatformWebView { @@ -936,8 +920,6 @@ class FakePlatformWebView { case 'clearCache': hasCache = false; return Future.sync(() {}); - case 'getUserAgent': - return Future.value(userAgent); } return Future.sync(() {}); } From 641537bc5f889d44f0412844247d82f6b9b595dd Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Thu, 15 Aug 2019 12:29:39 +0200 Subject: [PATCH 17/20] Fixed formatting issue --- .../webviewflutter/FlutterWebView.java | 160 +++++++++--------- .../example/test_driver/webview.dart | 2 +- 2 files changed, 85 insertions(+), 77 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index fb18036d2abb..c18b2535e78a 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -31,11 +31,16 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @SuppressWarnings("unchecked") - FlutterWebView(final Context context, BinaryMessenger messenger, int id, Map params, + FlutterWebView( + final Context context, + BinaryMessenger messenger, + int id, + Map params, final View containerView) { DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy(); - DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + DisplayManager displayManager = + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); displayListenerProxy.onPreWebViewInitialization(displayManager); webView = new InputAwareWebView(context, containerView); displayListenerProxy.onPostWebViewInitialization(displayManager); @@ -101,44 +106,44 @@ public void onInputConnectionLocked() { @Override public void onMethodCall(MethodCall methodCall, Result result) { switch (methodCall.method) { - case "loadUrl": - loadUrl(methodCall, result); - break; - case "updateSettings": - updateSettings(methodCall, result); - break; - case "canGoBack": - canGoBack(result); - break; - case "canGoForward": - canGoForward(result); - break; - case "goBack": - goBack(result); - break; - case "goForward": - goForward(result); - break; - case "reload": - reload(result); - break; - case "currentUrl": - currentUrl(result); - break; - case "evaluateJavascript": - evaluateJavaScript(methodCall, result); - break; - case "addJavascriptChannels": - addJavaScriptChannels(methodCall, result); - break; - case "removeJavascriptChannels": - removeJavaScriptChannels(methodCall, result); - break; - case "clearCache": - clearCache(result); - break; - default: - result.notImplemented(); + case "loadUrl": + loadUrl(methodCall, result); + break; + case "updateSettings": + updateSettings(methodCall, result); + break; + case "canGoBack": + canGoBack(result); + break; + case "canGoForward": + canGoForward(result); + break; + case "goBack": + goBack(result); + break; + case "goForward": + goForward(result); + break; + case "reload": + reload(result); + break; + case "currentUrl": + currentUrl(result); + break; + case "evaluateJavascript": + evaluateJavaScript(methodCall, result); + break; + case "addJavascriptChannels": + addJavaScriptChannels(methodCall, result); + break; + case "removeJavascriptChannels": + removeJavaScriptChannels(methodCall, result); + break; + case "clearCache": + clearCache(result); + break; + default: + result.notImplemented(); } } @@ -197,12 +202,14 @@ private void evaluateJavaScript(MethodCall methodCall, final Result result) { if (jsString == null) { throw new UnsupportedOperationException("JavaScript string cannot be null"); } - webView.evaluateJavascript(jsString, new android.webkit.ValueCallback() { - @Override - public void onReceiveValue(String value) { - result.success(value); - } - }); + webView.evaluateJavascript( + jsString, + new android.webkit.ValueCallback() { + @Override + public void onReceiveValue(String value) { + result.success(value); + } + }); } @SuppressWarnings("unchecked") @@ -230,40 +237,41 @@ private void clearCache(Result result) { private void applySettings(Map settings) { for (String key : settings.keySet()) { switch (key) { - case "jsMode": - updateJsMode((Integer) settings.get(key)); - break; - case "hasNavigationDelegate": - final boolean hasNavigationDelegate = (boolean) settings.get(key); - - final WebViewClient webViewClient = flutterWebViewClient.createWebViewClient(hasNavigationDelegate); - - webView.setWebViewClient(webViewClient); - break; - case "debuggingEnabled": - final boolean debuggingEnabled = (boolean) settings.get(key); - - webView.setWebContentsDebuggingEnabled(debuggingEnabled); - break; - case "userAgent": - updateUserAgent((String) settings.get(key)); - break; - default: - throw new IllegalArgumentException("Unknown WebView setting: " + key); + case "jsMode": + updateJsMode((Integer) settings.get(key)); + break; + case "hasNavigationDelegate": + final boolean hasNavigationDelegate = (boolean) settings.get(key); + + final WebViewClient webViewClient = + flutterWebViewClient.createWebViewClient(hasNavigationDelegate); + + webView.setWebViewClient(webViewClient); + break; + case "debuggingEnabled": + final boolean debuggingEnabled = (boolean) settings.get(key); + + webView.setWebContentsDebuggingEnabled(debuggingEnabled); + break; + case "userAgent": + updateUserAgent((String) settings.get(key)); + break; + default: + throw new IllegalArgumentException("Unknown WebView setting: " + key); } } } private void updateJsMode(int mode) { switch (mode) { - case 0: // disabled - webView.getSettings().setJavaScriptEnabled(false); - break; - case 1: // unrestricted - webView.getSettings().setJavaScriptEnabled(true); - break; - default: - throw new IllegalArgumentException("Trying to set unknown JavaScript mode: " + mode); + case 0: // disabled + webView.getSettings().setJavaScriptEnabled(false); + break; + case 1: // unrestricted + webView.getSettings().setJavaScriptEnabled(true); + break; + default: + throw new IllegalArgumentException("Trying to set unknown JavaScript mode: " + mode); } } @@ -277,8 +285,8 @@ private void updateAutoMediaPlaybackPolicy(int mode) { private void registerJavaScriptChannelNames(List channelNames) { for (String channelName : channelNames) { - webView.addJavascriptInterface(new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), - channelName); + webView.addJavascriptInterface( + new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName); } } diff --git a/packages/webview_flutter/example/test_driver/webview.dart b/packages/webview_flutter/example/test_driver/webview.dart index e16bd1753665..83f28f37e180 100644 --- a/packages/webview_flutter/example/test_driver/webview.dart +++ b/packages/webview_flutter/example/test_driver/webview.dart @@ -293,7 +293,7 @@ void main() { ), ); final String customUserAgent = await _getUserAgent(controller); - expect(customUserAgent, 'Custom"_User_"Agent'); + expect(customUserAgent, 'Custom_User_Agent'); // rebuilds the WebView with no user agent. await pumpWidget( Directionality( From db3cfb966009429c34d62e0acb2abfae0a7cccaf Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Thu, 15 Aug 2019 12:56:57 +0200 Subject: [PATCH 18/20] Fixed _getUserAgent in webview.dart --- .../webview_flutter/example/test_driver/webview.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/webview_flutter/example/test_driver/webview.dart b/packages/webview_flutter/example/test_driver/webview.dart index 83f28f37e180..be7e859df27c 100644 --- a/packages/webview_flutter/example/test_driver/webview.dart +++ b/packages/webview_flutter/example/test_driver/webview.dart @@ -288,7 +288,7 @@ void main() { key: _globalKey, initialUrl: 'https://flutter.dev/', javascriptMode: JavascriptMode.unrestricted, - userAgent: 'Custom"_User_"Agent', + userAgent: 'Custom_User_Agent', ), ), ); @@ -475,6 +475,9 @@ String _webviewBool(bool value) { /// Returns the value used for the HTTP User-Agent: request header in subsequent HTTP requests. Future _getUserAgent(WebViewController controller) async { - return await controller.evaluateJavascript('navigator.userAgent;') - ..toString(); + if (defaultTargetPlatform == TargetPlatform.iOS) { + return await controller.evaluateJavascript('navigator.userAgent;'); + } + return jsonDecode( + await controller.evaluateJavascript('navigator.userAgent;')); } From 974c16e0d026e6e0b94ccce707ba2e176adbb697 Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 16 Aug 2019 18:52:56 +0200 Subject: [PATCH 19/20] Reverted unrelated reformatting --- .../webviewflutter/FlutterWebView.java | 59 ++++++++----------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index c18b2535e78a..219d54d2df10 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -32,15 +32,15 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @SuppressWarnings("unchecked") FlutterWebView( - final Context context, - BinaryMessenger messenger, - int id, - Map params, - final View containerView) { + final Context context, + BinaryMessenger messenger, + int id, + Map params, + final View containerView) { DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy(); DisplayManager displayManager = - (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); displayListenerProxy.onPreWebViewInitialization(displayManager); webView = new InputAwareWebView(context, containerView); displayListenerProxy.onPostWebViewInitialization(displayManager); @@ -76,29 +76,21 @@ public View getView() { } // @Override - // This is overriding a method that hasn't rolled into stable Flutter yet. - // Including the - // annotation would cause compile time failures in versions of Flutter too old - // to include the new - // method. However leaving it raw like this means that the method will be - // ignored in old versions + // This is overriding a method that hasn't rolled into stable Flutter yet. Including the + // annotation would cause compile time failures in versions of Flutter too old to include the new + // method. However leaving it raw like this means that the method will be ignored in old versions // of Flutter but used as an override anyway wherever it's actually defined. - // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to - // stable. + // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable. public void onInputConnectionUnlocked() { webView.unlockInputConnection(); } // @Override - // This is overriding a method that hasn't rolled into stable Flutter yet. - // Including the - // annotation would cause compile time failures in versions of Flutter too old - // to include the new - // method. However leaving it raw like this means that the method will be - // ignored in old versions + // This is overriding a method that hasn't rolled into stable Flutter yet. Including the + // annotation would cause compile time failures in versions of Flutter too old to include the new + // method. However leaving it raw like this means that the method will be ignored in old versions // of Flutter but used as an override anyway wherever it's actually defined. - // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to - // stable. + // TODO(mklim): Add the @Override annotation once flutter/engine#9727 rolls to stable. public void onInputConnectionLocked() { webView.lockInputConnection(); } @@ -203,13 +195,13 @@ private void evaluateJavaScript(MethodCall methodCall, final Result result) { throw new UnsupportedOperationException("JavaScript string cannot be null"); } webView.evaluateJavascript( - jsString, - new android.webkit.ValueCallback() { - @Override - public void onReceiveValue(String value) { - result.success(value); - } - }); + jsString, + new android.webkit.ValueCallback() { + @Override + public void onReceiveValue(String value) { + result.success(value); + } + }); } @SuppressWarnings("unchecked") @@ -244,7 +236,7 @@ private void applySettings(Map settings) { final boolean hasNavigationDelegate = (boolean) settings.get(key); final WebViewClient webViewClient = - flutterWebViewClient.createWebViewClient(hasNavigationDelegate); + flutterWebViewClient.createWebViewClient(hasNavigationDelegate); webView.setWebViewClient(webViewClient); break; @@ -276,8 +268,7 @@ private void updateJsMode(int mode) { } private void updateAutoMediaPlaybackPolicy(int mode) { - // This is the index of the AutoMediaPlaybackPolicy enum, index 1 is - // always_allow, for all + // This is the index of the AutoMediaPlaybackPolicy enum, index 1 is always_allow, for all // other values we require a user gesture. boolean requireUserGesture = mode != 1; webView.getSettings().setMediaPlaybackRequiresUserGesture(requireUserGesture); @@ -286,7 +277,7 @@ private void updateAutoMediaPlaybackPolicy(int mode) { private void registerJavaScriptChannelNames(List channelNames) { for (String channelName : channelNames) { webView.addJavascriptInterface( - new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName); + new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName); } } @@ -299,4 +290,4 @@ public void dispose() { methodChannel.setMethodCallHandler(null); webView.dispose(); } -} +} \ No newline at end of file From 3282117f40828692453254d4b473e22ecf7e6cad Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 16 Aug 2019 19:12:40 +0200 Subject: [PATCH 20/20] Fixed another formatting issue. --- .../webviewflutter/FlutterWebView.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java index 0470bf442316..2288b8f52d5a 100644 --- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java +++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java @@ -32,15 +32,15 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) @SuppressWarnings("unchecked") FlutterWebView( - final Context context, - BinaryMessenger messenger, - int id, - Map params, - final View containerView) { + final Context context, + BinaryMessenger messenger, + int id, + Map params, + final View containerView) { DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy(); DisplayManager displayManager = - (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); displayListenerProxy.onPreWebViewInitialization(displayManager); webView = new InputAwareWebView(context, containerView); displayListenerProxy.onPostWebViewInitialization(displayManager); @@ -195,13 +195,13 @@ private void evaluateJavaScript(MethodCall methodCall, final Result result) { throw new UnsupportedOperationException("JavaScript string cannot be null"); } webView.evaluateJavascript( - jsString, - new android.webkit.ValueCallback() { - @Override - public void onReceiveValue(String value) { - result.success(value); - } - }); + jsString, + new android.webkit.ValueCallback() { + @Override + public void onReceiveValue(String value) { + result.success(value); + } + }); } @SuppressWarnings("unchecked") @@ -236,7 +236,7 @@ private void applySettings(Map settings) { final boolean hasNavigationDelegate = (boolean) settings.get(key); final WebViewClient webViewClient = - flutterWebViewClient.createWebViewClient(hasNavigationDelegate); + flutterWebViewClient.createWebViewClient(hasNavigationDelegate); webView.setWebViewClient(webViewClient); break; @@ -277,7 +277,7 @@ private void updateAutoMediaPlaybackPolicy(int mode) { private void registerJavaScriptChannelNames(List channelNames) { for (String channelName : channelNames) { webView.addJavascriptInterface( - new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName); + new JavaScriptChannel(methodChannel, channelName, platformThreadHandler), channelName); } } @@ -291,4 +291,4 @@ public void dispose() { webView.dispose(); webView.destroy(); } -} \ No newline at end of file +}