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 e5b528d49079..84a2650a873e 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 @@ -2584,6 +2584,18 @@ abstract class PigeonApiWebSettings( /** Enables or disables content URL access within WebView. */ abstract fun setAllowContentAccess(pigeon_instance: android.webkit.WebSettings, enabled: Boolean) + /** Enables or disables universal cross-origin access from file URLs. */ + abstract fun setAllowUniversalAccessFromFileURLs( + pigeon_instance: android.webkit.WebSettings, + enabled: Boolean + ) + + /** Enables or disables file URL access to other file URLs. */ + abstract fun setAllowFileAccessFromFileURLs( + pigeon_instance: android.webkit.WebSettings, + enabled: Boolean + ) + /** Sets whether Geolocation is enabled within WebView. */ abstract fun setGeolocationEnabled(pigeon_instance: android.webkit.WebSettings, enabled: Boolean) @@ -2915,6 +2927,54 @@ abstract class PigeonApiWebSettings( channel.setMessageHandler(null) } } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.webview_flutter_android.WebSettings.setAllowUniversalAccessFromFileURLs", + 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.setAllowUniversalAccessFromFileURLs(pigeon_instanceArg, enabledArg) + listOf(null) + } catch (exception: Throwable) { + AndroidWebkitLibraryPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = + BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.webview_flutter_android.WebSettings.setAllowFileAccessFromFileURLs", + 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.setAllowFileAccessFromFileURLs(pigeon_instanceArg, enabledArg) + listOf(null) + } catch (exception: Throwable) { + AndroidWebkitLibraryPigeonUtils.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 fb1a3638de35..41c1a985a722 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 @@ -86,6 +86,18 @@ public void setAllowContentAccess(@NonNull WebSettings pigeon_instance, boolean pigeon_instance.setAllowContentAccess(enabled); } + @Override + public void setAllowFileAccessFromFileURLs( + @NonNull WebSettings pigeon_instance, boolean enabled) { + pigeon_instance.setAllowFileAccessFromFileURLs(enabled); + } + + @Override + public void setAllowUniversalAccessFromFileURLs( + @NonNull WebSettings pigeon_instance, boolean enabled) { + pigeon_instance.setAllowUniversalAccessFromFileURLs(enabled); + } + @Override public void setGeolocationEnabled(@NonNull WebSettings pigeon_instance, boolean enabled) { pigeon_instance.setGeolocationEnabled(enabled); 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 5b05123527d4..f4a8c6f20a07 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 @@ -2458,6 +2458,40 @@ class WebSettings extends PigeonInternalProxyApiBaseClass { _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true); } + /// Enables or disables universal cross-origin access from file URLs. + Future setAllowUniversalAccessFromFileURLs(bool enabled) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = _pigeonVar_codecWebSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const pigeonVar_channelName = + 'dev.flutter.pigeon.webview_flutter_android.WebSettings.setAllowUniversalAccessFromFileURLs'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([this, enabled]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true); + } + + /// Enables or disables file URL access to other file URLs. + Future setAllowFileAccessFromFileURLs(bool enabled) async { + final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = _pigeonVar_codecWebSettings; + final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger; + const pigeonVar_channelName = + 'dev.flutter.pigeon.webview_flutter_android.WebSettings.setAllowFileAccessFromFileURLs'; + final pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send([this, enabled]); + final pigeonVar_replyList = await pigeonVar_sendFuture as List?; + + _extractReplyValueOrThrow(pigeonVar_replyList, pigeonVar_channelName, isNullValid: true); + } + /// Sets whether Geolocation is enabled within WebView. Future setGeolocationEnabled(bool enabled) async { final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec = _pigeonVar_codecWebSettings; 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 70d8a0aac5ff..18305ee0988f 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 @@ -620,6 +620,20 @@ class AndroidWebViewController extends PlatformWebViewController { Future setAllowContentAccess(bool enabled) => _webView.settings.setAllowContentAccess(enabled); + /// Sets the file URL access to other file URLs permission for the web view. + /// + /// The default value is true for apps targeting API 15 and below, and false + /// when targeting API 16 and above. + Future setAllowFileAccessFromFileURLs(bool enabled) => + _webView.settings.setAllowFileAccessFromFileURLs(enabled); + + /// Sets the universal cross-origin access from file URLs permission for the web view. + /// + /// The default value is true for apps targeting API 15 and below, and false + /// when targeting API 16 and above. + Future setAllowUniversalAccessFromFileURLs(bool enabled) => + _webView.settings.setAllowUniversalAccessFromFileURLs(enabled); + /// Sets whether Geolocation is enabled. /// /// The default is true. 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 d4f758224ca3..0c54f10919aa 100644 --- a/packages/webview_flutter/webview_flutter_android/pigeons/android_webkit.dart +++ b/packages/webview_flutter/webview_flutter_android/pigeons/android_webkit.dart @@ -428,6 +428,12 @@ abstract class WebSettings { /// Enables or disables content URL access within WebView. void setAllowContentAccess(bool enabled); + /// Enables or disables universal cross-origin access from file URLs. + void setAllowUniversalAccessFromFileURLs(bool enabled); + + /// Enables or disables file URL access to other file URLs. + void setAllowFileAccessFromFileURLs(bool enabled); + /// Sets whether Geolocation is enabled within WebView. void setGeolocationEnabled(bool enabled); 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 12cb351323f7..fbb83bf5a97d 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 @@ -1753,6 +1753,38 @@ void main() { verify(mockSettings.setAllowContentAccess(false)).called(1); }); + test('setAllowFileAccessFromFileURLs', () async { + final mockWebView = MockWebView(); + final mockSettings = MockWebSettings(); + final AndroidWebViewController controller = createControllerWithMocks( + mockWebView: mockWebView, + mockSettings: mockSettings, + ); + + clearInteractions(mockWebView); + + await controller.setAllowFileAccessFromFileURLs(false); + + verify(mockWebView.settings).called(1); + verify(mockSettings.setAllowFileAccessFromFileURLs(false)).called(1); + }); + + test('setAllowUniversalAccessFromFileURLs', () async { + final mockWebView = MockWebView(); + final mockSettings = MockWebSettings(); + final AndroidWebViewController controller = createControllerWithMocks( + mockWebView: mockWebView, + mockSettings: mockSettings, + ); + + clearInteractions(mockWebView); + + await controller.setAllowUniversalAccessFromFileURLs(false); + + verify(mockWebView.settings).called(1); + verify(mockSettings.setAllowUniversalAccessFromFileURLs(false)).called(1); + }); + test('setGeolocationEnabled', () async { final mockWebView = MockWebView(); final 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 ac71113886f4..3cbc523b1bf6 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 @@ -610,6 +610,24 @@ class MockAndroidWebViewController extends _i1.Mock implements _i7.AndroidWebVie ) as _i8.Future); + @override + _i8.Future setAllowFileAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowFileAccessFromFileURLs, [enabled]), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) + as _i8.Future); + + @override + _i8.Future setAllowUniversalAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowUniversalAccessFromFileURLs, [enabled]), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) + as _i8.Future); + @override _i8.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod( @@ -786,6 +804,15 @@ class MockAndroidWebViewController extends _i1.Mock implements _i7.AndroidWebVie returnValueForMissingStub: _i8.Future.value(), ) as _i8.Future); + + @override + _i8.Future setInsetsForWebContentToIgnore(List<_i7.AndroidWebViewInsets>? insets) => + (super.noSuchMethod( + Invocation.method(#setInsetsForWebContentToIgnore, [insets]), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) + as _i8.Future); } /// A class which mocks [AndroidWebViewWidgetCreationParams]. @@ -1718,6 +1745,24 @@ class MockWebSettings extends _i1.Mock implements _i2.WebSettings { ) as _i8.Future); + @override + _i8.Future setAllowUniversalAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowUniversalAccessFromFileURLs, [enabled]), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) + as _i8.Future); + + @override + _i8.Future setAllowFileAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowFileAccessFromFileURLs, [enabled]), + returnValue: _i8.Future.value(), + returnValueForMissingStub: _i8.Future.value(), + ) + as _i8.Future); + @override _i8.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod( 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 81e158f91e54..fa683dfa17d6 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 @@ -423,6 +423,24 @@ class MockAndroidWebViewController extends _i1.Mock implements _i6.AndroidWebVie ) as _i5.Future); + @override + _i5.Future setAllowFileAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowFileAccessFromFileURLs, [enabled]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + + @override + _i5.Future setAllowUniversalAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowUniversalAccessFromFileURLs, [enabled]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); + @override _i5.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod( @@ -593,4 +611,13 @@ class MockAndroidWebViewController extends _i1.Mock implements _i6.AndroidWebVie returnValueForMissingStub: _i5.Future.value(), ) as _i5.Future); + + @override + _i5.Future setInsetsForWebContentToIgnore(List<_i6.AndroidWebViewInsets>? insets) => + (super.noSuchMethod( + Invocation.method(#setInsetsForWebContentToIgnore, [insets]), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) + as _i5.Future); } 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 a2928df0253d..f937e0c50e0a 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 @@ -267,6 +267,24 @@ class MockWebSettings extends _i1.Mock implements _i2.WebSettings { ) as _i4.Future); + @override + _i4.Future setAllowUniversalAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowUniversalAccessFromFileURLs, [enabled]), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); + + @override + _i4.Future setAllowFileAccessFromFileURLs(bool? enabled) => + (super.noSuchMethod( + Invocation.method(#setAllowFileAccessFromFileURLs, [enabled]), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) + as _i4.Future); + @override _i4.Future setGeolocationEnabled(bool? enabled) => (super.noSuchMethod(