diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b94b454..78cc38b6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ ### BREAKING CHANGES - On Android, the `InAppWebView` widget uses hybrid composition by default (`useHybridComposition: true`). +- All properties of `GeolocationPermissionShowPromptResponse` cannot be `null`; ## 5.4.3+4 diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java index f032ee77..f0fcab94 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java @@ -13,11 +13,12 @@ import androidx.webkit.ServiceWorkerControllerCompat; import androidx.webkit.ServiceWorkerWebSettingsCompat; import androidx.webkit.WebViewFeature; +import com.pichillilorenzo.flutter_inappwebview.types.WebResourceRequestExt; +import com.pichillilorenzo.flutter_inappwebview.types.WebResourceResponseExt; + import java.io.ByteArrayInputStream; -import java.util.HashMap; import java.util.Map; -import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; @@ -44,7 +45,7 @@ public class ServiceWorkerManager implements MethodChannel.MethodCallHandler { } @Override - public void onMethodCall(MethodCall call, MethodChannel.Result result) { + public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { ServiceWorkerWebSettingsCompat serviceWorkerWebSettings = (serviceWorkerController != null) ? serviceWorkerController.getServiceWorkerWebSettings() : null; switch (call.method) { @@ -124,17 +125,11 @@ public class ServiceWorkerManager implements MethodChannel.MethodCallHandler { @Nullable @Override public WebResourceResponse shouldInterceptRequest(@NonNull WebResourceRequest request) { - final Map obj = new HashMap<>(); - obj.put("url", request.getUrl().toString()); - obj.put("method", request.getMethod()); - obj.put("headers", request.getRequestHeaders()); - obj.put("isForMainFrame", request.isForMainFrame()); - obj.put("hasGesture", request.hasGesture()); - obj.put("isRedirect", request.isRedirect()); - + WebResourceRequestExt requestExt = WebResourceRequestExt.fromWebResourceRequest(request); + Util.WaitFlutterResult flutterResult; try { - flutterResult = Util.invokeMethodAndWait(channel, "shouldInterceptRequest", obj); + flutterResult = Util.invokeMethodAndWait(channel, "shouldInterceptRequest", requestExt.toMap()); } catch (InterruptedException e) { e.printStackTrace(); return null; @@ -144,20 +139,22 @@ public class ServiceWorkerManager implements MethodChannel.MethodCallHandler { Log.e(LOG_TAG, flutterResult.error); } else if (flutterResult.result != null) { - Map res = (Map) flutterResult.result; - String contentType = (String) res.get("contentType"); - String contentEncoding = (String) res.get("contentEncoding"); - byte[] data = (byte[]) res.get("data"); - Map responseHeaders = (Map) res.get("headers"); - Integer statusCode = (Integer) res.get("statusCode"); - String reasonPhrase = (String) res.get("reasonPhrase"); + WebResourceResponseExt response = WebResourceResponseExt.fromMap((Map) flutterResult.result); + if (response != null) { + String contentType = response.getContentType(); + String contentEncoding = response.getContentEncoding(); + byte[] data = response.getData(); + Map responseHeaders = response.getHeaders(); + Integer statusCode = response.getStatusCode(); + String reasonPhrase = response.getReasonPhrase(); - ByteArrayInputStream inputStream = (data != null) ? new ByteArrayInputStream(data) : null; + ByteArrayInputStream inputStream = (data != null) ? new ByteArrayInputStream(data) : null; - if ((responseHeaders == null && statusCode == null && reasonPhrase == null) || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - return new WebResourceResponse(contentType, contentEncoding, inputStream); - } else { - return new WebResourceResponse(contentType, contentEncoding, statusCode, reasonPhrase, responseHeaders, inputStream); + if (statusCode != null && reasonPhrase != null) { + return new WebResourceResponse(contentType, contentEncoding, statusCode, reasonPhrase, responseHeaders, inputStream); + } else { + return new WebResourceResponse(contentType, contentEncoding, inputStream); + } } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java index 85a12331..6f4330cc 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java @@ -10,9 +10,12 @@ import android.os.Looper; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; +import com.pichillilorenzo.flutter_inappwebview.types.SyncBaseCallbackResultImpl; + import org.json.JSONArray; import org.json.JSONObject; @@ -127,6 +130,20 @@ public class Util { return new WaitFlutterResult(flutterResultMap.get("result"), (String) flutterResultMap.get("error")); } + public static T invokeMethodAndWaitResult(final @NonNull MethodChannel channel, + final @NonNull String method, final @Nullable Object arguments, + final @NonNull SyncBaseCallbackResultImpl callback) throws InterruptedException { + Handler handler = new Handler(Looper.getMainLooper()); + handler.post(new Runnable() { + @Override + public void run() { + channel.invokeMethod(method, arguments, callback); + } + }); + callback.latch.await(); + return callback.result; + } + public static class WaitFlutterResult { public Object result; public String error; @@ -137,8 +154,11 @@ public class Util { } } - public static PrivateKeyAndCertificates loadPrivateKeyAndCertificate(InAppWebViewFlutterPlugin plugin, String certificatePath, String certificatePassword, String keyStoreType) { - + @Nullable + public static PrivateKeyAndCertificates loadPrivateKeyAndCertificate(@NonNull InAppWebViewFlutterPlugin plugin, + @NonNull String certificatePath, + @Nullable String certificatePassword, + @NonNull String keyStoreType) { PrivateKeyAndCertificates privateKeyAndCertificates = null; try { @@ -150,7 +170,7 @@ public class Util { Enumeration aliases = keyStore.aliases(); String alias = aliases.nextElement(); - Key key = keyStore.getKey(alias, certificatePassword.toCharArray()); + Key key = keyStore.getKey(alias, certificatePassword != null ? certificatePassword.toCharArray() : null); if (key instanceof PrivateKey) { PrivateKey privateKey = (PrivateKey)key; Certificate cert = keyStore.getCertificate(alias); @@ -319,8 +339,8 @@ public class Util { return InetAddress.getByName(address).getCanonicalHostName(); } - public static Object getOrDefault(Map map, String key, Object defaultValue) { - return map.containsKey(key) ? map.get(key) : defaultValue; + public static T getOrDefault(Map map, String key, T defaultValue) { + return map.containsKey(key) ? (T) map.get(key) : defaultValue; } @Nullable diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java index ca63f24a..e60cdc13 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java @@ -77,14 +77,14 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl extras.putSerializable("actionButton", (Serializable) actionButton); extras.putSerializable("menuItemList", (Serializable) menuItemList); - Boolean isSingleInstance = (Boolean) Util.getOrDefault(settings, "isSingleInstance", false); - Boolean isTrustedWebActivity = (Boolean) Util.getOrDefault(settings, "isTrustedWebActivity", false); + Boolean isSingleInstance = Util.getOrDefault(settings, "isSingleInstance", false); + Boolean isTrustedWebActivity = Util.getOrDefault(settings, "isTrustedWebActivity", false); if (CustomTabActivityHelper.isAvailable(activity)) { intent = new Intent(activity, !isSingleInstance ? (!isTrustedWebActivity ? ChromeCustomTabsActivity.class : TrustedWebActivity.class) : (!isTrustedWebActivity ? ChromeCustomTabsActivitySingleInstance.class : TrustedWebActivitySingleInstance.class)); intent.putExtras(extras); - Boolean noHistory = (Boolean) Util.getOrDefault(settings, "noHistory", false); + Boolean noHistory = Util.getOrDefault(settings, "noHistory", false); if (noHistory) { intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java index 8a0d8175..22c6709b 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java @@ -5,6 +5,8 @@ import android.os.Handler; import android.util.Log; import android.webkit.WebResourceResponse; +import androidx.annotation.Nullable; + import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebView; import com.pichillilorenzo.flutter_inappwebview.Util; @@ -42,6 +44,7 @@ public class ContentBlockerHandler { this.ruleList = newRuleList; } + @Nullable public WebResourceResponse checkUrl(final InAppWebView webView, String url, ContentBlockerTriggerResourceType responseResourceType) throws URISyntaxException, InterruptedException, MalformedURLException { if (webView.customSettings.contentBlockers == null) return null; @@ -211,12 +214,14 @@ public class ContentBlockerHandler { } return null; } - + + @Nullable public WebResourceResponse checkUrl(final InAppWebView webView, String url) throws URISyntaxException, InterruptedException, MalformedURLException { ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromUrl(url); return checkUrl(webView, url, responseResourceType); } + @Nullable public WebResourceResponse checkUrl(final InAppWebView webView, String url, String contentType) throws URISyntaxException, InterruptedException, MalformedURLException { ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromContentType(contentType); return checkUrl(webView, url, responseResourceType); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/EventChannelDelegate.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/EventChannelDelegate.java new file mode 100644 index 00000000..e199049e --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/EventChannelDelegate.java @@ -0,0 +1,571 @@ +package com.pichillilorenzo.flutter_inappwebview.in_app_webview; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.pichillilorenzo.flutter_inappwebview.Util; +import com.pichillilorenzo.flutter_inappwebview.types.BaseCallbackResultImpl; +import com.pichillilorenzo.flutter_inappwebview.types.ClientCertChallenge; +import com.pichillilorenzo.flutter_inappwebview.types.ClientCertResponse; +import com.pichillilorenzo.flutter_inappwebview.types.CreateWindowAction; +import com.pichillilorenzo.flutter_inappwebview.types.CustomSchemeResponse; +import com.pichillilorenzo.flutter_inappwebview.types.DownloadStartRequest; +import com.pichillilorenzo.flutter_inappwebview.types.GeolocationPermissionShowPromptResponse; +import com.pichillilorenzo.flutter_inappwebview.types.HitTestResult; +import com.pichillilorenzo.flutter_inappwebview.types.HttpAuthResponse; +import com.pichillilorenzo.flutter_inappwebview.types.HttpAuthenticationChallenge; +import com.pichillilorenzo.flutter_inappwebview.types.JsAlertResponse; +import com.pichillilorenzo.flutter_inappwebview.types.JsBeforeUnloadResponse; +import com.pichillilorenzo.flutter_inappwebview.types.JsConfirmResponse; +import com.pichillilorenzo.flutter_inappwebview.types.JsPromptResponse; +import com.pichillilorenzo.flutter_inappwebview.types.NavigationAction; +import com.pichillilorenzo.flutter_inappwebview.types.NavigationActionPolicy; +import com.pichillilorenzo.flutter_inappwebview.types.PermissionResponse; +import com.pichillilorenzo.flutter_inappwebview.types.SafeBrowsingResponse; +import com.pichillilorenzo.flutter_inappwebview.types.ServerTrustAuthResponse; +import com.pichillilorenzo.flutter_inappwebview.types.ServerTrustChallenge; +import com.pichillilorenzo.flutter_inappwebview.types.SyncBaseCallbackResultImpl; +import com.pichillilorenzo.flutter_inappwebview.types.WebResourceErrorExt; +import com.pichillilorenzo.flutter_inappwebview.types.WebResourceRequestExt; +import com.pichillilorenzo.flutter_inappwebview.types.WebResourceResponseExt; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.flutter.plugin.common.MethodChannel; + +public class EventChannelDelegate { + @Nullable + private MethodChannel channel; + + public EventChannelDelegate(@Nullable MethodChannel channel) { + this.channel = channel; + } + + public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("activeMatchOrdinal", activeMatchOrdinal); + obj.put("numberOfMatches", numberOfMatches); + obj.put("isDoneCounting", isDoneCounting); + channel.invokeMethod("onFindResultReceived", obj); + } + + public void onLongPressHitTestResult(HitTestResult hitTestResult) { + if (channel == null) return; + channel.invokeMethod("onLongPressHitTestResult", hitTestResult.toMap()); + } + + public void onScrollChanged(int x, int y) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("x", x); + obj.put("y", y); + channel.invokeMethod("onScrollChanged", obj); + } + + public void onDownloadStartRequest(DownloadStartRequest downloadStartRequest) { + if (channel == null) return; + channel.invokeMethod("onDownloadStartRequest", downloadStartRequest.toMap()); + } + + public void onCreateContextMenu(HitTestResult hitTestResult) { + if (channel == null) return; + channel.invokeMethod("onCreateContextMenu", hitTestResult.toMap()); + } + + public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("x", scrollX); + obj.put("y", scrollY); + obj.put("clampedX", clampedX); + obj.put("clampedY", clampedY); + channel.invokeMethod("onOverScrolled", obj); + } + + public void onContextMenuActionItemClicked(int itemId, String itemTitle) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("id", itemId); + obj.put("androidId", itemId); + obj.put("iosId", null); + obj.put("title", itemTitle); + channel.invokeMethod("onContextMenuActionItemClicked", obj); + } + + public void onHideContextMenu() { + if (channel == null) return; + Map obj = new HashMap<>(); + channel.invokeMethod("onHideContextMenu", obj); + } + + public void onEnterFullscreen() { + if (channel == null) return; + Map obj = new HashMap<>(); + channel.invokeMethod("onEnterFullscreen", obj); + } + + public void onExitFullscreen() { + if (channel == null) return; + Map obj = new HashMap<>(); + channel.invokeMethod("onExitFullscreen", obj); + } + + public static class JsAlertCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public JsAlertResponse decodeResult(@Nullable Object obj) { + return JsAlertResponse.fromMap((Map) obj); + } + } + + public void onJsAlert(String url, String message, Boolean isMainFrame, @NonNull JsAlertCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + obj.put("message", message); + obj.put("isMainFrame", isMainFrame); + channel.invokeMethod("onJsAlert", obj, callback); + } + + public static class JsConfirmCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public JsConfirmResponse decodeResult(@Nullable Object obj) { + return JsConfirmResponse.fromMap((Map) obj); + } + } + + public void onJsConfirm(String url, String message, Boolean isMainFrame, @NonNull JsConfirmCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + obj.put("message", message); + obj.put("isMainFrame", isMainFrame); + channel.invokeMethod("onJsConfirm", obj, callback); + } + + public static class JsPromptCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public JsPromptResponse decodeResult(@Nullable Object obj) { + return JsPromptResponse.fromMap((Map) obj); + } + } + + public void onJsPrompt(String url, String message, String defaultValue, Boolean isMainFrame, @NonNull JsPromptCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + obj.put("message", message); + obj.put("defaultValue", defaultValue); + obj.put("isMainFrame", isMainFrame); + channel.invokeMethod("onJsPrompt", obj, callback); + } + + public static class JsBeforeUnloadCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public JsBeforeUnloadResponse decodeResult(@Nullable Object obj) { + return JsBeforeUnloadResponse.fromMap((Map) obj); + } + } + + public void onJsBeforeUnload(String url, String message, @NonNull JsBeforeUnloadCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + obj.put("message", message); + channel.invokeMethod("onJsBeforeUnload", obj, callback); + } + + public static class CreateWindowCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public Boolean decodeResult(@Nullable Object obj) { + return (obj instanceof Boolean) && (boolean) obj; + } + } + + public void onCreateWindow(CreateWindowAction createWindowAction, @NonNull CreateWindowCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + channel.invokeMethod("onCreateWindow", createWindowAction.toMap(), callback); + } + + public void onCloseWindow() { + if (channel == null) return; + Map obj = new HashMap<>(); + channel.invokeMethod("onCloseWindow", obj); + } + + public static class GeolocationPermissionsShowPromptCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public GeolocationPermissionShowPromptResponse decodeResult(@Nullable Object obj) { + return GeolocationPermissionShowPromptResponse.fromMap((Map) obj); + } + } + + public void onGeolocationPermissionsShowPrompt(String origin, @NonNull GeolocationPermissionsShowPromptCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("origin", origin); + channel.invokeMethod("onGeolocationPermissionsShowPrompt", obj, callback); + } + + public void onGeolocationPermissionsHidePrompt() { + if (channel == null) return; + Map obj = new HashMap<>(); + channel.invokeMethod("onGeolocationPermissionsHidePrompt", obj); + } + + public void onConsoleMessage(String message, int messageLevel) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("message", message); + obj.put("messageLevel", messageLevel); + channel.invokeMethod("onConsoleMessage", obj); + } + + public void onProgressChanged(int progress) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("progress", progress); + channel.invokeMethod("onProgressChanged", obj); + } + + public void onTitleChanged(String title) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("title", title); + channel.invokeMethod("onTitleChanged", obj); + } + + public void onReceivedIcon(byte[] icon) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("icon", icon); + channel.invokeMethod("onReceivedIcon", obj); + } + + public void onReceivedTouchIconUrl(String url, boolean precomposed) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("url", url); + obj.put("precomposed", precomposed); + channel.invokeMethod("onReceivedTouchIconUrl", obj); + } + + public static class PermissionRequestCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public PermissionResponse decodeResult(@Nullable Object obj) { + return PermissionResponse.fromMap((Map) obj); + } + } + + public void onPermissionRequest(String origin, List resources, Object frame, @NonNull PermissionRequestCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("origin", origin); + obj.put("resources", resources); + obj.put("frame", frame); + channel.invokeMethod("onPermissionRequest", obj, callback); + } + + public static class ShouldOverrideUrlLoadingCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public NavigationActionPolicy decodeResult(@Nullable Object obj) { + Integer action = Util.getOrDefault((Map) obj, + "action", NavigationActionPolicy.CANCEL.rawValue()); + return NavigationActionPolicy.fromValue(action); + } + } + + public void shouldOverrideUrlLoading(NavigationAction navigationAction, @NonNull ShouldOverrideUrlLoadingCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + channel.invokeMethod("shouldOverrideUrlLoading", navigationAction.toMap(), callback); + } + + public void onLoadStart(String url) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("url", url); + channel.invokeMethod("onLoadStart", obj); + } + + public void onLoadStop(String url) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("url", url); + channel.invokeMethod("onLoadStop", obj); + } + + public void onUpdateVisitedHistory(String url, boolean isReload) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("url", url); + obj.put("isReload", isReload); + channel.invokeMethod("onUpdateVisitedHistory", obj); + } + + public void onReceivedError(WebResourceRequestExt request, WebResourceErrorExt error) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("request", request.toMap()); + obj.put("error", error.toMap()); + channel.invokeMethod("onReceivedError", obj); + } + + public void onReceivedHttpError(WebResourceRequestExt request, WebResourceResponseExt errorResponse) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("request", request.toMap()); + obj.put("errorResponse", errorResponse.toMap()); + channel.invokeMethod("onReceivedHttpError", obj); + } + + public static class ReceivedHttpAuthRequestCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public HttpAuthResponse decodeResult(@Nullable Object obj) { + return HttpAuthResponse.fromMap((Map) obj); + } + } + + public void onReceivedHttpAuthRequest(HttpAuthenticationChallenge challenge, @NonNull ReceivedHttpAuthRequestCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + channel.invokeMethod("onReceivedHttpAuthRequest", challenge.toMap(), callback); + } + + public static class ReceivedServerTrustAuthRequestCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public ServerTrustAuthResponse decodeResult(@Nullable Object obj) { + return ServerTrustAuthResponse.fromMap((Map) obj); + } + } + + public void onReceivedServerTrustAuthRequest(ServerTrustChallenge challenge, @NonNull ReceivedServerTrustAuthRequestCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + channel.invokeMethod("onReceivedServerTrustAuthRequest", challenge.toMap(), callback); + } + + public static class ReceivedClientCertRequestCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public ClientCertResponse decodeResult(@Nullable Object obj) { + return ClientCertResponse.fromMap((Map) obj); + } + } + + public void onReceivedClientCertRequest(ClientCertChallenge challenge, @NonNull ReceivedClientCertRequestCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + channel.invokeMethod("onReceivedClientCertRequest", challenge.toMap(), callback); + } + + public void onZoomScaleChanged(float oldScale, float newScale) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("oldScale", oldScale); + obj.put("newScale", newScale); + channel.invokeMethod("onZoomScaleChanged", obj); + } + + public static class SafeBrowsingHitCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public SafeBrowsingResponse decodeResult(@Nullable Object obj) { + return SafeBrowsingResponse.fromMap((Map) obj); + } + } + + public void onSafeBrowsingHit(String url, int threatType, @NonNull SafeBrowsingHitCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + obj.put("threatType", threatType); + channel.invokeMethod("onSafeBrowsingHit", obj, callback); + } + + public static class FormResubmissionCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public Integer decodeResult(@Nullable Object obj) { + return obj != null ? (Integer) ((Map) obj).get("action") : null; + } + } + + public void onFormResubmission(String url, @NonNull FormResubmissionCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + channel.invokeMethod("onFormResubmission", obj, callback); + } + + public void onPageCommitVisible(String url) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("url", url); + channel.invokeMethod("onPageCommitVisible", obj); + } + + public void onRenderProcessGone(boolean didCrash, int rendererPriorityAtExit) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("didCrash", didCrash); + obj.put("rendererPriorityAtExit", rendererPriorityAtExit); + channel.invokeMethod("onRenderProcessGone", obj); + } + + public void onReceivedLoginRequest(String realm, String account, String args) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("realm", realm); + obj.put("account", account); + obj.put("args", args); + channel.invokeMethod("onReceivedLoginRequest", obj); + } + + public static class LoadResourceCustomSchemeCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public CustomSchemeResponse decodeResult(@Nullable Object obj) { + return CustomSchemeResponse.fromMap((Map) obj); + } + } + + public void onLoadResourceCustomScheme(String url, @NonNull LoadResourceCustomSchemeCallback callback) { + if (channel == null) return; + Map obj = new HashMap<>(); + obj.put("url", url); + channel.invokeMethod("onLoadResourceCustomScheme", obj, callback); + } + + public static class SyncLoadResourceCustomSchemeCallback extends SyncBaseCallbackResultImpl { + @Nullable + @Override + public CustomSchemeResponse decodeResult(@Nullable Object obj) { + return (new LoadResourceCustomSchemeCallback()).decodeResult(obj); + } + } + + @Nullable + public CustomSchemeResponse onLoadResourceCustomScheme(String url) throws InterruptedException { + if (channel == null) return null; + final Map obj = new HashMap<>(); + obj.put("url", url); + final SyncLoadResourceCustomSchemeCallback callback = new SyncLoadResourceCustomSchemeCallback(); + return Util.invokeMethodAndWaitResult(channel, "onLoadResourceCustomScheme", obj, callback); + } + + public static class ShouldInterceptRequestCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public WebResourceResponseExt decodeResult(@Nullable Object obj) { + return WebResourceResponseExt.fromMap((Map) obj); + } + } + + public void shouldInterceptRequest(WebResourceRequestExt request, @NonNull ShouldInterceptRequestCallback callback) { + if (channel == null) return; + channel.invokeMethod("shouldInterceptRequest", request.toMap(), callback); + } + + public static class SyncShouldInterceptRequestCallback extends SyncBaseCallbackResultImpl { + @Nullable + @Override + public WebResourceResponseExt decodeResult(@Nullable Object obj) { + return (new ShouldInterceptRequestCallback()).decodeResult(obj); + } + } + + @Nullable + public WebResourceResponseExt shouldInterceptRequest(WebResourceRequestExt request) throws InterruptedException { + if (channel == null) return null; + final SyncShouldInterceptRequestCallback callback = new SyncShouldInterceptRequestCallback(); + return Util.invokeMethodAndWaitResult(channel, "shouldInterceptRequest", request.toMap(), callback); + } + + public static class RenderProcessUnresponsiveCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public Integer decodeResult(@Nullable Object obj) { + return obj != null ? (Integer) ((Map) obj).get("action") : null; + } + } + + public void onRenderProcessUnresponsive(String url, @NonNull RenderProcessUnresponsiveCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + channel.invokeMethod("onRenderProcessUnresponsive", obj, callback); + } + + public static class RenderProcessResponsiveCallback extends BaseCallbackResultImpl { + @Nullable + @Override + public Integer decodeResult(@Nullable Object obj) { + return obj != null ? (Integer) ((Map) obj).get("action") : null; + } + } + + public void onRenderProcessResponsive(String url, @NonNull RenderProcessResponsiveCallback callback) { + if (channel == null) { + callback.defaultBehaviour(null); + return; + } + Map obj = new HashMap<>(); + obj.put("url", url); + channel.invokeMethod("onRenderProcessResponsive", obj, callback); + } + + public void dispose() { + channel = null; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java index 9977bf9b..a874a51f 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java @@ -154,6 +154,7 @@ public class FlutterWebView implements PlatformWebView { if (webView.inAppWebViewRenderProcessClient != null) { webView.inAppWebViewRenderProcessClient.dispose(); } + webView.eventChannelDelegate.dispose(); webView.inAppWebViewChromeClient.dispose(); webView.inAppWebViewClient.dispose(); webView.javaScriptBridgeInterface.dispose(); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java index a0e86c39..ef80b301 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java @@ -43,7 +43,6 @@ import android.webkit.WebBackForwardList; import android.webkit.WebHistoryItem; import android.webkit.WebSettings; import android.webkit.WebStorage; -import android.webkit.WebView; import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import android.widget.TextView; @@ -116,10 +115,15 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie public Object id; @Nullable public Integer windowId; + @Nullable public InAppWebViewClient inAppWebViewClient; + @Nullable public InAppWebViewChromeClient inAppWebViewChromeClient; @Nullable public InAppWebViewRenderProcessClient inAppWebViewRenderProcessClient; + @Nullable + public EventChannelDelegate eventChannelDelegate; + @Nullable public JavaScriptBridgeInterface javaScriptBridgeInterface; public InAppWebViewSettings customSettings; public boolean isLoading = false; @@ -184,20 +188,21 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie } public void prepare() { - httpClient = new OkHttpClient().newBuilder().build(); + eventChannelDelegate = new EventChannelDelegate(channel); + javaScriptBridgeInterface = new JavaScriptBridgeInterface(this); addJavascriptInterface(javaScriptBridgeInterface, JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME); - inAppWebViewChromeClient = new InAppWebViewChromeClient(plugin, channel, this, inAppBrowserDelegate); + inAppWebViewChromeClient = new InAppWebViewChromeClient(plugin, this, inAppBrowserDelegate); setWebChromeClient(inAppWebViewChromeClient); - inAppWebViewClient = new InAppWebViewClient(channel, inAppBrowserDelegate); + inAppWebViewClient = new InAppWebViewClient(inAppBrowserDelegate); setWebViewClient(inAppWebViewClient); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE)) { - inAppWebViewRenderProcessClient = new InAppWebViewRenderProcessClient(channel); + inAppWebViewRenderProcessClient = new InAppWebViewRenderProcessClient(); WebViewCompat.setWebViewRenderProcessClient(this, inAppWebViewRenderProcessClient); } @@ -392,11 +397,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie setFindListener(new FindListener() { @Override public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting) { - Map obj = new HashMap<>(); - obj.put("activeMatchOrdinal", activeMatchOrdinal); - obj.put("numberOfMatches", numberOfMatches); - obj.put("isDoneCounting", isDoneCounting); - channel.invokeMethod("onFindResultReceived", obj); + if (eventChannelDelegate != null) eventChannelDelegate.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting); } }); @@ -492,7 +493,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie public boolean onLongClick(View v) { com.pichillilorenzo.flutter_inappwebview.types.HitTestResult hitTestResult = com.pichillilorenzo.flutter_inappwebview.types.HitTestResult.fromWebViewHitTestResult(getHitTestResult()); - channel.invokeMethod("onLongPressHitTestResult", hitTestResult.toMap()); + if (eventChannelDelegate != null) eventChannelDelegate.onLongPressHitTestResult(hitTestResult); return false; } }); @@ -1193,10 +1194,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie floatingContextMenu.setVisibility(View.GONE); } - Map obj = new HashMap<>(); - obj.put("x", x); - obj.put("y", y); - channel.invokeMethod("onScrollChanged", obj); + if (eventChannelDelegate != null) eventChannelDelegate.onScrollChanged(x, y); } public void scrollTo(Integer x, Integer y, Boolean animated) { @@ -1233,7 +1231,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie URLUtil.guessFileName(url, contentDisposition, mimeType), null ); - channel.invokeMethod("onDownloadStartRequest", downloadStartRequest.toMap()); + if (eventChannelDelegate != null) eventChannelDelegate.onDownloadStartRequest(downloadStartRequest); } } @@ -1284,7 +1282,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie private void sendOnCreateContextMenuEvent() { com.pichillilorenzo.flutter_inappwebview.types.HitTestResult hitTestResult = com.pichillilorenzo.flutter_inappwebview.types.HitTestResult.fromWebViewHitTestResult(getHitTestResult()); - channel.invokeMethod("onCreateContextMenu", hitTestResult.toMap()); + if (eventChannelDelegate != null) eventChannelDelegate.onCreateContextMenu(hitTestResult); } private Point contextMenuPoint = new Point(0, 0); @@ -1323,12 +1321,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie } if (overScrolledHorizontally || overScrolledVertically) { - Map obj = new HashMap<>(); - obj.put("x", scrollX); - obj.put("y", scrollY); - obj.put("clampedX", overScrolledHorizontally); - obj.put("clampedY", overScrolledVertically); - channel.invokeMethod("onOverScrolled", obj); + if (eventChannelDelegate != null) eventChannelDelegate.onOverScrolled(scrollX, scrollY, overScrolledHorizontally, overScrolledVertically); } } @@ -1441,12 +1434,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie hideContextMenu(); callback.onActionItemClicked(actionMode, menuItem); - Map obj = new HashMap<>(); - obj.put("id", itemId); - obj.put("androidId", itemId); - obj.put("iosId", null); - obj.put("title", itemTitle); - channel.invokeMethod("onContextMenuActionItemClicked", obj); + if (eventChannelDelegate != null) eventChannelDelegate.onContextMenuActionItemClicked(itemId, itemTitle); } }); if (floatingContextMenu != null) { @@ -1466,12 +1454,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie public void onClick(View v) { hideContextMenu(); - Map obj = new HashMap<>(); - obj.put("id", itemId); - obj.put("androidId", itemId); - obj.put("iosId", null); - obj.put("title", itemTitle); - channel.invokeMethod("onContextMenuActionItemClicked", obj); + if (eventChannelDelegate != null) eventChannelDelegate.onContextMenuActionItemClicked(itemId, itemTitle); } }); if (floatingContextMenu != null) { @@ -1547,12 +1530,8 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie public void hideContextMenu() { removeView(floatingContextMenu); floatingContextMenu = null; - onHideContextMenu(); - } - - public void onHideContextMenu() { - Map obj = new HashMap<>(); - channel.invokeMethod("onHideContextMenu", obj); + + if (eventChannelDelegate != null) eventChannelDelegate.onHideContextMenu(); } public void onScrollStopped() { @@ -1813,6 +1792,17 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie callback.onReceiveValue(com.pichillilorenzo.flutter_inappwebview.types.HitTestResult.fromWebViewHitTestResult(getHitTestResult())); } + @Nullable + @Override + public EventChannelDelegate getEventChannelDelegate() { + return eventChannelDelegate; + } + + @Override + public void setEventChannelDelegate(@Nullable EventChannelDelegate eventChannelDelegate) { + this.eventChannelDelegate = eventChannelDelegate; + } + @Override public void dispose() { if (windowId != null) { @@ -1834,6 +1824,7 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie inAppWebViewClient = null; javaScriptBridgeInterface = null; inAppWebViewRenderProcessClient = null; + eventChannelDelegate = null; plugin = null; super.dispose(); } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java index 80b03afd..56e905d7 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java @@ -46,6 +46,12 @@ import com.pichillilorenzo.flutter_inappwebview.in_app_browser.ActivityResultLis import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate; import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.R; +import com.pichillilorenzo.flutter_inappwebview.types.GeolocationPermissionShowPromptResponse; +import com.pichillilorenzo.flutter_inappwebview.types.JsAlertResponse; +import com.pichillilorenzo.flutter_inappwebview.types.JsBeforeUnloadResponse; +import com.pichillilorenzo.flutter_inappwebview.types.JsConfirmResponse; +import com.pichillilorenzo.flutter_inappwebview.types.JsPromptResponse; +import com.pichillilorenzo.flutter_inappwebview.types.PermissionResponse; import com.pichillilorenzo.flutter_inappwebview.types.URLRequest; import java.io.ByteArrayOutputStream; @@ -54,7 +60,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import io.flutter.plugin.common.MethodChannel; @@ -66,7 +71,6 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR protected static final String LOG_TAG = "IABWebChromeClient"; private InAppBrowserDelegate inAppBrowserDelegate; - private final MethodChannel channel; public static Map windowWebViewMessages = new HashMap<>(); private static int windowAutoincrementId = 0; @@ -105,11 +109,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR @Nullable public InAppWebView inAppWebView; - public InAppWebViewChromeClient(@NonNull final InAppWebViewFlutterPlugin plugin, MethodChannel channel, + public InAppWebViewChromeClient(@NonNull final InAppWebViewFlutterPlugin plugin, @NonNull InAppWebView inAppWebView, InAppBrowserDelegate inAppBrowserDelegate) { super(); this.plugin = plugin; - this.channel = channel; this.inAppWebView = inAppWebView; this.inAppBrowserDelegate = inAppBrowserDelegate; if (this.inAppBrowserDelegate != null) { @@ -145,10 +148,11 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR this.mCustomViewCallback.onCustomViewHidden(); this.mCustomViewCallback = null; activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - Map obj = new HashMap<>(); - channel.invokeMethod("onExitFullscreen", obj); if (inAppWebView != null) { + EventChannelDelegate eventChannelDelegate = inAppWebView.eventChannelDelegate; + if (eventChannelDelegate != null) + eventChannelDelegate.onExitFullscreen(); inAppWebView.setInFullscreen(false); } } @@ -183,10 +187,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); ((FrameLayout) decorView).addView(this.mCustomView, FULLSCREEN_LAYOUT_PARAMS); - Map obj = new HashMap<>(); - channel.invokeMethod("onEnterFullscreen", obj); - if (inAppWebView != null) { + EventChannelDelegate eventChannelDelegate = inAppWebView.eventChannelDelegate; + if (eventChannelDelegate != null) + eventChannelDelegate.onEnterFullscreen(); inAppWebView.setInFullscreen(true); } } @@ -194,24 +198,12 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR @Override public boolean onJsAlert(final WebView view, String url, final String message, final JsResult result) { - Map obj = new HashMap<>(); - obj.put("url", url); - obj.put("message", message); - obj.put("isMainFrame", null); - - channel.invokeMethod("onJsAlert", obj, new MethodChannel.Result() { - @Override - public void success(@Nullable Object response) { - String responseMessage = null; - String confirmButtonTitle = null; - - if (response != null) { - Map responseMap = (Map) response; - responseMessage = (String) responseMap.get("message"); - confirmButtonTitle = (String) responseMap.get("confirmButtonTitle"); - Boolean handledByClient = (Boolean) responseMap.get("handledByClient"); - if (handledByClient != null && handledByClient) { - Integer action = (Integer) responseMap.get("action"); + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onJsAlert(url, message, null, new EventChannelDelegate.JsAlertCallback() { + @Override + public boolean nonNullSuccess(@NonNull JsAlertResponse response) { + if (response.isHandledByClient()) { + Integer action = response.getAction(); action = action != null ? action : 1; switch (action) { case 0: @@ -221,26 +213,33 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR default: result.cancel(); } - return; + return false; } + return true; } - createAlertDialog(view, message, result, responseMessage, confirmButtonTitle); - } + @Override + public void defaultBehaviour(@Nullable JsAlertResponse response) { + String responseMessage = null; + String confirmButtonTitle = null; + if (response != null) { + responseMessage = response.getMessage(); + confirmButtonTitle = response.getConfirmButtonTitle(); + } + createAlertDialog(view, message, result, responseMessage, confirmButtonTitle); + } - @Override - public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - result.cancel(); - } + @Override + public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { + Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + result.cancel(); + } + }); - @Override - public void notImplemented() { - createAlertDialog(view, message, result, null, null); - } - }); + return true; + } - return true; + return false; } public void createAlertDialog(WebView view, String message, final JsResult result, String responseMessage, String confirmButtonTitle) { @@ -282,26 +281,12 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR @Override public boolean onJsConfirm(final WebView view, String url, final String message, final JsResult result) { - Map obj = new HashMap<>(); - obj.put("url", url); - obj.put("message", message); - obj.put("isMainFrame", null); - - channel.invokeMethod("onJsConfirm", obj, new MethodChannel.Result() { - @Override - public void success(Object response) { - String responseMessage = null; - String confirmButtonTitle = null; - String cancelButtonTitle = null; - - if (response != null) { - Map responseMap = (Map) response; - responseMessage = (String) responseMap.get("message"); - confirmButtonTitle = (String) responseMap.get("confirmButtonTitle"); - cancelButtonTitle = (String) responseMap.get("cancelButtonTitle"); - Boolean handledByClient = (Boolean) responseMap.get("handledByClient"); - if (handledByClient != null && handledByClient) { - Integer action = (Integer) responseMap.get("action"); + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onJsConfirm(url, message, null, new EventChannelDelegate.JsConfirmCallback() { + @Override + public boolean nonNullSuccess(@NonNull JsConfirmResponse response) { + if (response.isHandledByClient()) { + Integer action = response.getAction(); action = action != null ? action : 1; switch (action) { case 0: @@ -311,26 +296,35 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR default: result.cancel(); } - return; + return false; } + return true; } - createConfirmDialog(view, message, result, responseMessage, confirmButtonTitle, cancelButtonTitle); - } + @Override + public void defaultBehaviour(@Nullable JsConfirmResponse response) { + String responseMessage = null; + String confirmButtonTitle = null; + String cancelButtonTitle = null; + if (response != null) { + responseMessage = response.getMessage(); + confirmButtonTitle = response.getConfirmButtonTitle(); + cancelButtonTitle = response.getCancelButtonTitle(); + } + createConfirmDialog(view, message, result, responseMessage, confirmButtonTitle, cancelButtonTitle); + } - @Override - public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - result.cancel(); - } + @Override + public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { + Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + result.cancel(); + } + }); - @Override - public void notImplemented() { - createConfirmDialog(view, message, result, null, null, null); - } - }); + return true; + } - return true; + return false; } public void createConfirmDialog(WebView view, String message, final JsResult result, String responseMessage, String confirmButtonTitle, String cancelButtonTitle) { @@ -383,60 +377,54 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR @Override public boolean onJsPrompt(final WebView view, String url, final String message, final String defaultValue, final JsPromptResult result) { - Map obj = new HashMap<>(); - obj.put("url", url); - obj.put("message", message); - obj.put("defaultValue", defaultValue); - obj.put("isMainFrame", null); - - channel.invokeMethod("onJsPrompt", obj, new MethodChannel.Result() { - @Override - public void success(Object response) { - String responseMessage = null; - String responseDefaultValue = null; - String confirmButtonTitle = null; - String cancelButtonTitle = null; - String value = null; - - if (response != null) { - Map responseMap = (Map) response; - responseMessage = (String) responseMap.get("message"); - responseDefaultValue = (String) responseMap.get("defaultValue"); - confirmButtonTitle = (String) responseMap.get("confirmButtonTitle"); - cancelButtonTitle = (String) responseMap.get("cancelButtonTitle"); - value = (String) responseMap.get("value"); - Boolean handledByClient = (Boolean) responseMap.get("handledByClient"); - if (handledByClient != null && handledByClient) { - Integer action = (Integer) responseMap.get("action"); + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onJsPrompt(url, message, defaultValue, null, new EventChannelDelegate.JsPromptCallback() { + @Override + public boolean nonNullSuccess(@NonNull JsPromptResponse response) { + if (response.isHandledByClient()) { + Integer action = response.getAction(); action = action != null ? action : 1; switch (action) { case 0: - result.confirm(value); + result.confirm(response.getValue()); break; case 1: default: result.cancel(); } - return; + return false; } + return true; } - createPromptDialog(view, message, defaultValue, result, responseMessage, responseDefaultValue, value, cancelButtonTitle, confirmButtonTitle); - } + @Override + public void defaultBehaviour(@Nullable JsPromptResponse response) { + String responseMessage = null; + String responseDefaultValue = null; + String value = null; + String confirmButtonTitle = null; + String cancelButtonTitle = null; + if (response != null) { + responseMessage = response.getMessage(); + responseDefaultValue = response.getDefaultValue(); + value = response.getValue(); + confirmButtonTitle = response.getConfirmButtonTitle(); + cancelButtonTitle = response.getCancelButtonTitle(); + } + createPromptDialog(view, message, defaultValue, result, responseMessage, responseDefaultValue, value, cancelButtonTitle, confirmButtonTitle); + } - @Override - public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - result.cancel(); - } + @Override + public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { + Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + result.cancel(); + } + }); - @Override - public void notImplemented() { - createPromptDialog(view, message, defaultValue, result, null, null, null, null, null); - } - }); + return true; + } - return true; + return false; } public void createPromptDialog(WebView view, String message, String defaultValue, final JsPromptResult result, String responseMessage, String responseDefaultValue, String value, String cancelButtonTitle, String confirmButtonTitle) { @@ -506,25 +494,12 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR @Override public boolean onJsBeforeUnload(final WebView view, String url, final String message, final JsResult result) { - Map obj = new HashMap<>(); - obj.put("url", url); - obj.put("message", message); - - channel.invokeMethod("onJsBeforeUnload", obj, new MethodChannel.Result() { - @Override - public void success(Object response) { - String responseMessage = null; - String confirmButtonTitle = null; - String cancelButtonTitle = null; - - if (response != null) { - Map responseMap = (Map) response; - responseMessage = (String) responseMap.get("message"); - confirmButtonTitle = (String) responseMap.get("confirmButtonTitle"); - cancelButtonTitle = (String) responseMap.get("cancelButtonTitle"); - Boolean handledByClient = (Boolean) responseMap.get("handledByClient"); - if (handledByClient != null && handledByClient) { - Integer action = (Integer) responseMap.get("action"); + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onJsBeforeUnload(url, message, new EventChannelDelegate.JsBeforeUnloadCallback() { + @Override + public boolean nonNullSuccess(@NonNull JsBeforeUnloadResponse response) { + if (response.isHandledByClient()) { + Integer action = response.getAction(); action = action != null ? action : 1; switch (action) { case 0: @@ -534,26 +509,35 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR default: result.cancel(); } - return; + return false; } + return true; } - createBeforeUnloadDialog(view, message, result, responseMessage, confirmButtonTitle, cancelButtonTitle); - } + @Override + public void defaultBehaviour(@Nullable JsBeforeUnloadResponse response) { + String responseMessage = null; + String confirmButtonTitle = null; + String cancelButtonTitle = null; + if (response != null) { + responseMessage = response.getMessage(); + confirmButtonTitle = response.getConfirmButtonTitle(); + cancelButtonTitle = response.getCancelButtonTitle(); + } + createBeforeUnloadDialog(view, message, result, responseMessage, confirmButtonTitle, cancelButtonTitle); + } - @Override - public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - result.cancel(); - } + @Override + public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { + Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + result.cancel(); + } + }); - @Override - public void notImplemented() { - createConfirmDialog(view, message, result, null, null, null); - } - }); + return true; + } - return true; + return false; } public void createBeforeUnloadDialog(WebView view, String message, final JsResult result, String responseMessage, String confirmButtonTitle, String cancelButtonTitle) { @@ -636,84 +620,82 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR windowWebViewMessages.put(windowId, resultMsg); - channel.invokeMethod("onCreateWindow", createWindowAction.toMap(), new MethodChannel.Result() { - @Override - public void success(@Nullable Object result) { - boolean handledByClient = false; - if (result instanceof Boolean) { - handledByClient = (boolean) result; + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onCreateWindow(createWindowAction, new EventChannelDelegate.CreateWindowCallback() { + @Override + public boolean nonNullSuccess(@NonNull Boolean handledByClient) { + return !handledByClient; } - if (!handledByClient && InAppWebViewChromeClient.windowWebViewMessages.containsKey(windowId)) { + + @Override + public void defaultBehaviour(@Nullable Boolean handledByClient) { InAppWebViewChromeClient.windowWebViewMessages.remove(windowId); } - } - @Override - public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - if (InAppWebViewChromeClient.windowWebViewMessages.containsKey(windowId)) { - InAppWebViewChromeClient.windowWebViewMessages.remove(windowId); + @Override + public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { + Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } - } + }); - @Override - public void notImplemented() { - if (InAppWebViewChromeClient.windowWebViewMessages.containsKey(windowId)) { - InAppWebViewChromeClient.windowWebViewMessages.remove(windowId); - } - } - }); + return true; + } - return true; + return false; } @Override public void onCloseWindow(WebView window) { - final Map obj = new HashMap<>(); - channel.invokeMethod("onCloseWindow", obj); + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onCloseWindow(); + } super.onCloseWindow(window); } @Override public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) { - Map obj = new HashMap<>(); - obj.put("origin", origin); - channel.invokeMethod("onGeolocationPermissionsShowPrompt", obj, new MethodChannel.Result() { + final EventChannelDelegate.GeolocationPermissionsShowPromptCallback resultCallback = new EventChannelDelegate.GeolocationPermissionsShowPromptCallback() { @Override - public void success(Object o) { - Map response = (Map) o; - if (response != null) - callback.invoke((String) response.get("origin"), (Boolean) response.get("allow"), (Boolean) response.get("retain")); - else - callback.invoke(origin, false, false); + public boolean nonNullSuccess(@NonNull GeolocationPermissionShowPromptResponse response) { + callback.invoke(response.getOrigin(), response.isAllow(), response.isRetain()); + return false; + } + + @Override + public void defaultBehaviour(@Nullable GeolocationPermissionShowPromptResponse response) { + callback.invoke(origin, false, false); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - callback.invoke(origin, false, false); + defaultBehaviour(null); } - - @Override - public void notImplemented() { - callback.invoke(origin, false, false); - } - }); + }; + + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onGeolocationPermissionsShowPrompt(origin, resultCallback); + } else { + resultCallback.defaultBehaviour(null); + } } @Override public void onGeolocationPermissionsHidePrompt() { - Map obj = new HashMap<>(); - channel.invokeMethod("onGeolocationPermissionsHidePrompt", obj); + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onGeolocationPermissionsHidePrompt(); + } } @Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) { - Map obj = new HashMap<>(); - obj.put("message", consoleMessage.message()); - obj.put("messageLevel", consoleMessage.messageLevel().ordinal()); - channel.invokeMethod("onConsoleMessage", obj); + if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onConsoleMessage( + consoleMessage.message(), + consoleMessage.messageLevel().ordinal()); + } return true; } @@ -721,19 +703,20 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR public void onProgressChanged(WebView view, int progress) { super.onProgressChanged(view, progress); - InAppWebView webView = (InAppWebView) view; - if (inAppBrowserDelegate != null) { inAppBrowserDelegate.didChangeProgress(progress); } + + InAppWebView webView = (InAppWebView) view; + if (webView.inAppWebViewClient != null) { webView.inAppWebViewClient.loadCustomJavaScriptOnPageStarted(view); } - Map obj = new HashMap<>(); - obj.put("progress", progress); - channel.invokeMethod("onProgressChanged", obj); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onProgressChanged(progress); + } } @Override @@ -743,10 +726,12 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR if (inAppBrowserDelegate != null) { inAppBrowserDelegate.didChangeTitle(title); } + + InAppWebView webView = (InAppWebView) view; - Map obj = new HashMap<>(); - obj.put("title", title); - channel.invokeMethod("onTitleChanged", obj); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onTitleChanged(title); + } } @Override @@ -766,9 +751,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR } icon.recycle(); - Map obj = new HashMap<>(); - obj.put("icon", byteArrayOutputStream.toByteArray()); - channel.invokeMethod("onReceivedIcon", obj); + InAppWebView webView = (InAppWebView) view; + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedIcon(byteArrayOutputStream.toByteArray()); + } } @Override @@ -777,10 +763,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR boolean precomposed) { super.onReceivedTouchIconUrl(view, url, precomposed); - Map obj = new HashMap<>(); - obj.put("url", url); - obj.put("precomposed", precomposed); - channel.invokeMethod("onReceivedTouchIconUrl", obj); + InAppWebView webView = (InAppWebView) view; + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedTouchIconUrl(url, precomposed); + } } @Nullable @@ -1171,47 +1157,44 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR @Override public void onPermissionRequest(final PermissionRequest request) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Map obj = new HashMap<>(); - obj.put("origin", request.getOrigin().toString()); - obj.put("resources", Arrays.asList(request.getResources())); - obj.put("frame", null); - channel.invokeMethod("onPermissionRequest", obj, new MethodChannel.Result() { + final EventChannelDelegate.PermissionRequestCallback callback = new EventChannelDelegate.PermissionRequestCallback() { @Override - public void success(Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - List resourceList = (List) responseMap.get("resources"); - if (resourceList == null) - resourceList = new ArrayList(); - String[] resources = new String[resourceList.size()]; - resources = resourceList.toArray(resources); - if (action != null) { - switch (action) { - case 1: - request.grant(resources); - return; - case 0: - default: - request.deny(); - return; - } + public boolean nonNullSuccess(@NonNull PermissionResponse response) { + Integer action = response.getAction(); + if (action != null) { + switch (action) { + case 1: + String[] resources = new String[response.getResources().size()]; + resources = response.getResources().toArray(resources); + request.grant(resources); + break; + case 0: + default: + request.deny(); } + return false; } + return true; + } + + @Override + public void defaultBehaviour(@Nullable PermissionResponse response) { request.deny(); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - request.deny(); + defaultBehaviour(null); } - - @Override - public void notImplemented() { - request.deny(); - } - }); + }; + + if(inAppWebView != null && inAppWebView.eventChannelDelegate != null) { + inAppWebView.eventChannelDelegate.onPermissionRequest(request.getOrigin().toString(), + Arrays.asList(request.getResources()), null, callback); + } else { + callback.defaultBehaviour(null); + } } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java index 3ba1a47d..1aab666c 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java @@ -26,7 +26,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.webkit.WebResourceRequestCompat; -import androidx.webkit.WebViewCompat; import androidx.webkit.WebViewFeature; import com.pichillilorenzo.flutter_inappwebview.Util; @@ -34,9 +33,13 @@ import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDa import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate; import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS; import com.pichillilorenzo.flutter_inappwebview.types.ClientCertChallenge; +import com.pichillilorenzo.flutter_inappwebview.types.ClientCertResponse; +import com.pichillilorenzo.flutter_inappwebview.types.CustomSchemeResponse; +import com.pichillilorenzo.flutter_inappwebview.types.HttpAuthResponse; import com.pichillilorenzo.flutter_inappwebview.types.HttpAuthenticationChallenge; import com.pichillilorenzo.flutter_inappwebview.types.NavigationAction; import com.pichillilorenzo.flutter_inappwebview.types.NavigationActionPolicy; +import com.pichillilorenzo.flutter_inappwebview.types.ServerTrustAuthResponse; import com.pichillilorenzo.flutter_inappwebview.types.ServerTrustChallenge; import com.pichillilorenzo.flutter_inappwebview.types.URLCredential; import com.pichillilorenzo.flutter_inappwebview.types.URLProtectionSpace; @@ -49,25 +52,19 @@ import java.io.ByteArrayInputStream; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; -import io.flutter.plugin.common.MethodChannel; - public class InAppWebViewClient extends WebViewClient { protected static final String LOG_TAG = "IAWebViewClient"; private InAppBrowserDelegate inAppBrowserDelegate; - private final MethodChannel channel; private static int previousAuthRequestFailureCount = 0; private static List credentialsProposed = null; - public InAppWebViewClient(MethodChannel channel, InAppBrowserDelegate inAppBrowserDelegate) { + public InAppWebViewClient(InAppBrowserDelegate inAppBrowserDelegate) { super(); - - this.channel = channel; this.inAppBrowserDelegate = inAppBrowserDelegate; } @@ -136,41 +133,37 @@ public class InAppWebViewClient extends WebViewClient { isRedirect ); - channel.invokeMethod("shouldOverrideUrlLoading", navigationAction.toMap(), new MethodChannel.Result() { + final EventChannelDelegate.ShouldOverrideUrlLoadingCallback callback = new EventChannelDelegate.ShouldOverrideUrlLoadingCallback() { @Override - public void success(Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - action = action != null ? action : NavigationActionPolicy.CANCEL.rawValue(); - - NavigationActionPolicy navigationActionPolicy = NavigationActionPolicy.fromValue(action); - if (navigationActionPolicy != null) { - switch (navigationActionPolicy) { - case ALLOW: - allowShouldOverrideUrlLoading(webView, url, headers, isForMainFrame); - return; - case CANCEL: - default: - return; - } - } - return; + public boolean nonNullSuccess(@NonNull NavigationActionPolicy result) { + switch (result) { + case ALLOW: + allowShouldOverrideUrlLoading(webView, url, headers, isForMainFrame); + break; + case CANCEL: + default: + break; } + return false; + } + + @Override + public void defaultBehaviour(@Nullable NavigationActionPolicy result) { allowShouldOverrideUrlLoading(webView, url, headers, isForMainFrame); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); - allowShouldOverrideUrlLoading(webView, url, headers, isForMainFrame); + defaultBehaviour(null); } - - @Override - public void notImplemented() { - allowShouldOverrideUrlLoading(webView, url, headers, isForMainFrame); - } - }); + }; + + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.shouldOverrideUrlLoading(navigationAction, callback); + } else { + callback.defaultBehaviour(null); + } } public void loadCustomJavaScriptOnPageStarted(WebView view) { @@ -211,9 +204,9 @@ public class InAppWebViewClient extends WebViewClient { inAppBrowserDelegate.didStartNavigation(url); } - Map obj = new HashMap<>(); - obj.put("url", url); - channel.invokeMethod("onLoadStart", obj); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onLoadStart(url); + } } @@ -245,26 +238,26 @@ public class InAppWebViewClient extends WebViewClient { webView.loadUrl("javascript:" + js.replaceAll("[\r\n]+", "")); } - Map obj = new HashMap<>(); - obj.put("url", url); - channel.invokeMethod("onLoadStop", obj); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onLoadStop(url); + } } @Override public void doUpdateVisitedHistory(WebView view, String url, boolean isReload) { super.doUpdateVisitedHistory(view, url, isReload); + // url argument sometimes doesn't contain the new changed URL, so we get it again from the webview. url = view.getUrl(); if (inAppBrowserDelegate != null) { inAppBrowserDelegate.didUpdateVisitedHistory(url); } - - Map obj = new HashMap<>(); - // url argument sometimes doesn't contain the new changed URL, so we get it again from the webview. - obj.put("url", url); - obj.put("isReload", isReload); - channel.invokeMethod("onUpdateVisitedHistory", obj); + + final InAppWebView webView = (InAppWebView) view; + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onUpdateVisitedHistory(url, isReload); + } } @RequiresApi(api = Build.VERSION_CODES.M) @@ -287,10 +280,11 @@ public class InAppWebViewClient extends WebViewClient { } } - Map obj = new HashMap<>(); - obj.put("request", WebResourceRequestExt.fromWebResourceRequest(request).toMap()); - obj.put("error", WebResourceErrorExt.fromWebResourceError(error).toMap()); - channel.invokeMethod("onReceivedError", obj); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedError( + WebResourceRequestExt.fromWebResourceRequest(request), + WebResourceErrorExt.fromWebResourceError(error)); + } } @Override @@ -323,10 +317,11 @@ public class InAppWebViewClient extends WebViewClient { description ); - Map obj = new HashMap<>(); - obj.put("request", request.toMap()); - obj.put("error",error.toMap()); - channel.invokeMethod("onReceivedError", obj); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedError( + request, + error); + } super.onReceivedError(view, errorCode, description, failingUrl); } @@ -336,15 +331,16 @@ public class InAppWebViewClient extends WebViewClient { public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { super.onReceivedHttpError(view, request, errorResponse); - Map obj = new HashMap<>(); - obj.put("request", WebResourceRequestExt.fromWebResourceRequest(request).toMap()); - obj.put("errorResponse", WebResourceResponseExt.fromWebResourceResponse(errorResponse).toMap()); - channel.invokeMethod("onReceivedHttpError", obj); + final InAppWebView webView = (InAppWebView) view; + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedHttpError( + WebResourceRequestExt.fromWebResourceRequest(request), + WebResourceResponseExt.fromWebResourceResponse(errorResponse)); + } } @Override public void onReceivedHttpAuthRequest(final WebView view, final HttpAuthHandler handler, final String host, final String realm) { - URI uri; try { uri = new URI(view.getUrl()); @@ -363,13 +359,6 @@ public class InAppWebViewClient extends WebViewClient { previousAuthRequestFailureCount++; - Map obj = new HashMap<>(); - obj.put("host", host); - obj.put("protocol", protocol); - obj.put("realm", realm); - obj.put("port", port); - obj.put("previousFailureCount", previousAuthRequestFailureCount); - if (credentialsProposed == null) credentialsProposed = CredentialDatabase.getInstance(view.getContext()).getHttpAuthCredentials(host, protocol, realm, port); @@ -381,56 +370,63 @@ public class InAppWebViewClient extends WebViewClient { URLProtectionSpace protectionSpace = new URLProtectionSpace(host, protocol, realm, port, view.getCertificate(), null); HttpAuthenticationChallenge challenge = new HttpAuthenticationChallenge(protectionSpace, previousAuthRequestFailureCount, credentialProposed); - channel.invokeMethod("onReceivedHttpAuthRequest", challenge.toMap(), new MethodChannel.Result() { + final InAppWebView webView = (InAppWebView) view; + final EventChannelDelegate.ReceivedHttpAuthRequestCallback callback = new EventChannelDelegate.ReceivedHttpAuthRequestCallback() { @Override - public void success(Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - if (action != null) { - switch (action) { - case 1: - String username = (String) responseMap.get("username"); - String password = (String) responseMap.get("password"); - Boolean permanentPersistence = (Boolean) responseMap.get("permanentPersistence"); - if (permanentPersistence != null && permanentPersistence) { - CredentialDatabase.getInstance(view.getContext()).setHttpAuthCredential(host, protocol, realm, port, username, password); - } - handler.proceed(username, password); - return; - case 2: - if (credentialsProposed.size() > 0) { - URLCredential credential = credentialsProposed.remove(0); - handler.proceed(credential.getUsername(), credential.getPassword()); - } else { - handler.cancel(); - } - // used custom CredentialDatabase! - // handler.useHttpAuthUsernamePassword(); - return; - case 0: - default: - credentialsProposed = null; - previousAuthRequestFailureCount = 0; + public boolean nonNullSuccess(@NonNull HttpAuthResponse response) { + Integer action = response.getAction(); + if (action != null) { + switch (action) { + case 1: + String username = response.getUsername(); + String password = response.getPassword(); + boolean permanentPersistence = response.isPermanentPersistence(); + if (permanentPersistence) { + CredentialDatabase.getInstance(view.getContext()) + .setHttpAuthCredential(host, protocol, realm, port, username, password); + } + handler.proceed(username, password); + break; + case 2: + if (credentialsProposed.size() > 0) { + URLCredential credential = credentialsProposed.remove(0); + handler.proceed(credential.getUsername(), credential.getPassword()); + } else { handler.cancel(); - return; - } + } + // used custom CredentialDatabase! + // handler.useHttpAuthUsernamePassword(); + break; + case 0: + default: + credentialsProposed = null; + previousAuthRequestFailureCount = 0; + handler.cancel(); } + + return false; } + return true; + } + + @Override + public void defaultBehaviour(@Nullable HttpAuthResponse result) { InAppWebViewClient.super.onReceivedHttpAuthRequest(view, handler, host, realm); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } - - @Override - public void notImplemented() { - InAppWebViewClient.super.onReceivedHttpAuthRequest(view, handler, host, realm); - } - }); + }; + + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedHttpAuthRequest(challenge, callback); + } else { + callback.defaultBehaviour(null); + } } @Override @@ -452,46 +448,49 @@ public class InAppWebViewClient extends WebViewClient { URLProtectionSpace protectionSpace = new URLProtectionSpace(host, protocol, realm, port, sslError.getCertificate(), sslError); ServerTrustChallenge challenge = new ServerTrustChallenge(protectionSpace); - channel.invokeMethod("onReceivedServerTrustAuthRequest", challenge.toMap(), new MethodChannel.Result() { + final InAppWebView webView = (InAppWebView) view; + final EventChannelDelegate.ReceivedServerTrustAuthRequestCallback callback = new EventChannelDelegate.ReceivedServerTrustAuthRequestCallback() { @Override - public void success(Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - if (action != null) { - switch (action) { - case 1: - handler.proceed(); - return; - case 0: - default: - handler.cancel(); - return; - } + public boolean nonNullSuccess(@NonNull ServerTrustAuthResponse response) { + Integer action = response.getAction(); + if (action != null) { + switch (action) { + case 1: + handler.proceed(); + break; + case 0: + default: + handler.cancel(); } + + return false; } + return true; + } + + @Override + public void defaultBehaviour(@Nullable ServerTrustAuthResponse result) { InAppWebViewClient.super.onReceivedSslError(view, handler, sslError); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } - - @Override - public void notImplemented() { - InAppWebViewClient.super.onReceivedSslError(view, handler, sslError); - } - }); + }; + + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedServerTrustAuthRequest(challenge, callback); + } else { + callback.defaultBehaviour(null); + } } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override public void onReceivedClientCertRequest(final WebView view, final ClientCertRequest request) { - - InAppWebView webView = (InAppWebView) view; - URI uri; try { uri = new URI(view.getUrl()); @@ -509,48 +508,58 @@ public class InAppWebViewClient extends WebViewClient { URLProtectionSpace protectionSpace = new URLProtectionSpace(host, protocol, realm, port, view.getCertificate(), null); ClientCertChallenge challenge = new ClientCertChallenge(protectionSpace, request.getPrincipals(), request.getKeyTypes()); - channel.invokeMethod("onReceivedClientCertRequest", challenge.toMap(), new MethodChannel.Result() { + final InAppWebView webView = (InAppWebView) view; + final EventChannelDelegate.ReceivedClientCertRequestCallback callback = new EventChannelDelegate.ReceivedClientCertRequestCallback() { @Override - public void success(Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - if (action != null) { - switch (action) { - case 1: - { - InAppWebView webView = (InAppWebView) view; - String certificatePath = (String) responseMap.get("certificatePath"); - String certificatePassword = (String) responseMap.get("certificatePassword"); - String androidKeyStoreType = (String) responseMap.get("androidKeyStoreType"); - Util.PrivateKeyAndCertificates privateKeyAndCertificates = Util.loadPrivateKeyAndCertificate(webView.plugin, certificatePath, certificatePassword, androidKeyStoreType); + public boolean nonNullSuccess(@NonNull ClientCertResponse response) { + Integer action = response.getAction(); + if (action != null && webView.plugin != null) { + switch (action) { + case 1: + { + String certificatePath = (String) response.getCertificatePath(); + String certificatePassword = (String) response.getCertificatePassword(); + String keyStoreType = (String) response.getKeyStoreType(); + Util.PrivateKeyAndCertificates privateKeyAndCertificates = + Util.loadPrivateKeyAndCertificate(webView.plugin, certificatePath, certificatePassword, keyStoreType); + if (privateKeyAndCertificates != null) { request.proceed(privateKeyAndCertificates.privateKey, privateKeyAndCertificates.certificates); + } else { + request.cancel(); } - return; - case 2: - request.ignore(); - return; - case 0: - default: - request.cancel(); - return; - } + } + break; + case 2: + request.ignore(); + break; + case 0: + default: + request.cancel(); } + + return false; } + return true; + } + + @Override + public void defaultBehaviour(@Nullable ClientCertResponse result) { InAppWebViewClient.super.onReceivedClientCertRequest(view, request); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } + }; - @Override - public void notImplemented() { - InAppWebViewClient.super.onReceivedClientCertRequest(view, request); - } - }); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedClientCertRequest(challenge, callback); + } else { + callback.defaultBehaviour(null); + } } @Override @@ -559,68 +568,64 @@ public class InAppWebViewClient extends WebViewClient { final InAppWebView webView = (InAppWebView) view; webView.zoomScale = newScale / Util.getPixelDensity(webView.getContext()); - Map obj = new HashMap<>(); - obj.put("oldScale", oldScale); - obj.put("newScale", newScale); - channel.invokeMethod("onZoomScaleChanged", obj); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onZoomScaleChanged(oldScale, newScale); + } } @RequiresApi(api = Build.VERSION_CODES.O_MR1) @Override public void onSafeBrowsingHit(final WebView view, final WebResourceRequest request, final int threatType, final SafeBrowsingResponse callback) { - Map obj = new HashMap<>(); - obj.put("url", request.getUrl().toString()); - obj.put("threatType", threatType); - - channel.invokeMethod("onSafeBrowsingHit", obj, new MethodChannel.Result() { + final InAppWebView webView = (InAppWebView) view; + final EventChannelDelegate.SafeBrowsingHitCallback resultCallback = new EventChannelDelegate.SafeBrowsingHitCallback() { @Override - public void success(Object response) { - if (response != null) { - Map responseMap = (Map) response; - Boolean report = (Boolean) responseMap.get("report"); - Integer action = (Integer) responseMap.get("action"); - - report = report != null ? report : true; - - if (action != null) { - switch (action) { - case 0: - callback.backToSafety(report); - return; - case 1: - callback.proceed(report); - return; - case 2: - default: - callback.showInterstitial(report); - return; - } + public boolean nonNullSuccess(@NonNull com.pichillilorenzo.flutter_inappwebview.types.SafeBrowsingResponse response) { + Integer action = response.getAction(); + if (action != null) { + boolean report = response.isReport(); + switch (action) { + case 0: + callback.backToSafety(report); + break; + case 1: + callback.proceed(report); + break; + case 2: + default: + callback.showInterstitial(report); } + + return false; } + return true; + } + + @Override + public void defaultBehaviour(@Nullable com.pichillilorenzo.flutter_inappwebview.types.SafeBrowsingResponse result) { InAppWebViewClient.super.onSafeBrowsingHit(view, request, threatType, callback); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } + }; - @Override - public void notImplemented() { - InAppWebViewClient.super.onSafeBrowsingHit(view, request, threatType, callback); - } - }); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onSafeBrowsingHit(request.getUrl().toString(), threatType, resultCallback); + } else { + resultCallback.defaultBehaviour(null); + } } @Override public WebResourceResponse shouldInterceptRequest(WebView view, final String url) { - final InAppWebView webView = (InAppWebView) view; if (webView.customSettings.useShouldInterceptRequest) { - WebResourceResponse onShouldInterceptResponse = onShouldInterceptRequest(url); - return onShouldInterceptResponse; + return onShouldInterceptRequest(view, url); } URI uri; @@ -641,32 +646,28 @@ public class InAppWebViewClient extends WebViewClient { String scheme = uri.getScheme(); if (webView.customSettings.resourceCustomSchemes != null && webView.customSettings.resourceCustomSchemes.contains(scheme)) { - final Map obj = new HashMap<>(); - obj.put("url", url); - - Util.WaitFlutterResult flutterResult; - try { - flutterResult = Util.invokeMethodAndWait(channel, "onLoadResourceCustomScheme", obj); - } catch (InterruptedException e) { - e.printStackTrace(); - return null; + CustomSchemeResponse customSchemeResponse = null; + if (webView.eventChannelDelegate != null) { + try { + customSchemeResponse = webView.eventChannelDelegate.onLoadResourceCustomScheme(url); + } catch (InterruptedException e) { + e.printStackTrace(); + return null; + } } - if (flutterResult.error != null) { - Log.e(LOG_TAG, flutterResult.error); - } - else if (flutterResult.result != null) { - Map res = (Map) flutterResult.result; + if (customSchemeResponse != null) { WebResourceResponse response = null; try { - response = webView.contentBlockerHandler.checkUrl(webView, url, res.get("contentType").toString()); + response = webView.contentBlockerHandler.checkUrl(webView, url, customSchemeResponse.getContentType()); } catch (Exception e) { e.printStackTrace(); } if (response != null) return response; - byte[] data = (byte[]) res.get("data"); - return new WebResourceResponse(res.get("contentType").toString(), res.get("contentEncoding").toString(), new ByteArrayInputStream(data)); + return new WebResourceResponse(customSchemeResponse.getContentType(), + customSchemeResponse.getContentType(), + new ByteArrayInputStream(customSchemeResponse.getData())); } } @@ -689,68 +690,50 @@ public class InAppWebViewClient extends WebViewClient { String url = request.getUrl().toString(); if (webView.customSettings.useShouldInterceptRequest) { - WebResourceResponse onShouldInterceptResponse = onShouldInterceptRequest(request); - return onShouldInterceptResponse; + return onShouldInterceptRequest(view, request); } return shouldInterceptRequest(view, url); } - public WebResourceResponse onShouldInterceptRequest(Object request) { - String url = request instanceof String ? (String) request : null; - String method = "GET"; - Map headers = null; - boolean hasGesture = false; - boolean isForMainFrame = true; - boolean isRedirect = false; - + public WebResourceResponse onShouldInterceptRequest(WebView view, Object request) { + final InAppWebView webView = (InAppWebView) view; + + WebResourceRequestExt requestExt; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && request instanceof WebResourceRequest) { WebResourceRequest webResourceRequest = (WebResourceRequest) request; - url = webResourceRequest.getUrl().toString(); - headers = webResourceRequest.getRequestHeaders(); - hasGesture = webResourceRequest.hasGesture(); - isForMainFrame = webResourceRequest.isForMainFrame(); - if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT)) { - isRedirect = WebResourceRequestCompat.isRedirect(webResourceRequest); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - isRedirect = webResourceRequest.isRedirect(); + requestExt = WebResourceRequestExt.fromWebResourceRequest(webResourceRequest); + } else { + requestExt = new WebResourceRequestExt( + Uri.parse((String) request), null, false, + false, true, "GET" + ); + } + + WebResourceResponseExt response = null; + if (webView.eventChannelDelegate != null) { + try { + response = webView.eventChannelDelegate.shouldInterceptRequest(requestExt); + } catch (InterruptedException e) { + e.printStackTrace(); + return null; } } - final Map obj = new HashMap<>(); - obj.put("url", url); - obj.put("method", method); - obj.put("headers", headers); - obj.put("isForMainFrame", isForMainFrame); - obj.put("hasGesture", hasGesture); - obj.put("isRedirect", isRedirect); - - Util.WaitFlutterResult flutterResult; - try { - flutterResult = Util.invokeMethodAndWait(channel, "shouldInterceptRequest", obj); - } catch (InterruptedException e) { - e.printStackTrace(); - return null; - } - - if (flutterResult.error != null) { - Log.e(LOG_TAG, flutterResult.error); - } - else if (flutterResult.result != null) { - Map res = (Map) flutterResult.result; - String contentType = (String) res.get("contentType"); - String contentEncoding = (String) res.get("contentEncoding"); - byte[] data = (byte[]) res.get("data"); - Map responseHeaders = (Map) res.get("headers"); - Integer statusCode = (Integer) res.get("statusCode"); - String reasonPhrase = (String) res.get("reasonPhrase"); + if (response != null) { + String contentType = response.getContentType(); + String contentEncoding = response.getContentEncoding(); + byte[] data = response.getData(); + Map responseHeaders = response.getHeaders(); + Integer statusCode = response.getStatusCode(); + String reasonPhrase = response.getReasonPhrase(); ByteArrayInputStream inputStream = (data != null) ? new ByteArrayInputStream(data) : null; - - if ((responseHeaders == null && statusCode == null && reasonPhrase == null) || Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - return new WebResourceResponse(contentType, contentEncoding, inputStream); - } else { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && statusCode != null && reasonPhrase != null) { return new WebResourceResponse(contentType, contentEncoding, statusCode, reasonPhrase, responseHeaders, inputStream); + } else { + return new WebResourceResponse(contentType, contentEncoding, inputStream); } } @@ -758,51 +741,49 @@ public class InAppWebViewClient extends WebViewClient { } @Override - public void onFormResubmission (final WebView view, final Message dontResend, final Message resend) { - Map obj = new HashMap<>(); - obj.put("url", view.getUrl()); - - channel.invokeMethod("onFormResubmission", obj, new MethodChannel.Result() { + public void onFormResubmission(final WebView view, final Message dontResend, final Message resend) { + final InAppWebView webView = (InAppWebView) view; + final EventChannelDelegate.FormResubmissionCallback callback = new EventChannelDelegate.FormResubmissionCallback() { + @Override + public boolean nonNullSuccess(@NonNull Integer action) { + switch (action) { + case 0: + resend.sendToTarget(); + break; + case 1: + default: + dontResend.sendToTarget(); + } + return false; + } @Override - public void success(@Nullable Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - if (action != null) { - switch (action) { - case 0: - resend.sendToTarget(); - return; - case 1: - default: - dontResend.sendToTarget(); - return; - } - } - } - + public void defaultBehaviour(@Nullable Integer result) { InAppWebViewClient.super.onFormResubmission(view, dontResend, resend); } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { - Log.e(LOG_TAG, "ERROR: " + errorCode + " " + errorMessage); + Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } + }; - @Override - public void notImplemented() { - InAppWebViewClient.super.onFormResubmission(view, dontResend, resend); - } - }); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onFormResubmission(webView.getUrl(), callback); + } else { + callback.defaultBehaviour(null); + } } @Override public void onPageCommitVisible(WebView view, String url) { super.onPageCommitVisible(view, url); - Map obj = new HashMap<>(); - obj.put("url", url); - channel.invokeMethod("onPageCommitVisible", obj); + + final InAppWebView webView = (InAppWebView) view; + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onPageCommitVisible(url); + } } @RequiresApi(api = Build.VERSION_CODES.O) @@ -810,16 +791,10 @@ public class InAppWebViewClient extends WebViewClient { public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) { final InAppWebView webView = (InAppWebView) view; - if (webView.customSettings.useOnRenderProcessGone) { - Boolean didCrash = detail.didCrash(); - Integer rendererPriorityAtExit = detail.rendererPriorityAtExit(); - - Map obj = new HashMap<>(); - obj.put("didCrash", didCrash); - obj.put("rendererPriorityAtExit", rendererPriorityAtExit); - - channel.invokeMethod("onRenderProcessGone", obj); - + if (webView.customSettings.useOnRenderProcessGone && webView.eventChannelDelegate != null) { + boolean didCrash = detail.didCrash(); + int rendererPriorityAtExit = detail.rendererPriorityAtExit(); + webView.eventChannelDelegate.onRenderProcessGone(didCrash, rendererPriorityAtExit); return true; } @@ -828,18 +803,14 @@ public class InAppWebViewClient extends WebViewClient { @Override public void onReceivedLoginRequest(WebView view, String realm, String account, String args) { - Map obj = new HashMap<>(); - obj.put("realm", realm); - obj.put("account", account); - obj.put("args", args); - - channel.invokeMethod("onReceivedLoginRequest", obj); + final InAppWebView webView = (InAppWebView) view; + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onReceivedLoginRequest(realm, account, args); + } } @Override - public void onUnhandledKeyEvent(WebView view, KeyEvent event) { - - } + public void onUnhandledKeyEvent(WebView view, KeyEvent event) {} public void dispose() { if (inAppBrowserDelegate != null) { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewRenderProcessClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewRenderProcessClient.java index b3d96c9b..174c647c 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewRenderProcessClient.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewRenderProcessClient.java @@ -9,88 +9,86 @@ import androidx.webkit.WebViewFeature; import androidx.webkit.WebViewRenderProcess; import androidx.webkit.WebViewRenderProcessClient; -import java.util.HashMap; -import java.util.Map; - -import io.flutter.plugin.common.MethodChannel; - public class InAppWebViewRenderProcessClient extends WebViewRenderProcessClient { protected static final String LOG_TAG = "IAWRenderProcessClient"; - private final MethodChannel channel; - public InAppWebViewRenderProcessClient(MethodChannel channel) { + public InAppWebViewRenderProcessClient() { super(); - - this.channel = channel; } @Override public void onRenderProcessUnresponsive(@NonNull WebView view, @Nullable final WebViewRenderProcess renderer) { - Map obj = new HashMap<>(); - obj.put("url", view.getUrl()); - channel.invokeMethod("onRenderProcessUnresponsive", obj, new MethodChannel.Result() { + final InAppWebView webView = (InAppWebView) view; + final EventChannelDelegate.RenderProcessUnresponsiveCallback callback = new EventChannelDelegate.RenderProcessUnresponsiveCallback() { + @Override + public boolean nonNullSuccess(@NonNull Integer action) { + if (renderer != null) { + switch (action) { + case 0: + if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_TERMINATE)) + renderer.terminate(); + break; + } + return false; + } + return true; + } @Override - public void success(@Nullable Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - if (action != null && renderer != null) { - switch (action) { - case 0: - if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_TERMINATE)) - renderer.terminate(); - break; - } - } - } + public void defaultBehaviour(@Nullable Integer result) { + } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } + }; - @Override - public void notImplemented() { - - } - }); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onRenderProcessUnresponsive(webView.getUrl(), callback); + } else { + callback.defaultBehaviour(null); + } } @Override public void onRenderProcessResponsive(@NonNull WebView view, @Nullable final WebViewRenderProcess renderer) { - Map obj = new HashMap<>(); - obj.put("url", view.getUrl()); - channel.invokeMethod("onRenderProcessResponsive", obj, new MethodChannel.Result() { + final InAppWebView webView = (InAppWebView) view; + final EventChannelDelegate.RenderProcessResponsiveCallback callback = new EventChannelDelegate.RenderProcessResponsiveCallback() { + @Override + public boolean nonNullSuccess(@NonNull Integer action) { + if (renderer != null) { + switch (action) { + case 0: + if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_TERMINATE)) + renderer.terminate(); + break; + } + return false; + } + return true; + } @Override - public void success(@Nullable Object response) { - if (response != null) { - Map responseMap = (Map) response; - Integer action = (Integer) responseMap.get("action"); - if (action != null && renderer != null) { - switch (action) { - case 0: - if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_VIEW_RENDERER_TERMINATE)) - renderer.terminate(); - break; - } - } - } + public void defaultBehaviour(@Nullable Integer result) { + } @Override public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { Log.e(LOG_TAG, errorCode + ", " + ((errorMessage != null) ? errorMessage : "")); + defaultBehaviour(null); } + }; - @Override - public void notImplemented() { - - } - }); + if (webView.eventChannelDelegate != null) { + webView.eventChannelDelegate.onRenderProcessResponsive(webView.getUrl(), callback); + } else { + callback.defaultBehaviour(null); + } } void dispose() { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/BaseCallbackResultImpl.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/BaseCallbackResultImpl.java new file mode 100644 index 00000000..4a31fdfb --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/BaseCallbackResultImpl.java @@ -0,0 +1,47 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public class BaseCallbackResultImpl implements ICallbackResult { + @Override + public boolean nonNullSuccess(@NonNull T result) { + return true; + } + + @Override + public boolean nullSuccess() { + return true; + } + + @Override + public void defaultBehaviour(@Nullable T result) {} + + @Override + public void success(@Nullable Object obj) { + T result = decodeResult(obj); + boolean shouldRunDefaultBehaviour; + if (result == null) { + shouldRunDefaultBehaviour = nullSuccess(); + } else { + shouldRunDefaultBehaviour = nonNullSuccess(result); + } + if (shouldRunDefaultBehaviour) { + defaultBehaviour(result); + } + } + + @Nullable + @Override + public T decodeResult(@Nullable Object obj) { + return null; + } + + @Override + public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {} + + @Override + public void notImplemented() { + defaultBehaviour(null); + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ClientCertResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ClientCertResponse.java new file mode 100644 index 00000000..ba604dcb --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ClientCertResponse.java @@ -0,0 +1,105 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Map; + +public class ClientCertResponse { + @NonNull + private String certificatePath; + @Nullable + private String certificatePassword; + @NonNull + private String keyStoreType; + @Nullable + private Integer action; + + public ClientCertResponse(@NonNull String certificatePath, @Nullable String certificatePassword, @NonNull String keyStoreType, @Nullable Integer action) { + this.certificatePath = certificatePath; + this.certificatePassword = certificatePassword; + this.keyStoreType = keyStoreType; + this.action = action; + } + + @Nullable + public static ClientCertResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String certificatePath = (String) map.get("certificatePath"); + String certificatePassword = (String) map.get("certificatePassword"); + String keyStoreType = (String) map.get("keyStoreType"); + Integer action = (Integer) map.get("action"); + return new ClientCertResponse(certificatePath, certificatePassword, keyStoreType, action); + } + + @NonNull + public String getCertificatePath() { + return certificatePath; + } + + public void setCertificatePath(@NonNull String certificatePath) { + this.certificatePath = certificatePath; + } + + @Nullable + public String getCertificatePassword() { + return certificatePassword; + } + + public void setCertificatePassword(@Nullable String certificatePassword) { + this.certificatePassword = certificatePassword; + } + + @NonNull + public String getKeyStoreType() { + return keyStoreType; + } + + public void setKeyStoreType(@NonNull String keyStoreType) { + this.keyStoreType = keyStoreType; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ClientCertResponse that = (ClientCertResponse) o; + + if (!certificatePath.equals(that.certificatePath)) return false; + if (certificatePassword != null ? !certificatePassword.equals(that.certificatePassword) : that.certificatePassword != null) + return false; + if (!keyStoreType.equals(that.keyStoreType)) return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = certificatePath.hashCode(); + result = 31 * result + (certificatePassword != null ? certificatePassword.hashCode() : 0); + result = 31 * result + keyStoreType.hashCode(); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "ClientCertResponse{" + + "certificatePath='" + certificatePath + '\'' + + ", certificatePassword='" + certificatePassword + '\'' + + ", keyStoreType='" + keyStoreType + '\'' + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomSchemeResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomSchemeResponse.java new file mode 100644 index 00000000..05d3e737 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/CustomSchemeResponse.java @@ -0,0 +1,89 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Arrays; +import java.util.Map; + +public class CustomSchemeResponse { + @NonNull + private byte[] data; + @NonNull + private String contentType; + @NonNull + private String contentEncoding; + + public CustomSchemeResponse(@NonNull byte[] data, @NonNull String contentType, @NonNull String contentEncoding) { + this.data = data; + this.contentType = contentType; + this.contentEncoding = contentEncoding; + } + + @Nullable + public static CustomSchemeResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + byte[] data = (byte[]) map.get("data"); + String contentType = (String) map.get("contentType"); + String contentEncoding = (String) map.get("contentEncoding"); + return new CustomSchemeResponse(data, contentType, contentEncoding); + } + + @NonNull + public byte[] getData() { + return data; + } + + public void setData(@NonNull byte[] data) { + this.data = data; + } + + @NonNull + public String getContentType() { + return contentType; + } + + public void setContentType(@NonNull String contentType) { + this.contentType = contentType; + } + + @NonNull + public String getContentEncoding() { + return contentEncoding; + } + + public void setContentEncoding(@NonNull String contentEncoding) { + this.contentEncoding = contentEncoding; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + CustomSchemeResponse that = (CustomSchemeResponse) o; + + if (!Arrays.equals(data, that.data)) return false; + if (!contentType.equals(that.contentType)) return false; + return contentEncoding.equals(that.contentEncoding); + } + + @Override + public int hashCode() { + int result = Arrays.hashCode(data); + result = 31 * result + contentType.hashCode(); + result = 31 * result + contentEncoding.hashCode(); + return result; + } + + @Override + public String toString() { + return "CustomSchemeResponse{" + + "data=" + Arrays.toString(data) + + ", contentType='" + contentType + '\'' + + ", contentEncoding='" + contentEncoding + '\'' + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/GeolocationPermissionShowPromptResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/GeolocationPermissionShowPromptResponse.java new file mode 100644 index 00000000..4ec0a321 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/GeolocationPermissionShowPromptResponse.java @@ -0,0 +1,84 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Map; + +public class GeolocationPermissionShowPromptResponse { + @NonNull + private String origin; + boolean allow; + boolean retain; + + public GeolocationPermissionShowPromptResponse(@NonNull String origin, boolean allow, boolean retain) { + this.origin = origin; + this.allow = allow; + this.retain = retain; + } + + @Nullable + public static GeolocationPermissionShowPromptResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String origin = (String) map.get("origin"); + boolean allow = (boolean) map.get("allow"); + boolean retain = (boolean) map.get("retain"); + return new GeolocationPermissionShowPromptResponse(origin, allow, retain); + } + + @NonNull + public String getOrigin() { + return origin; + } + + public void setOrigin(@NonNull String origin) { + this.origin = origin; + } + + public boolean isAllow() { + return allow; + } + + public void setAllow(boolean allow) { + this.allow = allow; + } + + public boolean isRetain() { + return retain; + } + + public void setRetain(boolean retain) { + this.retain = retain; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + GeolocationPermissionShowPromptResponse that = (GeolocationPermissionShowPromptResponse) o; + + if (allow != that.allow) return false; + if (retain != that.retain) return false; + return origin.equals(that.origin); + } + + @Override + public int hashCode() { + int result = origin.hashCode(); + result = 31 * result + (allow ? 1 : 0); + result = 31 * result + (retain ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "GeolocationPermissionShowPromptResponse{" + + "origin='" + origin + '\'' + + ", allow=" + allow + + ", retain=" + retain + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/HttpAuthResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/HttpAuthResponse.java new file mode 100644 index 00000000..06a0ba4a --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/HttpAuthResponse.java @@ -0,0 +1,102 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.Map; + +public class HttpAuthResponse { + @NonNull + private String username; + @NonNull + private String password; + boolean permanentPersistence; + @Nullable + private Integer action; + + public HttpAuthResponse(@NonNull String username, @NonNull String password, boolean permanentPersistence, @Nullable Integer action) { + this.username = username; + this.password = password; + this.permanentPersistence = permanentPersistence; + this.action = action; + } + + @Nullable + public static HttpAuthResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String username = (String) map.get("username"); + String password = (String) map.get("password"); + boolean permanentPersistence = (boolean) map.get("permanentPersistence"); + Integer action = (Integer) map.get("action"); + return new HttpAuthResponse(username, password, permanentPersistence, action); + } + + @NonNull + public String getUsername() { + return username; + } + + public void setUsername(@NonNull String username) { + this.username = username; + } + + @NonNull + public String getPassword() { + return password; + } + + public void setPassword(@NonNull String password) { + this.password = password; + } + + public boolean isPermanentPersistence() { + return permanentPersistence; + } + + public void setPermanentPersistence(boolean permanentPersistence) { + this.permanentPersistence = permanentPersistence; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + HttpAuthResponse that = (HttpAuthResponse) o; + + if (permanentPersistence != that.permanentPersistence) return false; + if (!username.equals(that.username)) return false; + if (!password.equals(that.password)) return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = username.hashCode(); + result = 31 * result + password.hashCode(); + result = 31 * result + (permanentPersistence ? 1 : 0); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "HttpAuthResponse{" + + "username='" + username + '\'' + + ", password='" + password + '\'' + + ", permanentPersistence=" + permanentPersistence + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ICallbackResult.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ICallbackResult.java new file mode 100644 index 00000000..af515221 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ICallbackResult.java @@ -0,0 +1,13 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import io.flutter.plugin.common.MethodChannel; + +public interface ICallbackResult extends MethodChannel.Result { + boolean nonNullSuccess(@NonNull T result); + boolean nullSuccess(); + void defaultBehaviour(@Nullable T result); + @Nullable T decodeResult(@Nullable Object obj); +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/InAppWebViewInterface.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/InAppWebViewInterface.java index aedaccdd..24e0a88d 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/InAppWebViewInterface.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/InAppWebViewInterface.java @@ -8,9 +8,12 @@ import android.webkit.ValueCallback; import android.webkit.WebMessage; import android.webkit.WebView; +import androidx.annotation.Nullable; + import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin; import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate; import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebViewSettings; +import com.pichillilorenzo.flutter_inappwebview.in_app_webview.EventChannelDelegate; import java.io.IOException; import java.util.HashMap; @@ -102,4 +105,7 @@ public interface InAppWebViewInterface { Looper getWebViewLooper(); boolean isInFullscreen(); void setInFullscreen(boolean inFullscreen); + @Nullable + EventChannelDelegate getEventChannelDelegate(); + void setEventChannelDelegate(@Nullable EventChannelDelegate eventChannelDelegate); } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsAlertResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsAlertResponse.java new file mode 100644 index 00000000..da4ddb14 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsAlertResponse.java @@ -0,0 +1,98 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.Nullable; + +import java.util.Map; + +public class JsAlertResponse { + private String message; + private String confirmButtonTitle; + private boolean handledByClient; + @Nullable + private Integer action; + + public JsAlertResponse(String message, String confirmButtonTitle, boolean handledByClient, @Nullable Integer action) { + this.message = message; + this.confirmButtonTitle = confirmButtonTitle; + this.handledByClient = handledByClient; + this.action = action; + } + + @Nullable + public static JsAlertResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String message = (String) map.get("message"); + String confirmButtonTitle = (String) map.get("confirmButtonTitle"); + boolean handledByClient = (boolean) map.get("handledByClient"); + Integer action = (Integer) map.get("action"); + return new JsAlertResponse(message, confirmButtonTitle, handledByClient, action); + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getConfirmButtonTitle() { + return confirmButtonTitle; + } + + public void setConfirmButtonTitle(String confirmButtonTitle) { + this.confirmButtonTitle = confirmButtonTitle; + } + + public boolean isHandledByClient() { + return handledByClient; + } + + public void setHandledByClient(boolean handledByClient) { + this.handledByClient = handledByClient; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JsAlertResponse that = (JsAlertResponse) o; + + if (handledByClient != that.handledByClient) return false; + if (message != null ? !message.equals(that.message) : that.message != null) return false; + if (confirmButtonTitle != null ? !confirmButtonTitle.equals(that.confirmButtonTitle) : that.confirmButtonTitle != null) + return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = message != null ? message.hashCode() : 0; + result = 31 * result + (confirmButtonTitle != null ? confirmButtonTitle.hashCode() : 0); + result = 31 * result + (handledByClient ? 1 : 0); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "JsAlertResponse{" + + "message='" + message + '\'' + + ", confirmButtonTitle='" + confirmButtonTitle + '\'' + + ", handledByClient=" + handledByClient + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsBeforeUnloadResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsBeforeUnloadResponse.java new file mode 100644 index 00000000..75a5d163 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsBeforeUnloadResponse.java @@ -0,0 +1,113 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.Nullable; + +import java.util.Map; + +public class JsBeforeUnloadResponse { + private String message; + private String confirmButtonTitle; + private String cancelButtonTitle; + private boolean handledByClient; + @Nullable + private Integer action; + + public JsBeforeUnloadResponse(String message, String confirmButtonTitle, String cancelButtonTitle, boolean handledByClient, @Nullable Integer action) { + this.message = message; + this.confirmButtonTitle = confirmButtonTitle; + this.cancelButtonTitle = cancelButtonTitle; + this.handledByClient = handledByClient; + this.action = action; + } + + @Nullable + public static JsBeforeUnloadResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String message = (String) map.get("message"); + String confirmButtonTitle = (String) map.get("confirmButtonTitle"); + String cancelButtonTitle = (String) map.get("cancelButtonTitle"); + boolean handledByClient = (boolean) map.get("handledByClient"); + Integer action = (Integer) map.get("action"); + return new JsBeforeUnloadResponse(message, confirmButtonTitle, cancelButtonTitle, handledByClient, action); + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getConfirmButtonTitle() { + return confirmButtonTitle; + } + + public void setConfirmButtonTitle(String confirmButtonTitle) { + this.confirmButtonTitle = confirmButtonTitle; + } + + public String getCancelButtonTitle() { + return cancelButtonTitle; + } + + public void setCancelButtonTitle(String cancelButtonTitle) { + this.cancelButtonTitle = cancelButtonTitle; + } + + public boolean isHandledByClient() { + return handledByClient; + } + + public void setHandledByClient(boolean handledByClient) { + this.handledByClient = handledByClient; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JsBeforeUnloadResponse that = (JsBeforeUnloadResponse) o; + + if (handledByClient != that.handledByClient) return false; + if (message != null ? !message.equals(that.message) : that.message != null) return false; + if (confirmButtonTitle != null ? !confirmButtonTitle.equals(that.confirmButtonTitle) : that.confirmButtonTitle != null) + return false; + if (cancelButtonTitle != null ? !cancelButtonTitle.equals(that.cancelButtonTitle) : that.cancelButtonTitle != null) + return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = message != null ? message.hashCode() : 0; + result = 31 * result + (confirmButtonTitle != null ? confirmButtonTitle.hashCode() : 0); + result = 31 * result + (cancelButtonTitle != null ? cancelButtonTitle.hashCode() : 0); + result = 31 * result + (handledByClient ? 1 : 0); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "JsConfirmResponse{" + + "message='" + message + '\'' + + ", confirmButtonTitle='" + confirmButtonTitle + '\'' + + ", cancelButtonTitle='" + cancelButtonTitle + '\'' + + ", handledByClient=" + handledByClient + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsConfirmResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsConfirmResponse.java new file mode 100644 index 00000000..4b8916ea --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsConfirmResponse.java @@ -0,0 +1,113 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.Nullable; + +import java.util.Map; + +public class JsConfirmResponse { + private String message; + private String confirmButtonTitle; + private String cancelButtonTitle; + private boolean handledByClient; + @Nullable + private Integer action; + + public JsConfirmResponse(String message, String confirmButtonTitle, String cancelButtonTitle, boolean handledByClient, @Nullable Integer action) { + this.message = message; + this.confirmButtonTitle = confirmButtonTitle; + this.cancelButtonTitle = cancelButtonTitle; + this.handledByClient = handledByClient; + this.action = action; + } + + @Nullable + public static JsConfirmResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String message = (String) map.get("message"); + String confirmButtonTitle = (String) map.get("confirmButtonTitle"); + String cancelButtonTitle = (String) map.get("cancelButtonTitle"); + boolean handledByClient = (boolean) map.get("handledByClient"); + Integer action = (Integer) map.get("action"); + return new JsConfirmResponse(message, confirmButtonTitle, cancelButtonTitle, handledByClient, action); + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getConfirmButtonTitle() { + return confirmButtonTitle; + } + + public void setConfirmButtonTitle(String confirmButtonTitle) { + this.confirmButtonTitle = confirmButtonTitle; + } + + public String getCancelButtonTitle() { + return cancelButtonTitle; + } + + public void setCancelButtonTitle(String cancelButtonTitle) { + this.cancelButtonTitle = cancelButtonTitle; + } + + public boolean isHandledByClient() { + return handledByClient; + } + + public void setHandledByClient(boolean handledByClient) { + this.handledByClient = handledByClient; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JsConfirmResponse that = (JsConfirmResponse) o; + + if (handledByClient != that.handledByClient) return false; + if (message != null ? !message.equals(that.message) : that.message != null) return false; + if (confirmButtonTitle != null ? !confirmButtonTitle.equals(that.confirmButtonTitle) : that.confirmButtonTitle != null) + return false; + if (cancelButtonTitle != null ? !cancelButtonTitle.equals(that.cancelButtonTitle) : that.cancelButtonTitle != null) + return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = message != null ? message.hashCode() : 0; + result = 31 * result + (confirmButtonTitle != null ? confirmButtonTitle.hashCode() : 0); + result = 31 * result + (cancelButtonTitle != null ? cancelButtonTitle.hashCode() : 0); + result = 31 * result + (handledByClient ? 1 : 0); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "JsConfirmResponse{" + + "message='" + message + '\'' + + ", confirmButtonTitle='" + confirmButtonTitle + '\'' + + ", cancelButtonTitle='" + cancelButtonTitle + '\'' + + ", handledByClient=" + handledByClient + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsPromptResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsPromptResponse.java new file mode 100644 index 00000000..f7146c20 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/JsPromptResponse.java @@ -0,0 +1,145 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.Nullable; + +import java.util.Map; + +public class JsPromptResponse { + private String message; + private String defaultValue; + private String confirmButtonTitle; + private String cancelButtonTitle; + private boolean handledByClient; + @Nullable + private String value; + @Nullable + private Integer action; + + public JsPromptResponse(String message, String defaultValue, String confirmButtonTitle, + String cancelButtonTitle, boolean handledByClient, @Nullable String value, @Nullable Integer action) { + this.message = message; + this.defaultValue = defaultValue; + this.confirmButtonTitle = confirmButtonTitle; + this.cancelButtonTitle = cancelButtonTitle; + this.handledByClient = handledByClient; + this.value = value; + this.action = action; + } + + @Nullable + public static JsPromptResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String message = (String) map.get("message"); + String defaultValue = (String) map.get("defaultValue"); + String confirmButtonTitle = (String) map.get("confirmButtonTitle"); + String cancelButtonTitle = (String) map.get("cancelButtonTitle"); + boolean handledByClient = (boolean) map.get("handledByClient"); + String value = (String) map.get("value"); + Integer action = (Integer) map.get("action"); + return new JsPromptResponse(message, defaultValue, confirmButtonTitle, cancelButtonTitle, handledByClient, value, action); + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getDefaultValue() { + return defaultValue; + } + + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + public String getConfirmButtonTitle() { + return confirmButtonTitle; + } + + public void setConfirmButtonTitle(String confirmButtonTitle) { + this.confirmButtonTitle = confirmButtonTitle; + } + + public String getCancelButtonTitle() { + return cancelButtonTitle; + } + + public void setCancelButtonTitle(String cancelButtonTitle) { + this.cancelButtonTitle = cancelButtonTitle; + } + + public boolean isHandledByClient() { + return handledByClient; + } + + public void setHandledByClient(boolean handledByClient) { + this.handledByClient = handledByClient; + } + + @Nullable + public String getValue() { + return value; + } + + public void setValue(@Nullable String value) { + this.value = value; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JsPromptResponse that = (JsPromptResponse) o; + + if (handledByClient != that.handledByClient) return false; + if (message != null ? !message.equals(that.message) : that.message != null) return false; + if (defaultValue != null ? !defaultValue.equals(that.defaultValue) : that.defaultValue != null) + return false; + if (confirmButtonTitle != null ? !confirmButtonTitle.equals(that.confirmButtonTitle) : that.confirmButtonTitle != null) + return false; + if (cancelButtonTitle != null ? !cancelButtonTitle.equals(that.cancelButtonTitle) : that.cancelButtonTitle != null) + return false; + if (value != null ? !value.equals(that.value) : that.value != null) return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = message != null ? message.hashCode() : 0; + result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0); + result = 31 * result + (confirmButtonTitle != null ? confirmButtonTitle.hashCode() : 0); + result = 31 * result + (cancelButtonTitle != null ? cancelButtonTitle.hashCode() : 0); + result = 31 * result + (handledByClient ? 1 : 0); + result = 31 * result + (value != null ? value.hashCode() : 0); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "JsPromptResponse{" + + "message='" + message + '\'' + + ", defaultValue='" + defaultValue + '\'' + + ", confirmButtonTitle='" + confirmButtonTitle + '\'' + + ", cancelButtonTitle='" + cancelButtonTitle + '\'' + + ", handledByClient=" + handledByClient + + ", value='" + value + '\'' + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/NavigationActionPolicy.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/NavigationActionPolicy.java index f75e13a2..cae8c91a 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/NavigationActionPolicy.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/NavigationActionPolicy.java @@ -15,7 +15,7 @@ public enum NavigationActionPolicy { } public static NavigationActionPolicy fromValue(int value) { - for( NavigationActionPolicy type : NavigationActionPolicy.values()) { + for(NavigationActionPolicy type : NavigationActionPolicy.values()) { if(value == type.value) return type; } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/PermissionResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/PermissionResponse.java new file mode 100644 index 00000000..9b38c9da --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/PermissionResponse.java @@ -0,0 +1,73 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.List; +import java.util.Map; + +public class PermissionResponse { + @NonNull + private List resources; + @Nullable + private Integer action; + + public PermissionResponse(@NonNull List resources, @Nullable Integer action) { + this.resources = resources; + this.action = action; + } + + @Nullable + public static PermissionResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + List resources = (List) map.get("resources"); + Integer action = (Integer) map.get("action"); + return new PermissionResponse(resources, action); + } + + @NonNull + public List getResources() { + return resources; + } + + public void setResources(@NonNull List resources) { + this.resources = resources; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PermissionResponse that = (PermissionResponse) o; + + if (!resources.equals(that.resources)) return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = resources.hashCode(); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "PermissionResponse{" + + "resources=" + resources + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/SafeBrowsingResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/SafeBrowsingResponse.java new file mode 100644 index 00000000..73b2fa85 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/SafeBrowsingResponse.java @@ -0,0 +1,69 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.Nullable; + +import java.util.Map; + +public class SafeBrowsingResponse { + private boolean report; + @Nullable + private Integer action; + + public SafeBrowsingResponse(boolean report, @Nullable Integer action) { + this.report = report; + this.action = action; + } + + @Nullable + public static SafeBrowsingResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + boolean report = (boolean) map.get("report"); + Integer action = (Integer) map.get("action"); + return new SafeBrowsingResponse(report, action); + } + + public boolean isReport() { + return report; + } + + public void setReport(boolean report) { + this.report = report; + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + SafeBrowsingResponse that = (SafeBrowsingResponse) o; + + if (report != that.report) return false; + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + int result = (report ? 1 : 0); + result = 31 * result + (action != null ? action.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "SafeBrowsingResponse{" + + "report=" + report + + ", action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ServerTrustAuthResponse.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ServerTrustAuthResponse.java new file mode 100644 index 00000000..5568dff0 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/ServerTrustAuthResponse.java @@ -0,0 +1,54 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.Nullable; + +import java.util.Map; + +public class ServerTrustAuthResponse { + @Nullable + private Integer action; + + public ServerTrustAuthResponse(@Nullable Integer action) { + this.action = action; + } + + @Nullable + public static ServerTrustAuthResponse fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + Integer action = (Integer) map.get("action"); + return new ServerTrustAuthResponse(action); + } + + @Nullable + public Integer getAction() { + return action; + } + + public void setAction(@Nullable Integer action) { + this.action = action; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ServerTrustAuthResponse that = (ServerTrustAuthResponse) o; + + return action != null ? action.equals(that.action) : that.action == null; + } + + @Override + public int hashCode() { + return action != null ? action.hashCode() : 0; + } + + @Override + public String toString() { + return "ServerTrustAuthResponse{" + + "action=" + action + + '}'; + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/SyncBaseCallbackResultImpl.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/SyncBaseCallbackResultImpl.java new file mode 100644 index 00000000..9b963a85 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/SyncBaseCallbackResultImpl.java @@ -0,0 +1,48 @@ +package com.pichillilorenzo.flutter_inappwebview.types; + +import androidx.annotation.CallSuper; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.concurrent.CountDownLatch; + +public class SyncBaseCallbackResultImpl extends BaseCallbackResultImpl { + final public CountDownLatch latch = new CountDownLatch(1); + @Nullable + public T result = null; + + @CallSuper + @Override + public void defaultBehaviour(@Nullable T result) { + latch.countDown(); + } + + @Override + public void success(@Nullable Object obj) { + T result = decodeResult(obj); + this.result = result; + boolean shouldRunDefaultBehaviour; + if (result == null) { + shouldRunDefaultBehaviour = nullSuccess(); + } else { + shouldRunDefaultBehaviour = nonNullSuccess(result); + } + if (shouldRunDefaultBehaviour) { + defaultBehaviour(result); + } else { + latch.countDown(); + } + } + + @CallSuper + @Override + public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) { + latch.countDown(); + } + + @CallSuper + @Override + public void notImplemented() { + defaultBehaviour(null); + } +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebResourceResponseExt.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebResourceResponseExt.java index 17a99cba..43d1d8cf 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebResourceResponseExt.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebResourceResponseExt.java @@ -24,7 +24,8 @@ public class WebResourceResponseExt { @Nullable private byte[] data; - public WebResourceResponseExt(String contentType, String contentEncoding, @Nullable Integer statusCode, @Nullable String reasonPhrase, @Nullable Map headers, @Nullable byte[] data) { + public WebResourceResponseExt(String contentType, String contentEncoding, @Nullable Integer statusCode, + @Nullable String reasonPhrase, @Nullable Map headers, @Nullable byte[] data) { this.contentType = contentType; this.contentEncoding = contentEncoding; this.statusCode = statusCode; @@ -51,6 +52,20 @@ public class WebResourceResponseExt { ); } + @Nullable + public static WebResourceResponseExt fromMap(@Nullable Map map) { + if (map == null) { + return null; + } + String contentType = (String) map.get("contentType"); + String contentEncoding = (String) map.get("contentEncoding"); + Integer statusCode = (Integer) map.get("statusCode"); + String reasonPhrase = (String) map.get("reasonPhrase"); + Map headers = (Map) map.get("headers"); + byte[] data = (byte[]) map.get("data"); + return new WebResourceResponseExt(contentType, contentEncoding, statusCode, reasonPhrase, headers, data); + } + public Map toMap() { Map webResourceResponseMap = new HashMap<>(); webResourceResponseMap.put("contentType", contentType); diff --git a/example/integration_test/in_app_webview/on_find_result_received.dart b/example/integration_test/in_app_webview/on_find_result_received.dart index 8b96cd83..f23d01f4 100644 --- a/example/integration_test/in_app_webview/on_find_result_received.dart +++ b/example/integration_test/in_app_webview/on_find_result_received.dart @@ -47,6 +47,7 @@ void onFindResultReceived() { await pageLoaded.future; await tester.pump(); + await Future.delayed(Duration(seconds: 1)); await controller.findAllAsync(find: "InAppWebViewInitialFileTest"); final int numberOfMatches = await numberOfMatchesCompleter.future; diff --git a/example/integration_test/in_app_webview/on_received_error.dart b/example/integration_test/in_app_webview/on_received_error.dart index 3d405b07..7f7fd67c 100644 --- a/example/integration_test/in_app_webview/on_received_error.dart +++ b/example/integration_test/in_app_webview/on_received_error.dart @@ -42,27 +42,6 @@ void onReceivedError() { expect(url, TEST_NOT_A_WEBSITE_URL.toString()); }); - testWidgets('file not found', (WidgetTester tester) async { - final Completer errorCodeCompleter = Completer(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: InAppWebView( - key: GlobalKey(), - initialUrlRequest: URLRequest(url: Uri.parse('file:flutter.dev')), - onReceivedError: (controller, request, error) { - errorCodeCompleter.complete(error.type); - }, - ), - ), - ); - - final WebResourceErrorType errorType = await errorCodeCompleter.future; - - expect(errorType, WebResourceErrorType.FILE_NOT_FOUND); - }); - testWidgets('event is not called with valid url', (WidgetTester tester) async { final Completer onReceivedErrorCompleter = Completer(); diff --git a/example/integration_test/proxy_controller/clear_and_set_proxy_override.dart b/example/integration_test/proxy_controller/clear_and_set_proxy_override.dart index 7418d000..f449cc21 100644 --- a/example/integration_test/proxy_controller/clear_and_set_proxy_override.dart +++ b/example/integration_test/proxy_controller/clear_and_set_proxy_override.dart @@ -53,8 +53,8 @@ void clearAndSetProxyOverride() { final String url = await pageLoaded.future; expect(url, TEST_URL_HTTP_EXAMPLE.toString()); - expect(await controller.evaluateJavascript(source: "document.getElementById('url')"), TEST_URL_HTTP_EXAMPLE.toString()); - expect(await controller.evaluateJavascript(source: "document.getElementById('method')"), "GET"); - expect(await controller.evaluateJavascript(source: "document.getElementById('headers')"), isNotNull); + expect(await controller.evaluateJavascript(source: "document.getElementById('url').innerHTML;"), TEST_URL_HTTP_EXAMPLE.toString()); + expect(await controller.evaluateJavascript(source: "document.getElementById('method').innerHTML;"), "GET"); + expect(await controller.evaluateJavascript(source: "document.getElementById('headers').innerHTML;"), isNotNull); }, skip: shouldSkip); } diff --git a/example/integration_test/service_worker_controller/should_intercept_request.dart b/example/integration_test/service_worker_controller/should_intercept_request.dart index c501381b..f4d3bac1 100644 --- a/example/integration_test/service_worker_controller/should_intercept_request.dart +++ b/example/integration_test/service_worker_controller/should_intercept_request.dart @@ -48,6 +48,6 @@ void shouldInterceptRequest() { ), ); - expect(completer.future, completes); + await expectLater(completer.future, completes); }, skip: shouldSkip); } diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index 9e98dd5e..dad54015 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -3,12 +3,11 @@ export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/2.10.4" export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example" export "COCOAPODS_PARALLEL_CODE_SIGN=true" -export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart" +export "FLUTTER_TARGET=lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" -export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==" export "DART_OBFUSCATION=false" -export "TRACK_WIDGET_CREATION=true" +export "TRACK_WIDGET_CREATION=false" export "TREE_SHAKE_ICONS=false" -export "PACKAGE_CONFIG=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/.dart_tool/package_config.json" +export "PACKAGE_CONFIG=.packages" diff --git a/lib/src/android/service_worker_controller.dart b/lib/src/android/service_worker_controller.dart index e9527a15..701f987f 100644 --- a/lib/src/android/service_worker_controller.dart +++ b/lib/src/android/service_worker_controller.dart @@ -45,7 +45,7 @@ class ServiceWorkerController { static Future _handleMethod(MethodCall call) async { ServiceWorkerController controller = ServiceWorkerController.instance(); - ServiceWorkerClient? serviceWorkerClient = controller.serviceWorkerClient; + ServiceWorkerClient? serviceWorkerClient = controller._serviceWorkerClient; switch (call.method) { case "shouldInterceptRequest": diff --git a/lib/src/in_app_webview/in_app_webview_settings.dart b/lib/src/in_app_webview/in_app_webview_settings.dart index e3d01c17..cc36e7f0 100755 --- a/lib/src/in_app_webview/in_app_webview_settings.dart +++ b/lib/src/in_app_webview/in_app_webview_settings.dart @@ -1407,131 +1407,132 @@ class InAppWebViewSettings ReferrerPolicy.fromValue(map["iframeReferrerPolicy"]); settings.iframeName = map["iframeName"]; settings.iframeCsp = map["iframeCsp"]; - } - if (defaultTargetPlatform == TargetPlatform.android) { - settings.textZoom = map["textZoom"]; - settings.clearSessionCache = map["clearSessionCache"]; - settings.builtInZoomControls = map["builtInZoomControls"]; - settings.displayZoomControls = map["displayZoomControls"]; - settings.databaseEnabled = map["databaseEnabled"]; - settings.domStorageEnabled = map["domStorageEnabled"]; - settings.useWideViewPort = map["useWideViewPort"]; - settings.safeBrowsingEnabled = map["safeBrowsingEnabled"]; - settings.mixedContentMode = - MixedContentMode.fromValue(map["mixedContentMode"]); - settings.allowContentAccess = map["allowContentAccess"]; - settings.allowFileAccess = map["allowFileAccess"]; - settings.appCachePath = map["appCachePath"]; - settings.blockNetworkImage = map["blockNetworkImage"]; - settings.blockNetworkLoads = map["blockNetworkLoads"]; - settings.cacheMode = CacheMode.fromValue(map["cacheMode"]); - settings.cursiveFontFamily = map["cursiveFontFamily"]; - settings.defaultFixedFontSize = map["defaultFixedFontSize"]; - settings.defaultFontSize = map["defaultFontSize"]; - settings.defaultTextEncodingName = map["defaultTextEncodingName"]; - settings.disabledActionModeMenuItems = - ActionModeMenuItem.fromValue(map["disabledActionModeMenuItems"]); - settings.fantasyFontFamily = map["fantasyFontFamily"]; - settings.fixedFontFamily = map["fixedFontFamily"]; - settings.forceDark = ForceDark.fromValue(map["forceDark"]); - settings.forceDarkStrategy = ForceDarkStrategy.fromValue(map["forceDarkStrategy"]); - settings.geolocationEnabled = map["geolocationEnabled"]; - settings.layoutAlgorithm = - LayoutAlgorithm.fromValue(map["layoutAlgorithm"]); - settings.loadWithOverviewMode = map["loadWithOverviewMode"]; - settings.loadsImagesAutomatically = map["loadsImagesAutomatically"]; - settings.minimumLogicalFontSize = map["minimumLogicalFontSize"]; - settings.initialScale = map["initialScale"]; - settings.needInitialFocus = map["needInitialFocus"]; - settings.offscreenPreRaster = map["offscreenPreRaster"]; - settings.sansSerifFontFamily = map["sansSerifFontFamily"]; - settings.serifFontFamily = map["serifFontFamily"]; - settings.standardFontFamily = map["standardFontFamily"]; - settings.saveFormData = map["saveFormData"]; - settings.thirdPartyCookiesEnabled = map["thirdPartyCookiesEnabled"]; - settings.hardwareAcceleration = map["hardwareAcceleration"]; - settings.supportMultipleWindows = map["supportMultipleWindows"]; - settings.regexToCancelSubFramesLoading = - map["regexToCancelSubFramesLoading"]; - settings.useHybridComposition = map["useHybridComposition"]; - settings.useShouldInterceptRequest = map["useShouldInterceptRequest"]; - settings.useOnRenderProcessGone = map["useOnRenderProcessGone"]; - settings.overScrollMode = OverScrollMode.fromValue(map["overScrollMode"]); - settings.networkAvailable = map["networkAvailable"]; - settings.scrollBarStyle = ScrollBarStyle.fromValue(map["scrollBarStyle"]); - settings.verticalScrollbarPosition = - VerticalScrollbarPosition.fromValue(map["verticalScrollbarPosition"]); - settings.scrollBarDefaultDelayBeforeFade = - map["scrollBarDefaultDelayBeforeFade"]; - settings.scrollbarFadingEnabled = map["scrollbarFadingEnabled"]; - settings.scrollBarFadeDuration = map["scrollBarFadeDuration"]; - settings.rendererPriorityPolicy = RendererPriorityPolicy.fromMap( - map["rendererPriorityPolicy"]?.cast()); - settings.disableDefaultErrorPage = map["disableDefaultErrorPage"]; - settings.verticalScrollbarThumbColor = - UtilColor.fromHex(map["verticalScrollbarThumbColor"]); - settings.verticalScrollbarTrackColor = - UtilColor.fromHex(map["verticalScrollbarTrackColor"]); - settings.horizontalScrollbarThumbColor = - UtilColor.fromHex(map["horizontalScrollbarThumbColor"]); - settings.horizontalScrollbarTrackColor = - UtilColor.fromHex(map["horizontalScrollbarTrackColor"]); - } - if (defaultTargetPlatform == TargetPlatform.iOS || - defaultTargetPlatform == TargetPlatform.macOS) { - settings.disallowOverScroll = map["disallowOverScroll"]; - settings.enableViewportScale = map["enableViewportScale"]; - settings.suppressesIncrementalRendering = - map["suppressesIncrementalRendering"]; - settings.allowsAirPlayForMediaPlayback = - map["allowsAirPlayForMediaPlayback"]; - settings.allowsBackForwardNavigationGestures = - map["allowsBackForwardNavigationGestures"]; - settings.allowsLinkPreview = map["allowsLinkPreview"]; - settings.ignoresViewportScaleLimits = map["ignoresViewportScaleLimits"]; - settings.allowsInlineMediaPlayback = map["allowsInlineMediaPlayback"]; - settings.allowsPictureInPictureMediaPlayback = - map["allowsPictureInPictureMediaPlayback"]; - settings.isFraudulentWebsiteWarningEnabled = - map["isFraudulentWebsiteWarningEnabled"]; - settings.selectionGranularity = - SelectionGranularity.fromValue(map["selectionGranularity"])!; - settings.dataDetectorTypes = dataDetectorTypes; - settings.sharedCookiesEnabled = map["sharedCookiesEnabled"]; - settings.automaticallyAdjustsScrollIndicatorInsets = - map["automaticallyAdjustsScrollIndicatorInsets"]; - settings.accessibilityIgnoresInvertColors = - map["accessibilityIgnoresInvertColors"]; - settings.decelerationRate = - ScrollViewDecelerationRate.fromValue(map["decelerationRate"])!; - settings.alwaysBounceVertical = map["alwaysBounceVertical"]; - settings.alwaysBounceHorizontal = map["alwaysBounceHorizontal"]; - settings.scrollsToTop = map["scrollsToTop"]; - settings.isPagingEnabled = map["isPagingEnabled"]; - settings.maximumZoomScale = map["maximumZoomScale"]; - settings.minimumZoomScale = map["minimumZoomScale"]; - settings.contentInsetAdjustmentBehavior = - ScrollViewContentInsetAdjustmentBehavior.fromValue( - map["contentInsetAdjustmentBehavior"])!; - settings.isDirectionalLockEnabled = map["isDirectionalLockEnabled"]; - settings.mediaType = map["mediaType"]; - settings.pageZoom = map["pageZoom"]; - settings.limitsNavigationsToAppBoundDomains = - map["limitsNavigationsToAppBoundDomains"]; - settings.useOnNavigationResponse = map["useOnNavigationResponse"]; - settings.applePayAPIEnabled = map["applePayAPIEnabled"]; - settings.allowingReadAccessTo = map["allowingReadAccessTo"] != null - ? Uri.parse(map["allowingReadAccessTo"]) - : null; - settings.disableLongPressContextMenuOnLinks = - map["disableLongPressContextMenuOnLinks"]; - settings.disableInputAccessoryView = map["disableInputAccessoryView"]; - settings.underPageBackgroundColor = - UtilColor.fromHex(map["underPageBackgroundColor"]); - settings.isTextInteractionEnabled = map["isTextInteractionEnabled"]; - settings.isSiteSpecificQuirksModeEnabled = - map["isSiteSpecificQuirksModeEnabled"]; - settings.upgradeKnownHostsToHTTPS = map["upgradeKnownHostsToHTTPS"]; + } else { + if (defaultTargetPlatform == TargetPlatform.android) { + settings.textZoom = map["textZoom"]; + settings.clearSessionCache = map["clearSessionCache"]; + settings.builtInZoomControls = map["builtInZoomControls"]; + settings.displayZoomControls = map["displayZoomControls"]; + settings.databaseEnabled = map["databaseEnabled"]; + settings.domStorageEnabled = map["domStorageEnabled"]; + settings.useWideViewPort = map["useWideViewPort"]; + settings.safeBrowsingEnabled = map["safeBrowsingEnabled"]; + settings.mixedContentMode = + MixedContentMode.fromValue(map["mixedContentMode"]); + settings.allowContentAccess = map["allowContentAccess"]; + settings.allowFileAccess = map["allowFileAccess"]; + settings.appCachePath = map["appCachePath"]; + settings.blockNetworkImage = map["blockNetworkImage"]; + settings.blockNetworkLoads = map["blockNetworkLoads"]; + settings.cacheMode = CacheMode.fromValue(map["cacheMode"]); + settings.cursiveFontFamily = map["cursiveFontFamily"]; + settings.defaultFixedFontSize = map["defaultFixedFontSize"]; + settings.defaultFontSize = map["defaultFontSize"]; + settings.defaultTextEncodingName = map["defaultTextEncodingName"]; + settings.disabledActionModeMenuItems = + ActionModeMenuItem.fromValue(map["disabledActionModeMenuItems"]); + settings.fantasyFontFamily = map["fantasyFontFamily"]; + settings.fixedFontFamily = map["fixedFontFamily"]; + settings.forceDark = ForceDark.fromValue(map["forceDark"]); + settings.forceDarkStrategy = ForceDarkStrategy.fromValue(map["forceDarkStrategy"]); + settings.geolocationEnabled = map["geolocationEnabled"]; + settings.layoutAlgorithm = + LayoutAlgorithm.fromValue(map["layoutAlgorithm"]); + settings.loadWithOverviewMode = map["loadWithOverviewMode"]; + settings.loadsImagesAutomatically = map["loadsImagesAutomatically"]; + settings.minimumLogicalFontSize = map["minimumLogicalFontSize"]; + settings.initialScale = map["initialScale"]; + settings.needInitialFocus = map["needInitialFocus"]; + settings.offscreenPreRaster = map["offscreenPreRaster"]; + settings.sansSerifFontFamily = map["sansSerifFontFamily"]; + settings.serifFontFamily = map["serifFontFamily"]; + settings.standardFontFamily = map["standardFontFamily"]; + settings.saveFormData = map["saveFormData"]; + settings.thirdPartyCookiesEnabled = map["thirdPartyCookiesEnabled"]; + settings.hardwareAcceleration = map["hardwareAcceleration"]; + settings.supportMultipleWindows = map["supportMultipleWindows"]; + settings.regexToCancelSubFramesLoading = + map["regexToCancelSubFramesLoading"]; + settings.useHybridComposition = map["useHybridComposition"]; + settings.useShouldInterceptRequest = map["useShouldInterceptRequest"]; + settings.useOnRenderProcessGone = map["useOnRenderProcessGone"]; + settings.overScrollMode = OverScrollMode.fromValue(map["overScrollMode"]); + settings.networkAvailable = map["networkAvailable"]; + settings.scrollBarStyle = ScrollBarStyle.fromValue(map["scrollBarStyle"]); + settings.verticalScrollbarPosition = + VerticalScrollbarPosition.fromValue(map["verticalScrollbarPosition"]); + settings.scrollBarDefaultDelayBeforeFade = + map["scrollBarDefaultDelayBeforeFade"]; + settings.scrollbarFadingEnabled = map["scrollbarFadingEnabled"]; + settings.scrollBarFadeDuration = map["scrollBarFadeDuration"]; + settings.rendererPriorityPolicy = RendererPriorityPolicy.fromMap( + map["rendererPriorityPolicy"]?.cast()); + settings.disableDefaultErrorPage = map["disableDefaultErrorPage"]; + settings.verticalScrollbarThumbColor = + UtilColor.fromHex(map["verticalScrollbarThumbColor"]); + settings.verticalScrollbarTrackColor = + UtilColor.fromHex(map["verticalScrollbarTrackColor"]); + settings.horizontalScrollbarThumbColor = + UtilColor.fromHex(map["horizontalScrollbarThumbColor"]); + settings.horizontalScrollbarTrackColor = + UtilColor.fromHex(map["horizontalScrollbarTrackColor"]); + } + else if (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) { + settings.disallowOverScroll = map["disallowOverScroll"]; + settings.enableViewportScale = map["enableViewportScale"]; + settings.suppressesIncrementalRendering = + map["suppressesIncrementalRendering"]; + settings.allowsAirPlayForMediaPlayback = + map["allowsAirPlayForMediaPlayback"]; + settings.allowsBackForwardNavigationGestures = + map["allowsBackForwardNavigationGestures"]; + settings.allowsLinkPreview = map["allowsLinkPreview"]; + settings.ignoresViewportScaleLimits = map["ignoresViewportScaleLimits"]; + settings.allowsInlineMediaPlayback = map["allowsInlineMediaPlayback"]; + settings.allowsPictureInPictureMediaPlayback = + map["allowsPictureInPictureMediaPlayback"]; + settings.isFraudulentWebsiteWarningEnabled = + map["isFraudulentWebsiteWarningEnabled"]; + settings.selectionGranularity = + SelectionGranularity.fromValue(map["selectionGranularity"])!; + settings.dataDetectorTypes = dataDetectorTypes; + settings.sharedCookiesEnabled = map["sharedCookiesEnabled"]; + settings.automaticallyAdjustsScrollIndicatorInsets = + map["automaticallyAdjustsScrollIndicatorInsets"]; + settings.accessibilityIgnoresInvertColors = + map["accessibilityIgnoresInvertColors"]; + settings.decelerationRate = + ScrollViewDecelerationRate.fromValue(map["decelerationRate"])!; + settings.alwaysBounceVertical = map["alwaysBounceVertical"]; + settings.alwaysBounceHorizontal = map["alwaysBounceHorizontal"]; + settings.scrollsToTop = map["scrollsToTop"]; + settings.isPagingEnabled = map["isPagingEnabled"]; + settings.maximumZoomScale = map["maximumZoomScale"]; + settings.minimumZoomScale = map["minimumZoomScale"]; + settings.contentInsetAdjustmentBehavior = + ScrollViewContentInsetAdjustmentBehavior.fromValue( + map["contentInsetAdjustmentBehavior"])!; + settings.isDirectionalLockEnabled = map["isDirectionalLockEnabled"]; + settings.mediaType = map["mediaType"]; + settings.pageZoom = map["pageZoom"]; + settings.limitsNavigationsToAppBoundDomains = + map["limitsNavigationsToAppBoundDomains"]; + settings.useOnNavigationResponse = map["useOnNavigationResponse"]; + settings.applePayAPIEnabled = map["applePayAPIEnabled"]; + settings.allowingReadAccessTo = map["allowingReadAccessTo"] != null + ? Uri.parse(map["allowingReadAccessTo"]) + : null; + settings.disableLongPressContextMenuOnLinks = + map["disableLongPressContextMenuOnLinks"]; + settings.disableInputAccessoryView = map["disableInputAccessoryView"]; + settings.underPageBackgroundColor = + UtilColor.fromHex(map["underPageBackgroundColor"]); + settings.isTextInteractionEnabled = map["isTextInteractionEnabled"]; + settings.isSiteSpecificQuirksModeEnabled = + map["isSiteSpecificQuirksModeEnabled"]; + settings.upgradeKnownHostsToHTTPS = map["upgradeKnownHostsToHTTPS"]; + } } return settings; } diff --git a/lib/src/types/client_cert_response.dart b/lib/src/types/client_cert_response.dart index 06cf5d49..1cee42fa 100644 --- a/lib/src/types/client_cert_response.dart +++ b/lib/src/types/client_cert_response.dart @@ -1,3 +1,5 @@ +import 'package:flutter/foundation.dart'; + import '../in_app_webview/webview.dart'; import 'client_cert_response_action.dart'; @@ -29,8 +31,12 @@ class ClientCertResponse { this.action = ClientCertResponseAction.CANCEL}) { if (this.action == ClientCertResponseAction.PROCEED) assert(certificatePath.isNotEmpty); + // ignore: deprecated_member_use_from_same_package this.keyStoreType = this.keyStoreType ?? this.androidKeyStoreType; + + if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) + assert(this.keyStoreType != null); } ///Converts instance to a map. diff --git a/lib/src/types/geolocation_permission_show_prompt_response.dart b/lib/src/types/geolocation_permission_show_prompt_response.dart index 5ded3785..59fe0da6 100644 --- a/lib/src/types/geolocation_permission_show_prompt_response.dart +++ b/lib/src/types/geolocation_permission_show_prompt_response.dart @@ -3,16 +3,17 @@ import '../in_app_webview/webview.dart'; ///Class used by the host application to set the Geolocation permission state for an origin during the [WebView.onGeolocationPermissionsShowPrompt] event. class GeolocationPermissionShowPromptResponse { ///The origin for which permissions are set. - String? origin; + String origin; ///Whether or not the origin should be allowed to use the Geolocation API. - bool? allow; + bool allow; ///Whether the permission should be retained beyond the lifetime of a page currently being displayed by a WebView - bool? retain; + ///The default value is `false`. + bool retain; GeolocationPermissionShowPromptResponse( - {this.origin, this.allow, this.retain}); + {required this.origin, required this.allow, this.retain = false}); ///Converts instance to a map. Map toMap() { diff --git a/lib/src/types/permission_resource_type.dart b/lib/src/types/permission_resource_type.dart index 5d4694b4..b773a3fd 100644 --- a/lib/src/types/permission_resource_type.dart +++ b/lib/src/types/permission_resource_type.dart @@ -59,10 +59,10 @@ class PermissionResourceType { ///- iOS ([Official API - WKMediaCaptureType.microphone](https://developer.apple.com/documentation/webkit/wkmediacapturetype/microphone)) static final MICROPHONE = PermissionResourceType._internal( 'MICROPHONE', - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? 'android.webkit.resource.AUDIO_CAPTURE' - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 1 : null)); @@ -74,7 +74,7 @@ class PermissionResourceType { ///- Android native WebView ([Official API - PermissionRequest.RESOURCE_MIDI_SYSEX](https://developer.android.com/reference/android/webkit/PermissionRequest#RESOURCE_MIDI_SYSEX)) static final MIDI_SYSEX = PermissionResourceType._internal( 'MIDI_SYSEX', - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? 'android.webkit.resource.MIDI_SYSEX' : null); @@ -84,7 +84,7 @@ class PermissionResourceType { ///- Android native WebView ([Official API - PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID](https://developer.android.com/reference/android/webkit/PermissionRequest#RESOURCE_PROTECTED_MEDIA_ID)) static final PROTECTED_MEDIA_ID = PermissionResourceType._internal( 'PROTECTED_MEDIA_ID', - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? 'android.webkit.resource.PROTECTED_MEDIA_ID' : null); @@ -95,10 +95,10 @@ class PermissionResourceType { ///- iOS ([Official API - WKMediaCaptureType.camera](https://developer.apple.com/documentation/webkit/wkmediacapturetype/camera)) static final CAMERA = PermissionResourceType._internal( 'CAMERA', - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? 'android.webkit.resource.VIDEO_CAPTURE' - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 0 : null)); @@ -108,8 +108,8 @@ class PermissionResourceType { ///- iOS ([Official API - WKMediaCaptureType.cameraAndMicrophone](https://developer.apple.com/documentation/webkit/wkmediacapturetype/cameraandmicrophone)) static final CAMERA_AND_MICROPHONE = PermissionResourceType._internal( 'CAMERA_AND_MICROPHONE', - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 2 : null); @@ -119,8 +119,8 @@ class PermissionResourceType { ///- iOS static final DEVICE_ORIENTATION_AND_MOTION = PermissionResourceType._internal( 'DEVICE_ORIENTATION_AND_MOTION', - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 'deviceOrientationAndMotion' : null); diff --git a/lib/src/types/ssl_error_type.dart b/lib/src/types/ssl_error_type.dart index 4352c981..b722e3e8 100644 --- a/lib/src/types/ssl_error_type.dart +++ b/lib/src/types/ssl_error_type.dart @@ -65,35 +65,35 @@ class SslErrorType { ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - SslError.SSL_NOTYETVALID](https://developer.android.com/reference/android/net/http/SslError#SSL_NOTYETVALID)) static final NOT_YET_VALID = SslErrorType._internal('NOT_YET_VALID', - (defaultTargetPlatform != TargetPlatform.android) ? 0 : -1); + (defaultTargetPlatform == TargetPlatform.android) ? 0 : -1); ///The certificate has expired. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - SslError.SSL_EXPIRED](https://developer.android.com/reference/android/net/http/SslError#SSL_EXPIRED)) static final EXPIRED = SslErrorType._internal( - 'EXPIRED', (defaultTargetPlatform != TargetPlatform.android) ? 1 : -1); + 'EXPIRED', (defaultTargetPlatform == TargetPlatform.android) ? 1 : -1); ///Hostname mismatch. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - SslError.SSL_IDMISMATCH](https://developer.android.com/reference/android/net/http/SslError#SSL_IDMISMATCH)) static final IDMISMATCH = SslErrorType._internal( - 'IDMISMATCH', (defaultTargetPlatform != TargetPlatform.android) ? 2 : -1); + 'IDMISMATCH', (defaultTargetPlatform == TargetPlatform.android) ? 2 : -1); ///The certificate authority is not trusted. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - SslError.SSL_UNTRUSTED](https://developer.android.com/reference/android/net/http/SslError#SSL_UNTRUSTED)) static final UNTRUSTED = SslErrorType._internal( - 'UNTRUSTED', (defaultTargetPlatform != TargetPlatform.android) ? 3 : -1); + 'UNTRUSTED', (defaultTargetPlatform == TargetPlatform.android) ? 3 : -1); ///The date of the certificate is invalid. /// ///**Supported Platforms/Implementations**: ///- Android native WebView ([Official API - SslError.SSL_DATE_INVALID](https://developer.android.com/reference/android/net/http/SslError#SSL_DATE_INVALID)) static final DATE_INVALID = SslErrorType._internal('DATE_INVALID', - (defaultTargetPlatform != TargetPlatform.android) ? 4 : -1); + (defaultTargetPlatform == TargetPlatform.android) ? 4 : -1); ///Indicates an invalid setting or result. A generic error occurred. /// @@ -102,10 +102,10 @@ class SslErrorType { ///- iOS ([Official API - SecTrustResultType.invalid](https://developer.apple.com/documentation/security/sectrustresulttype/invalid)) static final INVALID = SslErrorType._internal( 'INVALID', - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? 5 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 0 : -1)); @@ -120,8 +120,8 @@ class SslErrorType { ///- iOS ([Official API - SecTrustResultType.deny](https://developer.apple.com/documentation/security/sectrustresulttype/deny)) static final DENY = SslErrorType._internal( 'DENY', - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 3 : -1); @@ -138,8 +138,8 @@ class SslErrorType { ///- iOS ([Official API - SecTrustResultType.unspecified](https://developer.apple.com/documentation/security/sectrustresulttype/unspecified)) static final UNSPECIFIED = SslErrorType._internal( 'UNSPECIFIED', - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 4 : -1); @@ -157,8 +157,8 @@ class SslErrorType { ///- iOS ([Official API - SecTrustResultType.recoverableTrustFailure](https://developer.apple.com/documentation/security/sectrustresulttype/recoverabletrustfailure)) static final RECOVERABLE_TRUST_FAILURE = SslErrorType._internal( 'RECOVERABLE_TRUST_FAILURE', - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 5 : -1); @@ -173,8 +173,8 @@ class SslErrorType { ///- iOS ([Official API - SecTrustResultType.fatalTrustFailure](https://developer.apple.com/documentation/security/sectrustresulttype/fataltrustfailure)) static final FATAL_TRUST_FAILURE = SslErrorType._internal( 'FATAL_TRUST_FAILURE', - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 6 : -1); @@ -187,8 +187,8 @@ class SslErrorType { ///- iOS ([Official API - SecTrustResultType.otherError](https://developer.apple.com/documentation/security/sectrustresulttype/othererror)) static final OTHER_ERROR = SslErrorType._internal( 'OTHER_ERROR', - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? 7 : -1); diff --git a/lib/src/types/web_resource_error_type.dart b/lib/src/types/web_resource_error_type.dart index 7e17b5a9..e23058b9 100644 --- a/lib/src/types/web_resource_error_type.dart +++ b/lib/src/types/web_resource_error_type.dart @@ -107,7 +107,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_AUTHENTICATION](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_AUTHENTICATION)) static final USER_AUTHENTICATION_FAILED = WebResourceErrorType._internal( "USER_AUTHENTICATION_FAILED", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -4 : UNKNOWN._nativeValue); @@ -118,10 +118,10 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.badURL](https://developer.apple.com/documentation/foundation/urlerror/2293516-badurl)) static final BAD_URL = WebResourceErrorType._internal( "BAD_URL", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -12 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1000 : UNKNOWN._nativeValue)); @@ -132,10 +132,10 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotConnectToHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883001-cannotconnecttohost)) static final CANNOT_CONNECT_TO_HOST = WebResourceErrorType._internal( "CANNOT_CONNECT_TO_HOST", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -6 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1004 : UNKNOWN._nativeValue)); @@ -145,7 +145,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_FAILED_SSL_HANDSHAKE](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FAILED_SSL_HANDSHAKE)) static final FAILED_SSL_HANDSHAKE = WebResourceErrorType._internal( "FAILED_SSL_HANDSHAKE", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -11 : UNKNOWN._nativeValue); @@ -155,7 +155,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_FILE](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_FILE)) static final GENERIC_FILE_ERROR = WebResourceErrorType._internal( "GENERIC_FILE_ERROR", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -13 : UNKNOWN._nativeValue); @@ -166,10 +166,10 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.fileDoesNotExist](https://developer.apple.com/documentation/foundation/urlerror/code/2883074-filedoesnotexist)) static final FILE_NOT_FOUND = WebResourceErrorType._internal( "FILE_NOT_FOUND", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -14 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1100 : UNKNOWN._nativeValue)); @@ -180,10 +180,10 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotFindHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost)) static final HOST_LOOKUP = WebResourceErrorType._internal( "HOST_LOOKUP", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -2 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1003 : UNKNOWN._nativeValue)); @@ -193,7 +193,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_IO](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_IO)) static final IO = WebResourceErrorType._internal( "IO", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -7 : UNKNOWN._nativeValue); @@ -203,7 +203,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_PROXY_AUTHENTICATION](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_PROXY_AUTHENTICATION)) static final PROXY_AUTHENTICATION = WebResourceErrorType._internal( "PROXY_AUTHENTICATION", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -5 : UNKNOWN._nativeValue); @@ -214,10 +214,10 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotFindHost](https://developer.apple.com/documentation/foundation/urlerror/code/2883157-cannotfindhost)) static final TOO_MANY_REDIRECTS = WebResourceErrorType._internal( "TOO_MANY_REDIRECTS", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -9 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1007 : UNKNOWN._nativeValue)); @@ -228,10 +228,10 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.timedOut](https://developer.apple.com/documentation/foundation/urlerror/code/2883027-timedout)) static final TIMEOUT = WebResourceErrorType._internal( "TIMEOUT", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -8 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1001 : UNKNOWN._nativeValue)); @@ -241,7 +241,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_TOO_MANY_REQUESTS](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_TOO_MANY_REQUESTS)) static final TOO_MANY_REQUESTS = WebResourceErrorType._internal( "TOO_MANY_REQUESTS", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -15 : UNKNOWN._nativeValue); @@ -258,7 +258,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_UNSAFE_RESOURCE](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSAFE_RESOURCE)) static final UNSAFE_RESOURCE = WebResourceErrorType._internal( "UNSAFE_RESOURCE", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -16 : UNKNOWN._nativeValue); @@ -268,7 +268,7 @@ class WebResourceErrorType { ///- Android native WebView ([Official API - WebViewClient.ERROR_UNSUPPORTED_AUTH_SCHEME](https://developer.android.com/reference/android/webkit/WebViewClient#ERROR_UNSUPPORTED_AUTH_SCHEME)) static final UNSUPPORTED_AUTH_SCHEME = WebResourceErrorType._internal( "UNSUPPORTED_AUTH_SCHEME", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -3 : UNKNOWN._nativeValue); @@ -280,10 +280,10 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.unsupportedURL](https://developer.apple.com/documentation/foundation/urlerror/code/2883043-unsupportedurl)) static final UNSUPPORTED_SCHEME = WebResourceErrorType._internal( "UNSUPPORTED_SCHEME", - (defaultTargetPlatform != TargetPlatform.android) + (defaultTargetPlatform == TargetPlatform.android) ? -10 - : ((defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + : ((defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1002 : UNKNOWN._nativeValue)); @@ -293,8 +293,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cancelled](https://developer.apple.com/documentation/foundation/urlerror/code/2883178-cancelled)) static final CANCELLED = WebResourceErrorType._internal( "CANCELLED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -999 : UNKNOWN._nativeValue); @@ -304,8 +304,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.networkConnectionLost](https://developer.apple.com/documentation/foundation/urlerror/2293759-networkconnectionlost)) static final NETWORK_CONNECTION_LOST = WebResourceErrorType._internal( "NETWORK_CONNECTION_LOST", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1005 : UNKNOWN._nativeValue); @@ -316,8 +316,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.resourceUnavailable](https://developer.apple.com/documentation/foundation/urlerror/2293555-resourceunavailable)) static final RESOURCE_UNAVAILABLE = WebResourceErrorType._internal( "RESOURCE_UNAVAILABLE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1008 : UNKNOWN._nativeValue); @@ -327,8 +327,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.notConnectedToInternet](https://developer.apple.com/documentation/foundation/urlerror/2293104-notconnectedtointernet)) static final NOT_CONNECTED_TO_INTERNET = WebResourceErrorType._internal( "NOT_CONNECTED_TO_INTERNET", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1009 : UNKNOWN._nativeValue); @@ -339,8 +339,8 @@ class WebResourceErrorType { static final REDIRECT_TO_NON_EXISTENT_LOCATION = WebResourceErrorType._internal( "REDIRECT_TO_NON_EXISTENT_LOCATION", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1010 : UNKNOWN._nativeValue); @@ -350,8 +350,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.badServerResponse](https://developer.apple.com/documentation/foundation/urlerror/2293606-badserverresponse)) static final BAD_SERVER_RESPONSE = WebResourceErrorType._internal( "BAD_SERVER_RESPONSE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1011 : UNKNOWN._nativeValue); @@ -362,8 +362,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.userCancelledAuthentication](https://developer.apple.com/documentation/foundation/urlerror/2293330-usercancelledauthentication)) static final USER_CANCELLED_AUTHENTICATION = WebResourceErrorType._internal( "USER_CANCELLED_AUTHENTICATION", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1012 : UNKNOWN._nativeValue); @@ -373,8 +373,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.userAuthenticationRequired](https://developer.apple.com/documentation/foundation/urlerror/2293560-userauthenticationrequired)) static final USER_AUTHENTICATION_REQUIRED = WebResourceErrorType._internal( "USER_AUTHENTICATION_REQUIRED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1013 : UNKNOWN._nativeValue); @@ -384,8 +384,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.zeroByteResource](https://developer.apple.com/documentation/foundation/urlerror/2293773-zerobyteresource)) static final ZERO_BYTE_RESOURCE = WebResourceErrorType._internal( "ZERO_BYTE_RESOURCE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1014 : UNKNOWN._nativeValue); @@ -395,8 +395,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotDecodeRawData](https://developer.apple.com/documentation/foundation/urlerror/2293573-cannotdecoderawdata)) static final CANNOT_DECODE_RAW_DATA = WebResourceErrorType._internal( "CANNOT_DECODE_RAW_DATA", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1015 : UNKNOWN._nativeValue); @@ -406,8 +406,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotDecodeContentData](https://developer.apple.com/documentation/foundation/urlerror/2292983-cannotdecodecontentdata)) static final CANNOT_DECODE_CONTENT_DATA = WebResourceErrorType._internal( "CANNOT_DECODE_CONTENT_DATA", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1016 : UNKNOWN._nativeValue); @@ -417,8 +417,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotParseResponse](https://developer.apple.com/documentation/foundation/urlerror/code/2882919-cannotparseresponse)) static final CANNOT_PARSE_RESPONSE = WebResourceErrorType._internal( "CANNOT_PARSE_RESPONSE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1017 : UNKNOWN._nativeValue); @@ -429,8 +429,8 @@ class WebResourceErrorType { static final APP_TRANSPORT_SECURITY_REQUIRES_SECURE_CONNECTION = WebResourceErrorType._internal( "APP_TRANSPORT_SECURITY_REQUIRES_SECURE_CONNECTION", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1022 : UNKNOWN._nativeValue); @@ -440,8 +440,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.fileIsDirectory](https://developer.apple.com/documentation/foundation/urlerror/code/2883220-fileisdirectory)) static final FILE_IS_DIRECTORY = WebResourceErrorType._internal( "FILE_IS_DIRECTORY", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1101 : UNKNOWN._nativeValue); @@ -451,8 +451,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.noPermissionsToReadFile](https://developer.apple.com/documentation/foundation/urlerror/code/2882941-nopermissionstoreadfile)) static final NO_PERMISSIONS_TO_READ_FILE = WebResourceErrorType._internal( "NO_PERMISSIONS_TO_READ_FILE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1102 : UNKNOWN._nativeValue); @@ -462,8 +462,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.dataLengthExceedsMaximum](https://developer.apple.com/documentation/foundation/urlerror/code/2882930-datalengthexceedsmaximum)) static final DATA_LENGTH_EXCEEDS_MAXIMUM = WebResourceErrorType._internal( "DATA_LENGTH_EXCEEDS_MAXIMUM", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1103 : UNKNOWN._nativeValue); @@ -473,8 +473,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.secureConnectionFailed](https://developer.apple.com/documentation/foundation/urlerror/code/2883122-secureconnectionfailed)) static final SECURE_CONNECTION_FAILED = WebResourceErrorType._internal( "SECURE_CONNECTION_FAILED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1200 : UNKNOWN._nativeValue); @@ -484,8 +484,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.serverCertificateHasBadDate](https://developer.apple.com/documentation/foundation/urlerror/code/2883088-servercertificatehasbaddate)) static final SERVER_CERTIFICATE_HAS_BAD_DATE = WebResourceErrorType._internal( "SERVER_CERTIFICATE_HAS_BAD_DATE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1201 : UNKNOWN._nativeValue); @@ -495,8 +495,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.serverCertificateUntrusted](https://developer.apple.com/documentation/foundation/urlerror/code/2882976-servercertificateuntrusted)) static final SERVER_CERTIFICATE_UNTRUSTED = WebResourceErrorType._internal( "SERVER_CERTIFICATE_UNTRUSTED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1202 : UNKNOWN._nativeValue); @@ -507,8 +507,8 @@ class WebResourceErrorType { static final SERVER_CERTIFICATE_HAS_UNKNOWN_ROOT = WebResourceErrorType._internal( "SERVER_CERTIFICATE_HAS_UNKNOWN_ROOT", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1203 : UNKNOWN._nativeValue); @@ -519,8 +519,8 @@ class WebResourceErrorType { static final SERVER_CERTIFICATE_NOT_YET_VALID = WebResourceErrorType._internal( "SERVER_CERTIFICATE_NOT_YET_VALID", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1204 : UNKNOWN._nativeValue); @@ -530,8 +530,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.clientCertificateRejected](https://developer.apple.com/documentation/foundation/urlerror/code/2883091-clientcertificaterejected)) static final CLIENT_CERTIFICATE_REJECTED = WebResourceErrorType._internal( "CLIENT_CERTIFICATE_REJECTED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1205 : UNKNOWN._nativeValue); @@ -541,8 +541,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.clientCertificateRequired](https://developer.apple.com/documentation/foundation/urlerror/code/2883199-clientcertificaterequired)) static final CLIENT_CERTIFICATE_REQUIRED = WebResourceErrorType._internal( "CLIENT_CERTIFICATE_REQUIRED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1206 : UNKNOWN._nativeValue); @@ -552,8 +552,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotLoadFromNetwork](https://developer.apple.com/documentation/foundation/urlerror/code/2882968-cannotloadfromnetwork)) static final CANNOT_LOAD_FROM_NETWORK = WebResourceErrorType._internal( "CANNOT_LOAD_FROM_NETWORK", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -2000 : UNKNOWN._nativeValue); @@ -563,8 +563,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotCreateFile](https://developer.apple.com/documentation/foundation/urlerror/code/2883204-cannotcreatefile)) static final CANNOT_CREATE_FILE = WebResourceErrorType._internal( "CANNOT_CREATE_FILE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3000 : UNKNOWN._nativeValue); @@ -574,8 +574,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotOpenFile](https://developer.apple.com/documentation/foundation/urlerror/code/2883034-cannotopenfile)) static final CANNOT_OPEN_FILE = WebResourceErrorType._internal( "CANNOT_OPEN_FILE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3001 : UNKNOWN._nativeValue); @@ -585,8 +585,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotCloseFile](https://developer.apple.com/documentation/foundation/urlerror/code/2883215-cannotclosefile)) static final CANNOT_CLOSE_FILE = WebResourceErrorType._internal( "CANNOT_CLOSE_FILE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3002 : UNKNOWN._nativeValue); @@ -596,8 +596,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotWriteToFile](https://developer.apple.com/documentation/foundation/urlerror/code/2883098-cannotwritetofile)) static final CANNOT_WRITE_TO_FILE = WebResourceErrorType._internal( "CANNOT_WRITE_TO_FILE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3003 : UNKNOWN._nativeValue); @@ -607,8 +607,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotRemoveFile](https://developer.apple.com/documentation/foundation/urlerror/code/2883202-cannotremovefile)) static final CANNOT_REMOVE_FILE = WebResourceErrorType._internal( "CANNOT_REMOVE_FILE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3004 : UNKNOWN._nativeValue); @@ -618,8 +618,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.cannotMoveFile](https://developer.apple.com/documentation/foundation/urlerror/code/2883180-cannotmovefile)) static final CANNOT_MOVE_FILE = WebResourceErrorType._internal( "CANNOT_MOVE_FILE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3005 : UNKNOWN._nativeValue); @@ -630,8 +630,8 @@ class WebResourceErrorType { static final DOWNLOAD_DECODING_FAILED_MID_STREAM = WebResourceErrorType._internal( "DOWNLOAD_DECODING_FAILED_MID_STREAM", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3006 : UNKNOWN._nativeValue); @@ -642,8 +642,8 @@ class WebResourceErrorType { static final DOWNLOAD_DECODING_FAILED_TO_COMPLETE = WebResourceErrorType._internal( "DOWNLOAD_DECODING_FAILED_TO_COMPLETE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -3007 : UNKNOWN._nativeValue); @@ -653,8 +653,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.internationalRoamingOff](https://developer.apple.com/documentation/foundation/urlerror/code/2883134-internationalroamingoff)) static final INTERNATIONAL_ROAMING_OFF = WebResourceErrorType._internal( "INTERNATIONAL_ROAMING_OFF", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1018 : UNKNOWN._nativeValue); @@ -664,8 +664,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.callIsActive](https://developer.apple.com/documentation/foundation/urlerror/code/2883170-callisactive)) static final CALL_IS_ACTIVE = WebResourceErrorType._internal( "CALL_IS_ACTIVE", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1019 : UNKNOWN._nativeValue); @@ -675,8 +675,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.dataNotAllowed](https://developer.apple.com/documentation/foundation/urlerror/code/2883217-datanotallowed)) static final DATA_NOT_ALLOWED = WebResourceErrorType._internal( "DATA_NOT_ALLOWED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1020 : UNKNOWN._nativeValue); @@ -686,8 +686,8 @@ class WebResourceErrorType { ///- iOS ([Official API - URLError.requestBodyStreamExhausted](https://developer.apple.com/documentation/foundation/urlerror/code/2883176-requestbodystreamexhausted)) static final REQUEST_BODY_STREAM_EXHAUSTED = WebResourceErrorType._internal( "REQUEST_BODY_STREAM_EXHAUSTED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -1021 : UNKNOWN._nativeValue); @@ -698,8 +698,8 @@ class WebResourceErrorType { static final BACKGROUND_SESSION_REQUIRES_SHARED_CONTAINER = WebResourceErrorType._internal( "BACKGROUND_SESSION_REQUIRES_SHARED_CONTAINER", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -995 : UNKNOWN._nativeValue); @@ -710,8 +710,8 @@ class WebResourceErrorType { static final BACKGROUND_SESSION_IN_USE_BY_ANOTHER_PROCESS = WebResourceErrorType._internal( "BACKGROUND_SESSION_IN_USE_BY_ANOTHER_PROCESS", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -996 : UNKNOWN._nativeValue); @@ -722,8 +722,8 @@ class WebResourceErrorType { static final BACKGROUND_SESSION_WAS_DISCONNECTED = WebResourceErrorType._internal( "BACKGROUND_SESSION_WAS_DISCONNECTED", - (defaultTargetPlatform != TargetPlatform.iOS || - defaultTargetPlatform != TargetPlatform.macOS) + (defaultTargetPlatform == TargetPlatform.iOS || + defaultTargetPlatform == TargetPlatform.macOS) ? -997 : UNKNOWN._nativeValue); diff --git a/scripts/test.sh b/scripts/test.sh index c7364405..e38cca11 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -36,6 +36,7 @@ node index.js & flutter --version flutter clean +flutter pub get cd $PROJECT_DIR/example flutter clean if [ ! -z "$2" ] && [ $PLATFORM = "web" ]; then