diff --git a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md index 953ec4dbfce..abdeecea372 100644 --- a/packages/webview_flutter/webview_flutter_android/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_android/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 3.5.0 +* Adds support for `PlatformNavigationDelegate.onUrlChange`. * Bumps androidx.webkit:webkit from 1.6.0 to 1.6.1. * Fixes common typos in tests and documentation. 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 507c07a70bc..5f26060c72d 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 @@ -1,7 +1,7 @@ // 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. -// Autogenerated from Pigeon (v9.0.5), do not edit directly. +// Autogenerated from Pigeon (v9.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon package io.flutter.plugins.webviewflutter; @@ -22,15 +22,39 @@ import java.util.Map; /** Generated class from Pigeon. */ -@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"}) +@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) public class GeneratedAndroidWebView { + + /** Error class for passing custom error details to Flutter via a thrown PlatformException. */ + public static class FlutterError extends RuntimeException { + + /** The error code. */ + public final String code; + + /** The error details. Must be a datatype supported by the api codec. */ + public final Object details; + + public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) { + super(message); + this.code = code; + this.details = details; + } + } + @NonNull - private static ArrayList wrapError(@NonNull Throwable exception) { + protected static ArrayList wrapError(@NonNull Throwable exception) { ArrayList errorList = new ArrayList(3); - errorList.add(exception.toString()); - errorList.add(exception.getClass().getSimpleName()); - errorList.add( - "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); + if (exception instanceof FlutterError) { + FlutterError error = (FlutterError) exception; + errorList.add(error.code); + errorList.add(error.getMessage()); + errorList.add(error.details); + } else { + errorList.add(exception.toString()); + errorList.add(exception.getClass().getSimpleName()); + errorList.add( + "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); + } return errorList; } @@ -63,7 +87,7 @@ public enum FileChooserMode { */ SAVE(2); - private final int index; + final int index; private FileChooserMode(final int index) { this.index = index; @@ -85,8 +109,8 @@ public void setValue(@NonNull FileChooserMode setterArg) { this.value = setterArg; } - /** Constructor is private to enforce null safety; use Builder. */ - private FileChooserModeEnumData() {} + /** Constructor is non-public to enforce null safety; use Builder. */ + FileChooserModeEnumData() {} public static final class Builder { @@ -196,8 +220,8 @@ public void setRequestHeaders(@NonNull Map setterArg) { this.requestHeaders = setterArg; } - /** Constructor is private to enforce null safety; use Builder. */ - private WebResourceRequestData() {} + /** Constructor is non-public to enforce null safety; use Builder. */ + WebResourceRequestData() {} public static final class Builder { @@ -313,8 +337,8 @@ public void setDescription(@NonNull String setterArg) { this.description = setterArg; } - /** Constructor is private to enforce null safety; use Builder. */ - private WebResourceErrorData() {} + /** Constructor is non-public to enforce null safety; use Builder. */ + WebResourceErrorData() {} public static final class Builder { @@ -389,8 +413,8 @@ public void setY(@NonNull Long setterArg) { this.y = setterArg; } - /** Constructor is private to enforce null safety; use Builder. */ - private WebViewPoint() {} + /** Constructor is non-public to enforce null safety; use Builder. */ + WebViewPoint() {} public static final class Builder { @@ -435,9 +459,10 @@ ArrayList toList() { } public interface Result { + @SuppressWarnings("UnknownNullness") void success(T result); - void error(Throwable error); + void error(@NonNull Throwable error); } /** * Host API for managing the native `InstanceManager`. @@ -453,14 +478,15 @@ public interface InstanceManagerHostApi { void clear(); /** The codec used by InstanceManagerHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `InstanceManagerHostApi` to handle messages through the * `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, InstanceManagerHostApi api) { + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable InstanceManagerHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -472,7 +498,7 @@ static void setup(BinaryMessenger binaryMessenger, InstanceManagerHostApi api) { try { api.clear(); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -498,13 +524,13 @@ public interface JavaObjectHostApi { void dispose(@NonNull Long identifier); /** The codec used by JavaObjectHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `JavaObjectHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, JavaObjectHostApi api) { + static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable JavaObjectHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -513,16 +539,12 @@ static void setup(BinaryMessenger binaryMessenger, JavaObjectHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number identifierArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number identifierArg = (Number) args.get(0); - if (identifierArg == null) { - throw new NullPointerException("identifierArg unexpectedly null."); - } api.dispose((identifierArg == null) ? null : identifierArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -542,22 +564,23 @@ static void setup(BinaryMessenger binaryMessenger, JavaObjectHostApi api) { *

Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class JavaObjectFlutterApi { - private final BinaryMessenger binaryMessenger; + private final @NonNull BinaryMessenger binaryMessenger; - public JavaObjectFlutterApi(BinaryMessenger argBinaryMessenger) { + public JavaObjectFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { this.binaryMessenger = argBinaryMessenger; } /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") public interface Reply { void reply(T reply); } /** The codec used by JavaObjectFlutterApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } - public void dispose(@NonNull Long identifierArg, Reply callback) { + public void dispose(@NonNull Long identifierArg, @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, "dev.flutter.pigeon.JavaObjectFlutterApi.dispose", getCodec()); @@ -569,19 +592,20 @@ public void dispose(@NonNull Long identifierArg, Reply callback) { /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface CookieManagerHostApi { - void clearCookies(Result result); + void clearCookies(@NonNull Result result); void setCookie(@NonNull String url, @NonNull String value); /** The codec used by CookieManagerHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `CookieManagerHostApi` to handle messages through the * `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, CookieManagerHostApi api) { + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable CookieManagerHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -592,25 +616,20 @@ static void setup(BinaryMessenger binaryMessenger, CookieManagerHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); - try { - Result resultCallback = - new Result() { - public void success(Boolean result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.clearCookies(resultCallback); - } catch (Error | RuntimeException exception) { - ArrayList wrappedError = wrapError(exception); - reply.reply(wrappedError); - } + Result resultCallback = + new Result() { + public void success(Boolean result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.clearCookies(resultCallback); }); } else { channel.setMessageHandler(null); @@ -624,20 +643,13 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + String urlArg = (String) args.get(0); + String valueArg = (String) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - String urlArg = (String) args.get(0); - if (urlArg == null) { - throw new NullPointerException("urlArg unexpectedly null."); - } - String valueArg = (String) args.get(1); - if (valueArg == null) { - throw new NullPointerException("valueArg unexpectedly null."); - } api.setCookie(urlArg, valueArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -718,7 +730,7 @@ void loadUrl( void clearCache(@NonNull Long instanceId, @NonNull Boolean includeDiskFiles); void evaluateJavascript( - @NonNull Long instanceId, @NonNull String javascriptString, Result result); + @NonNull Long instanceId, @NonNull String javascriptString, @NonNull Result result); @Nullable String getTitle(@NonNull Long instanceId); @@ -752,11 +764,11 @@ void removeJavaScriptChannel( void setBackgroundColor(@NonNull Long instanceId, @NonNull Long color); /** The codec used by WebViewHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return WebViewHostApiCodec.INSTANCE; } /** Sets up an instance of `WebViewHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { + static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable WebViewHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -765,16 +777,12 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.create((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -792,26 +800,19 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + String dataArg = (String) args.get(1); + String mimeTypeArg = (String) args.get(2); + String encodingArg = (String) args.get(3); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - String dataArg = (String) args.get(1); - if (dataArg == null) { - throw new NullPointerException("dataArg unexpectedly null."); - } - String mimeTypeArg = (String) args.get(2); - String encodingArg = (String) args.get(3); api.loadData( (instanceIdArg == null) ? null : instanceIdArg.longValue(), dataArg, mimeTypeArg, encodingArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -831,21 +832,14 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + String baseUrlArg = (String) args.get(1); + String dataArg = (String) args.get(2); + String mimeTypeArg = (String) args.get(3); + String encodingArg = (String) args.get(4); + String historyUrlArg = (String) args.get(5); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - String baseUrlArg = (String) args.get(1); - String dataArg = (String) args.get(2); - if (dataArg == null) { - throw new NullPointerException("dataArg unexpectedly null."); - } - String mimeTypeArg = (String) args.get(3); - String encodingArg = (String) args.get(4); - String historyUrlArg = (String) args.get(5); api.loadDataWithBaseUrl( (instanceIdArg == null) ? null : instanceIdArg.longValue(), baseUrlArg, @@ -854,7 +848,7 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { encodingArg, historyUrlArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -872,27 +866,17 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + String urlArg = (String) args.get(1); + Map headersArg = (Map) args.get(2); try { - ArrayList args = (ArrayList) message; - assert args != null; - 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."); - } - Map headersArg = (Map) args.get(2); - if (headersArg == null) { - throw new NullPointerException("headersArg unexpectedly null."); - } api.loadUrl( (instanceIdArg == null) ? null : instanceIdArg.longValue(), urlArg, headersArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -910,25 +894,15 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + String urlArg = (String) args.get(1); + byte[] dataArg = (byte[]) args.get(2); try { - ArrayList args = (ArrayList) message; - assert args != null; - 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 == null) ? null : instanceIdArg.longValue(), urlArg, dataArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -946,17 +920,13 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } String output = api.getUrl((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -974,17 +944,13 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } Boolean output = api.canGoBack((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1002,17 +968,13 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } Boolean output = api.canGoForward((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1030,16 +992,12 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.goBack((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1057,16 +1015,12 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.goForward((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1084,16 +1038,12 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.reload((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1111,22 +1061,15 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean includeDiskFilesArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean includeDiskFilesArg = (Boolean) args.get(1); - if (includeDiskFilesArg == null) { - throw new NullPointerException("includeDiskFilesArg unexpectedly null."); - } api.clearCache( (instanceIdArg == null) ? null : instanceIdArg.longValue(), includeDiskFilesArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1146,38 +1089,26 @@ static void setup(BinaryMessenger binaryMessenger, WebViewHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); - try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - String javascriptStringArg = (String) args.get(1); - if (javascriptStringArg == null) { - throw new NullPointerException("javascriptStringArg unexpectedly null."); - } - Result resultCallback = - new Result() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.evaluateJavascript( - (instanceIdArg == null) ? null : instanceIdArg.longValue(), - javascriptStringArg, - resultCallback); - } catch (Error | RuntimeException exception) { - ArrayList wrappedError = wrapError(exception); - reply.reply(wrappedError); - } + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + String javascriptStringArg = (String) args.get(1); + Result resultCallback = + new Result() { + public void success(String result) { + wrapped.add(0, result); + reply.reply(wrapped); + } + + public void error(Throwable error) { + ArrayList wrappedError = wrapError(error); + reply.reply(wrappedError); + } + }; + + api.evaluateJavascript( + (instanceIdArg == null) ? null : instanceIdArg.longValue(), + javascriptStringArg, + resultCallback); }); } else { channel.setMessageHandler(null); @@ -1191,17 +1122,13 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } String output = api.getTitle((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1219,27 +1146,17 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number xArg = (Number) args.get(1); + Number yArg = (Number) args.get(2); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number xArg = (Number) args.get(1); - if (xArg == null) { - throw new NullPointerException("xArg unexpectedly null."); - } - Number yArg = (Number) args.get(2); - if (yArg == null) { - throw new NullPointerException("yArg unexpectedly null."); - } api.scrollTo( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (xArg == null) ? null : xArg.longValue(), (yArg == null) ? null : yArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1257,27 +1174,17 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number xArg = (Number) args.get(1); + Number yArg = (Number) args.get(2); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number xArg = (Number) args.get(1); - if (xArg == null) { - throw new NullPointerException("xArg unexpectedly null."); - } - Number yArg = (Number) args.get(2); - if (yArg == null) { - throw new NullPointerException("yArg unexpectedly null."); - } api.scrollBy( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (xArg == null) ? null : xArg.longValue(), (yArg == null) ? null : yArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1295,17 +1202,13 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } Long output = api.getScrollX((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1323,17 +1226,13 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } Long output = api.getScrollY((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1351,18 +1250,14 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } WebViewPoint output = api.getScrollPosition( (instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1382,16 +1277,12 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Boolean enabledArg = (Boolean) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Boolean enabledArg = (Boolean) args.get(0); - if (enabledArg == null) { - throw new NullPointerException("enabledArg unexpectedly null."); - } api.setWebContentsDebuggingEnabled(enabledArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1409,24 +1300,17 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number webViewClientInstanceIdArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number webViewClientInstanceIdArg = (Number) args.get(1); - if (webViewClientInstanceIdArg == null) { - throw new NullPointerException("webViewClientInstanceIdArg unexpectedly null."); - } api.setWebViewClient( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (webViewClientInstanceIdArg == null) ? null : webViewClientInstanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1446,25 +1330,17 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number javaScriptChannelInstanceIdArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number javaScriptChannelInstanceIdArg = (Number) args.get(1); - if (javaScriptChannelInstanceIdArg == null) { - throw new NullPointerException( - "javaScriptChannelInstanceIdArg unexpectedly null."); - } api.addJavaScriptChannel( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (javaScriptChannelInstanceIdArg == null) ? null : javaScriptChannelInstanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1484,25 +1360,17 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number javaScriptChannelInstanceIdArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number javaScriptChannelInstanceIdArg = (Number) args.get(1); - if (javaScriptChannelInstanceIdArg == null) { - throw new NullPointerException( - "javaScriptChannelInstanceIdArg unexpectedly null."); - } api.removeJavaScriptChannel( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (javaScriptChannelInstanceIdArg == null) ? null : javaScriptChannelInstanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1522,19 +1390,15 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number listenerInstanceIdArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number listenerInstanceIdArg = (Number) args.get(1); api.setDownloadListener( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (listenerInstanceIdArg == null) ? null : listenerInstanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1554,19 +1418,15 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number clientInstanceIdArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number clientInstanceIdArg = (Number) args.get(1); api.setWebChromeClient( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (clientInstanceIdArg == null) ? null : clientInstanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1586,22 +1446,15 @@ public void error(Throwable error) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number colorArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number colorArg = (Number) args.get(1); - if (colorArg == null) { - throw new NullPointerException("colorArg unexpectedly null."); - } api.setBackgroundColor( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (colorArg == null) ? null : colorArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1624,22 +1477,23 @@ public void error(Throwable error) { *

Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class WebViewFlutterApi { - private final BinaryMessenger binaryMessenger; + private final @NonNull BinaryMessenger binaryMessenger; - public WebViewFlutterApi(BinaryMessenger argBinaryMessenger) { + public WebViewFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { this.binaryMessenger = argBinaryMessenger; } /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") public interface Reply { void reply(T reply); } /** The codec used by WebViewFlutterApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** Create a new Dart instance and add it to the `InstanceManager`. */ - public void create(@NonNull Long identifierArg, Reply callback) { + public void create(@NonNull Long identifierArg, @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, "dev.flutter.pigeon.WebViewFlutterApi.create", getCodec()); @@ -1680,13 +1534,13 @@ public interface WebSettingsHostApi { void setTextZoom(@NonNull Long instanceId, @NonNull Long textZoom); /** The codec used by WebSettingsHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `WebSettingsHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { + static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable WebSettingsHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -1695,22 +1549,15 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number webViewInstanceIdArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number webViewInstanceIdArg = (Number) args.get(1); - if (webViewInstanceIdArg == null) { - throw new NullPointerException("webViewInstanceIdArg unexpectedly null."); - } api.create( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (webViewInstanceIdArg == null) ? null : webViewInstanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1730,21 +1577,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean flagArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean flagArg = (Boolean) args.get(1); - if (flagArg == null) { - throw new NullPointerException("flagArg unexpectedly null."); - } api.setDomStorageEnabled( (instanceIdArg == null) ? null : instanceIdArg.longValue(), flagArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1764,21 +1604,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean flagArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean flagArg = (Boolean) args.get(1); - if (flagArg == null) { - throw new NullPointerException("flagArg unexpectedly null."); - } api.setJavaScriptCanOpenWindowsAutomatically( (instanceIdArg == null) ? null : instanceIdArg.longValue(), flagArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1798,21 +1631,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean supportArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean supportArg = (Boolean) args.get(1); - if (supportArg == null) { - throw new NullPointerException("supportArg unexpectedly null."); - } api.setSupportMultipleWindows( (instanceIdArg == null) ? null : instanceIdArg.longValue(), supportArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1832,21 +1658,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean flagArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean flagArg = (Boolean) args.get(1); - if (flagArg == null) { - throw new NullPointerException("flagArg unexpectedly null."); - } api.setJavaScriptEnabled( (instanceIdArg == null) ? null : instanceIdArg.longValue(), flagArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1866,19 +1685,15 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + String userAgentStringArg = (String) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - String userAgentStringArg = (String) args.get(1); api.setUserAgentString( (instanceIdArg == null) ? null : instanceIdArg.longValue(), userAgentStringArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1898,21 +1713,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean requireArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean requireArg = (Boolean) args.get(1); - if (requireArg == null) { - throw new NullPointerException("requireArg unexpectedly null."); - } api.setMediaPlaybackRequiresUserGesture( (instanceIdArg == null) ? null : instanceIdArg.longValue(), requireArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1932,21 +1740,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean supportArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean supportArg = (Boolean) args.get(1); - if (supportArg == null) { - throw new NullPointerException("supportArg unexpectedly null."); - } api.setSupportZoom( (instanceIdArg == null) ? null : instanceIdArg.longValue(), supportArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -1966,21 +1767,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean overviewArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean overviewArg = (Boolean) args.get(1); - if (overviewArg == null) { - throw new NullPointerException("overviewArg unexpectedly null."); - } api.setLoadWithOverviewMode( (instanceIdArg == null) ? null : instanceIdArg.longValue(), overviewArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2000,21 +1794,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean useArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean useArg = (Boolean) args.get(1); - if (useArg == null) { - throw new NullPointerException("useArg unexpectedly null."); - } api.setUseWideViewPort( (instanceIdArg == null) ? null : instanceIdArg.longValue(), useArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2034,21 +1821,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean enabledArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean enabledArg = (Boolean) args.get(1); - if (enabledArg == null) { - throw new NullPointerException("enabledArg unexpectedly null."); - } api.setDisplayZoomControls( (instanceIdArg == null) ? null : instanceIdArg.longValue(), enabledArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2068,21 +1848,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean enabledArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean enabledArg = (Boolean) args.get(1); - if (enabledArg == null) { - throw new NullPointerException("enabledArg unexpectedly null."); - } api.setBuiltInZoomControls( (instanceIdArg == null) ? null : instanceIdArg.longValue(), enabledArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2102,21 +1875,14 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean enabledArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean enabledArg = (Boolean) args.get(1); - if (enabledArg == null) { - throw new NullPointerException("enabledArg unexpectedly null."); - } api.setAllowFileAccess( (instanceIdArg == null) ? null : instanceIdArg.longValue(), enabledArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2134,22 +1900,15 @@ static void setup(BinaryMessenger binaryMessenger, WebSettingsHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Number textZoomArg = (Number) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Number textZoomArg = (Number) args.get(1); - if (textZoomArg == null) { - throw new NullPointerException("textZoomArg unexpectedly null."); - } api.setTextZoom( (instanceIdArg == null) ? null : instanceIdArg.longValue(), (textZoomArg == null) ? null : textZoomArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2167,14 +1926,15 @@ public interface JavaScriptChannelHostApi { void create(@NonNull Long instanceId, @NonNull String channelName); /** The codec used by JavaScriptChannelHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `JavaScriptChannelHostApi` to handle messages through the * `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, JavaScriptChannelHostApi api) { + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable JavaScriptChannelHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -2183,21 +1943,14 @@ static void setup(BinaryMessenger binaryMessenger, JavaScriptChannelHostApi api) channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + String channelNameArg = (String) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - String channelNameArg = (String) args.get(1); - if (channelNameArg == null) { - throw new NullPointerException("channelNameArg unexpectedly null."); - } api.create( (instanceIdArg == null) ? null : instanceIdArg.longValue(), channelNameArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2211,23 +1964,24 @@ static void setup(BinaryMessenger binaryMessenger, JavaScriptChannelHostApi api) } /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class JavaScriptChannelFlutterApi { - private final BinaryMessenger binaryMessenger; + private final @NonNull BinaryMessenger binaryMessenger; - public JavaScriptChannelFlutterApi(BinaryMessenger argBinaryMessenger) { + public JavaScriptChannelFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { this.binaryMessenger = argBinaryMessenger; } /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") public interface Reply { void reply(T reply); } /** The codec used by JavaScriptChannelFlutterApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } public void postMessage( - @NonNull Long instanceIdArg, @NonNull String messageArg, Reply callback) { + @NonNull Long instanceIdArg, @NonNull String messageArg, @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2247,14 +2001,15 @@ void setSynchronousReturnValueForShouldOverrideUrlLoading( @NonNull Long instanceId, @NonNull Boolean value); /** The codec used by WebViewClientHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `WebViewClientHostApi` to handle messages through the * `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, WebViewClientHostApi api) { + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable WebViewClientHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -2263,16 +2018,12 @@ static void setup(BinaryMessenger binaryMessenger, WebViewClientHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.create((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2292,21 +2043,14 @@ static void setup(BinaryMessenger binaryMessenger, WebViewClientHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean valueArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean valueArg = (Boolean) args.get(1); - if (valueArg == null) { - throw new NullPointerException("valueArg unexpectedly null."); - } api.setSynchronousReturnValueForShouldOverrideUrlLoading( (instanceIdArg == null) ? null : instanceIdArg.longValue(), valueArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2352,18 +2096,19 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class WebViewClientFlutterApi { - private final BinaryMessenger binaryMessenger; + private final @NonNull BinaryMessenger binaryMessenger; - public WebViewClientFlutterApi(BinaryMessenger argBinaryMessenger) { + public WebViewClientFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { this.binaryMessenger = argBinaryMessenger; } /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") public interface Reply { void reply(T reply); } /** The codec used by WebViewClientFlutterApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return WebViewClientFlutterApiCodec.INSTANCE; } @@ -2371,7 +2116,7 @@ public void onPageStarted( @NonNull Long instanceIdArg, @NonNull Long webViewInstanceIdArg, @NonNull String urlArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2386,7 +2131,7 @@ public void onPageFinished( @NonNull Long instanceIdArg, @NonNull Long webViewInstanceIdArg, @NonNull String urlArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2402,7 +2147,7 @@ public void onReceivedRequestError( @NonNull Long webViewInstanceIdArg, @NonNull WebResourceRequestData requestArg, @NonNull WebResourceErrorData errorArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2420,7 +2165,7 @@ public void onReceivedError( @NonNull Long errorCodeArg, @NonNull String descriptionArg, @NonNull String failingUrlArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2441,7 +2186,7 @@ public void requestLoading( @NonNull Long instanceIdArg, @NonNull Long webViewInstanceIdArg, @NonNull WebResourceRequestData requestArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2456,7 +2201,7 @@ public void urlLoading( @NonNull Long instanceIdArg, @NonNull Long webViewInstanceIdArg, @NonNull String urlArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, "dev.flutter.pigeon.WebViewClientFlutterApi.urlLoading", getCodec()); @@ -2464,6 +2209,23 @@ public void urlLoading( new ArrayList(Arrays.asList(instanceIdArg, webViewInstanceIdArg, urlArg)), channelReply -> callback.reply(null)); } + + public void doUpdateVisitedHistory( + @NonNull Long instanceIdArg, + @NonNull Long webViewInstanceIdArg, + @NonNull String urlArg, + @NonNull Boolean isReloadArg, + @NonNull Reply callback) { + BasicMessageChannel channel = + new BasicMessageChannel<>( + binaryMessenger, + "dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory", + getCodec()); + channel.send( + new ArrayList( + Arrays.asList(instanceIdArg, webViewInstanceIdArg, urlArg, isReloadArg)), + channelReply -> callback.reply(null)); + } } /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ public interface DownloadListenerHostApi { @@ -2471,14 +2233,15 @@ public interface DownloadListenerHostApi { void create(@NonNull Long instanceId); /** The codec used by DownloadListenerHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `DownloadListenerHostApi` to handle messages through the * `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, DownloadListenerHostApi api) { + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable DownloadListenerHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -2487,16 +2250,12 @@ static void setup(BinaryMessenger binaryMessenger, DownloadListenerHostApi api) channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.create((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2510,18 +2269,19 @@ static void setup(BinaryMessenger binaryMessenger, DownloadListenerHostApi api) } /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class DownloadListenerFlutterApi { - private final BinaryMessenger binaryMessenger; + private final @NonNull BinaryMessenger binaryMessenger; - public DownloadListenerFlutterApi(BinaryMessenger argBinaryMessenger) { + public DownloadListenerFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { this.binaryMessenger = argBinaryMessenger; } /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") public interface Reply { void reply(T reply); } /** The codec used by DownloadListenerFlutterApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } @@ -2532,7 +2292,7 @@ public void onDownloadStart( @NonNull String contentDispositionArg, @NonNull String mimetypeArg, @NonNull Long contentLengthArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2559,14 +2319,15 @@ void setSynchronousReturnValueForOnShowFileChooser( @NonNull Long instanceId, @NonNull Boolean value); /** The codec used by WebChromeClientHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `WebChromeClientHostApi` to handle messages through the * `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, WebChromeClientHostApi api) { + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable WebChromeClientHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -2575,16 +2336,12 @@ static void setup(BinaryMessenger binaryMessenger, WebChromeClientHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.create((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2604,21 +2361,14 @@ static void setup(BinaryMessenger binaryMessenger, WebChromeClientHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); + Boolean valueArg = (Boolean) args.get(1); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } - Boolean valueArg = (Boolean) args.get(1); - if (valueArg == null) { - throw new NullPointerException("valueArg unexpectedly null."); - } api.setSynchronousReturnValueForOnShowFileChooser( (instanceIdArg == null) ? null : instanceIdArg.longValue(), valueArg); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2640,14 +2390,15 @@ public interface FlutterAssetManagerHostApi { String getAssetFilePathByName(@NonNull String name); /** The codec used by FlutterAssetManagerHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `FlutterAssetManagerHostApi` to handle messages through the * `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, FlutterAssetManagerHostApi api) { + static void setup( + @NonNull BinaryMessenger binaryMessenger, @Nullable FlutterAssetManagerHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -2656,16 +2407,12 @@ static void setup(BinaryMessenger binaryMessenger, FlutterAssetManagerHostApi ap channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + String pathArg = (String) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - String pathArg = (String) args.get(0); - if (pathArg == null) { - throw new NullPointerException("pathArg unexpectedly null."); - } List output = api.list(pathArg); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2685,16 +2432,12 @@ static void setup(BinaryMessenger binaryMessenger, FlutterAssetManagerHostApi ap channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + String nameArg = (String) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - String nameArg = (String) args.get(0); - if (nameArg == null) { - throw new NullPointerException("nameArg unexpectedly null."); - } String output = api.getAssetFilePathByName(nameArg); wrapped.add(0, output); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2708,18 +2451,19 @@ static void setup(BinaryMessenger binaryMessenger, FlutterAssetManagerHostApi ap } /** Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class WebChromeClientFlutterApi { - private final BinaryMessenger binaryMessenger; + private final @NonNull BinaryMessenger binaryMessenger; - public WebChromeClientFlutterApi(BinaryMessenger argBinaryMessenger) { + public WebChromeClientFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { this.binaryMessenger = argBinaryMessenger; } /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") public interface Reply { void reply(T reply); } /** The codec used by WebChromeClientFlutterApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } @@ -2727,7 +2471,7 @@ public void onProgressChanged( @NonNull Long instanceIdArg, @NonNull Long webViewInstanceIdArg, @NonNull Long progressArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2742,7 +2486,7 @@ public void onShowFileChooser( @NonNull Long instanceIdArg, @NonNull Long webViewInstanceIdArg, @NonNull Long paramsInstanceIdArg, - Reply> callback) { + @NonNull Reply> callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, @@ -2766,13 +2510,13 @@ public interface WebStorageHostApi { void deleteAllData(@NonNull Long instanceId); /** The codec used by WebStorageHostApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return new StandardMessageCodec(); } /** * Sets up an instance of `WebStorageHostApi` to handle messages through the `binaryMessenger`. */ - static void setup(BinaryMessenger binaryMessenger, WebStorageHostApi api) { + static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable WebStorageHostApi api) { { BasicMessageChannel channel = new BasicMessageChannel<>( @@ -2781,16 +2525,12 @@ static void setup(BinaryMessenger binaryMessenger, WebStorageHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.create((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2808,16 +2548,12 @@ static void setup(BinaryMessenger binaryMessenger, WebStorageHostApi api) { channel.setMessageHandler( (message, reply) -> { ArrayList wrapped = new ArrayList(); + ArrayList args = (ArrayList) message; + Number instanceIdArg = (Number) args.get(0); try { - ArrayList args = (ArrayList) message; - assert args != null; - Number instanceIdArg = (Number) args.get(0); - if (instanceIdArg == null) { - throw new NullPointerException("instanceIdArg unexpectedly null."); - } api.deleteAllData((instanceIdArg == null) ? null : instanceIdArg.longValue()); wrapped.add(0, null); - } catch (Error | RuntimeException exception) { + } catch (Throwable exception) { ArrayList wrappedError = wrapError(exception); wrapped = wrappedError; } @@ -2866,18 +2602,19 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { *

Generated class from Pigeon that represents Flutter messages that can be called from Java. */ public static class FileChooserParamsFlutterApi { - private final BinaryMessenger binaryMessenger; + private final @NonNull BinaryMessenger binaryMessenger; - public FileChooserParamsFlutterApi(BinaryMessenger argBinaryMessenger) { + public FileChooserParamsFlutterApi(@NonNull BinaryMessenger argBinaryMessenger) { this.binaryMessenger = argBinaryMessenger; } /** Public interface for sending reply. */ + @SuppressWarnings("UnknownNullness") public interface Reply { void reply(T reply); } /** The codec used by FileChooserParamsFlutterApi. */ - static MessageCodec getCodec() { + static @NonNull MessageCodec getCodec() { return FileChooserParamsFlutterApiCodec.INSTANCE; } @@ -2887,7 +2624,7 @@ public void create( @NonNull List acceptTypesArg, @NonNull FileChooserModeEnumData modeArg, @Nullable String filenameHintArg, - Reply callback) { + @NonNull Reply callback) { BasicMessageChannel channel = new BasicMessageChannel<>( binaryMessenger, "dev.flutter.pigeon.FileChooserParamsFlutterApi.create", getCodec()); 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 aad569dc47c..6893af953df 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 @@ -10,6 +10,7 @@ import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; +import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.webkit.WebResourceErrorCompat; import io.flutter.plugin.common.BinaryMessenger; @@ -202,6 +203,21 @@ public void urlLoading( urlLoading(getIdentifierForClient(webViewClient), webViewIdentifier, urlArg, callback); } + /** Passes arguments from {@link WebViewClient#doUpdateVisitedHistory} to Dart. */ + public void doUpdateVisitedHistory( + @NonNull WebViewClient webViewClient, + @NonNull WebView webView, + @NonNull String url, + boolean isReload, + @NonNull Reply callback) { + webViewFlutterApi.create(webView, reply -> {}); + + final Long webViewIdentifier = + Objects.requireNonNull(instanceManager.getIdentifierForStrongReference(webView)); + doUpdateVisitedHistory( + getIdentifierForClient(webViewClient), webViewIdentifier, url, isReload, callback); + } + private long getIdentifierForClient(WebViewClient webViewClient) { final Long identifier = instanceManager.getIdentifierForStrongReference(webViewClient); if (identifier == null) { diff --git a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java index 79c0210ec56..b5764f4ac8f 100644 --- a/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java +++ b/packages/webview_flutter/webview_flutter_android/android/src/main/java/io/flutter/plugins/webviewflutter/WebViewClientHostApiImpl.java @@ -82,6 +82,11 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { return returnValueForShouldOverrideUrlLoading; } + @Override + public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) { + flutterApi.doUpdateVisitedHistory(this, view, url, isReload, reply -> {}); + } + @Override public void onUnhandledKeyEvent(WebView view, KeyEvent event) { // Deliberately empty. Occasionally the webview will mark events as having failed to be @@ -155,7 +160,12 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { } @Override - public void onUnhandledKeyEvent(WebView view, KeyEvent event) { + public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) { + flutterApi.doUpdateVisitedHistory(this, view, url, isReload, reply -> {}); + } + + @Override + public void onUnhandledKeyEvent(@NonNull WebView view, @NonNull KeyEvent event) { // Deliberately empty. Occasionally the webview will mark events as having failed to be // handled even though they were handled. We don't want to propagate those as they're not // truly lost. @@ -175,7 +185,8 @@ public static class WebViewClientCreator { * @param flutterApi handles sending messages to Dart * @return the created {@link WebViewClient} */ - public WebViewClient createWebViewClient(WebViewClientFlutterApiImpl flutterApi) { + @NonNull + public WebViewClient createWebViewClient(@NonNull WebViewClientFlutterApiImpl flutterApi) { // WebViewClientCompat is used to get // shouldOverrideUrlLoading(WebView view, WebResourceRequest request) // invoked by the webview on older Android devices, without it pages that use iframes will 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 f9e836e4510..2462ef392eb 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 @@ -15,6 +15,7 @@ import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; +import androidx.annotation.NonNull; import io.flutter.plugins.webviewflutter.WebViewClientHostApiImpl.WebViewClientCompatImpl; import io.flutter.plugins.webviewflutter.WebViewClientHostApiImpl.WebViewClientCreator; import java.util.HashMap; @@ -111,8 +112,10 @@ public void setReturnValueForShouldOverrideUrlLoading() { new WebViewClientHostApiImpl( instanceManager, new WebViewClientCreator() { + @NonNull @Override - public WebViewClient createWebViewClient(WebViewClientFlutterApiImpl flutterApi) { + public WebViewClient createWebViewClient( + @NonNull WebViewClientFlutterApiImpl flutterApi) { return mockWebViewClient; } }, @@ -123,4 +126,12 @@ public WebViewClient createWebViewClient(WebViewClientFlutterApiImpl flutterApi) verify(mockWebViewClient).setReturnValueForShouldOverrideUrlLoading(false); } + + @Test + public void doUpdateVisitedHistory() { + webViewClient.doUpdateVisitedHistory(mockWebView, "https://www.google.com", true); + verify(mockFlutterApi) + .doUpdateVisitedHistory( + eq(webViewClient), eq(mockWebView), eq("https://www.google.com"), eq(true), any()); + } } diff --git a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart index 4ec7ae829e6..188687b6231 100644 --- a/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_android/example/integration_test/webview_flutter_test.dart @@ -942,6 +942,81 @@ Future main() async { final String? currentUrl = await controller.currentUrl(); expect(currentUrl, secondaryUrl); }); + + testWidgets('can receive url changes', (WidgetTester tester) async { + final Completer pageLoaded = Completer(); + + final PlatformNavigationDelegate navigationDelegate = + PlatformNavigationDelegate( + const PlatformNavigationDelegateCreationParams(), + )..setOnPageFinished((_) => pageLoaded.complete()); + + final PlatformWebViewController controller = PlatformWebViewController( + const PlatformWebViewControllerCreationParams(), + ) + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setPlatformNavigationDelegate(navigationDelegate) + ..loadRequest(LoadRequestParams(uri: Uri.parse(blankPageEncoded))); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) { + return PlatformWebViewWidget( + PlatformWebViewWidgetCreationParams(controller: controller), + ).build(context); + }, + )); + + await pageLoaded.future; + await navigationDelegate.setOnPageFinished((_) {}); + + final Completer urlChangeCompleter = Completer(); + await navigationDelegate.setOnUrlChange((UrlChange change) { + urlChangeCompleter.complete(change.url); + }); + + await controller.runJavaScript('location.href = "$primaryUrl"'); + + await expectLater(urlChangeCompleter.future, completion(primaryUrl)); + }); + + testWidgets('can receive updates to history state', + (WidgetTester tester) async { + final Completer pageLoaded = Completer(); + + final PlatformNavigationDelegate navigationDelegate = + PlatformNavigationDelegate( + const PlatformNavigationDelegateCreationParams(), + )..setOnPageFinished((_) => pageLoaded.complete()); + + final PlatformWebViewController controller = PlatformWebViewController( + const PlatformWebViewControllerCreationParams(), + ) + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setPlatformNavigationDelegate(navigationDelegate) + ..loadRequest(LoadRequestParams(uri: Uri.parse(primaryUrl))); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) { + return PlatformWebViewWidget( + PlatformWebViewWidgetCreationParams(controller: controller), + ).build(context); + }, + )); + + await pageLoaded.future; + await navigationDelegate.setOnPageFinished((_) {}); + + final Completer urlChangeCompleter = Completer(); + await navigationDelegate.setOnUrlChange((UrlChange change) { + urlChangeCompleter.complete(change.url); + }); + + await controller.runJavaScript( + 'window.history.pushState({}, "", "secondary.txt");', + ); + + await expectLater(urlChangeCompleter.future, completion(secondaryUrl)); + }); }); testWidgets('target _blank opens in same window', 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 3c6a51418f6..b8c9f7bc8cb 100644 --- a/packages/webview_flutter/webview_flutter_android/example/lib/main.dart +++ b/packages/webview_flutter/webview_flutter_android/example/lib/main.dart @@ -123,6 +123,9 @@ Page resource error: } debugPrint('allowing navigation to ${request.url}'); return NavigationDecision.navigate; + }) + ..setOnUrlChange((UrlChange change) { + debugPrint('url change to ${change.url}'); }), ) ..addJavaScriptChannel(JavaScriptChannelParams( diff --git a/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml index 83f3f00312f..8a190ff22eb 100644 --- a/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_android/example/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - webview_flutter_platform_interface: ^2.0.0 + webview_flutter_platform_interface: ^2.1.0 dev_dependencies: espresso: ^0.2.0 diff --git a/packages/webview_flutter/webview_flutter_android/lib/src/android_proxy.dart b/packages/webview_flutter/webview_flutter_android/lib/src/android_proxy.dart index a6505c21b2b..0d716220b05 100644 --- a/packages/webview_flutter/webview_flutter_android/lib/src/android_proxy.dart +++ b/packages/webview_flutter/webview_flutter_android/lib/src/android_proxy.dart @@ -58,6 +58,8 @@ class AndroidWebViewProxy { android_webview.WebResourceRequest request, )? requestLoading, void Function(android_webview.WebView webView, String url)? urlLoading, + void Function(android_webview.WebView webView, String url, bool isReload)? + doUpdateVisitedHistory, }) createAndroidWebViewClient; /// Constructs a [android_webview.FlutterAssetManager]. 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 5c552093e09..8ab89d4b875 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 @@ -677,6 +677,7 @@ class WebViewClient extends JavaObject { @Deprecated('Only called on Android version < 23.') this.onReceivedError, this.requestLoading, this.urlLoading, + this.doUpdateVisitedHistory, @visibleForTesting super.binaryMessenger, @visibleForTesting super.instanceManager, }) : super.detached() { @@ -696,6 +697,7 @@ class WebViewClient extends JavaObject { @Deprecated('Only called on Android version < 23.') this.onReceivedError, this.requestLoading, this.urlLoading, + this.doUpdateVisitedHistory, super.binaryMessenger, super.instanceManager, }) : super.detached(); @@ -840,6 +842,10 @@ class WebViewClient extends JavaObject { /// indicates whether the [WebView] loaded the URL. final void Function(WebView webView, String url)? urlLoading; + /// Notify the host application to update its visited links database. + final void Function(WebView webView, String url, bool isReload)? + doUpdateVisitedHistory; + /// Sets the required synchronous return value for the Java method, /// `WebViewClient.shouldOverrideUrlLoading(...)`. /// @@ -867,6 +873,7 @@ class WebViewClient extends JavaObject { onReceivedError: onReceivedError, requestLoading: requestLoading, urlLoading: urlLoading, + doUpdateVisitedHistory: doUpdateVisitedHistory, binaryMessenger: _api.binaryMessenger, instanceManager: _api.instanceManager, ); 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 d2976a86a8e..652928489ec 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 @@ -1,7 +1,7 @@ // 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. -// Autogenerated from Pigeon (v9.0.5), do not edit directly. +// Autogenerated from Pigeon (v9.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import @@ -1514,6 +1514,9 @@ abstract class WebViewClientFlutterApi { void urlLoading(int instanceId, int webViewInstanceId, String url); + void doUpdateVisitedHistory( + int instanceId, int webViewInstanceId, String url, bool isReload); + static void setup(WebViewClientFlutterApi? api, {BinaryMessenger? binaryMessenger}) { { @@ -1682,6 +1685,36 @@ abstract class WebViewClientFlutterApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null.'); + final List args = (message as List?)!; + final int? arg_instanceId = (args[0] as int?); + assert(arg_instanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null int.'); + final int? arg_webViewInstanceId = (args[1] as int?); + assert(arg_webViewInstanceId != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null int.'); + final String? arg_url = (args[2] as String?); + assert(arg_url != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null String.'); + final bool? arg_isReload = (args[3] as bool?); + assert(arg_isReload != null, + 'Argument for dev.flutter.pigeon.WebViewClientFlutterApi.doUpdateVisitedHistory was null, expected non-null bool.'); + api.doUpdateVisitedHistory( + arg_instanceId!, arg_webViewInstanceId!, arg_url!, arg_isReload!); + return; + }); + } + } } } 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 721caf7b9d0..0bc2c84c409 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 @@ -754,6 +754,30 @@ class WebViewClientFlutterApiImpl extends WebViewClientFlutterApi { instance.urlLoading!(webViewInstance!, url); } } + + @override + void doUpdateVisitedHistory( + int instanceId, + int webViewInstanceId, + String url, + bool isReload, + ) { + final WebViewClient? instance = instanceManager + .getInstanceWithWeakReference(instanceId) as WebViewClient?; + final WebView? webViewInstance = instanceManager + .getInstanceWithWeakReference(webViewInstanceId) as WebView?; + assert( + instance != null, + 'InstanceManager does not contain an WebViewClient with instanceId: $instanceId', + ); + assert( + webViewInstance != null, + 'InstanceManager does not contain an WebView with instanceId: $webViewInstanceId', + ); + if (instance!.doUpdateVisitedHistory != null) { + instance.doUpdateVisitedHistory!(webViewInstance!, url, isReload); + } + } } /// Host api implementation for [DownloadListener]. 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 f1fe1680f36..88a4bca84ab 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 @@ -704,6 +704,15 @@ class AndroidNavigationDelegateCreationParams final AndroidWebViewProxy androidWebViewProxy; } +/// Android details of the change to a web view's url. +class AndroidUrlChange extends UrlChange { + /// Constructs an [AndroidUrlChange]. + const AndroidUrlChange({required super.url, required this.isReload}); + + /// Whether the url is being reloaded. + final bool isReload; +} + /// A place to register callback methods responsible to handle navigation events /// triggered by the [android_webview.WebView]. class AndroidNavigationDelegate extends PlatformNavigationDelegate { @@ -720,13 +729,15 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate { .androidWebViewProxy .createAndroidWebViewClient( onPageFinished: (android_webview.WebView webView, String url) { - if (weakThis.target?._onPageFinished != null) { - weakThis.target!._onPageFinished!(url); + final PageEventCallback? callback = weakThis.target?._onPageFinished; + if (callback != null) { + callback(url); } }, onPageStarted: (android_webview.WebView webView, String url) { - if (weakThis.target?._onPageStarted != null) { - weakThis.target!._onPageStarted!(url); + final PageEventCallback? callback = weakThis.target?._onPageStarted; + if (callback != null) { + callback(url); } }, onReceivedRequestError: ( @@ -734,8 +745,10 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate { android_webview.WebResourceRequest request, android_webview.WebResourceError error, ) { - if (weakThis.target?._onWebResourceError != null) { - weakThis.target!._onWebResourceError!(AndroidWebResourceError._( + final WebResourceErrorCallback? callback = + weakThis.target?._onWebResourceError; + if (callback != null) { + callback(AndroidWebResourceError._( errorCode: error.errorCode, description: error.description, failingUrl: request.url, @@ -749,8 +762,10 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate { String description, String failingUrl, ) { - if (weakThis.target?._onWebResourceError != null) { - weakThis.target!._onWebResourceError!(AndroidWebResourceError._( + final WebResourceErrorCallback? callback = + weakThis.target?._onWebResourceError; + if (callback != null) { + callback(AndroidWebResourceError._( errorCode: errorCode, description: description, failingUrl: failingUrl, @@ -762,20 +777,23 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate { android_webview.WebView webView, android_webview.WebResourceRequest request, ) { - if (weakThis.target != null) { - weakThis.target!._handleNavigation( - request.url, - headers: request.requestHeaders, - isForMainFrame: request.isForMainFrame, - ); - } + weakThis.target?._handleNavigation( + request.url, + headers: request.requestHeaders, + isForMainFrame: request.isForMainFrame, + ); + }, + urlLoading: (android_webview.WebView webView, String url) { + weakThis.target?._handleNavigation(url, isForMainFrame: true); }, - urlLoading: ( + doUpdateVisitedHistory: ( android_webview.WebView webView, String url, + bool isReload, ) { - if (weakThis.target != null) { - weakThis.target!._handleNavigation(url, isForMainFrame: true); + final UrlChangeCallback? callback = weakThis.target?._onUrlChange; + if (callback != null) { + callback(AndroidUrlChange(url: url, isReload: isReload)); } }, ); @@ -833,6 +851,7 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate { WebResourceErrorCallback? _onWebResourceError; NavigationRequestCallback? _onNavigationRequest; LoadRequestCallback? _onLoadRequest; + UrlChangeCallback? _onUrlChange; void _handleNavigation( String url, { @@ -913,4 +932,9 @@ class AndroidNavigationDelegate extends PlatformNavigationDelegate { ) async { _onWebResourceError = onWebResourceError; } + + @override + Future setOnUrlChange(UrlChangeCallback onUrlChange) async { + _onUrlChange = onUrlChange; + } } 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 9978ed48bc8..1d232b24179 100644 --- a/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart +++ b/packages/webview_flutter/webview_flutter_android/pigeons/android_webview.dart @@ -292,6 +292,13 @@ abstract class WebViewClientFlutterApi { ); void urlLoading(int instanceId, int webViewInstanceId, String url); + + void doUpdateVisitedHistory( + int instanceId, + int webViewInstanceId, + String url, + bool isReload, + ); } @HostApi(dartHostTestHandler: 'TestDownloadListenerHostApi') diff --git a/packages/webview_flutter/webview_flutter_android/pubspec.yaml b/packages/webview_flutter/webview_flutter_android/pubspec.yaml index 37b38268374..7eb5411640e 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: 3.4.5 +version: 3.5.0 environment: sdk: ">=2.18.0 <4.0.0" @@ -20,7 +20,7 @@ flutter: dependencies: flutter: sdk: flutter - webview_flutter_platform_interface: ^2.0.0 + webview_flutter_platform_interface: ^2.1.0 dev_dependencies: build_runner: ^2.1.4 diff --git a/packages/webview_flutter/webview_flutter_android/test/android_navigation_delegate_test.dart b/packages/webview_flutter/webview_flutter_android/test/android_navigation_delegate_test.dart index 2bf563b293d..1801589f885 100644 --- a/packages/webview_flutter/webview_flutter_android/test/android_navigation_delegate_test.dart +++ b/packages/webview_flutter/webview_flutter_android/test/android_navigation_delegate_test.dart @@ -447,6 +447,27 @@ void main() { expect(completer.isCompleted, true); }); }); + + test('onUrlChange', () { + final AndroidNavigationDelegate androidNavigationDelegate = + AndroidNavigationDelegate(_buildCreationParams()); + + late final AndroidUrlChange urlChange; + androidNavigationDelegate.setOnUrlChange( + (UrlChange change) { + urlChange = change as AndroidUrlChange; + }, + ); + + CapturingWebViewClient.lastCreatedDelegate.doUpdateVisitedHistory!( + android_webview.WebView.detached(), + 'https://www.google.com', + false, + ); + + expect(urlChange.url, 'https://www.google.com'); + expect(urlChange.isReload, isFalse); + }); } AndroidNavigationDelegateCreationParams _buildCreationParams() { @@ -471,6 +492,7 @@ class CapturingWebViewClient extends android_webview.WebViewClient { super.onReceivedRequestError, super.requestLoading, super.urlLoading, + super.doUpdateVisitedHistory, super.binaryMessenger, super.instanceManager, }) : super.detached() { 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 78e31449cf5..f224ff1d1e5 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 @@ -105,6 +105,11 @@ void main() { )? requestLoading, void Function(android_webview.WebView webView, String url)? urlLoading, + void Function( + android_webview.WebView webView, + String url, + bool isReload, + )? doUpdateVisitedHistory, }) => mockWebViewClient ?? MockWebViewClient(), createFlutterAssetManager: () => 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 595db88c31e..e0c637efdd1 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 @@ -757,6 +757,11 @@ class MockAndroidWebViewProxy extends _i1.Mock })); @override _i2.WebViewClient Function({ + void Function( + _i2.WebView, + String, + bool, + )? doUpdateVisitedHistory, void Function( _i2.WebView, String, @@ -787,6 +792,11 @@ class MockAndroidWebViewProxy extends _i1.Mock }) get createAndroidWebViewClient => (super.noSuchMethod( Invocation.getter(#createAndroidWebViewClient), returnValue: ({ + void Function( + _i2.WebView, + String, + bool, + )? doUpdateVisitedHistory, void Function( _i2.WebView, String, @@ -820,6 +830,11 @@ class MockAndroidWebViewProxy extends _i1.Mock Invocation.getter(#createAndroidWebViewClient), ), returnValueForMissingStub: ({ + void Function( + _i2.WebView, + String, + bool, + )? doUpdateVisitedHistory, void Function( _i2.WebView, String, @@ -853,6 +868,11 @@ class MockAndroidWebViewProxy extends _i1.Mock Invocation.getter(#createAndroidWebViewClient), ), ) as _i2.WebViewClient Function({ + void Function( + _i2.WebView, + String, + bool, + )? doUpdateVisitedHistory, void Function( _i2.WebView, String, 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 f447926cc48..71c30b6e903 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 @@ -739,6 +739,33 @@ void main() { ); }); + test('doUpdateVisitedHistory', () { + late final List result; + when(mockWebViewClient.doUpdateVisitedHistory).thenReturn( + ( + WebView webView, + String url, + bool isReload, + ) { + result = [webView, url, isReload]; + }, + ); + + flutterApi.doUpdateVisitedHistory( + mockWebViewClientInstanceId, + mockWebViewInstanceId, + 'https://www.google.com', + false, + ); + + expect( + result, + containsAllInOrder( + [mockWebView, 'https://www.google.com', false], + ), + ); + }); + test('copy', () { expect(WebViewClient.detached().copy(), isA()); }); diff --git a/packages/webview_flutter/webview_flutter_android/test/test_android_webview.g.dart b/packages/webview_flutter/webview_flutter_android/test/test_android_webview.g.dart index 33ab0ecabca..5857a09876c 100644 --- a/packages/webview_flutter/webview_flutter_android/test/test_android_webview.g.dart +++ b/packages/webview_flutter/webview_flutter_android/test/test_android_webview.g.dart @@ -1,7 +1,7 @@ // 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. -// Autogenerated from Pigeon (v9.0.5), do not edit directly. +// Autogenerated from Pigeon (v9.2.3), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import // ignore_for_file: avoid_relative_lib_imports @@ -15,6 +15,8 @@ import 'package:webview_flutter_android/src/android_webview.g.dart'; /// Host API for managing the native `InstanceManager`. abstract class TestInstanceManagerHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); /// Clear the native `InstanceManager`. @@ -29,9 +31,12 @@ abstract class TestInstanceManagerHostApi { 'dev.flutter.pigeon.InstanceManagerHostApi.clear', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { // ignore message api.clear(); return []; @@ -47,6 +52,8 @@ abstract class TestInstanceManagerHostApi { /// /// See https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html. abstract class TestJavaObjectHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); void dispose(int identifier); @@ -58,9 +65,12 @@ abstract class TestJavaObjectHostApi { 'dev.flutter.pigeon.JavaObjectHostApi.dispose', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.JavaObjectHostApi.dispose was null.'); final List args = (message as List?)!; @@ -99,6 +109,8 @@ class _TestWebViewHostApiCodec extends StandardMessageCodec { } abstract class TestWebViewHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = _TestWebViewHostApiCodec(); void create(int instanceId); @@ -162,9 +174,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.create', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.create was null.'); final List args = (message as List?)!; @@ -181,9 +196,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.loadData', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.loadData was null.'); final List args = (message as List?)!; @@ -205,9 +223,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.loadDataWithBaseUrl was null.'); final List args = (message as List?)!; @@ -232,9 +253,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.loadUrl', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.loadUrl was null.'); final List args = (message as List?)!; @@ -258,9 +282,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.postUrl', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.postUrl was null.'); final List args = (message as List?)!; @@ -283,9 +310,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.getUrl', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.getUrl was null.'); final List args = (message as List?)!; @@ -302,9 +332,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.canGoBack', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.canGoBack was null.'); final List args = (message as List?)!; @@ -321,9 +354,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.canGoForward', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.canGoForward was null.'); final List args = (message as List?)!; @@ -340,9 +376,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.goBack', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.goBack was null.'); final List args = (message as List?)!; @@ -359,9 +398,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.goForward', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.goForward was null.'); final List args = (message as List?)!; @@ -378,9 +420,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.reload', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.reload was null.'); final List args = (message as List?)!; @@ -397,9 +442,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.clearCache', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.clearCache was null.'); final List args = (message as List?)!; @@ -419,9 +467,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.evaluateJavascript', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.evaluateJavascript was null.'); final List args = (message as List?)!; @@ -442,9 +493,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.getTitle', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.getTitle was null.'); final List args = (message as List?)!; @@ -461,9 +515,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.scrollTo', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.scrollTo was null.'); final List args = (message as List?)!; @@ -486,9 +543,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.scrollBy', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.scrollBy was null.'); final List args = (message as List?)!; @@ -511,9 +571,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.getScrollX', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.getScrollX was null.'); final List args = (message as List?)!; @@ -530,9 +593,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.getScrollY', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.getScrollY was null.'); final List args = (message as List?)!; @@ -549,9 +615,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.getScrollPosition', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.getScrollPosition was null.'); final List args = (message as List?)!; @@ -569,9 +638,12 @@ abstract class TestWebViewHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.setWebContentsDebuggingEnabled was null.'); final List args = (message as List?)!; @@ -588,9 +660,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.setWebViewClient', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.setWebViewClient was null.'); final List args = (message as List?)!; @@ -610,9 +685,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.addJavaScriptChannel was null.'); final List args = (message as List?)!; @@ -633,9 +711,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.removeJavaScriptChannel was null.'); final List args = (message as List?)!; @@ -656,9 +737,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.setDownloadListener', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.setDownloadListener was null.'); final List args = (message as List?)!; @@ -676,9 +760,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.setWebChromeClient', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.setWebChromeClient was null.'); final List args = (message as List?)!; @@ -696,9 +783,12 @@ abstract class TestWebViewHostApi { 'dev.flutter.pigeon.WebViewHostApi.setBackgroundColor', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewHostApi.setBackgroundColor was null.'); final List args = (message as List?)!; @@ -717,6 +807,8 @@ abstract class TestWebViewHostApi { } abstract class TestWebSettingsHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); void create(int instanceId, int webViewInstanceId); @@ -754,9 +846,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.create', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.create was null.'); final List args = (message as List?)!; @@ -776,9 +871,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDomStorageEnabled was null.'); final List args = (message as List?)!; @@ -799,9 +897,12 @@ abstract class TestWebSettingsHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptCanOpenWindowsAutomatically was null.'); final List args = (message as List?)!; @@ -823,9 +924,12 @@ abstract class TestWebSettingsHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportMultipleWindows was null.'); final List args = (message as List?)!; @@ -845,9 +949,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setJavaScriptEnabled was null.'); final List args = (message as List?)!; @@ -867,9 +974,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUserAgentString was null.'); final List args = (message as List?)!; @@ -888,9 +998,12 @@ abstract class TestWebSettingsHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setMediaPlaybackRequiresUserGesture was null.'); final List args = (message as List?)!; @@ -911,9 +1024,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setSupportZoom was null.'); final List args = (message as List?)!; @@ -934,9 +1050,12 @@ abstract class TestWebSettingsHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setLoadWithOverviewMode was null.'); final List args = (message as List?)!; @@ -956,9 +1075,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setUseWideViewPort was null.'); final List args = (message as List?)!; @@ -978,9 +1100,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setDisplayZoomControls was null.'); final List args = (message as List?)!; @@ -1000,9 +1125,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setBuiltInZoomControls was null.'); final List args = (message as List?)!; @@ -1022,9 +1150,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setAllowFileAccess', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setAllowFileAccess was null.'); final List args = (message as List?)!; @@ -1044,9 +1175,12 @@ abstract class TestWebSettingsHostApi { 'dev.flutter.pigeon.WebSettingsHostApi.setTextZoom', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebSettingsHostApi.setTextZoom was null.'); final List args = (message as List?)!; @@ -1065,6 +1199,8 @@ abstract class TestWebSettingsHostApi { } abstract class TestJavaScriptChannelHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); void create(int instanceId, String channelName); @@ -1076,9 +1212,12 @@ abstract class TestJavaScriptChannelHostApi { 'dev.flutter.pigeon.JavaScriptChannelHostApi.create', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.JavaScriptChannelHostApi.create was null.'); final List args = (message as List?)!; @@ -1097,6 +1236,8 @@ abstract class TestJavaScriptChannelHostApi { } abstract class TestWebViewClientHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); void create(int instanceId); @@ -1111,9 +1252,12 @@ abstract class TestWebViewClientHostApi { 'dev.flutter.pigeon.WebViewClientHostApi.create', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewClientHostApi.create was null.'); final List args = (message as List?)!; @@ -1131,9 +1275,12 @@ abstract class TestWebViewClientHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebViewClientHostApi.setSynchronousReturnValueForShouldOverrideUrlLoading was null.'); final List args = (message as List?)!; @@ -1153,6 +1300,8 @@ abstract class TestWebViewClientHostApi { } abstract class TestDownloadListenerHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); void create(int instanceId); @@ -1164,9 +1313,12 @@ abstract class TestDownloadListenerHostApi { 'dev.flutter.pigeon.DownloadListenerHostApi.create', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.DownloadListenerHostApi.create was null.'); final List args = (message as List?)!; @@ -1182,6 +1334,8 @@ abstract class TestDownloadListenerHostApi { } abstract class TestWebChromeClientHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); void create(int instanceId); @@ -1196,9 +1350,12 @@ abstract class TestWebChromeClientHostApi { 'dev.flutter.pigeon.WebChromeClientHostApi.create', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebChromeClientHostApi.create was null.'); final List args = (message as List?)!; @@ -1216,9 +1373,12 @@ abstract class TestWebChromeClientHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebChromeClientHostApi.setSynchronousReturnValueForOnShowFileChooser was null.'); final List args = (message as List?)!; @@ -1238,6 +1398,8 @@ abstract class TestWebChromeClientHostApi { } abstract class TestAssetManagerHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); List list(String path); @@ -1251,9 +1413,12 @@ abstract class TestAssetManagerHostApi { 'dev.flutter.pigeon.FlutterAssetManagerHostApi.list', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.FlutterAssetManagerHostApi.list was null.'); final List args = (message as List?)!; @@ -1271,9 +1436,12 @@ abstract class TestAssetManagerHostApi { codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.FlutterAssetManagerHostApi.getAssetFilePathByName was null.'); final List args = (message as List?)!; @@ -1289,6 +1457,8 @@ abstract class TestAssetManagerHostApi { } abstract class TestWebStorageHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; static const MessageCodec codec = StandardMessageCodec(); void create(int instanceId); @@ -1302,9 +1472,12 @@ abstract class TestWebStorageHostApi { 'dev.flutter.pigeon.WebStorageHostApi.create', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebStorageHostApi.create was null.'); final List args = (message as List?)!; @@ -1321,9 +1494,12 @@ abstract class TestWebStorageHostApi { 'dev.flutter.pigeon.WebStorageHostApi.deleteAllData', codec, binaryMessenger: binaryMessenger); if (api == null) { - channel.setMockMessageHandler(null); + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); } else { - channel.setMockMessageHandler((Object? message) async { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { assert(message != null, 'Argument for dev.flutter.pigeon.WebStorageHostApi.deleteAllData was null.'); final List args = (message as List?)!; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md index bfce2091252..dc83b548e65 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md +++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.3.0 + +* Adds support for `PlatformNavigationDelegate.onUrlChange`. + ## 3.2.4 * Updates pigeon to fix warnings with clang 15. diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart index b51d7d86a8b..42b55556782 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/integration_test/webview_flutter_test.dart @@ -1002,6 +1002,81 @@ Future main() async { final String? currentUrl = await controller.currentUrl(); expect(currentUrl, secondaryUrl); }); + + testWidgets('can receive url changes', (WidgetTester tester) async { + final Completer pageLoaded = Completer(); + + final PlatformNavigationDelegate navigationDelegate = + PlatformNavigationDelegate( + const PlatformNavigationDelegateCreationParams(), + )..setOnPageFinished((_) => pageLoaded.complete()); + + final PlatformWebViewController controller = PlatformWebViewController( + const PlatformWebViewControllerCreationParams(), + ) + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setPlatformNavigationDelegate(navigationDelegate) + ..loadRequest(LoadRequestParams(uri: Uri.parse(blankPageEncoded))); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) { + return PlatformWebViewWidget( + PlatformWebViewWidgetCreationParams(controller: controller), + ).build(context); + }, + )); + + await pageLoaded.future; + await navigationDelegate.setOnPageFinished((_) {}); + + final Completer urlChangeCompleter = Completer(); + await navigationDelegate.setOnUrlChange((UrlChange change) { + urlChangeCompleter.complete(change.url); + }); + + await controller.runJavaScript('location.href = "$primaryUrl"'); + + await expectLater(urlChangeCompleter.future, completion(primaryUrl)); + }); + + testWidgets('can receive updates to history state', + (WidgetTester tester) async { + final Completer pageLoaded = Completer(); + + final PlatformNavigationDelegate navigationDelegate = + PlatformNavigationDelegate( + const PlatformNavigationDelegateCreationParams(), + )..setOnPageFinished((_) => pageLoaded.complete()); + + final PlatformWebViewController controller = PlatformWebViewController( + const PlatformWebViewControllerCreationParams(), + ) + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setPlatformNavigationDelegate(navigationDelegate) + ..loadRequest(LoadRequestParams(uri: Uri.parse(primaryUrl))); + + await tester.pumpWidget(Builder( + builder: (BuildContext context) { + return PlatformWebViewWidget( + PlatformWebViewWidgetCreationParams(controller: controller), + ).build(context); + }, + )); + + await pageLoaded.future; + await navigationDelegate.setOnPageFinished((_) {}); + + final Completer urlChangeCompleter = Completer(); + await navigationDelegate.setOnUrlChange((UrlChange change) { + urlChangeCompleter.complete(change.url); + }); + + await controller.runJavaScript( + 'window.history.pushState({}, "", "secondary.txt");', + ); + + await expectLater(urlChangeCompleter.future, completion(secondaryUrl)); + }); }); testWidgets('launches with gestureNavigationEnabled on iOS', diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj index 9e1038d0827..19e2b39a5c1 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/Runner.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 8F4FF949299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */; }; + 8F4FF94B29AC223F000A6586 /* FWFURLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */; }; 8FA6A87928062CD000A4B183 /* FWFInstanceManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */; }; 8FB79B5328134C3100C101D3 /* FWFWebViewHostApiTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */; }; 8FB79B55281B24F600C101D3 /* FWFDataConvertersTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */; }; @@ -78,6 +79,7 @@ 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 8F4FF948299ADC2D000A6586 /* FWFWebViewFlutterWKWebViewExternalAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewFlutterWKWebViewExternalAPITests.m; sourceTree = ""; }; + 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFURLTests.m; sourceTree = ""; }; 8FA6A87828062CD000A4B183 /* FWFInstanceManagerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFInstanceManagerTests.m; sourceTree = ""; }; 8FB79B5228134C3100C101D3 /* FWFWebViewHostApiTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFWebViewHostApiTests.m; sourceTree = ""; }; 8FB79B54281B24F600C101D3 /* FWFDataConvertersTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FWFDataConvertersTests.m; sourceTree = ""; }; @@ -162,6 +164,7 @@ 8FB79B8E2820BAB300C101D3 /* FWFScrollViewHostApiTests.m */, 8FB79B902820BAC700C101D3 /* FWFUIViewHostApiTests.m */, 8FB79B962821985200C101D3 /* FWFObjectHostApiTests.m */, + 8F4FF94A29AC223F000A6586 /* FWFURLTests.m */, ); path = RunnerTests; sourceTree = ""; @@ -463,6 +466,7 @@ buildActionMask = 2147483647; files = ( 8FA6A87928062CD000A4B183 /* FWFInstanceManagerTests.m in Sources */, + 8F4FF94B29AC223F000A6586 /* FWFURLTests.m in Sources */, 8FB79B852820A3A400C101D3 /* FWFUIDelegateHostApiTests.m in Sources */, 8FB79B972821985200C101D3 /* FWFObjectHostApiTests.m in Sources */, 8FB79B672820453400C101D3 /* FWFHTTPCookieStoreHostApiTests.m in Sources */, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m index b8e41d14233..888a3a1e9a6 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFObjectHostApiTests.m @@ -139,7 +139,43 @@ - (void)testObserveValueForKeyPath { return value[0].value == FWFNSKeyValueChangeKeyEnumOldValue; }] changeValues:[OCMArg checkWithBlock:^BOOL(id value) { - return [@"key" isEqual:value[0]]; + FWFObjectOrIdentifier *object = (FWFObjectOrIdentifier *)value[0]; + return !object.isIdentifier.boolValue && + [@"key" isEqual:object.value]; + }] + completion:OCMOCK_ANY]); +} + +- (void)testObserveValueForKeyPathWithIdentifier { + FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init]; + + FWFObject *mockObject = [self mockObjectWithManager:instanceManager identifier:0]; + FWFObjectFlutterApiImpl *mockFlutterAPI = [self mockFlutterApiWithManager:instanceManager]; + + OCMStub([mockObject objectApi]).andReturn(mockFlutterAPI); + + NSObject *object = [[NSObject alloc] init]; + [instanceManager addDartCreatedInstance:object withIdentifier:1]; + + NSObject *returnedObject = [[NSObject alloc] init]; + [instanceManager addDartCreatedInstance:returnedObject withIdentifier:2]; + + [mockObject observeValueForKeyPath:@"keyPath" + ofObject:object + change:@{NSKeyValueChangeOldKey : returnedObject} + context:nil]; + OCMVerify([mockFlutterAPI + observeValueForObjectWithIdentifier:@0 + keyPath:@"keyPath" + objectIdentifier:@1 + changeKeys:[OCMArg checkWithBlock:^BOOL( + NSArray + *value) { + return value[0].value == FWFNSKeyValueChangeKeyEnumOldValue; + }] + changeValues:[OCMArg checkWithBlock:^BOOL(id value) { + FWFObjectOrIdentifier *object = (FWFObjectOrIdentifier *)value[0]; + return object.isIdentifier.boolValue && [@(2) isEqual:object.value]; }] completion:OCMOCK_ANY]); } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLTests.m b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLTests.m new file mode 100644 index 00000000000..bf4dc36048f --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/ios/RunnerTests/FWFURLTests.m @@ -0,0 +1,48 @@ +// 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. + +@import Flutter; +@import XCTest; +@import webview_flutter_wkwebview; + +#import + +@interface FWFURLTests : XCTestCase +@end + +@implementation FWFURLTests +- (void)testAbsoluteString { + NSURL *mockUrl = OCMClassMock([NSURL class]); + OCMStub([mockUrl absoluteString]).andReturn(@"https://www.google.com"); + + FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init]; + [instanceManager addDartCreatedInstance:mockUrl withIdentifier:0]; + + FWFURLHostApiImpl *hostApi = [[FWFURLHostApiImpl alloc] + initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger)) + instanceManager:instanceManager]; + + FlutterError *error; + XCTAssertEqualObjects([hostApi absoluteStringForNSURLWithIdentifier:@(0) error:&error], + @"https://www.google.com"); + XCTAssertNil(error); +} + +- (void)testFlutterApiCreate { + FWFInstanceManager *instanceManager = [[FWFInstanceManager alloc] init]; + FWFURLFlutterApiImpl *flutterApi = [[FWFURLFlutterApiImpl alloc] + initWithBinaryMessenger:OCMProtocolMock(@protocol(FlutterBinaryMessenger)) + instanceManager:instanceManager]; + + flutterApi.api = OCMClassMock([FWFNSUrlFlutterApi class]); + + NSURL *url = [[NSURL alloc] initWithString:@"https://www.google.com"]; + [flutterApi create:url + completion:^(FlutterError *error){ + }]; + + long identifier = [instanceManager identifierWithStrongReferenceForInstance:url]; + OCMVerify([flutterApi.api createWithIdentifier:@(identifier) completion:OCMOCK_ANY]); +} +@end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/lib/main.dart b/packages/webview_flutter/webview_flutter_wkwebview/example/lib/main.dart index 64894756722..a793c2ca00e 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/lib/main.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/lib/main.dart @@ -124,6 +124,9 @@ Page resource error: } debugPrint('allowing navigation to ${request.url}'); return NavigationDecision.navigate; + }) + ..setOnUrlChange((UrlChange change) { + debugPrint('url change to ${change.url}'); }), ) ..addJavaScriptChannel(JavaScriptChannelParams( diff --git a/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml index 4af215cee74..b1ee0822395 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/example/pubspec.yaml @@ -10,7 +10,7 @@ dependencies: flutter: sdk: flutter path_provider: ^2.0.6 - webview_flutter_platform_interface: ^2.0.0 + webview_flutter_platform_interface: ^2.1.0 webview_flutter_wkwebview: # When depending on this package from a real application you should use: # webview_flutter: ^x.y.z diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.m index 6233a4e8ca2..2f919839aa5 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FLTWebViewFlutterPlugin.m @@ -13,6 +13,7 @@ #import "FWFScrollViewHostApi.h" #import "FWFUIDelegateHostApi.h" #import "FWFUIViewHostApi.h" +#import "FWFURLHostApi.h" #import "FWFUserContentControllerHostApi.h" #import "FWFWebViewConfigurationHostApi.h" #import "FWFWebViewHostApi.h" @@ -100,6 +101,9 @@ + (void)registerWithRegistrar:(NSObject *)registrar { FWFWKWebViewHostApiSetup(registrar.messenger, [[FWFWebViewHostApiImpl alloc] initWithBinaryMessenger:registrar.messenger instanceManager:instanceManager]); + FWFNSUrlHostApiSetup(registrar.messenger, + [[FWFURLHostApiImpl alloc] initWithBinaryMessenger:registrar.messenger + instanceManager:instanceManager]); FWFWebViewFactory *webviewFactory = [[FWFWebViewFactory alloc] initWithManager:instanceManager]; [registrar registerViewFactory:webviewFactory withId:@"plugins.flutter.io/webview"]; diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h index 0ebb4022234..1eb95ff890a 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.h @@ -159,6 +159,7 @@ typedef NS_ENUM(NSUInteger, FWFWKNavigationType) { @class FWFNSErrorData; @class FWFWKScriptMessageData; @class FWFNSHttpCookieData; +@class FWFObjectOrIdentifier; @interface FWFNSKeyValueObservingOptionsEnumData : NSObject /// `init` unavailable to enforce nonnull fields, see the `make` class method. @@ -300,6 +301,19 @@ typedef NS_ENUM(NSUInteger, FWFWKNavigationType) { @property(nonatomic, strong) NSArray *propertyValues; @end +/// An object that can represent either a value supported by +/// `StandardMessageCodec`, a data class in this pigeon file, or an identifier +/// of an object stored in an `InstanceManager`. +@interface FWFObjectOrIdentifier : NSObject +/// `init` unavailable to enforce nonnull fields, see the `make` class method. +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)makeWithValue:(id)value isIdentifier:(NSNumber *)isIdentifier; +@property(nonatomic, strong) id value; +/// Whether value is an int that is used to retrieve an instance stored in an +/// `InstanceManager`. +@property(nonatomic, strong) NSNumber *isIdentifier; +@end + /// The codec used by FWFWKWebsiteDataStoreHostApi. NSObject *FWFWKWebsiteDataStoreHostApiGetCodec(void); @@ -583,7 +597,7 @@ NSObject *FWFNSObjectFlutterApiGetCodec(void); keyPath:(NSString *)keyPath objectIdentifier:(NSNumber *)objectIdentifier changeKeys:(NSArray *)changeKeys - changeValues:(NSArray *)changeValues + changeValues:(NSArray *)changeValues completion:(void (^)(FlutterError *_Nullable))completion; - (void)disposeObjectWithIdentifier:(NSNumber *)identifier completion:(void (^)(FlutterError *_Nullable))completion; @@ -702,4 +716,39 @@ NSObject *FWFWKHttpCookieStoreHostApiGetCodec(void); extern void FWFWKHttpCookieStoreHostApiSetup(id binaryMessenger, NSObject *_Nullable api); +/// The codec used by FWFNSUrlHostApi. +NSObject *FWFNSUrlHostApiGetCodec(void); + +/// Host API for `NSUrl`. +/// +/// This class may handle instantiating and adding native object instances that +/// are attached to a Dart instance or method calls on the associated native +/// class or an instance of the class. +/// +/// See https://developer.apple.com/documentation/foundation/nsurl?language=objc. +@protocol FWFNSUrlHostApi +- (nullable NSString *)absoluteStringForNSURLWithIdentifier:(NSNumber *)identifier + error: + (FlutterError *_Nullable *_Nonnull)error; +@end + +extern void FWFNSUrlHostApiSetup(id binaryMessenger, + NSObject *_Nullable api); + +/// The codec used by FWFNSUrlFlutterApi. +NSObject *FWFNSUrlFlutterApiGetCodec(void); + +/// Flutter API for `NSUrl`. +/// +/// 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.apple.com/documentation/foundation/nsurl?language=objc. +@interface FWFNSUrlFlutterApi : NSObject +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger; +- (void)createWithIdentifier:(NSNumber *)identifier + completion:(void (^)(FlutterError *_Nullable))completion; +@end + NS_ASSUME_NONNULL_END diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m index 957a4decd67..610bc020b32 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFGeneratedWebKitApis.m @@ -108,6 +108,12 @@ + (nullable FWFNSHttpCookieData *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end +@interface FWFObjectOrIdentifier () ++ (FWFObjectOrIdentifier *)fromList:(NSArray *)list; ++ (nullable FWFObjectOrIdentifier *)nullableFromList:(NSArray *)list; +- (NSArray *)toList; +@end + @implementation FWFNSKeyValueObservingOptionsEnumData + (instancetype)makeWithValue:(FWFNSKeyValueObservingOptionsEnum)value { FWFNSKeyValueObservingOptionsEnumData *pigeonResult = @@ -470,6 +476,31 @@ - (NSArray *)toList { } @end +@implementation FWFObjectOrIdentifier ++ (instancetype)makeWithValue:(id)value isIdentifier:(NSNumber *)isIdentifier { + FWFObjectOrIdentifier *pigeonResult = [[FWFObjectOrIdentifier alloc] init]; + pigeonResult.value = value; + pigeonResult.isIdentifier = isIdentifier; + return pigeonResult; +} ++ (FWFObjectOrIdentifier *)fromList:(NSArray *)list { + FWFObjectOrIdentifier *pigeonResult = [[FWFObjectOrIdentifier alloc] init]; + pigeonResult.value = GetNullableObjectAtIndex(list, 0); + pigeonResult.isIdentifier = GetNullableObjectAtIndex(list, 1); + NSAssert(pigeonResult.isIdentifier != nil, @""); + return pigeonResult; +} ++ (nullable FWFObjectOrIdentifier *)nullableFromList:(NSArray *)list { + return (list) ? [FWFObjectOrIdentifier fromList:list] : nil; +} +- (NSArray *)toList { + return @[ + (self.value ?: [NSNull null]), + (self.isIdentifier ?: [NSNull null]), + ]; +} +@end + @interface FWFWKWebsiteDataStoreHostApiCodecReader : FlutterStandardReader @end @implementation FWFWKWebsiteDataStoreHostApiCodecReader @@ -1680,33 +1711,9 @@ @implementation FWFNSObjectFlutterApiCodecReader - (nullable id)readValueOfType:(UInt8)type { switch (type) { case 128: - return [FWFNSErrorData fromList:[self readValue]]; - case 129: - return [FWFNSHttpCookieData fromList:[self readValue]]; - case 130: - return [FWFNSHttpCookiePropertyKeyEnumData fromList:[self readValue]]; - case 131: return [FWFNSKeyValueChangeKeyEnumData fromList:[self readValue]]; - case 132: - return [FWFNSKeyValueObservingOptionsEnumData fromList:[self readValue]]; - case 133: - return [FWFNSUrlRequestData fromList:[self readValue]]; - case 134: - return [FWFWKAudiovisualMediaTypeEnumData fromList:[self readValue]]; - case 135: - return [FWFWKFrameInfoData fromList:[self readValue]]; - case 136: - return [FWFWKNavigationActionData fromList:[self readValue]]; - case 137: - return [FWFWKNavigationActionPolicyEnumData fromList:[self readValue]]; - case 138: - return [FWFWKScriptMessageData fromList:[self readValue]]; - case 139: - return [FWFWKUserScriptData fromList:[self readValue]]; - case 140: - return [FWFWKUserScriptInjectionTimeEnumData fromList:[self readValue]]; - case 141: - return [FWFWKWebsiteDataTypeEnumData fromList:[self readValue]]; + case 129: + return [FWFObjectOrIdentifier fromList:[self readValue]]; default: return [super readValueOfType:type]; } @@ -1717,48 +1724,12 @@ @interface FWFNSObjectFlutterApiCodecWriter : FlutterStandardWriter @end @implementation FWFNSObjectFlutterApiCodecWriter - (void)writeValue:(id)value { - if ([value isKindOfClass:[FWFNSErrorData class]]) { + if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) { [self writeByte:128]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFNSHttpCookieData class]]) { + } else if ([value isKindOfClass:[FWFObjectOrIdentifier class]]) { [self writeByte:129]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFNSHttpCookiePropertyKeyEnumData class]]) { - [self writeByte:130]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFNSKeyValueChangeKeyEnumData class]]) { - [self writeByte:131]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFNSKeyValueObservingOptionsEnumData class]]) { - [self writeByte:132]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) { - [self writeByte:133]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) { - [self writeByte:134]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) { - [self writeByte:135]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) { - [self writeByte:136]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) { - [self writeByte:137]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) { - [self writeByte:138]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) { - [self writeByte:139]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) { - [self writeByte:140]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) { - [self writeByte:141]; - [self writeValue:[value toList]]; } else { [super writeValue:value]; } @@ -1805,7 +1776,7 @@ - (void)observeValueForObjectWithIdentifier:(NSNumber *)arg_identifier objectIdentifier:(NSNumber *)arg_objectIdentifier changeKeys: (NSArray *)arg_changeKeys - changeValues:(NSArray *)arg_changeValues + changeValues:(NSArray *)arg_changeValues completion:(void (^)(FlutterError *_Nullable))completion { FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel messageChannelWithName:@"dev.flutter.pigeon.NSObjectFlutterApi.observeValue" @@ -1851,20 +1822,22 @@ - (nullable id)readValueOfType:(UInt8)type { case 133: return [FWFNSUrlRequestData fromList:[self readValue]]; case 134: - return [FWFWKAudiovisualMediaTypeEnumData fromList:[self readValue]]; + return [FWFObjectOrIdentifier fromList:[self readValue]]; case 135: - return [FWFWKFrameInfoData fromList:[self readValue]]; + return [FWFWKAudiovisualMediaTypeEnumData fromList:[self readValue]]; case 136: - return [FWFWKNavigationActionData fromList:[self readValue]]; + return [FWFWKFrameInfoData fromList:[self readValue]]; case 137: - return [FWFWKNavigationActionPolicyEnumData fromList:[self readValue]]; + return [FWFWKNavigationActionData fromList:[self readValue]]; case 138: - return [FWFWKScriptMessageData fromList:[self readValue]]; + return [FWFWKNavigationActionPolicyEnumData fromList:[self readValue]]; case 139: - return [FWFWKUserScriptData fromList:[self readValue]]; + return [FWFWKScriptMessageData fromList:[self readValue]]; case 140: - return [FWFWKUserScriptInjectionTimeEnumData fromList:[self readValue]]; + return [FWFWKUserScriptData fromList:[self readValue]]; case 141: + return [FWFWKUserScriptInjectionTimeEnumData fromList:[self readValue]]; + case 142: return [FWFWKWebsiteDataTypeEnumData fromList:[self readValue]]; default: return [super readValueOfType:type]; @@ -1894,30 +1867,33 @@ - (void)writeValue:(id)value { } else if ([value isKindOfClass:[FWFNSUrlRequestData class]]) { [self writeByte:133]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) { + } else if ([value isKindOfClass:[FWFObjectOrIdentifier class]]) { [self writeByte:134]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) { + } else if ([value isKindOfClass:[FWFWKAudiovisualMediaTypeEnumData class]]) { [self writeByte:135]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) { + } else if ([value isKindOfClass:[FWFWKFrameInfoData class]]) { [self writeByte:136]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) { + } else if ([value isKindOfClass:[FWFWKNavigationActionData class]]) { [self writeByte:137]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) { + } else if ([value isKindOfClass:[FWFWKNavigationActionPolicyEnumData class]]) { [self writeByte:138]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) { + } else if ([value isKindOfClass:[FWFWKScriptMessageData class]]) { [self writeByte:139]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) { + } else if ([value isKindOfClass:[FWFWKUserScriptData class]]) { [self writeByte:140]; [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) { + } else if ([value isKindOfClass:[FWFWKUserScriptInjectionTimeEnumData class]]) { [self writeByte:141]; [self writeValue:[value toList]]; + } else if ([value isKindOfClass:[FWFWKWebsiteDataTypeEnumData class]]) { + [self writeByte:142]; + [self writeValue:[value toList]]; } else { [super writeValue:value]; } @@ -2599,3 +2575,64 @@ void FWFWKHttpCookieStoreHostApiSetup(id binaryMessenger } } } +NSObject *FWFNSUrlHostApiGetCodec(void) { + static FlutterStandardMessageCodec *sSharedObject = nil; + sSharedObject = [FlutterStandardMessageCodec sharedInstance]; + return sSharedObject; +} + +void FWFNSUrlHostApiSetup(id binaryMessenger, + NSObject *api) { + { + FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] + initWithName:@"dev.flutter.pigeon.NSUrlHostApi.getAbsoluteString" + binaryMessenger:binaryMessenger + codec:FWFNSUrlHostApiGetCodec()]; + if (api) { + NSCAssert([api respondsToSelector:@selector(absoluteStringForNSURLWithIdentifier:error:)], + @"FWFNSUrlHostApi api (%@) doesn't respond to " + @"@selector(absoluteStringForNSURLWithIdentifier:error:)", + api); + [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { + NSArray *args = message; + NSNumber *arg_identifier = GetNullableObjectAtIndex(args, 0); + FlutterError *error; + NSString *output = [api absoluteStringForNSURLWithIdentifier:arg_identifier error:&error]; + callback(wrapResult(output, error)); + }]; + } else { + [channel setMessageHandler:nil]; + } + } +} +NSObject *FWFNSUrlFlutterApiGetCodec(void) { + static FlutterStandardMessageCodec *sSharedObject = nil; + sSharedObject = [FlutterStandardMessageCodec sharedInstance]; + return sSharedObject; +} + +@interface FWFNSUrlFlutterApi () +@property(nonatomic, strong) NSObject *binaryMessenger; +@end + +@implementation FWFNSUrlFlutterApi + +- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger { + self = [super init]; + if (self) { + _binaryMessenger = binaryMessenger; + } + return self; +} +- (void)createWithIdentifier:(NSNumber *)arg_identifier + completion:(void (^)(FlutterError *_Nullable))completion { + FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel + messageChannelWithName:@"dev.flutter.pigeon.NSUrlFlutterApi.create" + binaryMessenger:self.binaryMessenger + codec:FWFNSUrlFlutterApiGetCodec()]; + [channel sendMessage:@[ arg_identifier ?: [NSNull null] ] + reply:^(id reply) { + completion(nil); + }]; +} +@end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m index 7da383c99f2..4b014a71010 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFObjectHostApi.m @@ -3,9 +3,14 @@ // found in the LICENSE file. #import "FWFObjectHostApi.h" +#import #import "FWFDataConverters.h" +#import "FWFURLHostApi.h" @interface FWFObjectFlutterApiImpl () +// BinaryMessenger must be weak to prevent a circular reference with the host API it +// references. +@property(nonatomic, weak) id binaryMessenger; // InstanceManager must be weak to prevent a circular reference with the object it stores. @property(nonatomic, weak) FWFInstanceManager *instanceManager; @end @@ -15,6 +20,7 @@ - (instancetype)initWithBinaryMessenger:(id)binaryMessen instanceManager:(FWFInstanceManager *)instanceManager { self = [self initWithBinaryMessenger:binaryMessenger]; if (self) { + _binaryMessenger = binaryMessenger; _instanceManager = instanceManager; } return self; @@ -34,7 +40,25 @@ - (void)observeValueForObject:(NSObject *)instance [change enumerateKeysAndObjectsUsingBlock:^(NSKeyValueChangeKey key, id value, BOOL *stop) { [changeKeys addObject:FWFNSKeyValueChangeKeyEnumDataFromNSKeyValueChangeKey(key)]; - [changeValues addObject:value]; + BOOL isIdentifier = NO; + if ([self.instanceManager containsInstance:value]) { + isIdentifier = YES; + } else if (object_getClass(value) == [NSURL class]) { + FWFURLFlutterApiImpl *flutterApi = + [[FWFURLFlutterApiImpl alloc] initWithBinaryMessenger:self.binaryMessenger + instanceManager:self.instanceManager]; + [flutterApi create:value + completion:^(FlutterError *error) { + NSAssert(!error, @"%@", error); + }]; + isIdentifier = YES; + } + + id returnValue = isIdentifier + ? @([self.instanceManager identifierWithStrongReferenceForInstance:value]) + : value; + [changeValues addObject:[FWFObjectOrIdentifier makeWithValue:returnValue + isIdentifier:@(isIdentifier)]]; }]; NSNumber *objectIdentifier = diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.h new file mode 100644 index 00000000000..248f0b7f20b --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.h @@ -0,0 +1,42 @@ +// 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. + +#import +#import +#import "FWFGeneratedWebKitApis.h" +#import "FWFInstanceManager.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Host API implementation for `NSURL`. + * + * This class may handle instantiating and adding native object instances that are attached to a + * Dart instance or method calls on the associated native class or an instance of the class. + */ +@interface FWFURLHostApiImpl : NSObject +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + instanceManager:(FWFInstanceManager *)instanceManager; +@end + +/** + * Flutter API implementation for `NSURL`. + * + * This class may handle instantiating and adding Dart instances that are attached to a native + * instance or sending callback methods from an overridden native class. + */ +@interface FWFURLFlutterApiImpl : NSObject +/** + * The Flutter API used to send messages back to Dart. + */ +@property FWFNSUrlFlutterApi *api; +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + instanceManager:(FWFInstanceManager *)instanceManager; +/** + * Sends a message to Dart to create a new Dart instance and add it to the `InstanceManager`. + */ +- (void)create:(NSURL *)instance completion:(void (^)(FlutterError *_Nullable))completion; +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.m b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.m new file mode 100644 index 00000000000..9f747c22994 --- /dev/null +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/FWFURLHostApi.m @@ -0,0 +1,74 @@ +// 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. + +#import "FWFURLHostApi.h" + +@interface FWFURLHostApiImpl () +// BinaryMessenger must be weak to prevent a circular reference with the host API it +// references. +@property(nonatomic, weak) id binaryMessenger; +// InstanceManager must be weak to prevent a circular reference with the object it stores. +@property(nonatomic, weak) FWFInstanceManager *instanceManager; +@end + +@interface FWFURLFlutterApiImpl () +// InstanceManager must be weak to prevent a circular reference with the object it stores. +@property(nonatomic, weak) FWFInstanceManager *instanceManager; +@end + +@implementation FWFURLHostApiImpl +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + instanceManager:(FWFInstanceManager *)instanceManager { + self = [self init]; + if (self) { + _binaryMessenger = binaryMessenger; + _instanceManager = instanceManager; + } + return self; +} + +- (nullable NSString *) + absoluteStringForNSURLWithIdentifier:(nonnull NSNumber *)identifier + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + NSURL *instance = [self urlForIdentifier:identifier error:error]; + if (*error) { + return nil; + } + + return instance.absoluteString; +} + +- (nullable NSURL *)urlForIdentifier:(NSNumber *)identifier + error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error { + NSURL *instance = (NSURL *)[self.instanceManager instanceForIdentifier:identifier.longValue]; + + if (!instance) { + NSString *message = + [NSString stringWithFormat:@"InstanceManager does not contain an NSURL with identifier: %@", + identifier]; + *error = [FlutterError errorWithCode:NSInternalInconsistencyException + message:message + details:nil]; + } + + return instance; +} +@end + +@implementation FWFURLFlutterApiImpl +- (instancetype)initWithBinaryMessenger:(id)binaryMessenger + instanceManager:(FWFInstanceManager *)instanceManager { + self = [self init]; + if (self) { + _instanceManager = instanceManager; + _api = [[FWFNSUrlFlutterApi alloc] initWithBinaryMessenger:binaryMessenger]; + } + return self; +} + +- (void)create:(NSURL *)instance completion:(void (^)(FlutterError *_Nullable))completion { + [self.api createWithIdentifier:@([self.instanceManager addHostCreatedInstance:instance]) + completion:completion]; +} +@end diff --git a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/webview-umbrella.h b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/webview-umbrella.h index 9cf4ed27d3c..283682957c2 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/webview-umbrella.h +++ b/packages/webview_flutter/webview_flutter_wkwebview/ios/Classes/webview-umbrella.h @@ -16,6 +16,7 @@ #import "FWFScrollViewHostApi.h" #import "FWFUIDelegateHostApi.h" #import "FWFUIViewHostApi.h" +#import "FWFURLHostApi.h" #import "FWFUserContentControllerHostApi.h" #import "FWFWebViewConfigurationHostApi.h" #import "FWFWebViewFlutterWKWebViewExternalAPI.h" diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart index 75d7aabf233..c44e52a7148 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/common/web_kit.g.dart @@ -513,6 +513,37 @@ class NSHttpCookieData { } } +/// An object that can represent either a value supported by +/// `StandardMessageCodec`, a data class in this pigeon file, or an identifier +/// of an object stored in an `InstanceManager`. +class ObjectOrIdentifier { + ObjectOrIdentifier({ + this.value, + required this.isIdentifier, + }); + + Object? value; + + /// Whether value is an int that is used to retrieve an instance stored in an + /// `InstanceManager`. + bool isIdentifier; + + Object encode() { + return [ + value, + isIdentifier, + ]; + } + + static ObjectOrIdentifier decode(Object result) { + result as List; + return ObjectOrIdentifier( + value: result[0] as Object?, + isIdentifier: result[1]! as bool, + ); + } +} + class _WKWebsiteDataStoreHostApiCodec extends StandardMessageCodec { const _WKWebsiteDataStoreHostApiCodec(); @override @@ -1699,48 +1730,12 @@ class _NSObjectFlutterApiCodec extends StandardMessageCodec { const _NSObjectFlutterApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is NSErrorData) { + if (value is NSKeyValueChangeKeyEnumData) { buffer.putUint8(128); writeValue(buffer, value.encode()); - } else if (value is NSHttpCookieData) { + } else if (value is ObjectOrIdentifier) { buffer.putUint8(129); writeValue(buffer, value.encode()); - } else if (value is NSHttpCookiePropertyKeyEnumData) { - buffer.putUint8(130); - writeValue(buffer, value.encode()); - } else if (value is NSKeyValueChangeKeyEnumData) { - buffer.putUint8(131); - writeValue(buffer, value.encode()); - } else if (value is NSKeyValueObservingOptionsEnumData) { - buffer.putUint8(132); - writeValue(buffer, value.encode()); - } else if (value is NSUrlRequestData) { - buffer.putUint8(133); - writeValue(buffer, value.encode()); - } else if (value is WKAudiovisualMediaTypeEnumData) { - buffer.putUint8(134); - writeValue(buffer, value.encode()); - } else if (value is WKFrameInfoData) { - buffer.putUint8(135); - writeValue(buffer, value.encode()); - } else if (value is WKNavigationActionData) { - buffer.putUint8(136); - writeValue(buffer, value.encode()); - } else if (value is WKNavigationActionPolicyEnumData) { - buffer.putUint8(137); - writeValue(buffer, value.encode()); - } else if (value is WKScriptMessageData) { - buffer.putUint8(138); - writeValue(buffer, value.encode()); - } else if (value is WKUserScriptData) { - buffer.putUint8(139); - writeValue(buffer, value.encode()); - } else if (value is WKUserScriptInjectionTimeEnumData) { - buffer.putUint8(140); - writeValue(buffer, value.encode()); - } else if (value is WKWebsiteDataTypeEnumData) { - buffer.putUint8(141); - writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -1750,33 +1745,9 @@ class _NSObjectFlutterApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: - return NSErrorData.decode(readValue(buffer)!); - case 129: - return NSHttpCookieData.decode(readValue(buffer)!); - case 130: - return NSHttpCookiePropertyKeyEnumData.decode(readValue(buffer)!); - case 131: return NSKeyValueChangeKeyEnumData.decode(readValue(buffer)!); - case 132: - return NSKeyValueObservingOptionsEnumData.decode(readValue(buffer)!); - case 133: - return NSUrlRequestData.decode(readValue(buffer)!); - case 134: - return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!); - case 135: - return WKFrameInfoData.decode(readValue(buffer)!); - case 136: - return WKNavigationActionData.decode(readValue(buffer)!); - case 137: - return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!); - case 138: - return WKScriptMessageData.decode(readValue(buffer)!); - case 139: - return WKUserScriptData.decode(readValue(buffer)!); - case 140: - return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!); - case 141: - return WKWebsiteDataTypeEnumData.decode(readValue(buffer)!); + case 129: + return ObjectOrIdentifier.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); } @@ -1794,7 +1765,7 @@ abstract class NSObjectFlutterApi { String keyPath, int objectIdentifier, List changeKeys, - List changeValues); + List changeValues); void dispose(int identifier); @@ -1824,10 +1795,10 @@ abstract class NSObjectFlutterApi { (args[3] as List?)?.cast(); assert(arg_changeKeys != null, 'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null List.'); - final List? arg_changeValues = - (args[4] as List?)?.cast(); + final List? arg_changeValues = + (args[4] as List?)?.cast(); assert(arg_changeValues != null, - 'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null List.'); + 'Argument for dev.flutter.pigeon.NSObjectFlutterApi.observeValue was null, expected non-null List.'); api.observeValue(arg_identifier!, arg_keyPath!, arg_objectIdentifier!, arg_changeKeys!, arg_changeValues!); return; @@ -1878,30 +1849,33 @@ class _WKWebViewHostApiCodec extends StandardMessageCodec { } else if (value is NSUrlRequestData) { buffer.putUint8(133); writeValue(buffer, value.encode()); - } else if (value is WKAudiovisualMediaTypeEnumData) { + } else if (value is ObjectOrIdentifier) { buffer.putUint8(134); writeValue(buffer, value.encode()); - } else if (value is WKFrameInfoData) { + } else if (value is WKAudiovisualMediaTypeEnumData) { buffer.putUint8(135); writeValue(buffer, value.encode()); - } else if (value is WKNavigationActionData) { + } else if (value is WKFrameInfoData) { buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is WKNavigationActionPolicyEnumData) { + } else if (value is WKNavigationActionData) { buffer.putUint8(137); writeValue(buffer, value.encode()); - } else if (value is WKScriptMessageData) { + } else if (value is WKNavigationActionPolicyEnumData) { buffer.putUint8(138); writeValue(buffer, value.encode()); - } else if (value is WKUserScriptData) { + } else if (value is WKScriptMessageData) { buffer.putUint8(139); writeValue(buffer, value.encode()); - } else if (value is WKUserScriptInjectionTimeEnumData) { + } else if (value is WKUserScriptData) { buffer.putUint8(140); writeValue(buffer, value.encode()); - } else if (value is WKWebsiteDataTypeEnumData) { + } else if (value is WKUserScriptInjectionTimeEnumData) { buffer.putUint8(141); writeValue(buffer, value.encode()); + } else if (value is WKWebsiteDataTypeEnumData) { + buffer.putUint8(142); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -1923,20 +1897,22 @@ class _WKWebViewHostApiCodec extends StandardMessageCodec { case 133: return NSUrlRequestData.decode(readValue(buffer)!); case 134: - return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!); + return ObjectOrIdentifier.decode(readValue(buffer)!); case 135: - return WKFrameInfoData.decode(readValue(buffer)!); + return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!); case 136: - return WKNavigationActionData.decode(readValue(buffer)!); + return WKFrameInfoData.decode(readValue(buffer)!); case 137: - return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!); + return WKNavigationActionData.decode(readValue(buffer)!); case 138: - return WKScriptMessageData.decode(readValue(buffer)!); + return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!); case 139: - return WKUserScriptData.decode(readValue(buffer)!); + return WKScriptMessageData.decode(readValue(buffer)!); case 140: - return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!); + return WKUserScriptData.decode(readValue(buffer)!); case 141: + return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!); + case 142: return WKWebsiteDataTypeEnumData.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -2587,3 +2563,78 @@ class WKHttpCookieStoreHostApi { } } } + +/// Host API for `NSUrl`. +/// +/// This class may handle instantiating and adding native object instances that +/// are attached to a Dart instance or method calls on the associated native +/// class or an instance of the class. +/// +/// See https://developer.apple.com/documentation/foundation/nsurl?language=objc. +class NSUrlHostApi { + /// Constructor for [NSUrlHostApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + NSUrlHostApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + Future getAbsoluteString(int arg_identifier) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.NSUrlHostApi.getAbsoluteString', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_identifier]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } +} + +/// Flutter API for `NSUrl`. +/// +/// 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.apple.com/documentation/foundation/nsurl?language=objc. +abstract class NSUrlFlutterApi { + static const MessageCodec codec = StandardMessageCodec(); + + void create(int identifier); + + static void setup(NSUrlFlutterApi? api, {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.NSUrlFlutterApi.create', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.NSUrlFlutterApi.create was null.'); + final List args = (message as List?)!; + final int? arg_identifier = (args[0] as int?); + assert(arg_identifier != null, + 'Argument for dev.flutter.pigeon.NSUrlFlutterApi.create was null, expected non-null int.'); + api.create(arg_identifier!); + return; + }); + } + } + } +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart index 4d85c392df6..a9bbdc5f104 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation.dart @@ -235,6 +235,42 @@ class NSHttpCookie { final Map properties; } +/// An object that represents the location of a resource, such as an item on a +/// remote server or the path to a local file. +/// +/// See https://developer.apple.com/documentation/foundation/nsurl?language=objc. +class NSUrl extends NSObject { + /// Instantiates a [NSUrl] without creating and attaching to an instance + /// of the associated native class. + /// + /// This should only be used outside of tests by subclasses created by this + /// library or to create a copy for an [InstanceManager]. + @protected + NSUrl.detached({super.binaryMessenger, super.instanceManager}) + : _nsUrlHostApi = NSUrlHostApiImpl( + binaryMessenger: binaryMessenger, + instanceManager: instanceManager, + ), + super.detached(); + + final NSUrlHostApiImpl _nsUrlHostApi; + + /// The URL string for the receiver as an absolute URL. (read-only) + /// + /// Represents [NSURL.absoluteString](https://developer.apple.com/documentation/foundation/nsurl/1409868-absolutestring?language=objc). + Future getAbsoluteString() { + return _nsUrlHostApi.getAbsoluteStringFromInstances(this); + } + + @override + NSObject copy() { + return NSUrl.detached( + binaryMessenger: _nsUrlHostApi.binaryMessenger, + instanceManager: _nsUrlHostApi.instanceManager, + ); + } +} + /// The root class of most Objective-C class hierarchies. @immutable class NSObject with Copyable { diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart index 445e232bb0a..4f73c082558 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/foundation/foundation_api_impls.dart @@ -52,7 +52,9 @@ class FoundationFlutterApis { BinaryMessenger? binaryMessenger, InstanceManager? instanceManager, }) : _binaryMessenger = binaryMessenger, - object = NSObjectFlutterApiImpl( + object = NSObjectFlutterApiImpl(instanceManager: instanceManager), + url = NSUrlFlutterApiImpl( + binaryMessenger: binaryMessenger, instanceManager: instanceManager, ); @@ -76,6 +78,10 @@ class FoundationFlutterApis { @visibleForTesting final NSObjectFlutterApiImpl object; + /// Flutter Api for [NSUrl]. + @visibleForTesting + final NSUrlFlutterApiImpl url; + /// Ensures all the Flutter APIs have been set up to receive calls from native code. void ensureSetUp() { if (!_hasBeenSetUp) { @@ -83,6 +89,7 @@ class FoundationFlutterApis { object, binaryMessenger: _binaryMessenger, ); + NSUrlFlutterApi.setup(url, binaryMessenger: _binaryMessenger); _hasBeenSetUp = true; } } @@ -154,7 +161,7 @@ class NSObjectFlutterApiImpl extends NSObjectFlutterApi { String keyPath, int objectIdentifier, List changeKeys, - List changeValues, + List changeValues, ) { final void Function(String, NSObject, Map)? function = _getObject(identifier).observeValue; @@ -163,11 +170,20 @@ class NSObjectFlutterApiImpl extends NSObjectFlutterApi { instanceManager.getInstanceWithWeakReference(objectIdentifier)! as NSObject, Map.fromIterables( - changeKeys.map( - (NSKeyValueChangeKeyEnumData? data) { - return data!.toNSKeyValueChangeKey(); - }, - ), changeValues), + changeKeys.map( + (NSKeyValueChangeKeyEnumData? data) { + return data!.toNSKeyValueChangeKey(); + }, + ), + changeValues.map((ObjectOrIdentifier? value) { + if (value != null && value.isIdentifier) { + return instanceManager.getInstanceWithWeakReference( + value.value! as int, + ); + } + return value?.value; + }), + ), ); } @@ -176,3 +192,60 @@ class NSObjectFlutterApiImpl extends NSObjectFlutterApi { instanceManager.remove(identifier); } } + +/// Host api implementation for [NSUrl]. +class NSUrlHostApiImpl extends NSUrlHostApi { + /// Constructs an [NSUrlHostApiImpl]. + NSUrlHostApiImpl({ + this.binaryMessenger, + InstanceManager? instanceManager, + }) : instanceManager = instanceManager ?? NSObject.globalInstanceManager, + super(binaryMessenger: binaryMessenger); + + /// Sends 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 Objective-C objects. + final InstanceManager instanceManager; + + /// Calls [getAbsoluteString] with the ids of the provided object instances. + Future getAbsoluteStringFromInstances(NSUrl instance) { + return getAbsoluteString(instanceManager.getIdentifier(instance)!); + } +} + +/// Flutter API implementation for [NSUrl]. +/// +/// 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 NSUrlFlutterApiImpl implements NSUrlFlutterApi { + /// Constructs a [NSUrlFlutterApiImpl]. + NSUrlFlutterApiImpl({ + this.binaryMessenger, + InstanceManager? instanceManager, + }) : instanceManager = instanceManager ?? NSObject.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( + NSUrl.detached( + binaryMessenger: binaryMessenger, + instanceManager: instanceManager, + ), + identifier, + ); + } +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart index 76d4a172f4c..9ca4744440e 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/lib/src/webkit_webview_controller.dart @@ -130,6 +130,14 @@ class WebKitWebViewController extends PlatformWebViewController { NSKeyValueObservingOptions.newValue, }, ); + + _webView.addObserver( + _webView, + keyPath: 'URL', + options: { + NSKeyValueObservingOptions.newValue, + }, + ); } /// The WebKit WebView being controlled. @@ -142,13 +150,30 @@ class WebKitWebViewController extends PlatformWebViewController { String keyPath, NSObject object, Map change, - ) { - final ProgressCallback? progressCallback = - weakReference.target?._currentNavigationDelegate?._onProgress; - if (progressCallback != null) { - final double progress = - change[NSKeyValueChangeKey.newValue]! as double; - progressCallback((progress * 100).round()); + ) async { + final WebKitWebViewController? controller = weakReference.target; + if (controller == null) { + return; + } + + switch (keyPath) { + case 'estimatedProgress': + final ProgressCallback? progressCallback = + controller._currentNavigationDelegate?._onProgress; + if (progressCallback != null) { + final double progress = + change[NSKeyValueChangeKey.newValue]! as double; + progressCallback((progress * 100).round()); + } + break; + case 'URL': + final UrlChangeCallback? urlChangeCallback = + controller._currentNavigationDelegate?._onUrlChange; + if (urlChangeCallback != null) { + final NSUrl url = change[NSKeyValueChangeKey.newValue]! as NSUrl; + urlChangeCallback(UrlChange(url: await url.getAbsoluteString())); + } + break; } }; }), @@ -691,6 +716,7 @@ class WebKitNavigationDelegate extends PlatformNavigationDelegate { ProgressCallback? _onProgress; WebResourceErrorCallback? _onWebResourceError; NavigationRequestCallback? _onNavigationRequest; + UrlChangeCallback? _onUrlChange; @override Future setOnPageFinished(PageEventCallback onPageFinished) async { @@ -720,4 +746,9 @@ class WebKitNavigationDelegate extends PlatformNavigationDelegate { ) async { _onNavigationRequest = onNavigationRequest; } + + @override + Future setOnUrlChange(UrlChangeCallback onUrlChange) async { + _onUrlChange = onUrlChange; + } } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart index 7e6c8471051..8dcbc2abd00 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/pigeons/web_kit.dart @@ -258,6 +258,17 @@ class NSHttpCookieData { late List propertyValues; } +/// An object that can represent either a value supported by +/// `StandardMessageCodec`, a data class in this pigeon file, or an identifier +/// of an object stored in an `InstanceManager`. +class ObjectOrIdentifier { + late Object? value; + + /// Whether value is an int that is used to retrieve an instance stored in an + /// `InstanceManager`. + late bool isIdentifier; +} + /// Mirror of WKWebsiteDataStore. /// /// See https://developer.apple.com/documentation/webkit/wkwebsitedatastore?language=objc. @@ -536,7 +547,7 @@ abstract class NSObjectFlutterApi { // conform to `NSCopying`. This splits the map of properties into a list of // keys and values with the ordered maintained. List changeKeys, - List changeValues, + List changeValues, ); @ObjCSelector('disposeObjectWithIdentifier:') @@ -646,3 +657,29 @@ abstract class WKHttpCookieStoreHostApi { @async void setCookie(int identifier, NSHttpCookieData cookie); } + +/// Host API for `NSUrl`. +/// +/// This class may handle instantiating and adding native object instances that +/// are attached to a Dart instance or method calls on the associated native +/// class or an instance of the class. +/// +/// See https://developer.apple.com/documentation/foundation/nsurl?language=objc. +@HostApi(dartHostTestHandler: 'TestNSUrlHostApi') +abstract class NSUrlHostApi { + @ObjCSelector('absoluteStringForNSURLWithIdentifier:') + String? getAbsoluteString(int identifier); +} + +/// Flutter API for `NSUrl`. +/// +/// 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.apple.com/documentation/foundation/nsurl?language=objc. +@FlutterApi() +abstract class NSUrlFlutterApi { + @ObjCSelector('createWithIdentifier:') + void create(int identifier); +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml index 6d3286796ca..4c5c7484c5c 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml +++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml @@ -2,7 +2,7 @@ name: webview_flutter_wkwebview description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control. repository: https://github.com/flutter/packages/tree/main/packages/webview_flutter/webview_flutter_wkwebview issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22 -version: 3.2.4 +version: 3.3.0 environment: sdk: ">=2.18.0 <4.0.0" @@ -20,7 +20,7 @@ dependencies: flutter: sdk: flutter path: ^1.8.0 - webview_flutter_platform_interface: ^2.0.0 + webview_flutter_platform_interface: ^2.1.0 dev_dependencies: build_runner: ^2.1.5 diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart index ce6ecb66241..a9b27a0d731 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/common/test_web_kit.g.dart @@ -986,30 +986,33 @@ class _TestWKWebViewHostApiCodec extends StandardMessageCodec { } else if (value is NSUrlRequestData) { buffer.putUint8(133); writeValue(buffer, value.encode()); - } else if (value is WKAudiovisualMediaTypeEnumData) { + } else if (value is ObjectOrIdentifier) { buffer.putUint8(134); writeValue(buffer, value.encode()); - } else if (value is WKFrameInfoData) { + } else if (value is WKAudiovisualMediaTypeEnumData) { buffer.putUint8(135); writeValue(buffer, value.encode()); - } else if (value is WKNavigationActionData) { + } else if (value is WKFrameInfoData) { buffer.putUint8(136); writeValue(buffer, value.encode()); - } else if (value is WKNavigationActionPolicyEnumData) { + } else if (value is WKNavigationActionData) { buffer.putUint8(137); writeValue(buffer, value.encode()); - } else if (value is WKScriptMessageData) { + } else if (value is WKNavigationActionPolicyEnumData) { buffer.putUint8(138); writeValue(buffer, value.encode()); - } else if (value is WKUserScriptData) { + } else if (value is WKScriptMessageData) { buffer.putUint8(139); writeValue(buffer, value.encode()); - } else if (value is WKUserScriptInjectionTimeEnumData) { + } else if (value is WKUserScriptData) { buffer.putUint8(140); writeValue(buffer, value.encode()); - } else if (value is WKWebsiteDataTypeEnumData) { + } else if (value is WKUserScriptInjectionTimeEnumData) { buffer.putUint8(141); writeValue(buffer, value.encode()); + } else if (value is WKWebsiteDataTypeEnumData) { + buffer.putUint8(142); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -1031,20 +1034,22 @@ class _TestWKWebViewHostApiCodec extends StandardMessageCodec { case 133: return NSUrlRequestData.decode(readValue(buffer)!); case 134: - return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!); + return ObjectOrIdentifier.decode(readValue(buffer)!); case 135: - return WKFrameInfoData.decode(readValue(buffer)!); + return WKAudiovisualMediaTypeEnumData.decode(readValue(buffer)!); case 136: - return WKNavigationActionData.decode(readValue(buffer)!); + return WKFrameInfoData.decode(readValue(buffer)!); case 137: - return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!); + return WKNavigationActionData.decode(readValue(buffer)!); case 138: - return WKScriptMessageData.decode(readValue(buffer)!); + return WKNavigationActionPolicyEnumData.decode(readValue(buffer)!); case 139: - return WKUserScriptData.decode(readValue(buffer)!); + return WKScriptMessageData.decode(readValue(buffer)!); case 140: - return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!); + return WKUserScriptData.decode(readValue(buffer)!); case 141: + return WKUserScriptInjectionTimeEnumData.decode(readValue(buffer)!); + case 142: return WKWebsiteDataTypeEnumData.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -1664,3 +1669,43 @@ abstract class TestWKHttpCookieStoreHostApi { } } } + +/// Host API for `NSUrl`. +/// +/// This class may handle instantiating and adding native object instances that +/// are attached to a Dart instance or method calls on the associated native +/// class or an instance of the class. +/// +/// See https://developer.apple.com/documentation/foundation/nsurl?language=objc. +abstract class TestNSUrlHostApi { + static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => + TestDefaultBinaryMessengerBinding.instance; + static const MessageCodec codec = StandardMessageCodec(); + + String? getAbsoluteString(int identifier); + + static void setup(TestNSUrlHostApi? api, {BinaryMessenger? binaryMessenger}) { + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.NSUrlHostApi.getAbsoluteString', codec, + binaryMessenger: binaryMessenger); + if (api == null) { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, null); + } else { + _testBinaryMessengerBinding!.defaultBinaryMessenger + .setMockDecodedMessageHandler(channel, + (Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.NSUrlHostApi.getAbsoluteString was null.'); + final List args = (message as List?)!; + final int? arg_identifier = (args[0] as int?); + assert(arg_identifier != null, + 'Argument for dev.flutter.pigeon.NSUrlHostApi.getAbsoluteString was null, expected non-null int.'); + final String? output = api.getAbsoluteString(arg_identifier!); + return [output]; + }); + } + } + } +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart index b9536208c71..a6e042791f0 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.dart @@ -17,6 +17,7 @@ import 'foundation_test.mocks.dart'; @GenerateMocks([ TestNSObjectHostApi, + TestNSUrlHostApi, ]) void main() { TestWidgetsFlutterBinding.ensureInitialized(); @@ -137,7 +138,9 @@ void main() { [ NSKeyValueChangeKeyEnumData(value: NSKeyValueChangeKeyEnum.oldValue) ], - ['value'], + [ + ObjectOrIdentifier(isIdentifier: false, value: 'value'), + ], ); expect( @@ -152,6 +155,55 @@ void main() { ); }); + test('observeValue returns object in an `InstanceManager`', () async { + final Completer> argsCompleter = + Completer>(); + + FoundationFlutterApis.instance = FoundationFlutterApis( + instanceManager: instanceManager, + ); + + object = NSObject.detached( + instanceManager: instanceManager, + observeValue: ( + String keyPath, + NSObject object, + Map change, + ) { + argsCompleter.complete([keyPath, object, change]); + }, + ); + instanceManager.addHostCreatedInstance(object, 1); + + final NSObject returnedObject = NSObject.detached( + instanceManager: instanceManager, + ); + instanceManager.addHostCreatedInstance(returnedObject, 2); + + FoundationFlutterApis.instance.object.observeValue( + 1, + 'keyPath', + 1, + [ + NSKeyValueChangeKeyEnumData(value: NSKeyValueChangeKeyEnum.oldValue) + ], + [ + ObjectOrIdentifier(isIdentifier: true, value: 2), + ], + ); + + expect( + argsCompleter.future, + completion([ + 'keyPath', + object, + { + NSKeyValueChangeKey.oldValue: returnedObject, + }, + ]), + ); + }); + test('NSObjectFlutterApi.dispose', () { FoundationFlutterApis.instance = FoundationFlutterApis( instanceManager: instanceManager, @@ -166,5 +218,32 @@ void main() { expect(instanceManager.containsIdentifier(1), isFalse); }); }); + + group('NSUrl', () { + // Ensure the test host api is removed after each test run. + tearDown(() => TestNSUrlHostApi.setup(null)); + + test('getAbsoluteString', () async { + final MockTestNSUrlHostApi mockApi = MockTestNSUrlHostApi(); + TestNSUrlHostApi.setup(mockApi); + + final NSUrl url = NSUrl.detached(instanceManager: instanceManager); + instanceManager.addHostCreatedInstance(url, 0); + + when(mockApi.getAbsoluteString(0)).thenReturn('myString'); + + expect(await url.getAbsoluteString(), 'myString'); + }); + + test('Flutter API create', () { + final NSUrlFlutterApi flutterApi = NSUrlFlutterApiImpl( + instanceManager: instanceManager, + ); + + flutterApi.create(0); + + expect(instanceManager.getInstanceWithWeakReference(0), isA()); + }); + }); }); } diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart index 81c919ed51c..a648fc65a4d 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/src/foundation/foundation_test.mocks.dart @@ -73,3 +73,19 @@ class MockTestNSObjectHostApi extends _i1.Mock returnValueForMissingStub: null, ); } + +/// A class which mocks [TestNSUrlHostApi]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockTestNSUrlHostApi extends _i1.Mock implements _i2.TestNSUrlHostApi { + MockTestNSUrlHostApi() { + _i1.throwOnMissingStub(this); + } + + @override + String? getAbsoluteString(int? identifier) => + (super.noSuchMethod(Invocation.method( + #getAbsoluteString, + [identifier], + )) as String?); +} diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart index abf3f798d92..dc7085bc52e 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.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:async'; import 'dart:math'; // TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#104231) // ignore: unnecessary_import @@ -23,6 +24,7 @@ import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; import 'webkit_webview_controller_test.mocks.dart'; @GenerateMocks([ + NSUrl, UIScrollView, WKPreferences, WKUserContentController, @@ -929,6 +931,70 @@ void main() { expect(callbackProgress, 0); }); + test('setPlatformNavigationDelegate onUrlChange', () async { + final MockWKWebView mockWebView = MockWKWebView(); + + late final void Function( + String keyPath, + NSObject object, + Map change, + ) webViewObserveValue; + + final WebKitWebViewController controller = createControllerWithMocks( + createMockWebView: ( + _, { + void Function( + String keyPath, + NSObject object, + Map change, + )? observeValue, + }) { + webViewObserveValue = observeValue!; + return mockWebView; + }, + ); + + verify( + mockWebView.addObserver( + mockWebView, + keyPath: 'URL', + options: { + NSKeyValueObservingOptions.newValue, + }, + ), + ); + + final WebKitNavigationDelegate navigationDelegate = + WebKitNavigationDelegate( + const WebKitNavigationDelegateCreationParams( + webKitProxy: WebKitProxy( + createNavigationDelegate: CapturingNavigationDelegate.new, + createUIDelegate: WKUIDelegate.detached, + ), + ), + ); + + final Completer urlChangeCompleter = Completer(); + navigationDelegate.setOnUrlChange( + (UrlChange change) => urlChangeCompleter.complete(change), + ); + + await controller.setPlatformNavigationDelegate(navigationDelegate); + + final MockNSUrl mockNSUrl = MockNSUrl(); + when(mockNSUrl.getAbsoluteString()).thenAnswer((_) { + return Future.value('https://www.google.com'); + }); + webViewObserveValue( + 'URL', + mockWebView, + {NSKeyValueChangeKey.newValue: mockNSUrl}, + ); + + final UrlChange urlChange = await urlChangeCompleter.future; + expect(urlChange.url, 'https://www.google.com'); + }); + test('webViewIdentifier', () { final InstanceManager instanceManager = InstanceManager( onWeakReferenceRemoved: (_) {}, diff --git a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart index 184d0a68aaf..9eb03971e82 100644 --- a/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart +++ b/packages/webview_flutter/webview_flutter_wkwebview/test/webkit_webview_controller_test.mocks.dart @@ -3,15 +3,15 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i5; -import 'dart:math' as _i2; -import 'dart:ui' as _i6; +import 'dart:async' as _i6; +import 'dart:math' as _i3; +import 'dart:ui' as _i7; import 'package:mockito/mockito.dart' as _i1; import 'package:webview_flutter_wkwebview/src/foundation/foundation.dart' - as _i7; -import 'package:webview_flutter_wkwebview/src/ui_kit/ui_kit.dart' as _i3; -import 'package:webview_flutter_wkwebview/src/web_kit/web_kit.dart' as _i4; + as _i2; +import 'package:webview_flutter_wkwebview/src/ui_kit/ui_kit.dart' as _i4; +import 'package:webview_flutter_wkwebview/src/web_kit/web_kit.dart' as _i5; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -24,9 +24,8 @@ import 'package:webview_flutter_wkwebview/src/web_kit/web_kit.dart' as _i4; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakePoint_0 extends _i1.SmartFake - implements _i2.Point { - _FakePoint_0( +class _FakeNSObject_0 extends _i1.SmartFake implements _i2.NSObject { + _FakeNSObject_0( Object parent, Invocation parentInvocation, ) : super( @@ -35,8 +34,9 @@ class _FakePoint_0 extends _i1.SmartFake ); } -class _FakeUIScrollView_1 extends _i1.SmartFake implements _i3.UIScrollView { - _FakeUIScrollView_1( +class _FakePoint_1 extends _i1.SmartFake + implements _i3.Point { + _FakePoint_1( Object parent, Invocation parentInvocation, ) : super( @@ -45,8 +45,8 @@ class _FakeUIScrollView_1 extends _i1.SmartFake implements _i3.UIScrollView { ); } -class _FakeWKPreferences_2 extends _i1.SmartFake implements _i4.WKPreferences { - _FakeWKPreferences_2( +class _FakeUIScrollView_2 extends _i1.SmartFake implements _i4.UIScrollView { + _FakeUIScrollView_2( Object parent, Invocation parentInvocation, ) : super( @@ -55,9 +55,8 @@ class _FakeWKPreferences_2 extends _i1.SmartFake implements _i4.WKPreferences { ); } -class _FakeWKUserContentController_3 extends _i1.SmartFake - implements _i4.WKUserContentController { - _FakeWKUserContentController_3( +class _FakeWKPreferences_3 extends _i1.SmartFake implements _i5.WKPreferences { + _FakeWKPreferences_3( Object parent, Invocation parentInvocation, ) : super( @@ -66,9 +65,9 @@ class _FakeWKUserContentController_3 extends _i1.SmartFake ); } -class _FakeWKHttpCookieStore_4 extends _i1.SmartFake - implements _i4.WKHttpCookieStore { - _FakeWKHttpCookieStore_4( +class _FakeWKUserContentController_4 extends _i1.SmartFake + implements _i5.WKUserContentController { + _FakeWKUserContentController_4( Object parent, Invocation parentInvocation, ) : super( @@ -77,9 +76,9 @@ class _FakeWKHttpCookieStore_4 extends _i1.SmartFake ); } -class _FakeWKWebsiteDataStore_5 extends _i1.SmartFake - implements _i4.WKWebsiteDataStore { - _FakeWKWebsiteDataStore_5( +class _FakeWKHttpCookieStore_5 extends _i1.SmartFake + implements _i5.WKHttpCookieStore { + _FakeWKHttpCookieStore_5( Object parent, Invocation parentInvocation, ) : super( @@ -88,9 +87,9 @@ class _FakeWKWebsiteDataStore_5 extends _i1.SmartFake ); } -class _FakeWKWebViewConfiguration_6 extends _i1.SmartFake - implements _i4.WKWebViewConfiguration { - _FakeWKWebViewConfiguration_6( +class _FakeWKWebsiteDataStore_6 extends _i1.SmartFake + implements _i5.WKWebsiteDataStore { + _FakeWKWebsiteDataStore_6( Object parent, Invocation parentInvocation, ) : super( @@ -99,8 +98,9 @@ class _FakeWKWebViewConfiguration_6 extends _i1.SmartFake ); } -class _FakeWKWebView_7 extends _i1.SmartFake implements _i4.WKWebView { - _FakeWKWebView_7( +class _FakeWKWebViewConfiguration_7 extends _i1.SmartFake + implements _i5.WKWebViewConfiguration { + _FakeWKWebViewConfiguration_7( Object parent, Invocation parentInvocation, ) : super( @@ -109,85 +109,159 @@ class _FakeWKWebView_7 extends _i1.SmartFake implements _i4.WKWebView { ); } +class _FakeWKWebView_8 extends _i1.SmartFake implements _i5.WKWebView { + _FakeWKWebView_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [NSUrl]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockNSUrl extends _i1.Mock implements _i2.NSUrl { + MockNSUrl() { + _i1.throwOnMissingStub(this); + } + + @override + _i6.Future getAbsoluteString() => (super.noSuchMethod( + Invocation.method( + #getAbsoluteString, + [], + ), + returnValue: _i6.Future.value(), + ) as _i6.Future); + @override + _i2.NSObject copy() => (super.noSuchMethod( + Invocation.method( + #copy, + [], + ), + returnValue: _FakeNSObject_0( + this, + Invocation.method( + #copy, + [], + ), + ), + ) as _i2.NSObject); + @override + _i6.Future addObserver( + _i2.NSObject? observer, { + required String? keyPath, + required Set<_i2.NSKeyValueObservingOptions>? options, + }) => + (super.noSuchMethod( + Invocation.method( + #addObserver, + [observer], + { + #keyPath: keyPath, + #options: options, + }, + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + @override + _i6.Future removeObserver( + _i2.NSObject? observer, { + required String? keyPath, + }) => + (super.noSuchMethod( + Invocation.method( + #removeObserver, + [observer], + {#keyPath: keyPath}, + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); +} + /// A class which mocks [UIScrollView]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { +class MockUIScrollView extends _i1.Mock implements _i4.UIScrollView { MockUIScrollView() { _i1.throwOnMissingStub(this); } @override - _i5.Future<_i2.Point> getContentOffset() => (super.noSuchMethod( + _i6.Future<_i3.Point> getContentOffset() => (super.noSuchMethod( Invocation.method( #getContentOffset, [], ), - returnValue: _i5.Future<_i2.Point>.value(_FakePoint_0( + returnValue: _i6.Future<_i3.Point>.value(_FakePoint_1( this, Invocation.method( #getContentOffset, [], ), )), - ) as _i5.Future<_i2.Point>); + ) as _i6.Future<_i3.Point>); @override - _i5.Future scrollBy(_i2.Point? offset) => (super.noSuchMethod( + _i6.Future scrollBy(_i3.Point? offset) => (super.noSuchMethod( Invocation.method( #scrollBy, [offset], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future setContentOffset(_i2.Point? offset) => + _i6.Future setContentOffset(_i3.Point? offset) => (super.noSuchMethod( Invocation.method( #setContentOffset, [offset], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i3.UIScrollView copy() => (super.noSuchMethod( + _i4.UIScrollView copy() => (super.noSuchMethod( Invocation.method( #copy, [], ), - returnValue: _FakeUIScrollView_1( + returnValue: _FakeUIScrollView_2( this, Invocation.method( #copy, [], ), ), - ) as _i3.UIScrollView); + ) as _i4.UIScrollView); @override - _i5.Future setBackgroundColor(_i6.Color? color) => (super.noSuchMethod( + _i6.Future setBackgroundColor(_i7.Color? color) => (super.noSuchMethod( Invocation.method( #setBackgroundColor, [color], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future setOpaque(bool? opaque) => (super.noSuchMethod( + _i6.Future setOpaque(bool? opaque) => (super.noSuchMethod( Invocation.method( #setOpaque, [opaque], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future addObserver( - _i7.NSObject? observer, { + _i6.Future addObserver( + _i2.NSObject? observer, { required String? keyPath, - required Set<_i7.NSKeyValueObservingOptions>? options, + required Set<_i2.NSKeyValueObservingOptions>? options, }) => (super.noSuchMethod( Invocation.method( @@ -198,12 +272,12 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { #options: options, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeObserver( - _i7.NSObject? observer, { + _i6.Future removeObserver( + _i2.NSObject? observer, { required String? keyPath, }) => (super.noSuchMethod( @@ -212,48 +286,48 @@ class MockUIScrollView extends _i1.Mock implements _i3.UIScrollView { [observer], {#keyPath: keyPath}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); } /// A class which mocks [WKPreferences]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockWKPreferences extends _i1.Mock implements _i4.WKPreferences { +class MockWKPreferences extends _i1.Mock implements _i5.WKPreferences { MockWKPreferences() { _i1.throwOnMissingStub(this); } @override - _i5.Future setJavaScriptEnabled(bool? enabled) => (super.noSuchMethod( + _i6.Future setJavaScriptEnabled(bool? enabled) => (super.noSuchMethod( Invocation.method( #setJavaScriptEnabled, [enabled], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i4.WKPreferences copy() => (super.noSuchMethod( + _i5.WKPreferences copy() => (super.noSuchMethod( Invocation.method( #copy, [], ), - returnValue: _FakeWKPreferences_2( + returnValue: _FakeWKPreferences_3( this, Invocation.method( #copy, [], ), ), - ) as _i4.WKPreferences); + ) as _i5.WKPreferences); @override - _i5.Future addObserver( - _i7.NSObject? observer, { + _i6.Future addObserver( + _i2.NSObject? observer, { required String? keyPath, - required Set<_i7.NSKeyValueObservingOptions>? options, + required Set<_i2.NSKeyValueObservingOptions>? options, }) => (super.noSuchMethod( Invocation.method( @@ -264,12 +338,12 @@ class MockWKPreferences extends _i1.Mock implements _i4.WKPreferences { #options: options, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeObserver( - _i7.NSObject? observer, { + _i6.Future removeObserver( + _i2.NSObject? observer, { required String? keyPath, }) => (super.noSuchMethod( @@ -278,9 +352,9 @@ class MockWKPreferences extends _i1.Mock implements _i4.WKPreferences { [observer], {#keyPath: keyPath}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); } /// A class which mocks [WKUserContentController]. @@ -288,14 +362,14 @@ class MockWKPreferences extends _i1.Mock implements _i4.WKPreferences { /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockWKUserContentController extends _i1.Mock - implements _i4.WKUserContentController { + implements _i5.WKUserContentController { MockWKUserContentController() { _i1.throwOnMissingStub(this); } @override - _i5.Future addScriptMessageHandler( - _i4.WKScriptMessageHandler? handler, + _i6.Future addScriptMessageHandler( + _i5.WKScriptMessageHandler? handler, String? name, ) => (super.noSuchMethod( @@ -306,66 +380,66 @@ class MockWKUserContentController extends _i1.Mock name, ], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeScriptMessageHandler(String? name) => + _i6.Future removeScriptMessageHandler(String? name) => (super.noSuchMethod( Invocation.method( #removeScriptMessageHandler, [name], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeAllScriptMessageHandlers() => (super.noSuchMethod( + _i6.Future removeAllScriptMessageHandlers() => (super.noSuchMethod( Invocation.method( #removeAllScriptMessageHandlers, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future addUserScript(_i4.WKUserScript? userScript) => + _i6.Future addUserScript(_i5.WKUserScript? userScript) => (super.noSuchMethod( Invocation.method( #addUserScript, [userScript], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeAllUserScripts() => (super.noSuchMethod( + _i6.Future removeAllUserScripts() => (super.noSuchMethod( Invocation.method( #removeAllUserScripts, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i4.WKUserContentController copy() => (super.noSuchMethod( + _i5.WKUserContentController copy() => (super.noSuchMethod( Invocation.method( #copy, [], ), - returnValue: _FakeWKUserContentController_3( + returnValue: _FakeWKUserContentController_4( this, Invocation.method( #copy, [], ), ), - ) as _i4.WKUserContentController); + ) as _i5.WKUserContentController); @override - _i5.Future addObserver( - _i7.NSObject? observer, { + _i6.Future addObserver( + _i2.NSObject? observer, { required String? keyPath, - required Set<_i7.NSKeyValueObservingOptions>? options, + required Set<_i2.NSKeyValueObservingOptions>? options, }) => (super.noSuchMethod( Invocation.method( @@ -376,12 +450,12 @@ class MockWKUserContentController extends _i1.Mock #options: options, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeObserver( - _i7.NSObject? observer, { + _i6.Future removeObserver( + _i2.NSObject? observer, { required String? keyPath, }) => (super.noSuchMethod( @@ -390,9 +464,9 @@ class MockWKUserContentController extends _i1.Mock [observer], {#keyPath: keyPath}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); } /// A class which mocks [WKWebsiteDataStore]. @@ -400,22 +474,22 @@ class MockWKUserContentController extends _i1.Mock /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockWKWebsiteDataStore extends _i1.Mock - implements _i4.WKWebsiteDataStore { + implements _i5.WKWebsiteDataStore { MockWKWebsiteDataStore() { _i1.throwOnMissingStub(this); } @override - _i4.WKHttpCookieStore get httpCookieStore => (super.noSuchMethod( + _i5.WKHttpCookieStore get httpCookieStore => (super.noSuchMethod( Invocation.getter(#httpCookieStore), - returnValue: _FakeWKHttpCookieStore_4( + returnValue: _FakeWKHttpCookieStore_5( this, Invocation.getter(#httpCookieStore), ), - ) as _i4.WKHttpCookieStore); + ) as _i5.WKHttpCookieStore); @override - _i5.Future removeDataOfTypes( - Set<_i4.WKWebsiteDataType>? dataTypes, + _i6.Future removeDataOfTypes( + Set<_i5.WKWebsiteDataType>? dataTypes, DateTime? since, ) => (super.noSuchMethod( @@ -426,27 +500,27 @@ class MockWKWebsiteDataStore extends _i1.Mock since, ], ), - returnValue: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i6.Future.value(false), + ) as _i6.Future); @override - _i4.WKWebsiteDataStore copy() => (super.noSuchMethod( + _i5.WKWebsiteDataStore copy() => (super.noSuchMethod( Invocation.method( #copy, [], ), - returnValue: _FakeWKWebsiteDataStore_5( + returnValue: _FakeWKWebsiteDataStore_6( this, Invocation.method( #copy, [], ), ), - ) as _i4.WKWebsiteDataStore); + ) as _i5.WKWebsiteDataStore); @override - _i5.Future addObserver( - _i7.NSObject? observer, { + _i6.Future addObserver( + _i2.NSObject? observer, { required String? keyPath, - required Set<_i7.NSKeyValueObservingOptions>? options, + required Set<_i2.NSKeyValueObservingOptions>? options, }) => (super.noSuchMethod( Invocation.method( @@ -457,12 +531,12 @@ class MockWKWebsiteDataStore extends _i1.Mock #options: options, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeObserver( - _i7.NSObject? observer, { + _i6.Future removeObserver( + _i2.NSObject? observer, { required String? keyPath, }) => (super.noSuchMethod( @@ -471,84 +545,84 @@ class MockWKWebsiteDataStore extends _i1.Mock [observer], {#keyPath: keyPath}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); } /// A class which mocks [WKWebView]. /// /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable -class MockWKWebView extends _i1.Mock implements _i4.WKWebView { +class MockWKWebView extends _i1.Mock implements _i5.WKWebView { MockWKWebView() { _i1.throwOnMissingStub(this); } @override - _i4.WKWebViewConfiguration get configuration => (super.noSuchMethod( + _i5.WKWebViewConfiguration get configuration => (super.noSuchMethod( Invocation.getter(#configuration), - returnValue: _FakeWKWebViewConfiguration_6( + returnValue: _FakeWKWebViewConfiguration_7( this, Invocation.getter(#configuration), ), - ) as _i4.WKWebViewConfiguration); + ) as _i5.WKWebViewConfiguration); @override - _i3.UIScrollView get scrollView => (super.noSuchMethod( + _i4.UIScrollView get scrollView => (super.noSuchMethod( Invocation.getter(#scrollView), - returnValue: _FakeUIScrollView_1( + returnValue: _FakeUIScrollView_2( this, Invocation.getter(#scrollView), ), - ) as _i3.UIScrollView); + ) as _i4.UIScrollView); @override - _i5.Future setUIDelegate(_i4.WKUIDelegate? delegate) => + _i6.Future setUIDelegate(_i5.WKUIDelegate? delegate) => (super.noSuchMethod( Invocation.method( #setUIDelegate, [delegate], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future setNavigationDelegate(_i4.WKNavigationDelegate? delegate) => + _i6.Future setNavigationDelegate(_i5.WKNavigationDelegate? delegate) => (super.noSuchMethod( Invocation.method( #setNavigationDelegate, [delegate], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future getUrl() => (super.noSuchMethod( + _i6.Future getUrl() => (super.noSuchMethod( Invocation.method( #getUrl, [], ), - returnValue: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future getEstimatedProgress() => (super.noSuchMethod( + _i6.Future getEstimatedProgress() => (super.noSuchMethod( Invocation.method( #getEstimatedProgress, [], ), - returnValue: _i5.Future.value(0.0), - ) as _i5.Future); + returnValue: _i6.Future.value(0.0), + ) as _i6.Future); @override - _i5.Future loadRequest(_i7.NSUrlRequest? request) => + _i6.Future loadRequest(_i2.NSUrlRequest? request) => (super.noSuchMethod( Invocation.method( #loadRequest, [request], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future loadHtmlString( + _i6.Future loadHtmlString( String? string, { String? baseUrl, }) => @@ -558,11 +632,11 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { [string], {#baseUrl: baseUrl}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future loadFileUrl( + _i6.Future loadFileUrl( String? url, { required String? readAccessUrl, }) => @@ -572,134 +646,134 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { [url], {#readAccessUrl: readAccessUrl}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future loadFlutterAsset(String? key) => (super.noSuchMethod( + _i6.Future loadFlutterAsset(String? key) => (super.noSuchMethod( Invocation.method( #loadFlutterAsset, [key], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future canGoBack() => (super.noSuchMethod( + _i6.Future canGoBack() => (super.noSuchMethod( Invocation.method( #canGoBack, [], ), - returnValue: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i6.Future.value(false), + ) as _i6.Future); @override - _i5.Future canGoForward() => (super.noSuchMethod( + _i6.Future canGoForward() => (super.noSuchMethod( Invocation.method( #canGoForward, [], ), - returnValue: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i6.Future.value(false), + ) as _i6.Future); @override - _i5.Future goBack() => (super.noSuchMethod( + _i6.Future goBack() => (super.noSuchMethod( Invocation.method( #goBack, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future goForward() => (super.noSuchMethod( + _i6.Future goForward() => (super.noSuchMethod( Invocation.method( #goForward, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future reload() => (super.noSuchMethod( + _i6.Future reload() => (super.noSuchMethod( Invocation.method( #reload, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future getTitle() => (super.noSuchMethod( + _i6.Future getTitle() => (super.noSuchMethod( Invocation.method( #getTitle, [], ), - returnValue: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future setAllowsBackForwardNavigationGestures(bool? allow) => + _i6.Future setAllowsBackForwardNavigationGestures(bool? allow) => (super.noSuchMethod( Invocation.method( #setAllowsBackForwardNavigationGestures, [allow], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future setCustomUserAgent(String? userAgent) => (super.noSuchMethod( + _i6.Future setCustomUserAgent(String? userAgent) => (super.noSuchMethod( Invocation.method( #setCustomUserAgent, [userAgent], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future evaluateJavaScript(String? javaScriptString) => + _i6.Future evaluateJavaScript(String? javaScriptString) => (super.noSuchMethod( Invocation.method( #evaluateJavaScript, [javaScriptString], ), - returnValue: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + ) as _i6.Future); @override - _i4.WKWebView copy() => (super.noSuchMethod( + _i5.WKWebView copy() => (super.noSuchMethod( Invocation.method( #copy, [], ), - returnValue: _FakeWKWebView_7( + returnValue: _FakeWKWebView_8( this, Invocation.method( #copy, [], ), ), - ) as _i4.WKWebView); + ) as _i5.WKWebView); @override - _i5.Future setBackgroundColor(_i6.Color? color) => (super.noSuchMethod( + _i6.Future setBackgroundColor(_i7.Color? color) => (super.noSuchMethod( Invocation.method( #setBackgroundColor, [color], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future setOpaque(bool? opaque) => (super.noSuchMethod( + _i6.Future setOpaque(bool? opaque) => (super.noSuchMethod( Invocation.method( #setOpaque, [opaque], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future addObserver( - _i7.NSObject? observer, { + _i6.Future addObserver( + _i2.NSObject? observer, { required String? keyPath, - required Set<_i7.NSKeyValueObservingOptions>? options, + required Set<_i2.NSKeyValueObservingOptions>? options, }) => (super.noSuchMethod( Invocation.method( @@ -710,12 +784,12 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { #options: options, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeObserver( - _i7.NSObject? observer, { + _i6.Future removeObserver( + _i2.NSObject? observer, { required String? keyPath, }) => (super.noSuchMethod( @@ -724,9 +798,9 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { [observer], {#keyPath: keyPath}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); } /// A class which mocks [WKWebViewConfiguration]. @@ -734,75 +808,75 @@ class MockWKWebView extends _i1.Mock implements _i4.WKWebView { /// See the documentation for Mockito's code generation for more information. // ignore: must_be_immutable class MockWKWebViewConfiguration extends _i1.Mock - implements _i4.WKWebViewConfiguration { + implements _i5.WKWebViewConfiguration { MockWKWebViewConfiguration() { _i1.throwOnMissingStub(this); } @override - _i4.WKUserContentController get userContentController => (super.noSuchMethod( + _i5.WKUserContentController get userContentController => (super.noSuchMethod( Invocation.getter(#userContentController), - returnValue: _FakeWKUserContentController_3( + returnValue: _FakeWKUserContentController_4( this, Invocation.getter(#userContentController), ), - ) as _i4.WKUserContentController); + ) as _i5.WKUserContentController); @override - _i4.WKPreferences get preferences => (super.noSuchMethod( + _i5.WKPreferences get preferences => (super.noSuchMethod( Invocation.getter(#preferences), - returnValue: _FakeWKPreferences_2( + returnValue: _FakeWKPreferences_3( this, Invocation.getter(#preferences), ), - ) as _i4.WKPreferences); + ) as _i5.WKPreferences); @override - _i4.WKWebsiteDataStore get websiteDataStore => (super.noSuchMethod( + _i5.WKWebsiteDataStore get websiteDataStore => (super.noSuchMethod( Invocation.getter(#websiteDataStore), - returnValue: _FakeWKWebsiteDataStore_5( + returnValue: _FakeWKWebsiteDataStore_6( this, Invocation.getter(#websiteDataStore), ), - ) as _i4.WKWebsiteDataStore); + ) as _i5.WKWebsiteDataStore); @override - _i5.Future setAllowsInlineMediaPlayback(bool? allow) => + _i6.Future setAllowsInlineMediaPlayback(bool? allow) => (super.noSuchMethod( Invocation.method( #setAllowsInlineMediaPlayback, [allow], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future setMediaTypesRequiringUserActionForPlayback( - Set<_i4.WKAudiovisualMediaType>? types) => + _i6.Future setMediaTypesRequiringUserActionForPlayback( + Set<_i5.WKAudiovisualMediaType>? types) => (super.noSuchMethod( Invocation.method( #setMediaTypesRequiringUserActionForPlayback, [types], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i4.WKWebViewConfiguration copy() => (super.noSuchMethod( + _i5.WKWebViewConfiguration copy() => (super.noSuchMethod( Invocation.method( #copy, [], ), - returnValue: _FakeWKWebViewConfiguration_6( + returnValue: _FakeWKWebViewConfiguration_7( this, Invocation.method( #copy, [], ), ), - ) as _i4.WKWebViewConfiguration); + ) as _i5.WKWebViewConfiguration); @override - _i5.Future addObserver( - _i7.NSObject? observer, { + _i6.Future addObserver( + _i2.NSObject? observer, { required String? keyPath, - required Set<_i7.NSKeyValueObservingOptions>? options, + required Set<_i2.NSKeyValueObservingOptions>? options, }) => (super.noSuchMethod( Invocation.method( @@ -813,12 +887,12 @@ class MockWKWebViewConfiguration extends _i1.Mock #options: options, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); @override - _i5.Future removeObserver( - _i7.NSObject? observer, { + _i6.Future removeObserver( + _i2.NSObject? observer, { required String? keyPath, }) => (super.noSuchMethod( @@ -827,7 +901,7 @@ class MockWKWebViewConfiguration extends _i1.Mock [observer], {#keyPath: keyPath}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); }