fixed tests, added android webview EventChannelDelegate, fixed some enum native values based on target platform

This commit is contained in:
Lorenzo Pichilli 2022-05-04 02:17:33 +02:00
parent 3edbbbc396
commit 55f3b64a24
41 changed files with 2673 additions and 973 deletions

View File

@ -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

View File

@ -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<String, Object> 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<String, Object> res = (Map<String, Object>) flutterResult.result;
String contentType = (String) res.get("contentType");
String contentEncoding = (String) res.get("contentEncoding");
byte[] data = (byte[]) res.get("data");
Map<String, String> responseHeaders = (Map<String, String>) res.get("headers");
Integer statusCode = (Integer) res.get("statusCode");
String reasonPhrase = (String) res.get("reasonPhrase");
WebResourceResponseExt response = WebResourceResponseExt.fromMap((Map<String, Object>) flutterResult.result);
if (response != null) {
String contentType = response.getContentType();
String contentEncoding = response.getContentEncoding();
byte[] data = response.getData();
Map<String, String> 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);
}
}
}

View File

@ -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> T invokeMethodAndWaitResult(final @NonNull MethodChannel channel,
final @NonNull String method, final @Nullable Object arguments,
final @NonNull SyncBaseCallbackResultImpl<T> 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<String> 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> T getOrDefault(Map<String, Object> map, String key, T defaultValue) {
return map.containsKey(key) ? (T) map.get(key) : defaultValue;
}
@Nullable

View File

@ -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.<Boolean>getOrDefault(settings, "isSingleInstance", false);
Boolean isTrustedWebActivity = Util.<Boolean>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.<Boolean>getOrDefault(settings, "noHistory", false);
if (noHistory) {
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
}

View File

@ -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);

View File

@ -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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> obj = new HashMap<>();
channel.invokeMethod("onHideContextMenu", obj);
}
public void onEnterFullscreen() {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
channel.invokeMethod("onEnterFullscreen", obj);
}
public void onExitFullscreen() {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
channel.invokeMethod("onExitFullscreen", obj);
}
public static class JsAlertCallback extends BaseCallbackResultImpl<JsAlertResponse> {
@Nullable
@Override
public JsAlertResponse decodeResult(@Nullable Object obj) {
return JsAlertResponse.fromMap((Map<String, Object>) obj);
}
}
public void onJsAlert(String url, String message, Boolean isMainFrame, @NonNull JsAlertCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> 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<JsConfirmResponse> {
@Nullable
@Override
public JsConfirmResponse decodeResult(@Nullable Object obj) {
return JsConfirmResponse.fromMap((Map<String, Object>) obj);
}
}
public void onJsConfirm(String url, String message, Boolean isMainFrame, @NonNull JsConfirmCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> 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<JsPromptResponse> {
@Nullable
@Override
public JsPromptResponse decodeResult(@Nullable Object obj) {
return JsPromptResponse.fromMap((Map<String, Object>) obj);
}
}
public void onJsPrompt(String url, String message, String defaultValue, Boolean isMainFrame, @NonNull JsPromptCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> 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<JsBeforeUnloadResponse> {
@Nullable
@Override
public JsBeforeUnloadResponse decodeResult(@Nullable Object obj) {
return JsBeforeUnloadResponse.fromMap((Map<String, Object>) obj);
}
}
public void onJsBeforeUnload(String url, String message, @NonNull JsBeforeUnloadCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
obj.put("message", message);
channel.invokeMethod("onJsBeforeUnload", obj, callback);
}
public static class CreateWindowCallback extends BaseCallbackResultImpl<Boolean> {
@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<String, Object> obj = new HashMap<>();
channel.invokeMethod("onCloseWindow", obj);
}
public static class GeolocationPermissionsShowPromptCallback extends BaseCallbackResultImpl<GeolocationPermissionShowPromptResponse> {
@Nullable
@Override
public GeolocationPermissionShowPromptResponse decodeResult(@Nullable Object obj) {
return GeolocationPermissionShowPromptResponse.fromMap((Map<String, Object>) obj);
}
}
public void onGeolocationPermissionsShowPrompt(String origin, @NonNull GeolocationPermissionsShowPromptCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> obj = new HashMap<>();
obj.put("origin", origin);
channel.invokeMethod("onGeolocationPermissionsShowPrompt", obj, callback);
}
public void onGeolocationPermissionsHidePrompt() {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
channel.invokeMethod("onGeolocationPermissionsHidePrompt", obj);
}
public void onConsoleMessage(String message, int messageLevel) {
if (channel == null) return;
Map<String, Object> 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<String, Object> obj = new HashMap<>();
obj.put("progress", progress);
channel.invokeMethod("onProgressChanged", obj);
}
public void onTitleChanged(String title) {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
obj.put("title", title);
channel.invokeMethod("onTitleChanged", obj);
}
public void onReceivedIcon(byte[] icon) {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
obj.put("icon", icon);
channel.invokeMethod("onReceivedIcon", obj);
}
public void onReceivedTouchIconUrl(String url, boolean precomposed) {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
obj.put("precomposed", precomposed);
channel.invokeMethod("onReceivedTouchIconUrl", obj);
}
public static class PermissionRequestCallback extends BaseCallbackResultImpl<PermissionResponse> {
@Nullable
@Override
public PermissionResponse decodeResult(@Nullable Object obj) {
return PermissionResponse.fromMap((Map<String, Object>) obj);
}
}
public void onPermissionRequest(String origin, List<String> resources, Object frame, @NonNull PermissionRequestCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> 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<NavigationActionPolicy> {
@Nullable
@Override
public NavigationActionPolicy decodeResult(@Nullable Object obj) {
Integer action = Util.<Integer>getOrDefault((Map<String, Object>) 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<String, Object> obj = new HashMap<>();
obj.put("url", url);
channel.invokeMethod("onLoadStart", obj);
}
public void onLoadStop(String url) {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
channel.invokeMethod("onLoadStop", obj);
}
public void onUpdateVisitedHistory(String url, boolean isReload) {
if (channel == null) return;
Map<String, Object> 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<String, Object> 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<String, Object> obj = new HashMap<>();
obj.put("request", request.toMap());
obj.put("errorResponse", errorResponse.toMap());
channel.invokeMethod("onReceivedHttpError", obj);
}
public static class ReceivedHttpAuthRequestCallback extends BaseCallbackResultImpl<HttpAuthResponse> {
@Nullable
@Override
public HttpAuthResponse decodeResult(@Nullable Object obj) {
return HttpAuthResponse.fromMap((Map<String, Object>) 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<ServerTrustAuthResponse> {
@Nullable
@Override
public ServerTrustAuthResponse decodeResult(@Nullable Object obj) {
return ServerTrustAuthResponse.fromMap((Map<String, Object>) 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<ClientCertResponse> {
@Nullable
@Override
public ClientCertResponse decodeResult(@Nullable Object obj) {
return ClientCertResponse.fromMap((Map<String, Object>) 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<String, Object> obj = new HashMap<>();
obj.put("oldScale", oldScale);
obj.put("newScale", newScale);
channel.invokeMethod("onZoomScaleChanged", obj);
}
public static class SafeBrowsingHitCallback extends BaseCallbackResultImpl<SafeBrowsingResponse> {
@Nullable
@Override
public SafeBrowsingResponse decodeResult(@Nullable Object obj) {
return SafeBrowsingResponse.fromMap((Map<String, Object>) obj);
}
}
public void onSafeBrowsingHit(String url, int threatType, @NonNull SafeBrowsingHitCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
obj.put("threatType", threatType);
channel.invokeMethod("onSafeBrowsingHit", obj, callback);
}
public static class FormResubmissionCallback extends BaseCallbackResultImpl<Integer> {
@Nullable
@Override
public Integer decodeResult(@Nullable Object obj) {
return obj != null ? (Integer) ((Map<String, Object>) obj).get("action") : null;
}
}
public void onFormResubmission(String url, @NonNull FormResubmissionCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
channel.invokeMethod("onFormResubmission", obj, callback);
}
public void onPageCommitVisible(String url) {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
channel.invokeMethod("onPageCommitVisible", obj);
}
public void onRenderProcessGone(boolean didCrash, int rendererPriorityAtExit) {
if (channel == null) return;
Map<String, Object> 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<String, Object> 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<CustomSchemeResponse> {
@Nullable
@Override
public CustomSchemeResponse decodeResult(@Nullable Object obj) {
return CustomSchemeResponse.fromMap((Map<String, Object>) obj);
}
}
public void onLoadResourceCustomScheme(String url, @NonNull LoadResourceCustomSchemeCallback callback) {
if (channel == null) return;
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
channel.invokeMethod("onLoadResourceCustomScheme", obj, callback);
}
public static class SyncLoadResourceCustomSchemeCallback extends SyncBaseCallbackResultImpl<CustomSchemeResponse> {
@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<String, Object> 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<WebResourceResponseExt> {
@Nullable
@Override
public WebResourceResponseExt decodeResult(@Nullable Object obj) {
return WebResourceResponseExt.fromMap((Map<String, Object>) 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<WebResourceResponseExt> {
@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<Integer> {
@Nullable
@Override
public Integer decodeResult(@Nullable Object obj) {
return obj != null ? (Integer) ((Map<String, Object>) obj).get("action") : null;
}
}
public void onRenderProcessUnresponsive(String url, @NonNull RenderProcessUnresponsiveCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
channel.invokeMethod("onRenderProcessUnresponsive", obj, callback);
}
public static class RenderProcessResponsiveCallback extends BaseCallbackResultImpl<Integer> {
@Nullable
@Override
public Integer decodeResult(@Nullable Object obj) {
return obj != null ? (Integer) ((Map<String, Object>) obj).get("action") : null;
}
}
public void onRenderProcessResponsive(String url, @NonNull RenderProcessResponsiveCallback callback) {
if (channel == null) {
callback.defaultBehaviour(null);
return;
}
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
channel.invokeMethod("onRenderProcessResponsive", obj, callback);
}
public void dispose() {
channel = null;
}
}

View File

@ -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();

View File

@ -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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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();
}

View File

@ -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<Integer, Message> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> 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<String, Object> response = (Map<String, Object>) 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<String, Object> obj = new HashMap<>();
channel.invokeMethod("onGeolocationPermissionsHidePrompt", obj);
if (inAppWebView != null && inAppWebView.eventChannelDelegate != null) {
inAppWebView.eventChannelDelegate.onGeolocationPermissionsHidePrompt();
}
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) response;
Integer action = (Integer) responseMap.get("action");
List<String> resourceList = (List<String>) responseMap.get("resources");
if (resourceList == null)
resourceList = new ArrayList<String>();
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);
}
}
}

View File

@ -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<URLCredential> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> res = (Map<String, Object>) 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<String, String> 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<String, Object> 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<String, Object> res = (Map<String, Object>) flutterResult.result;
String contentType = (String) res.get("contentType");
String contentEncoding = (String) res.get("contentEncoding");
byte[] data = (byte[]) res.get("data");
Map<String, String> responseHeaders = (Map<String, String>) 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<String, String> 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> 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<String, Object> 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) {

View File

@ -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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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<String, Object> 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<String, Object> responseMap = (Map<String, Object>) 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() {

View File

@ -0,0 +1,47 @@
package com.pichillilorenzo.flutter_inappwebview.types;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class BaseCallbackResultImpl<T> implements ICallbackResult<T> {
@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);
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<String, Object> 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 + '\'' +
'}';
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<T> extends MethodChannel.Result {
boolean nonNullSuccess(@NonNull T result);
boolean nullSuccess();
void defaultBehaviour(@Nullable T result);
@Nullable T decodeResult(@Nullable Object obj);
}

View File

@ -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);
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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;
}

View File

@ -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<String> resources;
@Nullable
private Integer action;
public PermissionResponse(@NonNull List<String> resources, @Nullable Integer action) {
this.resources = resources;
this.action = action;
}
@Nullable
public static PermissionResponse fromMap(@Nullable Map<String, Object> map) {
if (map == null) {
return null;
}
List<String> resources = (List<String>) map.get("resources");
Integer action = (Integer) map.get("action");
return new PermissionResponse(resources, action);
}
@NonNull
public List<String> getResources() {
return resources;
}
public void setResources(@NonNull List<String> 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 +
'}';
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<String, Object> 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 +
'}';
}
}

View File

@ -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<T> extends BaseCallbackResultImpl<T> {
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);
}
}

View File

@ -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<String, String> headers, @Nullable byte[] data) {
public WebResourceResponseExt(String contentType, String contentEncoding, @Nullable Integer statusCode,
@Nullable String reasonPhrase, @Nullable Map<String, String> 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<String, Object> 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<String, String> headers = (Map<String, String>) map.get("headers");
byte[] data = (byte[]) map.get("data");
return new WebResourceResponseExt(contentType, contentEncoding, statusCode, reasonPhrase, headers, data);
}
public Map<String, Object> toMap() {
Map<String, Object> webResourceResponseMap = new HashMap<>();
webResourceResponseMap.put("contentType", contentType);

View File

@ -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;

View File

@ -42,27 +42,6 @@ void onReceivedError() {
expect(url, TEST_NOT_A_WEBSITE_URL.toString());
});
testWidgets('file not found', (WidgetTester tester) async {
final Completer<WebResourceErrorType> errorCodeCompleter = Completer<WebResourceErrorType>();
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<void> onReceivedErrorCompleter = Completer<void>();

View File

@ -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);
}

View File

@ -48,6 +48,6 @@ void shouldInterceptRequest() {
),
);
expect(completer.future, completes);
await expectLater(completer.future, completes);
}, skip: shouldSkip);
}

View File

@ -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"

View File

@ -45,7 +45,7 @@ class ServiceWorkerController {
static Future<dynamic> _handleMethod(MethodCall call) async {
ServiceWorkerController controller = ServiceWorkerController.instance();
ServiceWorkerClient? serviceWorkerClient = controller.serviceWorkerClient;
ServiceWorkerClient? serviceWorkerClient = controller._serviceWorkerClient;
switch (call.method) {
case "shouldInterceptRequest":

View File

@ -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<String, dynamic>());
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<String, dynamic>());
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;
}

View File

@ -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.

View File

@ -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<String, dynamic> toMap() {

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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