Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 4.8.0

* Adds `AndroidWebViewController.setMixedContentMode` to control how
mixed-content pages load.

## 4.7.0

* Adds support to respond to recoverable SSL certificate errors. See `AndroidNavigationDelegate.setOnSSlAuthError`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ private class AndroidWebkitLibraryPigeonProxyApiBaseCodec(
value is ConsoleMessageLevel ||
value is OverScrollMode ||
value is SslErrorType ||
value is MixedContentMode ||
value == null) {
super.writeValue(stream, value)
return
Expand Down Expand Up @@ -886,6 +887,32 @@ enum class SslErrorType(val raw: Int) {
}
}

/**
* Options for mixed content mode support.
*
* See https://developer.android.com/reference/android/webkit/WebSettings#MIXED_CONTENT_ALWAYS_ALLOW
*/
enum class MixedContentMode(val raw: Int) {
/**
* The WebView will allow a secure origin to load content from any other origin, even if that
* origin is insecure.
*/
ALWAYS_ALLOW(0),
/**
* The WebView will attempt to be compatible with the approach of a modern web browser with regard
* to mixed content.
*/
COMPATIBILITY_MODE(1),
/** The WebView will not allow a secure origin to load content from an insecure origin. */
NEVER_ALLOW(2);

companion object {
fun ofRaw(raw: Int): MixedContentMode? {
return values().firstOrNull { it.raw == raw }
}
}
}

private open class AndroidWebkitLibraryPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return when (type) {
Expand All @@ -901,6 +928,9 @@ private open class AndroidWebkitLibraryPigeonCodec : StandardMessageCodec() {
132.toByte() -> {
return (readValue(buffer) as Long?)?.let { SslErrorType.ofRaw(it.toInt()) }
}
133.toByte() -> {
return (readValue(buffer) as Long?)?.let { MixedContentMode.ofRaw(it.toInt()) }
}
else -> super.readValueOfType(type, buffer)
}
}
Expand All @@ -923,6 +953,10 @@ private open class AndroidWebkitLibraryPigeonCodec : StandardMessageCodec() {
stream.write(132)
writeValue(stream, value.raw)
}
is MixedContentMode -> {
stream.write(133)
writeValue(stream, value.raw)
}
else -> super.writeValue(stream, value)
}
}
Expand Down Expand Up @@ -2285,6 +2319,12 @@ abstract class PigeonApiWebSettings(
/** Gets the WebView's user-agent string. */
abstract fun getUserAgentString(pigeon_instance: android.webkit.WebSettings): String

/** Configures the WebView's behavior when handling mixed content. */
abstract fun setMixedContentMode(
pigeon_instance: android.webkit.WebSettings,
mode: MixedContentMode
)

companion object {
@Suppress("LocalVariableName")
fun setUpMessageHandlers(binaryMessenger: BinaryMessenger, api: PigeonApiWebSettings?) {
Expand Down Expand Up @@ -2671,6 +2711,30 @@ abstract class PigeonApiWebSettings(
channel.setMessageHandler(null)
}
}
run {
val channel =
BasicMessageChannel<Any?>(
binaryMessenger,
"dev.flutter.pigeon.webview_flutter_android.WebSettings.setMixedContentMode",
codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val pigeon_instanceArg = args[0] as android.webkit.WebSettings
val modeArg = args[1] as MixedContentMode
val wrapped: List<Any?> =
try {
api.setMixedContentMode(pigeon_instanceArg, modeArg)
listOf(null)
} catch (exception: Throwable) {
AndroidWebkitLibraryPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,20 @@ public void setTextZoom(@NonNull WebSettings pigeon_instance, long textZoom) {
public String getUserAgentString(@NonNull WebSettings pigeon_instance) {
return pigeon_instance.getUserAgentString();
}

@Override
public void setMixedContentMode(
@NonNull WebSettings pigeon_instance, @NonNull MixedContentMode mode) {
switch (mode) {
case ALWAYS_ALLOW:
pigeon_instance.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
break;
case COMPATIBILITY_MODE:
pigeon_instance.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
break;
case NEVER_ALLOW:
pigeon_instance.setMixedContentMode(WebSettings.MIXED_CONTENT_NEVER_ALLOW);
break;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,4 +166,14 @@ public void getUserAgentString() {

assertEquals(value, api.getUserAgentString(instance));
}

@Test
public void setMixedContentMode() {
final PigeonApiWebSettings api = new TestProxyApiRegistrar().getPigeonApiWebSettings();

final WebSettings instance = mock(WebSettings.class);
api.setMixedContentMode(instance, MixedContentMode.COMPATIBILITY_MODE);

verify(instance).setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,23 @@ enum SslErrorType {
unknown,
}

/// Options for mixed content mode support.
///
/// See https://developer.android.com/reference/android/webkit/WebSettings#MIXED_CONTENT_ALWAYS_ALLOW
enum MixedContentMode {
/// The WebView will allow a secure origin to load content from any other
/// origin, even if that origin is insecure.
alwaysAllow,

/// The WebView will attempt to be compatible with the approach of a modern
/// web browser with regard to mixed content.
compatibilityMode,

/// The WebView will not allow a secure origin to load content from an
/// insecure origin.
neverAllow,
}

class _PigeonCodec extends StandardMessageCodec {
const _PigeonCodec();
@override
Expand All @@ -589,6 +606,9 @@ class _PigeonCodec extends StandardMessageCodec {
} else if (value is SslErrorType) {
buffer.putUint8(132);
writeValue(buffer, value.index);
} else if (value is MixedContentMode) {
buffer.putUint8(133);
writeValue(buffer, value.index);
} else {
super.writeValue(buffer, value);
}
Expand All @@ -609,6 +629,9 @@ class _PigeonCodec extends StandardMessageCodec {
case 132:
final int? value = readValue(buffer) as int?;
return value == null ? null : SslErrorType.values[value];
case 133:
final int? value = readValue(buffer) as int?;
return value == null ? null : MixedContentMode.values[value];
default:
return super.readValueOfType(type, buffer);
}
Expand Down Expand Up @@ -2895,6 +2918,36 @@ class WebSettings extends PigeonInternalProxyApiBaseClass {
}
}

/// Configures the WebView's behavior when handling mixed content.
Future<void> setMixedContentMode(MixedContentMode mode) async {
final _PigeonInternalProxyApiBaseCodec pigeonChannelCodec =
_pigeonVar_codecWebSettings;
final BinaryMessenger? pigeonVar_binaryMessenger = pigeon_binaryMessenger;
const String pigeonVar_channelName =
'dev.flutter.pigeon.webview_flutter_android.WebSettings.setMixedContentMode';
final BasicMessageChannel<Object?> pigeonVar_channel =
BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture =
pigeonVar_channel.send(<Object?>[this, mode]);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
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;
}
}

@override
WebSettings pigeon_copy() {
return WebSettings.pigeon_detached(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,19 @@ class AndroidWebViewController extends PlatformWebViewController {
_ => throw UnsupportedError('Android does not support $mode.'),
};
}

/// Configures the WebView's behavior when handling mixed content.
Future<void> setMixedContentMode(MixedContentMode mode) {
final android_webview.MixedContentMode androidMode = switch (mode) {
MixedContentMode.alwaysAllow =>
android_webview.MixedContentMode.alwaysAllow,
MixedContentMode.compatibilityMode =>
android_webview.MixedContentMode.compatibilityMode,
MixedContentMode.neverAllow =>
android_webview.MixedContentMode.neverAllow,
};
return _webView.settings.setMixedContentMode(androidMode);
}
}

/// Android implementation of [PlatformWebViewPermissionRequest].
Expand Down Expand Up @@ -866,6 +879,35 @@ enum FileSelectorMode {
save,
}

/// Mode for controlling mixed content handling.
/// See [AndroidWebViewController.setMixedContentMode].
enum MixedContentMode {
/// The WebView will allow a secure origin to load content from any other
/// origin, even if that origin is insecure.
///
/// This is the least secure mode of operation, and where possible apps should
/// not set this mode.
alwaysAllow,

/// The WebView will attempt to be compatible with the approach of a modern
/// web browser with regard to mixed content.
///
/// The types of content are allowed or blocked may change release to release
/// of the underlying Android WebView, and are not explicitly defined. This
/// mode is intended to be used by apps that are not in control of the content
/// that they render but desire to operate in a reasonably secure environment.
compatibilityMode,

/// The WebView will not allow a secure origin to load content from an
/// insecure origin.
///
/// This is the preferred and most secure mode of operation, and apps are
/// strongly advised to use this mode.
///
/// This is the default mode.
neverAllow,
}

/// Parameters received when the `WebView` should show a file selector.
@immutable
class FileSelectorParams {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,23 @@ enum SslErrorType {
unknown,
}

/// Options for mixed content mode support.
///
/// See https://developer.android.com/reference/android/webkit/WebSettings#MIXED_CONTENT_ALWAYS_ALLOW
enum MixedContentMode {
/// The WebView will allow a secure origin to load content from any other
/// origin, even if that origin is insecure.
alwaysAllow,

/// The WebView will attempt to be compatible with the approach of a modern
/// web browser with regard to mixed content.
compatibilityMode,

/// The WebView will not allow a secure origin to load content from an
/// insecure origin.
neverAllow,
}

/// Encompasses parameters to the `WebViewClient.shouldInterceptRequest` method.
///
/// See https://developer.android.com/reference/android/webkit/WebResourceRequest.
Expand Down Expand Up @@ -410,6 +427,9 @@ abstract class WebSettings {

/// Gets the WebView's user-agent string.
String getUserAgentString();

/// Configures the WebView's behavior when handling mixed content.
void setMixedContentMode(MixedContentMode mode);
}

/// A JavaScript interface for exposing Javascript callbacks to Dart.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.7.0
version: 4.8.0

environment:
sdk: ^3.6.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,21 @@ void main() {
verify(mockSettings.setTextZoom(100)).called(1);
});

test('setMixedContentMode', () async {
final MockWebView mockWebView = MockWebView();
final MockWebSettings mockSettings = MockWebSettings();
final AndroidWebViewController controller = createControllerWithMocks(
mockWebView: mockWebView,
mockSettings: mockSettings,
);

await controller.setMixedContentMode(MixedContentMode.compatibilityMode);

verify(mockSettings.setMixedContentMode(
android_webview.MixedContentMode.compatibilityMode,
)).called(1);
});

test('setOverScrollMode', () async {
final MockWebView mockWebView = MockWebView();
final AndroidWebViewController controller = createControllerWithMocks(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,17 @@ class MockAndroidWebViewController extends _i1.Mock
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);

@override
_i8.Future<void> setMixedContentMode(_i7.MixedContentMode? mode) =>
(super.noSuchMethod(
Invocation.method(
#setMixedContentMode,
[mode],
),
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);
}

/// A class which mocks [AndroidWebViewProxy].
Expand Down Expand Up @@ -3001,6 +3012,17 @@ class MockWebSettings extends _i1.Mock implements _i2.WebSettings {
)),
) as _i8.Future<String>);

@override
_i8.Future<void> setMixedContentMode(_i2.MixedContentMode? mode) =>
(super.noSuchMethod(
Invocation.method(
#setMixedContentMode,
[mode],
),
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);

@override
_i2.WebSettings pigeon_copy() => (super.noSuchMethod(
Invocation.method(
Expand Down
Loading