[webview_flutter] Implement loadRequest in Android package. (#4563)
Implements the `loadRequest` method added in #4450 for the Android package.
Related issue:
- flutter/flutter#27730
diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md
index e8d9e63..ce73ab2 100644
--- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md
+++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.7.0
+
+* Adds support for the `loadRequest` method from the platform interface.
+
## 2.6.0
* Adds implementation of the `loadFlutterAsset` method from the platform interface.
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java
index 0123790..0e6776e 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/GeneratedAndroidWebView.java
@@ -186,6 +186,8 @@
void loadUrl(Long instanceId, String url, Map<String, String> headers);
+ void postUrl(Long instanceId, String url, byte[] data);
+
String getUrl(Long instanceId);
Boolean canGoBack(Long instanceId);
@@ -413,6 +415,39 @@
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.WebViewHostApi.postUrl", getCodec());
+ if (api != null) {
+ channel.setMessageHandler(
+ (message, reply) -> {
+ Map<String, Object> wrapped = new HashMap<>();
+ try {
+ ArrayList<Object> args = (ArrayList<Object>) message;
+ Number instanceIdArg = (Number) args.get(0);
+ if (instanceIdArg == null) {
+ throw new NullPointerException("instanceIdArg unexpectedly null.");
+ }
+ String urlArg = (String) args.get(1);
+ if (urlArg == null) {
+ throw new NullPointerException("urlArg unexpectedly null.");
+ }
+ byte[] dataArg = (byte[]) args.get(2);
+ if (dataArg == null) {
+ throw new NullPointerException("dataArg unexpectedly null.");
+ }
+ api.postUrl(instanceIdArg.longValue(), urlArg, dataArg);
+ wrapped.put("result", null);
+ } catch (Error | RuntimeException exception) {
+ wrapped.put("error", wrapError(exception));
+ }
+ reply.reply(wrapped);
+ });
+ } else {
+ channel.setMessageHandler(null);
+ }
+ }
+ {
+ BasicMessageChannel<Object> channel =
+ new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.WebViewHostApi.getUrl", getCodec());
if (api != null) {
channel.setMessageHandler(
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java
index 78b06aa..0f31613 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewHostApiImpl.java
@@ -383,6 +383,12 @@
}
@Override
+ public void postUrl(Long instanceId, String url, byte[] data) {
+ final WebView webView = (WebView) instanceManager.getInstance(instanceId);
+ webView.postUrl(url, data);
+ }
+
+ @Override
public String getUrl(Long instanceId) {
final WebView webView = (WebView) instanceManager.getInstance(instanceId);
final String result = webView.getUrl();
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java
index dc58b9b..2312b76 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewTest.java
@@ -209,6 +209,12 @@
}
@Test
+ public void postUrl() {
+ testHostApiImpl.postUrl(0L, "https://www.google.com", new byte[] {0x01, 0x02});
+ verify(mockWebView).postUrl("https://www.google.com", new byte[] {0x01, 0x02});
+ }
+
+ @Test
public void getUrl() {
when(mockWebView.getUrl()).thenReturn("https://www.google.com");
assertEquals(testHostApiImpl.getUrl(0L), "https://www.google.com");
diff --git a/packages/webview_flutter/webview_flutter_android/example/lib/main.dart b/packages/webview_flutter/webview_flutter_android/example/lib/main.dart
index 3bd283c..eb3162a 100644
--- a/packages/webview_flutter/webview_flutter_android/example/lib/main.dart
+++ b/packages/webview_flutter/webview_flutter_android/example/lib/main.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
+import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_driver/driver_extension.dart';
@@ -189,6 +190,7 @@
loadLocalFile,
loadHtmlString,
transparentBackground,
+ doPostRequest,
}
class _SampleMenu extends StatelessWidget {
@@ -239,6 +241,9 @@
case _MenuOptions.transparentBackground:
_onTransparentBackground(controller.data!, context);
break;
+ case _MenuOptions.doPostRequest:
+ _onDoPostRequest(controller.data!, context);
+ break;
}
},
itemBuilder: (BuildContext context) => <PopupMenuItem<_MenuOptions>>[
@@ -288,6 +293,10 @@
value: _MenuOptions.transparentBackground,
child: Text('Transparent background example'),
),
+ const PopupMenuItem<_MenuOptions>(
+ value: _MenuOptions.doPostRequest,
+ child: Text('Post Request'),
+ ),
],
);
},
@@ -382,6 +391,16 @@
await controller.loadHtmlString(kExamplePage);
}
+ Future<void> _onDoPostRequest(
+ WebViewController controller, BuildContext context) async {
+ final WebViewRequest request = WebViewRequest(
+ uri: Uri.parse('https://httpbin.org/post'),
+ method: WebViewRequestMethod.post,
+ body: Uint8List.fromList('Test Body'.codeUnits),
+ );
+ await controller.loadRequest(request);
+ }
+
Widget _getCookieList(String cookies) {
if (cookies == null || cookies == '""') {
return Container();
diff --git a/packages/webview_flutter/webview_flutter_android/example/lib/web_view.dart b/packages/webview_flutter/webview_flutter_android/example/lib/web_view.dart
index b32deab..adaf7fb 100644
--- a/packages/webview_flutter/webview_flutter_android/example/lib/web_view.dart
+++ b/packages/webview_flutter/webview_flutter_android/example/lib/web_view.dart
@@ -418,6 +418,11 @@
return _webViewPlatformController.loadUrl(url, headers);
}
+ /// Loads a page by making the specified request.
+ Future<void> loadRequest(WebViewRequest request) async {
+ return _webViewPlatformController.loadRequest(request);
+ }
+
/// Accessor to the current URL that the WebView is displaying.
///
/// If [WebView.initialUrl] was never specified, returns `null`.
diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart
index a7561ce..d027016 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.dart
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/foundation.dart';
@@ -169,6 +170,13 @@
return api.loadUrlFromInstance(this, url, headers);
}
+ /// Loads the URL with postData using "POST" method into this WebView.
+ ///
+ /// If url is not a network URL, it will be loaded with [loadUrl] instead, ignoring the postData param.
+ Future<void> postUrl(String url, Uint8List data) {
+ return api.postUrlFromInstance(this, url, data);
+ }
+
/// Gets the URL for the current page.
///
/// This is not always the same as the URL passed to
diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart
index f936856..e0a1db3 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.pigeon.dart
@@ -220,6 +220,33 @@
}
}
+ Future<void> postUrl(
+ int arg_instanceId, String arg_url, Uint8List arg_data) async {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.WebViewHostApi.postUrl', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(<Object>[arg_instanceId, arg_url, arg_data])
+ as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return;
+ }
+ }
+
Future<String> getUrl(int arg_instanceId) async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.WebViewHostApi.getUrl', codec,
diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart
index 51efdaa..1db5ed4 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview_api_impls.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'dart:typed_data';
+
import 'package:flutter/services.dart';
import 'android_webview.dart';
@@ -153,6 +155,15 @@
}
/// Helper method to convert instances ids to objects.
+ Future<void> postUrlFromInstance(
+ WebView instance,
+ String url,
+ Uint8List data,
+ ) {
+ return postUrl(instanceManager.getInstanceId(instance)!, url, data);
+ }
+
+ /// Helper method to convert instances ids to objects.
Future<String> getUrlFromInstance(WebView instance) {
return getUrl(instanceManager.getInstanceId(instance)!);
}
diff --git a/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart b/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart
index 25f9874..fc295be 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/webview_android_widget.dart
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
+import 'dart:typed_data';
import 'package:flutter/widgets.dart';
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart';
@@ -210,6 +211,28 @@
return webView.loadUrl(url, headers ?? <String, String>{});
}
+ /// When making a POST request, headers are ignored. As a workaround, make
+ /// the request manually and load the response data using [loadHTMLString].
+ @override
+ Future<void> loadRequest(
+ WebViewRequest request,
+ ) async {
+ if (!request.uri.hasScheme) {
+ throw ArgumentError('WebViewRequest#uri is required to have a scheme.');
+ }
+ switch (request.method) {
+ case WebViewRequestMethod.get:
+ return webView.loadUrl(request.uri.toString(), request.headers);
+ case WebViewRequestMethod.post:
+ return webView.postUrl(
+ request.uri.toString(), request.body ?? Uint8List(0));
+ default:
+ throw UnimplementedError(
+ 'This version of webview_android_widget currently has no implementation for HTTP method ${request.method.serialize()} in loadRequest.',
+ );
+ }
+ }
+
@override
Future<String?> currentUrl() => webView.getUrl();
diff --git a/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
index 78672ea..4907dad 100644
--- a/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
+++ b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
@@ -46,6 +46,12 @@
Map<String, String> headers,
);
+ void postUrl(
+ int instanceId,
+ String url,
+ Uint8List data,
+ );
+
String getUrl(int instanceId);
bool canGoBack(int instanceId);
diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml
index bbe9ee1..08bcbb5 100644
--- a/packages/webview_flutter/webview_flutter_android/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter_android/pubspec.yaml
@@ -2,7 +2,7 @@
description: A Flutter plugin that provides a WebView widget on Android.
repository: https://github.com/flutter/plugins/tree/master/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: 2.6.0
+version: 2.7.0
environment:
sdk: ">=2.14.0 <3.0.0"
diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview.pigeon.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview.pigeon.dart
index 90c1474..1e47c79 100644
--- a/packages/webview_flutter/webview_flutter_android/test/android_webview.pigeon.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/android_webview.pigeon.dart
@@ -27,6 +27,7 @@
void loadDataWithBaseUrl(int instanceId, String baseUrl, String data,
String mimeType, String encoding, String historyUrl);
void loadUrl(int instanceId, String url, Map<String?, String?> headers);
+ void postUrl(int instanceId, String url, Uint8List data);
String getUrl(int instanceId);
bool canGoBack(int instanceId);
bool canGoForward(int instanceId);
@@ -182,6 +183,31 @@
}
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.WebViewHostApi.postUrl', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMockMessageHandler(null);
+ } else {
+ channel.setMockMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null.');
+ final List<Object?> args = (message as List<Object?>?)!;
+ final int? arg_instanceId = (args[0] as int?);
+ assert(arg_instanceId != null,
+ 'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null, expected non-null int.');
+ final String? arg_url = (args[1] as String?);
+ assert(arg_url != null,
+ 'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null, expected non-null String.');
+ final Uint8List? arg_data = (args[2] as Uint8List?);
+ assert(arg_data != null,
+ 'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null, expected non-null Uint8List.');
+ api.postUrl(arg_instanceId!, arg_url!, arg_data!);
+ return <Object?, Object?>{};
+ });
+ }
+ }
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.WebViewHostApi.getUrl', codec,
binaryMessenger: binaryMessenger);
if (api == null) {
diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart
index a08019e..8bb5694 100644
--- a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.mocks.dart
@@ -1,9 +1,14 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
// Mocks generated by Mockito 5.0.16 from annotations
// in webview_flutter_android/test/android_webview_test.dart.
// Do not manually edit this file.
-import 'dart:async' as _i4;
-import 'dart:ui' as _i5;
+import 'dart:async' as _i5;
+import 'dart:typed_data' as _i4;
+import 'dart:ui' as _i6;
import 'package:mockito/mockito.dart' as _i1;
import 'package:webview_flutter_android/src/android_webview.dart' as _i2;
@@ -241,6 +246,10 @@
Invocation.method(#loadUrl, [instanceId, url, headers]),
returnValueForMissingStub: null);
@override
+ void postUrl(int? instanceId, String? url, _i4.Uint8List? data) =>
+ super.noSuchMethod(Invocation.method(#postUrl, [instanceId, url, data]),
+ returnValueForMissingStub: null);
+ @override
String getUrl(int? instanceId) =>
(super.noSuchMethod(Invocation.method(#getUrl, [instanceId]),
returnValue: '') as String);
@@ -270,12 +279,12 @@
Invocation.method(#clearCache, [instanceId, includeDiskFiles]),
returnValueForMissingStub: null);
@override
- _i4.Future<String> evaluateJavascript(
+ _i5.Future<String> evaluateJavascript(
int? instanceId, String? javascriptString) =>
(super.noSuchMethod(
Invocation.method(
#evaluateJavascript, [instanceId, javascriptString]),
- returnValue: Future<String>.value('')) as _i4.Future<String>);
+ returnValue: Future<String>.value('')) as _i5.Future<String>);
@override
String getTitle(int? instanceId) =>
(super.noSuchMethod(Invocation.method(#getTitle, [instanceId]),
@@ -394,15 +403,15 @@
(super.noSuchMethod(Invocation.getter(#settings),
returnValue: _FakeWebSettings_0()) as _i2.WebSettings);
@override
- _i4.Future<void> loadData(
+ _i5.Future<void> loadData(
{String? data, String? mimeType, String? encoding}) =>
(super.noSuchMethod(
Invocation.method(#loadData, [],
{#data: data, #mimeType: mimeType, #encoding: encoding}),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> loadDataWithBaseUrl(
+ _i5.Future<void> loadDataWithBaseUrl(
{String? baseUrl,
String? data,
String? mimeType,
@@ -417,109 +426,114 @@
#historyUrl: historyUrl
}),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> loadUrl(String? url, Map<String, String>? headers) =>
+ _i5.Future<void> loadUrl(String? url, Map<String, String>? headers) =>
(super.noSuchMethod(Invocation.method(#loadUrl, [url, headers]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<String?> getUrl() =>
+ _i5.Future<void> postUrl(String? url, _i4.Uint8List? data) =>
+ (super.noSuchMethod(Invocation.method(#postUrl, [url, data]),
+ returnValue: Future<void>.value(),
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
+ @override
+ _i5.Future<String?> getUrl() =>
(super.noSuchMethod(Invocation.method(#getUrl, []),
- returnValue: Future<String?>.value()) as _i4.Future<String?>);
+ returnValue: Future<String?>.value()) as _i5.Future<String?>);
@override
- _i4.Future<bool> canGoBack() =>
+ _i5.Future<bool> canGoBack() =>
(super.noSuchMethod(Invocation.method(#canGoBack, []),
- returnValue: Future<bool>.value(false)) as _i4.Future<bool>);
+ returnValue: Future<bool>.value(false)) as _i5.Future<bool>);
@override
- _i4.Future<bool> canGoForward() =>
+ _i5.Future<bool> canGoForward() =>
(super.noSuchMethod(Invocation.method(#canGoForward, []),
- returnValue: Future<bool>.value(false)) as _i4.Future<bool>);
+ returnValue: Future<bool>.value(false)) as _i5.Future<bool>);
@override
- _i4.Future<void> goBack() =>
+ _i5.Future<void> goBack() =>
(super.noSuchMethod(Invocation.method(#goBack, []),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> goForward() =>
+ _i5.Future<void> goForward() =>
(super.noSuchMethod(Invocation.method(#goForward, []),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> reload() =>
+ _i5.Future<void> reload() =>
(super.noSuchMethod(Invocation.method(#reload, []),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> clearCache(bool? includeDiskFiles) =>
+ _i5.Future<void> clearCache(bool? includeDiskFiles) =>
(super.noSuchMethod(Invocation.method(#clearCache, [includeDiskFiles]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<String?> evaluateJavascript(String? javascriptString) => (super
+ _i5.Future<String?> evaluateJavascript(String? javascriptString) => (super
.noSuchMethod(Invocation.method(#evaluateJavascript, [javascriptString]),
- returnValue: Future<String?>.value()) as _i4.Future<String?>);
+ returnValue: Future<String?>.value()) as _i5.Future<String?>);
@override
- _i4.Future<String?> getTitle() =>
+ _i5.Future<String?> getTitle() =>
(super.noSuchMethod(Invocation.method(#getTitle, []),
- returnValue: Future<String?>.value()) as _i4.Future<String?>);
+ returnValue: Future<String?>.value()) as _i5.Future<String?>);
@override
- _i4.Future<void> scrollTo(int? x, int? y) =>
+ _i5.Future<void> scrollTo(int? x, int? y) =>
(super.noSuchMethod(Invocation.method(#scrollTo, [x, y]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> scrollBy(int? x, int? y) =>
+ _i5.Future<void> scrollBy(int? x, int? y) =>
(super.noSuchMethod(Invocation.method(#scrollBy, [x, y]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<int> getScrollX() =>
+ _i5.Future<int> getScrollX() =>
(super.noSuchMethod(Invocation.method(#getScrollX, []),
- returnValue: Future<int>.value(0)) as _i4.Future<int>);
+ returnValue: Future<int>.value(0)) as _i5.Future<int>);
@override
- _i4.Future<int> getScrollY() =>
+ _i5.Future<int> getScrollY() =>
(super.noSuchMethod(Invocation.method(#getScrollY, []),
- returnValue: Future<int>.value(0)) as _i4.Future<int>);
+ returnValue: Future<int>.value(0)) as _i5.Future<int>);
@override
- _i4.Future<void> setWebViewClient(_i2.WebViewClient? webViewClient) =>
+ _i5.Future<void> setWebViewClient(_i2.WebViewClient? webViewClient) =>
(super.noSuchMethod(Invocation.method(#setWebViewClient, [webViewClient]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> addJavaScriptChannel(
+ _i5.Future<void> addJavaScriptChannel(
_i2.JavaScriptChannel? javaScriptChannel) =>
(super.noSuchMethod(
Invocation.method(#addJavaScriptChannel, [javaScriptChannel]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> removeJavaScriptChannel(
+ _i5.Future<void> removeJavaScriptChannel(
_i2.JavaScriptChannel? javaScriptChannel) =>
(super.noSuchMethod(
Invocation.method(#removeJavaScriptChannel, [javaScriptChannel]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> setDownloadListener(_i2.DownloadListener? listener) =>
+ _i5.Future<void> setDownloadListener(_i2.DownloadListener? listener) =>
(super.noSuchMethod(Invocation.method(#setDownloadListener, [listener]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> setWebChromeClient(_i2.WebChromeClient? client) =>
+ _i5.Future<void> setWebChromeClient(_i2.WebChromeClient? client) =>
(super.noSuchMethod(Invocation.method(#setWebChromeClient, [client]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> setBackgroundColor(_i5.Color? color) =>
+ _i5.Future<void> setBackgroundColor(_i6.Color? color) =>
(super.noSuchMethod(Invocation.method(#setBackgroundColor, [color]),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
- _i4.Future<void> release() =>
+ _i5.Future<void> release() =>
(super.noSuchMethod(Invocation.method(#release, []),
returnValue: Future<void>.value(),
- returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ returnValueForMissingStub: Future<void>.value()) as _i5.Future<void>);
@override
String toString() => super.toString();
}
diff --git a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart
index f3867b3..c203ef0 100644
--- a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.dart
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
+import 'dart:typed_data';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -407,6 +408,81 @@
));
});
+ group('loadRequest', () {
+ testWidgets('Throws ArgumentError for empty scheme',
+ (WidgetTester tester) async {
+ await buildWidget(tester);
+
+ expect(
+ () async => await testController.loadRequest(
+ WebViewRequest(
+ uri: Uri.parse('www.google.com'),
+ method: WebViewRequestMethod.get,
+ ),
+ ),
+ throwsA(const TypeMatcher<ArgumentError>()));
+ });
+
+ testWidgets('GET without headers', (WidgetTester tester) async {
+ await buildWidget(tester);
+
+ await testController.loadRequest(WebViewRequest(
+ uri: Uri.parse('https://www.google.com'),
+ method: WebViewRequestMethod.get,
+ ));
+
+ verify(mockWebView.loadUrl(
+ 'https://www.google.com',
+ <String, String>{},
+ ));
+ });
+
+ testWidgets('GET with headers', (WidgetTester tester) async {
+ await buildWidget(tester);
+
+ await testController.loadRequest(WebViewRequest(
+ uri: Uri.parse('https://www.google.com'),
+ method: WebViewRequestMethod.get,
+ headers: <String, String>{'a': 'header'},
+ ));
+
+ verify(mockWebView.loadUrl(
+ 'https://www.google.com',
+ <String, String>{'a': 'header'},
+ ));
+ });
+
+ testWidgets('POST without body', (WidgetTester tester) async {
+ await buildWidget(tester);
+
+ await testController.loadRequest(WebViewRequest(
+ uri: Uri.parse('https://www.google.com'),
+ method: WebViewRequestMethod.post,
+ ));
+
+ verify(mockWebView.postUrl(
+ 'https://www.google.com',
+ Uint8List(0),
+ ));
+ });
+
+ testWidgets('POST with body', (WidgetTester tester) async {
+ await buildWidget(tester);
+
+ final Uint8List body = Uint8List.fromList('Test Body'.codeUnits);
+
+ await testController.loadRequest(WebViewRequest(
+ uri: Uri.parse('https://www.google.com'),
+ method: WebViewRequestMethod.post,
+ body: body));
+
+ verify(mockWebView.postUrl(
+ 'https://www.google.com',
+ body,
+ ));
+ });
+ });
+
testWidgets('currentUrl', (WidgetTester tester) async {
await buildWidget(tester);
diff --git a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart
index f3b06ea..ece17ad 100644
--- a/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/webview_android_widget_test.mocks.dart
@@ -1,13 +1,18 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
// Mocks generated by Mockito 5.0.16 from annotations
// in webview_flutter_android/test/webview_android_widget_test.dart.
// Do not manually edit this file.
import 'dart:async' as _i4;
-import 'dart:ui' as _i5;
+import 'dart:typed_data' as _i5;
+import 'dart:ui' as _i6;
import 'package:mockito/mockito.dart' as _i1;
import 'package:webview_flutter_android/src/android_webview.dart' as _i2;
-import 'package:webview_flutter_android/webview_android_widget.dart' as _i6;
+import 'package:webview_flutter_android/webview_android_widget.dart' as _i7;
import 'package:webview_flutter_platform_interface/webview_flutter_platform_interface.dart'
as _i3;
@@ -165,6 +170,11 @@
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
@override
+ _i4.Future<void> postUrl(String? url, _i5.Uint8List? data) =>
+ (super.noSuchMethod(Invocation.method(#postUrl, [url, data]),
+ returnValue: Future<void>.value(),
+ returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
+ @override
_i4.Future<String?> getUrl() =>
(super.noSuchMethod(Invocation.method(#getUrl, []),
returnValue: Future<String?>.value()) as _i4.Future<String?>);
@@ -252,7 +262,7 @@
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
@override
- _i4.Future<void> setBackgroundColor(_i5.Color? color) =>
+ _i4.Future<void> setBackgroundColor(_i6.Color? color) =>
(super.noSuchMethod(Invocation.method(#setBackgroundColor, [color]),
returnValue: Future<void>.value(),
returnValueForMissingStub: Future<void>.value()) as _i4.Future<void>);
@@ -269,7 +279,7 @@
///
/// See the documentation for Mockito's code generation for more information.
class MockWebViewAndroidDownloadListener extends _i1.Mock
- implements _i6.WebViewAndroidDownloadListener {
+ implements _i7.WebViewAndroidDownloadListener {
MockWebViewAndroidDownloadListener() {
_i1.throwOnMissingStub(this);
}
@@ -295,7 +305,7 @@
///
/// See the documentation for Mockito's code generation for more information.
class MockWebViewAndroidJavaScriptChannel extends _i1.Mock
- implements _i6.WebViewAndroidJavaScriptChannel {
+ implements _i7.WebViewAndroidJavaScriptChannel {
MockWebViewAndroidJavaScriptChannel() {
_i1.throwOnMissingStub(this);
}
@@ -321,7 +331,7 @@
///
/// See the documentation for Mockito's code generation for more information.
class MockWebViewAndroidWebChromeClient extends _i1.Mock
- implements _i6.WebViewAndroidWebChromeClient {
+ implements _i7.WebViewAndroidWebChromeClient {
MockWebViewAndroidWebChromeClient() {
_i1.throwOnMissingStub(this);
}
@@ -338,7 +348,7 @@
///
/// See the documentation for Mockito's code generation for more information.
class MockWebViewAndroidWebViewClient extends _i1.Mock
- implements _i6.WebViewAndroidWebViewClient {
+ implements _i7.WebViewAndroidWebViewClient {
MockWebViewAndroidWebViewClient() {
_i1.throwOnMissingStub(this);
}
@@ -470,7 +480,7 @@
/// A class which mocks [WebViewProxy].
///
/// See the documentation for Mockito's code generation for more information.
-class MockWebViewProxy extends _i1.Mock implements _i6.WebViewProxy {
+class MockWebViewProxy extends _i1.Mock implements _i7.WebViewProxy {
MockWebViewProxy() {
_i1.throwOnMissingStub(this);
}