added AndroidWebViewFeature, AndroidServiceWorkerController, AndroidServiceWorkerClient classes
This commit is contained in:
parent
a023d34fd9
commit
37fa32b31e
|
@ -5,12 +5,11 @@
|
|||
- Added `allowUniversalAccessFromFileURLs` and `allowFileAccessFromFileURLs` WebView options also for iOS (also thanks to [liranhao](https://github.com/liranhao))
|
||||
- Added limited cookies support on iOS below 11.0 using JavaScript
|
||||
- Added `IOSCookieManager` class and `CookieManager.instance().ios.getAllCookies` iOS-specific method
|
||||
- Added `UserScript` and `UserScriptInjectionTime` classes
|
||||
- Added `UserScript`, `UserScriptInjectionTime`, `ContentWorld`, `AndroidWebViewFeature`, `AndroidServiceWorkerController`, `AndroidServiceWorkerClient` classes
|
||||
- Added `initialUserScripts` WebView option
|
||||
- Added `addUserScript`, `addUserScripts`, `removeUserScript`, `removeUserScripts`, `removeAllUserScripts` WebView methods
|
||||
- Added `isDirectionalLockEnabled`, `mediaType`, `pageZoom`, `limitsNavigationsToAppBoundDomains` iOS-specific webview options
|
||||
- Added `handlesURLScheme` iOS-specific webview method
|
||||
- Added `ContentWorld` class
|
||||
- Updated integration tests
|
||||
- Merge "Upgraded appcompat to 1.2.0-rc-02" [#465](https://github.com/pichillilorenzo/flutter_inappwebview/pull/465) (thanks to [andreidiaconu](https://github.com/andreidiaconu))
|
||||
- Merge "Added missing field 'headers' which returned by WebResourceResponse.toMap()" [#490](https://github.com/pichillilorenzo/flutter_inappwebview/pull/490) (thanks to [Doflatango](https://github.com/Doflatango))
|
||||
|
|
|
@ -35,20 +35,16 @@ import android.webkit.CookieManager;
|
|||
import android.webkit.DownloadListener;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebBackForwardList;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebHistoryItem;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebStorage;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.webkit.WebViewCompat;
|
||||
import androidx.webkit.WebViewFeature;
|
||||
import androidx.webkit.WebViewRenderProcessClient;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlocker;
|
||||
import com.pichillilorenzo.flutter_inappwebview.ContentBlocker.ContentBlockerAction;
|
||||
|
@ -63,9 +59,6 @@ import com.pichillilorenzo.flutter_inappwebview.Util;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.CertificateParsingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
@ -131,10 +124,11 @@ final public class InAppWebView extends InputAwareWebView {
|
|||
"}";
|
||||
|
||||
static final String contentWorldWrapperJS = "(function() {" +
|
||||
" var iframe = document.getElementById('$CONTENT_WORLD_NAME');" +
|
||||
" var iframeId = '" + JavaScriptBridgeInterface.name + "_$CONTENT_WORLD_NAME';" +
|
||||
" var iframe = document.getElementById(iframeId);" +
|
||||
" if (iframe == null) {" +
|
||||
" iframe = document.createElement('iframe');" +
|
||||
" iframe.id = '$CONTENT_WORLD_NAME';" +
|
||||
" iframe.id = iframeId;" +
|
||||
" iframe.style = 'display: none; z-index: 0; position: absolute; width: 0px; height: 0px';" +
|
||||
" document.body.append(iframe);" +
|
||||
" }" +
|
||||
|
|
|
@ -29,6 +29,8 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
|||
public static MyCookieManager myCookieManager;
|
||||
public static CredentialDatabaseHandler credentialDatabaseHandler;
|
||||
public static MyWebStorage myWebStorage;
|
||||
public static ServiceWorkerManager serviceWorkerManager;
|
||||
public static WebViewFeatureManager webViewFeatureManager;
|
||||
public static ValueCallback<Uri> filePathCallbackLegacy;
|
||||
public static ValueCallback<Uri[]> filePathCallback;
|
||||
|
||||
|
@ -65,12 +67,17 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
|||
|
||||
platformViewRegistry.registerViewFactory(
|
||||
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(messenger, flutterView));
|
||||
|
||||
inAppWebViewStatic = new InAppWebViewStatic(messenger);
|
||||
myCookieManager = new MyCookieManager(messenger);
|
||||
myWebStorage = new MyWebStorage(messenger);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
serviceWorkerManager = new ServiceWorkerManager(messenger);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
credentialDatabaseHandler = new CredentialDatabaseHandler(messenger);
|
||||
}
|
||||
webViewFeatureManager = new WebViewFeatureManager(messenger);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,6 +110,14 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
|||
inAppWebViewStatic.dispose();
|
||||
inAppWebViewStatic = null;
|
||||
}
|
||||
if (serviceWorkerManager != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
serviceWorkerManager.dispose();
|
||||
serviceWorkerManager = null;
|
||||
}
|
||||
if (webViewFeatureManager != null) {
|
||||
webViewFeatureManager.dispose();
|
||||
webViewFeatureManager = null;
|
||||
}
|
||||
filePathCallbackLegacy = null;
|
||||
filePathCallback = null;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ public abstract class RequestPermissionHandler implements ActivityCompat.OnReque
|
|||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
Log.d("asdasd", "\n\na asd asd \n\n");
|
||||
if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
||||
List<Runnable> callbacks = actionDictionary.get(requestCode);
|
||||
for (Runnable runnable : callbacks) {
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
package com.pichillilorenzo.flutter_inappwebview;
|
||||
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebResourceResponse;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.webkit.ServiceWorkerClientCompat;
|
||||
import androidx.webkit.ServiceWorkerControllerCompat;
|
||||
import androidx.webkit.ServiceWorkerWebSettingsCompat;
|
||||
import androidx.webkit.WebViewFeature;
|
||||
|
||||
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;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public class ServiceWorkerManager implements MethodChannel.MethodCallHandler {
|
||||
|
||||
static final String LOG_TAG = "ServiceWorkerManager";
|
||||
|
||||
public static MethodChannel channel;
|
||||
@Nullable
|
||||
public static ServiceWorkerControllerCompat serviceWorkerController;
|
||||
|
||||
public ServiceWorkerManager(BinaryMessenger messenger) {
|
||||
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_android_serviceworkercontroller");
|
||||
channel.setMethodCallHandler(this);
|
||||
if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) {
|
||||
serviceWorkerController = ServiceWorkerControllerCompat.getInstance();
|
||||
serviceWorkerController.setServiceWorkerClient(new ServiceWorkerClientCompat() {
|
||||
@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());
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
serviceWorkerController = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
|
||||
ServiceWorkerWebSettingsCompat serviceWorkerWebSettings = (serviceWorkerController != null) ? serviceWorkerController.getServiceWorkerWebSettings() : null;
|
||||
|
||||
switch (call.method) {
|
||||
case "getAllowContentAccess":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS)) {
|
||||
result.success(serviceWorkerWebSettings.getAllowContentAccess());
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
case "getAllowFileAccess":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_FILE_ACCESS)) {
|
||||
result.success(serviceWorkerWebSettings.getAllowFileAccess());
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
case "getBlockNetworkLoads":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS)) {
|
||||
result.success(serviceWorkerWebSettings.getBlockNetworkLoads());
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
case "getCacheMode":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_CACHE_MODE)) {
|
||||
result.success(serviceWorkerWebSettings.getCacheMode());
|
||||
} else {
|
||||
result.success(null);
|
||||
}
|
||||
break;
|
||||
case "setAllowContentAccess":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS)) {
|
||||
Boolean allow = (Boolean) call.argument("allow");
|
||||
serviceWorkerWebSettings.setAllowContentAccess(allow);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "setAllowFileAccess":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_FILE_ACCESS)) {
|
||||
Boolean allow = (Boolean) call.argument("allow");
|
||||
serviceWorkerWebSettings.setAllowFileAccess(allow);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "setBlockNetworkLoads":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS)) {
|
||||
Boolean flag = (Boolean) call.argument("flag");
|
||||
serviceWorkerWebSettings.setBlockNetworkLoads(flag);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
case "setCacheMode":
|
||||
if (serviceWorkerWebSettings != null && WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_CACHE_MODE)) {
|
||||
Integer mode = (Integer) call.argument("mode");
|
||||
serviceWorkerWebSettings.setCacheMode(mode);
|
||||
}
|
||||
result.success(true);
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.pichillilorenzo.flutter_inappwebview;
|
||||
|
||||
import androidx.webkit.WebViewFeature;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
|
||||
public class WebViewFeatureManager implements MethodChannel.MethodCallHandler {
|
||||
|
||||
static final String LOG_TAG = "WebViewFeatureManager";
|
||||
|
||||
public static MethodChannel channel;
|
||||
|
||||
public WebViewFeatureManager(BinaryMessenger messenger) {
|
||||
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_android_webviewfeature");
|
||||
channel.setMethodCallHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
|
||||
switch (call.method) {
|
||||
case "isFeatureSupported":
|
||||
String feature = (String) call.argument("feature");
|
||||
result.success(WebViewFeature.isFeatureSupported(feature));
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"android":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-04 01:10:32.198308","version":"1.26.0-18.0.pre.90"}
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"android":[{"name":"device_info","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-2.0.0-nullsafety.2/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":["device_info"]},{"name":"integration_test","path":"/Users/lorenzopichilli/flutter/.pub-cache/git/plugins-16f3281b04b0db12e609352b1c9544901392e428/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.0.1+1/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.4/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.4+3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":["device_info"]},{"name":"integration_test","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"permission_handler","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_linux","url_launcher_macos","url_launcher_windows"]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]}],"date_created":"2021-02-04 21:51:34.603760","version":"1.26.0-18.0.pre.90"}
|
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -9,7 +9,7 @@
|
|||
/* Begin PBXBuildFile section */
|
||||
020EF14E4245221B2C22ACE5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0FC2CF7A6002799890B3102 /* Pods_Runner.framework */; };
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
25A517508F43E58C47090625 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
|
||||
25A517508F43E58C47090625 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
61FF730023634CA10069C557 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 61FF72FF23634CA10069C557 /* libsqlite3.tbd */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
|
@ -46,7 +46,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
61FF730023634CA10069C557 /* libsqlite3.tbd in Frameworks */,
|
||||
25A517508F43E58C47090625 /* BuildFile in Frameworks */,
|
||||
25A517508F43E58C47090625 /* (null) in Frameworks */,
|
||||
020EF14E4245221B2C22ACE5 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
|
@ -81,7 +81,7 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
BoxDecoration(border: Border.all(color: Colors.blueAccent)),
|
||||
child: InAppWebView(
|
||||
// contextMenu: contextMenu,
|
||||
initialUrl: "https://flutter.dev/",
|
||||
initialUrl: "https://flutter.dev",
|
||||
// initialFile: "assets/index.html",
|
||||
initialHeaders: {},
|
||||
initialUserScripts: UnmodifiableListView<UserScript>([
|
||||
|
@ -91,12 +91,14 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
|||
crossPlatform: InAppWebViewOptions(
|
||||
useShouldOverrideUrlLoading: false,
|
||||
mediaPlaybackRequiresUserGesture: false,
|
||||
clearCache: true
|
||||
),
|
||||
android: AndroidInAppWebViewOptions(
|
||||
useHybridComposition: true,
|
||||
),
|
||||
ios: IOSInAppWebViewOptions(
|
||||
allowsInlineMediaPlayback: true,
|
||||
// limitsNavigationsToAppBoundDomains: true // adds Service Worker API on iOS 14.0+
|
||||
)
|
||||
),
|
||||
onWebViewCreated: (controller) {
|
||||
|
|
|
@ -12,6 +12,8 @@ import 'package:flutter_inappwebview_example/in_app_browser_example.screen.dart'
|
|||
|
||||
// InAppLocalhostServer localhostServer = new InAppLocalhostServer();
|
||||
|
||||
AndroidServiceWorkerController serviceWorkerController = AndroidServiceWorkerController.instance();
|
||||
|
||||
Future main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
// await Permission.camera.request();
|
||||
|
@ -19,6 +21,16 @@ Future main() async {
|
|||
if (Platform.isAndroid) {
|
||||
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
|
||||
}
|
||||
|
||||
if (await AndroidWebViewFeature.isFeatureSupported(AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST)) {
|
||||
serviceWorkerController.serviceWorkerClient = AndroidServiceWorkerClient(
|
||||
shouldInterceptRequest: (request) async {
|
||||
print(request);
|
||||
return null;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -38,3 +38,5 @@ export 'src/web_storage_manager.dart';
|
|||
export 'src/context_menu.dart';
|
||||
export 'src/web_storage.dart';
|
||||
export 'src/X509Certificate/main.dart';
|
||||
export 'src/android/service_worker_controller.dart';
|
||||
export 'src/android/webview_feature.dart';
|
|
@ -0,0 +1,179 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'webview_feature.dart';
|
||||
import '../types.dart';
|
||||
|
||||
///Class that represents an Android-specific class that manages Service Workers used by [WebView].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerControllerCompat
|
||||
class AndroidServiceWorkerController {
|
||||
static AndroidServiceWorkerController? _instance;
|
||||
static const MethodChannel _channel = const MethodChannel(
|
||||
'com.pichillilorenzo/flutter_inappwebview_android_serviceworkercontroller');
|
||||
|
||||
AndroidServiceWorkerClient? serviceWorkerClient;
|
||||
|
||||
///Gets the [AndroidServiceWorkerController] shared instance.
|
||||
static AndroidServiceWorkerController instance() {
|
||||
return (_instance != null) ? _instance! : _init();
|
||||
}
|
||||
|
||||
static AndroidServiceWorkerController _init() {
|
||||
_channel.setMethodCallHandler(_handleMethod);
|
||||
_instance = AndroidServiceWorkerController();
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
static Future<dynamic> _handleMethod(MethodCall call) async {
|
||||
AndroidServiceWorkerController controller = AndroidServiceWorkerController.instance();
|
||||
AndroidServiceWorkerClient? serviceWorkerClient = controller.serviceWorkerClient;
|
||||
|
||||
switch (call.method) {
|
||||
case "shouldInterceptRequest":
|
||||
String url = call.arguments["url"];
|
||||
String method = call.arguments["method"];
|
||||
Map<String, String>? headers =
|
||||
call.arguments["headers"]?.cast<String, String>();
|
||||
bool isForMainFrame = call.arguments["isForMainFrame"];
|
||||
bool hasGesture = call.arguments["hasGesture"];
|
||||
bool isRedirect = call.arguments["isRedirect"];
|
||||
|
||||
var request = new WebResourceRequest(
|
||||
url: url,
|
||||
method: method,
|
||||
headers: headers,
|
||||
isForMainFrame: isForMainFrame,
|
||||
hasGesture: hasGesture,
|
||||
isRedirect: isRedirect);
|
||||
|
||||
if (serviceWorkerClient != null && serviceWorkerClient.shouldInterceptRequest != null) {
|
||||
return (await serviceWorkerClient.shouldInterceptRequest!(request))
|
||||
?.toMap();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
///Gets whether Service Workers support content URL access.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_CONTENT_ACCESS].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getAllowContentAccess()
|
||||
static Future<bool> getAllowContentAccess() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _channel.invokeMethod('getAllowContentAccess', args);
|
||||
}
|
||||
|
||||
///Gets whether Service Workers support file access.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_FILE_ACCESS].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getAllowFileAccess()
|
||||
static Future<bool> getAllowFileAccess() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _channel.invokeMethod('getAllowFileAccess', args);
|
||||
}
|
||||
|
||||
///Gets whether Service Workers are prohibited from loading any resources from the network.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getBlockNetworkLoads()
|
||||
static Future<bool> getBlockNetworkLoads() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return await _channel.invokeMethod('getBlockNetworkLoads', args);
|
||||
}
|
||||
|
||||
///Gets the current setting for overriding the cache mode.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_CACHE_MODE].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#getCacheMode()
|
||||
static Future<AndroidCacheMode?> getCacheMode() async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
return AndroidCacheMode.fromValue(await _channel.invokeMethod('getCacheMode', args));
|
||||
}
|
||||
|
||||
///Enables or disables content URL access from Service Workers.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_CONTENT_ACCESS].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setAllowContentAccess(boolean)
|
||||
static Future<void> setAllowContentAccess(bool allow) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent("allow", () => allow);
|
||||
await _channel.invokeMethod('setAllowContentAccess', args);
|
||||
}
|
||||
|
||||
///Enables or disables file access within Service Workers.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_FILE_ACCESS].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setAllowFileAccess(boolean)
|
||||
static Future<void> setAllowFileAccess(bool allow) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent("allow", () => allow);
|
||||
await _channel.invokeMethod('setAllowFileAccess', args);
|
||||
}
|
||||
|
||||
///Sets whether Service Workers should not load resources from the network.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setBlockNetworkLoads(boolean)
|
||||
static Future<void> setBlockNetworkLoads(bool flag) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent("flag", () => flag);
|
||||
await _channel.invokeMethod('setBlockNetworkLoads', args);
|
||||
}
|
||||
|
||||
///Overrides the way the cache is used.
|
||||
///This method should only be called if [AndroidWebViewFeature.isFeatureSupported] returns `true` for [AndroidWebViewFeature.SERVICE_WORKER_CACHE_MODE].
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerWebSettingsCompat#setCacheMode(int)
|
||||
static Future<void> setCacheMode(AndroidCacheMode mode) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent("mode", () => mode.toValue());
|
||||
await _channel.invokeMethod('setCacheMode', args);
|
||||
}
|
||||
}
|
||||
|
||||
///Class that represents an Android-specific class for clients to capture Service Worker related callbacks.
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/ServiceWorkerClientCompat
|
||||
class AndroidServiceWorkerClient {
|
||||
|
||||
///Notify the host application of a resource request and allow the application to return the data.
|
||||
///If the return value is `null`, the Service Worker will continue to load the resource as usual.
|
||||
///Otherwise, the return response and data will be used.
|
||||
///
|
||||
///This method is called only if [AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST] is supported.
|
||||
///You can check whether that flag is supported using [AndroidWebViewFeature.isFeatureSupported].
|
||||
///
|
||||
///[request] represents an object containing the details of the request.
|
||||
///
|
||||
///**NOTE**: available on Android 24+.
|
||||
final Future<WebResourceResponse?> Function(WebResourceRequest request)?
|
||||
shouldInterceptRequest;
|
||||
|
||||
AndroidServiceWorkerClient({
|
||||
this.shouldInterceptRequest
|
||||
});
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
///Class that represents an Android-specific utility class for checking which WebView Support Library features are supported on the device.
|
||||
class AndroidWebViewFeature {
|
||||
static const MethodChannel _channel = const MethodChannel(
|
||||
'com.pichillilorenzo/flutter_inappwebview_android_webviewfeature');
|
||||
|
||||
static Future<dynamic> _handleMethod(MethodCall call) async {}
|
||||
|
||||
final String _value;
|
||||
|
||||
const AndroidWebViewFeature._internal(this._value);
|
||||
|
||||
static final Set<AndroidWebViewFeature> values = [
|
||||
AndroidWebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
||||
AndroidWebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS,
|
||||
AndroidWebViewFeature.FORCE_DARK,
|
||||
AndroidWebViewFeature.FORCE_DARK_STRATEGY,
|
||||
AndroidWebViewFeature.GET_WEB_CHROME_CLIENT,
|
||||
AndroidWebViewFeature.GET_WEB_VIEW_CLIENT,
|
||||
AndroidWebViewFeature.GET_WEB_VIEW_RENDERER,
|
||||
AndroidWebViewFeature.MULTI_PROCESS,
|
||||
AndroidWebViewFeature.OFF_SCREEN_PRERASTER,
|
||||
AndroidWebViewFeature.POST_WEB_MESSAGE,
|
||||
AndroidWebViewFeature.PROXY_OVERRIDE,
|
||||
AndroidWebViewFeature.RECEIVE_HTTP_ERROR,
|
||||
AndroidWebViewFeature.RECEIVE_WEB_RESOURCE_ERROR,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_ALLOWLIST,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_ENABLE,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_HIT,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL,
|
||||
AndroidWebViewFeature.SAFE_BROWSING_WHITELIST,
|
||||
AndroidWebViewFeature.SERVICE_WORKER_BASIC_USAGE,
|
||||
AndroidWebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS,
|
||||
AndroidWebViewFeature.SERVICE_WORKER_CACHE_MODE,
|
||||
AndroidWebViewFeature.SERVICE_WORKER_CONTENT_ACCESS,
|
||||
AndroidWebViewFeature.SERVICE_WORKER_FILE_ACCESS,
|
||||
AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
|
||||
AndroidWebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS,
|
||||
AndroidWebViewFeature.START_SAFE_BROWSING,
|
||||
AndroidWebViewFeature.TRACING_CONTROLLER_BASIC_USAGE,
|
||||
AndroidWebViewFeature.VISUAL_STATE_CALLBACK,
|
||||
AndroidWebViewFeature.WEB_MESSAGE_CALLBACK_ON_MESSAGE,
|
||||
AndroidWebViewFeature.WEB_MESSAGE_LISTENER,
|
||||
AndroidWebViewFeature.WEB_MESSAGE_PORT_CLOSE,
|
||||
AndroidWebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE,
|
||||
AndroidWebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK,
|
||||
AndroidWebViewFeature.WEB_RESOURCE_ERROR_GET_CODE,
|
||||
AndroidWebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION,
|
||||
AndroidWebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT,
|
||||
AndroidWebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE,
|
||||
AndroidWebViewFeature.WEB_VIEW_RENDERER_TERMINATE,
|
||||
].toSet();
|
||||
|
||||
static AndroidWebViewFeature? fromValue(String? value) {
|
||||
if (value != null) {
|
||||
try {
|
||||
return AndroidWebViewFeature.values.firstWhere(
|
||||
(element) => element.toValue() == value);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String toValue() => _value;
|
||||
|
||||
@override
|
||||
String toString() => _value;
|
||||
|
||||
///
|
||||
static const CREATE_WEB_MESSAGE_CHANNEL = const AndroidWebViewFeature._internal("CREATE_WEB_MESSAGE_CHANNEL");
|
||||
|
||||
///
|
||||
static const DISABLED_ACTION_MODE_MENU_ITEMS = const AndroidWebViewFeature._internal("DISABLED_ACTION_MODE_MENU_ITEMS");
|
||||
|
||||
///
|
||||
static const FORCE_DARK = const AndroidWebViewFeature._internal("FORCE_DARK");
|
||||
|
||||
///
|
||||
static const FORCE_DARK_STRATEGY = const AndroidWebViewFeature._internal("FORCE_DARK_STRATEGY");
|
||||
|
||||
///
|
||||
static const GET_WEB_CHROME_CLIENT = const AndroidWebViewFeature._internal("GET_WEB_CHROME_CLIENT");
|
||||
|
||||
///
|
||||
static const GET_WEB_VIEW_CLIENT = const AndroidWebViewFeature._internal("GET_WEB_VIEW_CLIENT");
|
||||
|
||||
///
|
||||
static const GET_WEB_VIEW_RENDERER = const AndroidWebViewFeature._internal("GET_WEB_VIEW_RENDERER");
|
||||
|
||||
///
|
||||
static const MULTI_PROCESS = const AndroidWebViewFeature._internal("MULTI_PROCESS");
|
||||
|
||||
///
|
||||
static const OFF_SCREEN_PRERASTER = const AndroidWebViewFeature._internal("OFF_SCREEN_PRERASTER");
|
||||
|
||||
///
|
||||
static const POST_WEB_MESSAGE = const AndroidWebViewFeature._internal("POST_WEB_MESSAGE");
|
||||
|
||||
///
|
||||
static const PROXY_OVERRIDE = const AndroidWebViewFeature._internal("PROXY_OVERRIDE");
|
||||
|
||||
///
|
||||
static const RECEIVE_HTTP_ERROR = const AndroidWebViewFeature._internal("RECEIVE_HTTP_ERROR");
|
||||
|
||||
///
|
||||
static const RECEIVE_WEB_RESOURCE_ERROR = const AndroidWebViewFeature._internal("RECEIVE_WEB_RESOURCE_ERROR");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_ALLOWLIST = const AndroidWebViewFeature._internal("SAFE_BROWSING_ALLOWLIST");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_ENABLE = const AndroidWebViewFeature._internal("SAFE_BROWSING_ENABLE");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_HIT = const AndroidWebViewFeature._internal("SAFE_BROWSING_HIT");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_PRIVACY_POLICY_URL = const AndroidWebViewFeature._internal("SAFE_BROWSING_PRIVACY_POLICY_URL");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = const AndroidWebViewFeature._internal("SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_RESPONSE_PROCEED = const AndroidWebViewFeature._internal("SAFE_BROWSING_RESPONSE_PROCEED");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = const AndroidWebViewFeature._internal("SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL");
|
||||
|
||||
///
|
||||
static const SAFE_BROWSING_WHITELIST = const AndroidWebViewFeature._internal("SAFE_BROWSING_WHITELIST");
|
||||
|
||||
///
|
||||
static const SERVICE_WORKER_BASIC_USAGE = const AndroidWebViewFeature._internal("SERVICE_WORKER_BASIC_USAGE");
|
||||
|
||||
///
|
||||
static const SERVICE_WORKER_BLOCK_NETWORK_LOADS = const AndroidWebViewFeature._internal("SERVICE_WORKER_BLOCK_NETWORK_LOADS");
|
||||
|
||||
///
|
||||
static const SERVICE_WORKER_CACHE_MODE = const AndroidWebViewFeature._internal("SERVICE_WORKER_CACHE_MODE");
|
||||
|
||||
///
|
||||
static const SERVICE_WORKER_CONTENT_ACCESS = const AndroidWebViewFeature._internal("SERVICE_WORKER_CONTENT_ACCESS");
|
||||
|
||||
///
|
||||
static const SERVICE_WORKER_FILE_ACCESS = const AndroidWebViewFeature._internal("SERVICE_WORKER_FILE_ACCESS");
|
||||
|
||||
///
|
||||
static const SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = const AndroidWebViewFeature._internal("SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST");
|
||||
|
||||
///
|
||||
static const SHOULD_OVERRIDE_WITH_REDIRECTS = const AndroidWebViewFeature._internal("SHOULD_OVERRIDE_WITH_REDIRECTS");
|
||||
|
||||
///
|
||||
static const START_SAFE_BROWSING = const AndroidWebViewFeature._internal("START_SAFE_BROWSING");
|
||||
|
||||
///
|
||||
static const TRACING_CONTROLLER_BASIC_USAGE = const AndroidWebViewFeature._internal("TRACING_CONTROLLER_BASIC_USAGE");
|
||||
|
||||
///
|
||||
static const VISUAL_STATE_CALLBACK = const AndroidWebViewFeature._internal("VISUAL_STATE_CALLBACK");
|
||||
|
||||
///
|
||||
static const WEB_MESSAGE_CALLBACK_ON_MESSAGE = const AndroidWebViewFeature._internal("WEB_MESSAGE_CALLBACK_ON_MESSAGE");
|
||||
|
||||
///
|
||||
static const WEB_MESSAGE_LISTENER = const AndroidWebViewFeature._internal("WEB_MESSAGE_LISTENER");
|
||||
|
||||
///
|
||||
static const WEB_MESSAGE_PORT_CLOSE = const AndroidWebViewFeature._internal("WEB_MESSAGE_PORT_CLOSE");
|
||||
|
||||
///
|
||||
static const WEB_MESSAGE_PORT_POST_MESSAGE = const AndroidWebViewFeature._internal("WEB_MESSAGE_PORT_POST_MESSAGE");
|
||||
|
||||
///
|
||||
static const WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = const AndroidWebViewFeature._internal("WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK");
|
||||
|
||||
///
|
||||
static const WEB_RESOURCE_ERROR_GET_CODE = const AndroidWebViewFeature._internal("WEB_RESOURCE_ERROR_GET_CODE");
|
||||
|
||||
///
|
||||
static const WEB_RESOURCE_ERROR_GET_DESCRIPTION = const AndroidWebViewFeature._internal("WEB_RESOURCE_ERROR_GET_DESCRIPTION");
|
||||
|
||||
///
|
||||
static const WEB_RESOURCE_REQUEST_IS_REDIRECT = const AndroidWebViewFeature._internal("WEB_RESOURCE_REQUEST_IS_REDIRECT");
|
||||
|
||||
///
|
||||
static const WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = const AndroidWebViewFeature._internal("WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE");
|
||||
|
||||
///
|
||||
static const WEB_VIEW_RENDERER_TERMINATE = const AndroidWebViewFeature._internal("WEB_VIEW_RENDERER_TERMINATE");
|
||||
|
||||
bool operator ==(value) => value == _value;
|
||||
|
||||
@override
|
||||
int get hashCode => _value.hashCode;
|
||||
|
||||
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
||||
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
||||
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
||||
///
|
||||
///**Official Android API**: https://developer.android.com/reference/androidx/webkit/WebViewFeature#isFeatureSupported(java.lang.String)
|
||||
static Future<bool> isFeatureSupported(AndroidWebViewFeature feature) async {
|
||||
Map<String, dynamic> args = <String, dynamic>{};
|
||||
args.putIfAbsent("feature", () => feature.toValue());
|
||||
return await _channel.invokeMethod('isFeatureSupported', args);
|
||||
}
|
||||
}
|
|
@ -929,6 +929,7 @@ class InAppWebViewController {
|
|||
default:
|
||||
throw UnimplementedError("Unimplemented ${call.method} method");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
///Gets the URL for the current page.
|
||||
|
|
|
@ -4601,7 +4601,7 @@ class UserScript {
|
|||
///
|
||||
///**NOTE for iOS 14.0+**: this class represents the native [WKContentWorld](https://developer.apple.com/documentation/webkit/wkcontentworld) class.
|
||||
///
|
||||
///**NOTE for Android**: it will create and append an `<iframe>` HTML element with `id` equals to [name] to the webpage's content that contains only the scripts
|
||||
///**NOTE for Android**: it will create and append an `<iframe>` HTML element with `id` equals to `flutter_inappwebview_[name]` to the webpage's content that contains only the scripts
|
||||
///in order to define a new scope of execution for JavaScript code. Unfortunately, there isn't any other way to do it.
|
||||
///For any [ContentWorld], except [ContentWorld.page], if you need to access to the `window` or `document` global Object,
|
||||
///you need to use `window.top` and `window.top.document` because the code runs inside an `<iframe>`.
|
||||
|
|
Loading…
Reference in New Issue