diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index 24633e85bd8..539c54c8a9f 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -1,3 +1,9 @@ +## 4.3.0 + +* Adds support for disabling content URL access within WebView and disabling the Geolocation API. + See `AndroidWebViewController.setAllowContentAccess` and + `AndroidWebViewController.setGeolocationEnabled`. + ## 4.2.0 * Adds support for configuring file access permissions. See `AndroidWebViewController.setAllowFileAccess`. diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt index f2808272548..92cbf74aaa1 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/AndroidWebkitLibrary.g.kt @@ -2104,6 +2104,12 @@ abstract class PigeonApiWebSettings( /** Enables or disables file access within WebView. */ abstract fun setAllowFileAccess(pigeon_instance: android.webkit.WebSettings, enabled: Boolean) + /** Enables or disables content URL access within WebView. */ + abstract fun setAllowContentAccess(pigeon_instance: android.webkit.WebSettings, enabled: Boolean) + + /** Sets whether Geolocation is enabled within WebView. */ + abstract fun setGeolocationEnabled(pigeon_instance: android.webkit.WebSettings, enabled: Boolean) + /** Sets the text zoom of the page in percent. */ abstract fun setTextZoom(pigeon_instance: android.webkit.WebSettings, textZoom: Long) @@ -2402,6 +2408,54 @@ abstract class PigeonApiWebSettings( channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.webview_flutter_android.WebSettings.setAllowContentAccess", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.webkit.WebSettings + val enabledArg = args[1] as Boolean + val wrapped: List = + try { + api.setAllowContentAccess(pigeon_instanceArg, enabledArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.webview_flutter_android.WebSettings.setGeolocationEnabled", + codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val pigeon_instanceArg = args[0] as android.webkit.WebSettings + val enabledArg = args[1] as Boolean + val wrapped: List = + try { + api.setGeolocationEnabled(pigeon_instanceArg, enabledArg) + listOf(null) + } catch (exception: Throwable) { + wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel( diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebSettingsProxyApi.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebSettingsProxyApi.java index 82fa32b8150..43966249703 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebSettingsProxyApi.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebSettingsProxyApi.java @@ -81,6 +81,16 @@ public void setAllowFileAccess(@NonNull WebSettings pigeon_instance, boolean ena pigeon_instance.setAllowFileAccess(enabled); } + @Override + public void setAllowContentAccess(@NonNull WebSettings pigeon_instance, boolean enabled) { + pigeon_instance.setAllowContentAccess(enabled); + } + + @Override + public void setGeolocationEnabled(@NonNull WebSettings pigeon_instance, boolean enabled) { + pigeon_instance.setGeolocationEnabled(enabled); + } + @Override public void setTextZoom(@NonNull WebSettings pigeon_instance, long textZoom) { pigeon_instance.setTextZoom((int) textZoom); diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart index fc7174a27d0..3ae3a187867 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webkit.g.dart @@ -2615,6 +2615,62 @@ class WebSettings extends PigeonInternalProxyApiBaseClass { } } + /// Enables or disables content URL access within WebView. + Future setAllowContentAccess(bool enabled) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecWebSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.webview_flutter_android.WebSettings.setAllowContentAccess'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, enabled]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + /// Sets whether Geolocation is enabled within WebView. + Future setGeolocationEnabled(bool enabled) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = + _pigeonVar_codecWebSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const String pigeonVar_channelName = + 'dev.flutter.pigeon.webview_flutter_android.WebSettings.setGeolocationEnabled'; + final BasicMessageChannel pigeonVar_channel = + BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final List? pigeonVar_replyList = await pigeonVar_channel + .send([this, enabled]) as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + /// Sets the text zoom of the page in percent. Future setTextZoom(int textZoom) async { final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart index 3cde232ca9f..7dc1c797376 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_controller.dart @@ -599,6 +599,18 @@ class AndroidWebViewController extends PlatformWebViewController { Future setTextZoom(int textZoom) => _webView.settings.setTextZoom(textZoom); + /// Enables or disables content URL access. + /// + /// The default is true. + Future setAllowContentAccess(bool enabled) => + _webView.settings.setAllowContentAccess(enabled); + + /// Sets whether Geolocation is enabled. + /// + /// The default is true. + Future setGeolocationEnabled(bool enabled) => + _webView.settings.setGeolocationEnabled(enabled); + /// Sets the callback that is invoked when the client should show a file /// selector. Future setOnShowFileSelector( diff --git a/packages/webview_flutter/webview_flutter_android/pigeons/android_webkit.dart b/packages/webview_flutter/webview_flutter_android/pigeons/android_webkit.dart index 22435d5b97d..8d3a4dbed5c 100644 --- a/packages/webview_flutter/webview_flutter_android/pigeons/android_webkit.dart +++ b/packages/webview_flutter/webview_flutter_android/pigeons/android_webkit.dart @@ -354,6 +354,12 @@ abstract class WebSettings { /// Enables or disables file access within WebView. void setAllowFileAccess(bool enabled); + /// Enables or disables content URL access within WebView. + void setAllowContentAccess(bool enabled); + + /// Sets whether Geolocation is enabled within WebView. + void setGeolocationEnabled(bool enabled); + /// Sets the text zoom of the page in percent. void setTextZoom(int textZoom); diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index 44f19b2af19..bd248b40f5d 100644 --- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_android description: A Flutter plugin that provides a WebView widget on Android. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 4.2.0 +version: 4.3.0 environment: sdk: ^3.5.0 diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart index 167b660aa53..6762d1f0169 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.dart @@ -1526,6 +1526,38 @@ void main() { verify(mockSettings.setMediaPlaybackRequiresUserGesture(true)).called(1); }); + test('setAllowContentAccess', () async { + final MockWebView mockWebView = MockWebView(); + final MockWebSettings mockSettings = MockWebSettings(); + final AndroidWebViewController controller = createControllerWithMocks( + mockWebView: mockWebView, + mockSettings: mockSettings, + ); + + clearInteractions(mockWebView); + + await controller.setAllowContentAccess(false); + + verify(mockWebView.settings).called(1); + verify(mockSettings.setAllowContentAccess(false)).called(1); + }); + + test('setGeolocationEnabled', () async { + final MockWebView mockWebView = MockWebView(); + final MockWebSettings mockSettings = MockWebSettings(); + final AndroidWebViewController controller = createControllerWithMocks( + mockWebView: mockWebView, + mockSettings: mockSettings, + ); + + clearInteractions(mockWebView); + + await controller.setGeolocationEnabled(false); + + verify(mockWebView.settings).called(1); + verify(mockSettings.setGeolocationEnabled(false)).called(1); + }); + test('setTextZoom', () async { final MockWebView mockWebView = MockWebView(); final MockWebSettings mockSettings = MockWebSettings(); diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart index d0254f2bd80..2e13f747bd6 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_controller_test.mocks.dart @@ -455,6 +455,16 @@ class MockAndroidWebViewController extends _i1.Mock ), ) as _i3.PlatformWebViewControllerCreationParams); + @override + _i8.Future setAllowFileAccess(bool? allow) => (super.noSuchMethod( + Invocation.method( + #setAllowFileAccess, + [allow], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + @override _i8.Future loadFile(String? absoluteFilePath) => (super.noSuchMethod( Invocation.method( @@ -789,6 +799,26 @@ class MockAndroidWebViewController extends _i1.Mock returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override + _i8.Future setAllowContentAccess(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setAllowContentAccess, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setGeolocationEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + @override _i8.Future setOnShowFileSelector( _i8.Future> Function(_i7.FileSelectorParams)? @@ -2638,6 +2668,26 @@ class MockWebSettings extends _i1.Mock implements _i2.WebSettings { returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + @override + _i8.Future setAllowContentAccess(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setAllowContentAccess, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + + @override + _i8.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setGeolocationEnabled, + [enabled], + ), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) as _i8.Future); + @override _i8.Future setTextZoom(int? textZoom) => (super.noSuchMethod( Invocation.method( diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart index 303f54d46f6..9a80b3c10f1 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_cookie_manager_test.mocks.dart @@ -178,6 +178,16 @@ class MockAndroidWebViewController extends _i1.Mock ), ) as _i3.PlatformWebViewControllerCreationParams); + @override + _i5.Future setAllowFileAccess(bool? allow) => (super.noSuchMethod( + Invocation.method( + #setAllowFileAccess, + [allow], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override _i5.Future loadFile(String? absoluteFilePath) => (super.noSuchMethod( Invocation.method( @@ -494,6 +504,26 @@ class MockAndroidWebViewController extends _i1.Mock returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + @override + _i5.Future setAllowContentAccess(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setAllowContentAccess, + [enabled], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + + @override + _i5.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setGeolocationEnabled, + [enabled], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override _i5.Future setOnShowFileSelector( _i5.Future> Function(_i6.FileSelectorParams)? diff --git a/packages/webview_flutter/webview_flutter_android/test/legacy/webview_android_widget_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/legacy/webview_android_widget_test.mocks.dart index 44c8b8adb47..ff695040404 100644 --- a/packages/webview_flutter/webview_flutter_android/test/legacy/webview_android_widget_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_android/test/legacy/webview_android_widget_test.mocks.dart @@ -355,6 +355,26 @@ class MockWebSettings extends _i1.Mock implements _i2.WebSettings { returnValueForMissingStub: _i4.Future.value(), ) as _i4.Future); + @override + _i4.Future setAllowContentAccess(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setAllowContentAccess, + [enabled], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod( + Invocation.method( + #setGeolocationEnabled, + [enabled], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + @override _i4.Future setTextZoom(int? textZoom) => (super.noSuchMethod( Invocation.method(