[webview_flutter_android] Adds a WebViewFlutterApi (#3324)
[webview_flutter_android] Adds a WebViewFlutterApi
diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md
index 6bd5861..5c20834 100644
--- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md
+++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 3.4.1
+
+* Fixes a potential bug where a `WebView` that was not added to the `InstanceManager` could be
+ returned by a `WebViewClient` or `WebChromeClient`.
+
## 3.4.0
* Adds support to set text zoom of a page. See `AndroidWebViewController.setTextZoom`.
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java
index 6797859..cacf364 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/FileChooserParamsFlutterApiImpl.java
@@ -57,18 +57,16 @@
/**
* Stores the FileChooserParams instance and notifies Dart to create a new FileChooserParams
* instance that is attached to this one.
- *
- * @return the instanceId of the stored instance
*/
- public long create(WebChromeClient.FileChooserParams instance, Reply<Void> callback) {
- final long instanceId = instanceManager.addHostCreatedInstance(instance);
- create(
- instanceId,
- instance.isCaptureEnabled(),
- Arrays.asList(instance.getAcceptTypes()),
- toFileChooserEnumData(instance.getMode()),
- instance.getFilenameHint(),
- callback);
- return instanceId;
+ public void create(WebChromeClient.FileChooserParams instance, Reply<Void> callback) {
+ if (!instanceManager.containsInstance(instance)) {
+ create(
+ instanceManager.addHostCreatedInstance(instance),
+ instance.isCaptureEnabled(),
+ Arrays.asList(instance.getAcceptTypes()),
+ toFileChooserEnumData(instance.getMode()),
+ instance.getFilenameHint(),
+ callback);
+ }
}
}
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 6fa20fe..189b85c 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
@@ -1574,6 +1574,42 @@
}
}
}
+ /**
+ * Flutter API for `WebView`.
+ *
+ * <p>This class may handle instantiating and adding Dart instances that are attached to a native
+ * instance or receiving callback methods from an overridden native class.
+ *
+ * <p>See https://developer.android.com/reference/android/webkit/WebView.
+ *
+ * <p>Generated class from Pigeon that represents Flutter messages that can be called from Java.
+ */
+ public static class WebViewFlutterApi {
+ private final BinaryMessenger binaryMessenger;
+
+ public WebViewFlutterApi(BinaryMessenger argBinaryMessenger) {
+ this.binaryMessenger = argBinaryMessenger;
+ }
+
+ public interface Reply<T> {
+ void reply(T reply);
+ }
+ /** The codec used by WebViewFlutterApi. */
+ static MessageCodec<Object> getCodec() {
+ return new StandardMessageCodec();
+ }
+ /** Create a new Dart instance and add it to the `InstanceManager`. */
+ public void create(@NonNull Long identifierArg, Reply<Void> callback) {
+ BasicMessageChannel<Object> channel =
+ new BasicMessageChannel<>(
+ binaryMessenger, "dev.flutter.pigeon.WebViewFlutterApi.create", getCodec());
+ channel.send(
+ new ArrayList<Object>(Collections.singletonList(identifierArg)),
+ channelReply -> {
+ callback.reply(null);
+ });
+ }
+ }
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
public interface WebSettingsHostApi {
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java
index 92f0e41..ece8e62 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebChromeClientFlutterApiImpl.java
@@ -21,6 +21,7 @@
public class WebChromeClientFlutterApiImpl extends WebChromeClientFlutterApi {
private final BinaryMessenger binaryMessenger;
private final InstanceManager instanceManager;
+ private final WebViewFlutterApiImpl webViewFlutterApi;
/**
* Creates a Flutter api that sends messages to Dart.
@@ -33,15 +34,16 @@
super(binaryMessenger);
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
+ webViewFlutterApi = new WebViewFlutterApiImpl(binaryMessenger, instanceManager);
}
/** Passes arguments from {@link WebChromeClient#onProgressChanged} to Dart. */
public void onProgressChanged(
WebChromeClient webChromeClient, WebView webView, Long progress, Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
super.onProgressChanged(
getIdentifierForClient(webChromeClient), webViewIdentifier, progress, callback);
}
@@ -53,17 +55,15 @@
WebView webView,
WebChromeClient.FileChooserParams fileChooserParams,
Reply<List<String>> callback) {
- Long paramsInstanceId = instanceManager.getIdentifierForStrongReference(fileChooserParams);
- if (paramsInstanceId == null) {
- final FileChooserParamsFlutterApiImpl flutterApi =
- new FileChooserParamsFlutterApiImpl(binaryMessenger, instanceManager);
- paramsInstanceId = flutterApi.create(fileChooserParams, reply -> {});
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ new FileChooserParamsFlutterApiImpl(binaryMessenger, instanceManager)
+ .create(fileChooserParams, reply -> {});
onShowFileChooser(
Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webChromeClient)),
Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView)),
- paramsInstanceId,
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(fileChooserParams)),
callback);
}
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java
index 0dc0bbb..aad569d 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientFlutterApiImpl.java
@@ -15,6 +15,7 @@
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebViewClientFlutterApi;
import java.util.HashMap;
+import java.util.Objects;
/**
* Flutter Api implementation for {@link WebViewClient}.
@@ -22,7 +23,9 @@
* <p>Passes arguments of callbacks methods from a {@link WebViewClient} to Dart.
*/
public class WebViewClientFlutterApiImpl extends WebViewClientFlutterApi {
+ private final BinaryMessenger binaryMessenger;
private final InstanceManager instanceManager;
+ private final WebViewFlutterApiImpl webViewFlutterApi;
@RequiresApi(api = Build.VERSION_CODES.M)
static GeneratedAndroidWebView.WebResourceErrorData createWebResourceErrorData(
@@ -71,26 +74,28 @@
public WebViewClientFlutterApiImpl(
BinaryMessenger binaryMessenger, InstanceManager instanceManager) {
super(binaryMessenger);
+ this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
+ webViewFlutterApi = new WebViewFlutterApiImpl(binaryMessenger, instanceManager);
}
/** Passes arguments from {@link WebViewClient#onPageStarted} to Dart. */
public void onPageStarted(
WebViewClient webViewClient, WebView webView, String urlArg, Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
onPageStarted(getIdentifierForClient(webViewClient), webViewIdentifier, urlArg, callback);
}
/** Passes arguments from {@link WebViewClient#onPageFinished} to Dart. */
public void onPageFinished(
WebViewClient webViewClient, WebView webView, String urlArg, Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
onPageFinished(getIdentifierForClient(webViewClient), webViewIdentifier, urlArg, callback);
}
@@ -105,10 +110,10 @@
WebResourceRequest request,
WebResourceError error,
Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
onReceivedRequestError(
getIdentifierForClient(webViewClient),
webViewIdentifier,
@@ -128,10 +133,10 @@
WebResourceRequest request,
WebResourceErrorCompat error,
Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
onReceivedRequestError(
getIdentifierForClient(webViewClient),
webViewIdentifier,
@@ -151,10 +156,10 @@
String descriptionArg,
String failingUrlArg,
Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
onReceivedError(
getIdentifierForClient(webViewClient),
webViewIdentifier,
@@ -174,10 +179,10 @@
WebView webView,
WebResourceRequest request,
Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
requestLoading(
getIdentifierForClient(webViewClient),
webViewIdentifier,
@@ -190,10 +195,10 @@
*/
public void urlLoading(
WebViewClient webViewClient, WebView webView, String urlArg, Reply<Void> callback) {
- final Long webViewIdentifier = instanceManager.getIdentifierForStrongReference(webView);
- if (webViewIdentifier == null) {
- throw new IllegalStateException("Could not find identifier for WebView.");
- }
+ webViewFlutterApi.create(webView, reply -> {});
+
+ final Long webViewIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView));
urlLoading(getIdentifierForClient(webViewClient), webViewIdentifier, urlArg, callback);
}
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterApiImpl.java
new file mode 100644
index 0000000..d468cf8
--- /dev/null
+++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewFlutterApiImpl.java
@@ -0,0 +1,59 @@
+// 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.
+
+package io.flutter.plugins.webviewflutter;
+
+import android.webkit.WebView;
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebViewFlutterApi;
+
+/**
+ * Flutter API implementation for `WebView`.
+ *
+ * <p>This class may handle adding native instances that are attached to a Dart instance or passing
+ * arguments of callbacks methods to a Dart instance.
+ */
+public class WebViewFlutterApiImpl {
+ // To ease adding additional methods, this value is added prematurely.
+ @SuppressWarnings({"unused", "FieldCanBeLocal"})
+ private final BinaryMessenger binaryMessenger;
+
+ private final InstanceManager instanceManager;
+ private WebViewFlutterApi api;
+
+ /**
+ * Constructs a {@link WebViewFlutterApiImpl}.
+ *
+ * @param binaryMessenger used to communicate with Dart over asynchronous messages
+ * @param instanceManager maintains instances stored to communicate with attached Dart objects
+ */
+ public WebViewFlutterApiImpl(
+ @NonNull BinaryMessenger binaryMessenger, @NonNull InstanceManager instanceManager) {
+ this.binaryMessenger = binaryMessenger;
+ this.instanceManager = instanceManager;
+ api = new WebViewFlutterApi(binaryMessenger);
+ }
+
+ /**
+ * Stores the `WebView` instance and notifies Dart to create and store a new `WebView` instance
+ * that is attached to this one. If `instance` has already been added, this method does nothing.
+ */
+ public void create(@NonNull WebView instance, @NonNull WebViewFlutterApi.Reply<Void> callback) {
+ if (!instanceManager.containsInstance(instance)) {
+ api.create(instanceManager.addHostCreatedInstance(instance), callback);
+ }
+ }
+
+ /**
+ * Sets the Flutter API used to send messages to Dart.
+ *
+ * <p>This is only visible for testing.
+ */
+ @VisibleForTesting
+ void setApi(@NonNull WebViewFlutterApi api) {
+ this.api = api;
+ }
+}
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebChromeClientTest.java b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebChromeClientTest.java
index e821537..be301fa 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebChromeClientTest.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebChromeClientTest.java
@@ -47,8 +47,6 @@
public void setUp() {
instanceManager = InstanceManager.open(identifier -> {});
- instanceManager.addDartCreatedInstance(mockWebView, 0L);
-
final WebChromeClientCreator webChromeClientCreator =
new WebChromeClientCreator() {
@Override
diff --git a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java
index 3267291..b1cf110 100644
--- a/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java
+++ b/packages/webview_flutter/webview_flutter_android/android/src/test/java/io/flutter/plugins/webviewflutter/WebViewClientTest.java
@@ -43,8 +43,6 @@
public void setUp() {
instanceManager = InstanceManager.open(identifier -> {});
- instanceManager.addDartCreatedInstance(mockWebView, 0L);
-
final WebViewClientCreator webViewClientCreator =
new WebViewClientCreator() {
@Override
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 1721ccd..4a36184 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
@@ -7,6 +7,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -18,6 +19,7 @@
import android.webkit.WebChromeClient;
import android.webkit.WebViewClient;
import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugins.webviewflutter.GeneratedAndroidWebView.WebViewFlutterApi;
import io.flutter.plugins.webviewflutter.WebViewHostApiImpl.WebViewPlatformView;
import java.util.HashMap;
import java.util.Objects;
@@ -314,4 +316,23 @@
assertTrue(destroyCalled[0]);
}
+
+ @Test
+ public void flutterApiCreate() {
+ final InstanceManager instanceManager = InstanceManager.open(identifier -> {});
+
+ final WebViewFlutterApiImpl flutterApiImpl =
+ new WebViewFlutterApiImpl(mockBinaryMessenger, instanceManager);
+
+ final WebViewFlutterApi mockFlutterApi = mock(WebViewFlutterApi.class);
+ flutterApiImpl.setApi(mockFlutterApi);
+
+ flutterApiImpl.create(mockWebView, reply -> {});
+
+ final long instanceIdentifier =
+ Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(mockWebView));
+ verify(mockFlutterApi).create(eq(instanceIdentifier), any());
+
+ instanceManager.close();
+ }
}
diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.g.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.g.dart
index 6c9ba8e..ebfb0cc 100644
--- a/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.g.dart
+++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_webview.g.dart
@@ -944,6 +944,43 @@
}
}
+/// Flutter API for `WebView`.
+///
+/// This class may handle instantiating and adding Dart instances that are
+/// attached to a native instance or receiving callback methods from an
+/// overridden native class.
+///
+/// See https://developer.android.com/reference/android/webkit/WebView.
+abstract class WebViewFlutterApi {
+ static const MessageCodec<Object?> codec = StandardMessageCodec();
+
+ /// Create a new Dart instance and add it to the `InstanceManager`.
+ void create(int identifier);
+
+ static void setup(WebViewFlutterApi? api,
+ {BinaryMessenger? binaryMessenger}) {
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.WebViewFlutterApi.create', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMessageHandler(null);
+ } else {
+ channel.setMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.WebViewFlutterApi.create was null.');
+ final List<Object?> args = (message as List<Object?>?)!;
+ final int? arg_identifier = (args[0] as int?);
+ assert(arg_identifier != null,
+ 'Argument for dev.flutter.pigeon.WebViewFlutterApi.create was null, expected non-null int.');
+ api.create(arg_identifier!);
+ return;
+ });
+ }
+ }
+ }
+}
+
class WebSettingsHostApi {
/// Constructor for [WebSettingsHostApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
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 0db0f04..ce34673 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
@@ -346,6 +346,33 @@
}
}
+/// Flutter API implementation for [WebView].
+///
+/// This class may handle instantiating and adding Dart instances that are
+/// attached to a native instance or receiving callback methods from an
+/// overridden native class.
+class WebViewFlutterApiImpl implements WebViewFlutterApi {
+ /// Constructs a [WebViewFlutterApiImpl].
+ WebViewFlutterApiImpl({
+ this.binaryMessenger,
+ InstanceManager? instanceManager,
+ }) : instanceManager = instanceManager ?? JavaObject.globalInstanceManager;
+
+ /// Receives binary data across the Flutter platform barrier.
+ ///
+ /// If it is null, the default BinaryMessenger will be used which routes to
+ /// the host platform.
+ final BinaryMessenger? binaryMessenger;
+
+ /// Maintains instances stored to communicate with native language objects.
+ final InstanceManager instanceManager;
+
+ @override
+ void create(int identifier) {
+ instanceManager.addHostCreatedInstance(WebView.detached(), identifier);
+ }
+}
+
/// Host api implementation for [WebSettings].
class WebSettingsHostApiImpl extends WebSettingsHostApi {
/// Constructs a [WebSettingsHostApiImpl].
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 b8c22e5..20bc915 100644
--- a/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
+++ b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart
@@ -191,6 +191,19 @@
void setBackgroundColor(int instanceId, int color);
}
+/// Flutter API for `WebView`.
+///
+/// This class may handle instantiating and adding Dart instances that are
+/// attached to a native instance or receiving callback methods from an
+/// overridden native class.
+///
+/// See https://developer.android.com/reference/android/webkit/WebView.
+@FlutterApi()
+abstract class WebViewFlutterApi {
+ /// Create a new Dart instance and add it to the `InstanceManager`.
+ void create(int identifier);
+}
+
@HostApi(dartHostTestHandler: 'TestWebSettingsHostApi')
abstract class WebSettingsHostApi {
void create(int instanceId, int webViewInstanceId);
diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml
index 3217263..d38b866 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/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: 3.4.0
+version: 3.4.1
environment:
sdk: ">=2.17.0 <3.0.0"
diff --git a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart
index 79b5b3f..a618472 100644
--- a/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart
+++ b/packages/webview_flutter/webview_flutter_android/test/android_webview_test.dart
@@ -364,6 +364,24 @@
));
});
+ test('FlutterAPI create', () {
+ final InstanceManager instanceManager = InstanceManager(
+ onWeakReferenceRemoved: (_) {},
+ );
+
+ final WebViewFlutterApiImpl api = WebViewFlutterApiImpl(
+ instanceManager: instanceManager,
+ );
+
+ const int instanceIdentifier = 0;
+ api.create(instanceIdentifier);
+
+ expect(
+ instanceManager.getInstanceWithWeakReference(instanceIdentifier),
+ isA<WebView>(),
+ );
+ });
+
test('copy', () {
expect(webView.copy(), isA<WebView>());
});