fix #732, fix #759, Fixed Android ChromeSafariBrowser menu item callback not called because of PendingIntents extra were cached

This commit is contained in:
Lorenzo Pichilli 2021-03-28 04:17:09 +02:00
parent a0e3bc2de7
commit 71a8fe23ea
36 changed files with 411 additions and 290 deletions

View File

@ -1,8 +1,6 @@
<component name="libraryTable">
<library name="Flutter Plugins">
<CLASSES>
<root url="file://$PROJECT_DIR$" />
</CLASSES>
<CLASSES />
<JAVADOC />
<SOURCES />
</library>

View File

@ -7,6 +7,9 @@
- Removed `final` keyword for all `HeadlessInAppWebView` events
- Fixed wrong usage of Android WebView scale property
- Fixed "java.lang.NullPointerException: com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebViewRenderProcessClient$1.success(InAppWebViewRenderProcessClient.java:37)" [#757](https://github.com/pichillilorenzo/flutter_inappwebview/issues/757)
- Fixed "In a multi-activity app, the plugin doesn't reattach to the first activity" [#732](https://github.com/pichillilorenzo/flutter_inappwebview/issues/732)
- Fixed "ChromeSafariBrowser isn't calling its events, and not keeping track of isOpen properly" [#759](https://github.com/pichillilorenzo/flutter_inappwebview/issues/759)
- Fixed Android ChromeSafariBrowser menu item callback not called because of PendingIntents extra were cached
## 5.2.1+1

View File

@ -24,64 +24,76 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
protected static final String LOG_TAG = "InAppWebViewFlutterPL";
public static PlatformUtil platformUtil;
public static InAppBrowserManager inAppBrowserManager;
public static HeadlessInAppWebViewManager headlessInAppWebViewManager;
public static ChromeSafariBrowserManager chromeSafariBrowserManager;
public static InAppWebViewStatic inAppWebViewStatic;
public static MyCookieManager myCookieManager;
public static CredentialDatabaseHandler credentialDatabaseHandler;
public static MyWebStorage myWebStorage;
public static ServiceWorkerManager serviceWorkerManager;
public static WebViewFeatureManager webViewFeatureManager;
public PlatformUtil platformUtil;
public InAppBrowserManager inAppBrowserManager;
public HeadlessInAppWebViewManager headlessInAppWebViewManager;
public ChromeSafariBrowserManager chromeSafariBrowserManager;
public InAppWebViewStatic inAppWebViewStatic;
public MyCookieManager myCookieManager;
public CredentialDatabaseHandler credentialDatabaseHandler;
public MyWebStorage myWebStorage;
public ServiceWorkerManager serviceWorkerManager;
public WebViewFeatureManager webViewFeatureManager;
public FlutterWebViewFactory flutterWebViewFactory;
public static ValueCallback<Uri> filePathCallbackLegacy;
public static ValueCallback<Uri[]> filePathCallback;
public Context applicationContext;
public PluginRegistry.Registrar registrar;
public BinaryMessenger messenger;
public FlutterPlugin.FlutterAssets flutterAssets;
public ActivityPluginBinding activityPluginBinding;
public Activity activity;
@SuppressWarnings("deprecation")
public FlutterView flutterView;
public InAppWebViewFlutterPlugin() {}
@SuppressWarnings("deprecation")
public static void registerWith(PluginRegistry.Registrar registrar) {
final InAppWebViewFlutterPlugin instance = new InAppWebViewFlutterPlugin();
Shared.registrar = registrar;
instance.registrar = registrar;
instance.onAttachedToEngine(
registrar.context(), registrar.messenger(), registrar.activity(), registrar.platformViewRegistry(), registrar.view());
}
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
Shared.flutterAssets = binding.getFlutterAssets();
this.flutterAssets = binding.getFlutterAssets();
// Shared.activity could be null or not.
// It depends on who is called first between onAttachedToEngine event and onAttachedToActivity event.
//
// See https://github.com/pichillilorenzo/flutter_inappwebview/issues/390#issuecomment-647039084
onAttachedToEngine(
binding.getApplicationContext(), binding.getBinaryMessenger(), Shared.activity, binding.getPlatformViewRegistry(), null);
binding.getApplicationContext(), binding.getBinaryMessenger(), this.activity, binding.getPlatformViewRegistry(), null);
}
@SuppressWarnings("deprecation")
private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) {
this.applicationContext = applicationContext;
this.activity = activity;
this.messenger = messenger;
this.flutterView = flutterView;
Shared.applicationContext = applicationContext;
Shared.activity = activity;
Shared.messenger = messenger;
inAppBrowserManager = new InAppBrowserManager(messenger);
headlessInAppWebViewManager = new HeadlessInAppWebViewManager(messenger);
chromeSafariBrowserManager = new ChromeSafariBrowserManager(messenger);
inAppBrowserManager = new InAppBrowserManager(this);
headlessInAppWebViewManager = new HeadlessInAppWebViewManager(this);
chromeSafariBrowserManager = new ChromeSafariBrowserManager(this);
flutterWebViewFactory = new FlutterWebViewFactory(this);
platformViewRegistry.registerViewFactory(
"com.pichillilorenzo/flutter_inappwebview", new FlutterWebViewFactory(messenger, flutterView));
"com.pichillilorenzo/flutter_inappwebview", flutterWebViewFactory);
platformUtil = new PlatformUtil(messenger);
inAppWebViewStatic = new InAppWebViewStatic(messenger);
myCookieManager = new MyCookieManager(messenger);
myWebStorage = new MyWebStorage(messenger);
platformUtil = new PlatformUtil(this);
inAppWebViewStatic = new InAppWebViewStatic(this);
myCookieManager = new MyCookieManager(this);
myWebStorage = new MyWebStorage(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
serviceWorkerManager = new ServiceWorkerManager(messenger);
serviceWorkerManager = new ServiceWorkerManager(this);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
credentialDatabaseHandler = new CredentialDatabaseHandler(messenger);
credentialDatabaseHandler = new CredentialDatabaseHandler(this);
}
webViewFeatureManager = new WebViewFeatureManager(messenger);
webViewFeatureManager = new WebViewFeatureManager(this);
}
@Override
@ -132,25 +144,25 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
@Override
public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
Shared.activityPluginBinding = activityPluginBinding;
Shared.activity = activityPluginBinding.getActivity();
this.activityPluginBinding = activityPluginBinding;
this.activity = activityPluginBinding.getActivity();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
Shared.activityPluginBinding = null;
Shared.activity = null;
this.activityPluginBinding = null;
this.activity = null;
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
Shared.activityPluginBinding = activityPluginBinding;
Shared.activity = activityPluginBinding.getActivity();
this.activityPluginBinding = activityPluginBinding;
this.activity = activityPluginBinding.getActivity();
}
@Override
public void onDetachedFromActivity() {
Shared.activityPluginBinding = null;
Shared.activity = null;
this.activityPluginBinding = null;
this.activity = null;
}
}

View File

@ -548,7 +548,7 @@ public class InAppWebViewMethodHandler implements MethodChannel.MethodCallHandle
case "addWebMessageListener":
if (webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
Map<String, Object> webMessageListenerMap = (Map<String, Object>) call.argument("webMessageListener");
WebMessageListener webMessageListener = WebMessageListener.fromMap(webMessageListenerMap);
WebMessageListener webMessageListener = WebMessageListener.fromMap(webView.plugin.messenger, webMessageListenerMap);
try {
webView.addWebMessageListener(webMessageListener);
result.success(true);

View File

@ -1,12 +1,12 @@
package com.pichillilorenzo.flutter_inappwebview;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.WebView;
import androidx.annotation.Nullable;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;
@ -17,17 +17,19 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
public MethodChannel channel;
protected static final String LOG_TAG = "InAppWebViewStatic";
public MethodChannel channel;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public InAppWebViewStatic(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_static");
public InAppWebViewStatic(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_static");
channel.setMethodCallHandler(this);
}
@ -35,7 +37,7 @@ public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
public void onMethodCall(MethodCall call, final MethodChannel.Result result) {
switch (call.method) {
case "getDefaultUserAgent":
result.success(WebSettings.getDefaultUserAgent(Shared.applicationContext));
result.success(WebSettings.getDefaultUserAgent(plugin.applicationContext));
break;
case "clearClientCertPreferences":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
@ -78,7 +80,7 @@ public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
break;
case "getCurrentWebViewPackage":
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
result.success(convertWebViewPackageToMap(WebViewCompat.getCurrentWebViewPackage(Shared.activity)));
result.success(convertWebViewPackageToMap(WebViewCompat.getCurrentWebViewPackage(plugin.activity)));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//with Android Lollipop (API 21) they started to update the WebView
//as a separate APK with the PlayStore and they added the
@ -122,5 +124,6 @@ public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
plugin = null;
}
}

View File

@ -23,8 +23,7 @@ public class JavaScriptBridgeInterface {
private static final String LOG_TAG = "JSBridgeInterface";
private InAppWebView inAppWebView;
private final MethodChannel channel;
public JavaScriptBridgeInterface(InAppWebView inAppWebView) {
this.inAppWebView = inAppWebView;
this.channel = this.inAppWebView.channel;

View File

@ -16,7 +16,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
@ -24,11 +23,14 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
static final String LOG_TAG = "MyCookieManager";
public static MethodChannel channel;
public MethodChannel channel;
public static CookieManager cookieManager;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public MyCookieManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_cookiemanager");
public MyCookieManager(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_cookiemanager");
channel.setMethodCallHandler(this);
cookieManager = getCookieManager();
}
@ -49,7 +51,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
Boolean isSecure = (Boolean) call.argument("isSecure");
Boolean isHttpOnly = (Boolean) call.argument("isHttpOnly");
String sameSite = (String) call.argument("sameSite");
MyCookieManager.setCookie(url,
setCookie(url,
name,
value,
domain,
@ -63,7 +65,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
}
break;
case "getCookies":
result.success(MyCookieManager.getCookies((String) call.argument("url")));
result.success(getCookies((String) call.argument("url")));
break;
case "deleteCookie":
{
@ -71,7 +73,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
String name = (String) call.argument("name");
String domain = (String) call.argument("domain");
String path = (String) call.argument("path");
MyCookieManager.deleteCookie(url, name, domain, path, result);
deleteCookie(url, name, domain, path, result);
}
break;
case "deleteCookies":
@ -79,11 +81,11 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
String url = (String) call.argument("url");
String domain = (String) call.argument("domain");
String path = (String) call.argument("path");
MyCookieManager.deleteCookies(url, domain, path, result);
deleteCookies(url, domain, path, result);
}
break;
case "deleteAllCookies":
MyCookieManager.deleteAllCookies(result);
deleteAllCookies(result);
break;
default:
result.notImplemented();
@ -124,7 +126,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
return cookieManager;
}
public static void setCookie(String url,
public void setCookie(String url,
String name,
String value,
String domain,
@ -167,7 +169,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
cookieManager.flush();
}
else {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync();
cookieManager.setCookie(url, cookieValue);
result.success(true);
@ -176,7 +178,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
}
}
public static List<Map<String, Object>> getCookies(final String url) {
public List<Map<String, Object>> getCookies(final String url) {
final List<Map<String, Object>> cookieListMap = new ArrayList<>();
@ -209,7 +211,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
}
public static void deleteCookie(String url, String name, String domain, String path, final MethodChannel.Result result) {
public void deleteCookie(String url, String name, String domain, String path, final MethodChannel.Result result) {
cookieManager = getCookieManager();
if (cookieManager == null) return;
@ -225,7 +227,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
cookieManager.flush();
}
else {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync();
cookieManager.setCookie(url, cookieValue);
result.success(true);
@ -234,7 +236,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
}
}
public static void deleteCookies(String url, String domain, String path, final MethodChannel.Result result) {
public void deleteCookies(String url, String domain, String path, final MethodChannel.Result result) {
cookieManager = getCookieManager();
if (cookieManager == null) return;
@ -244,7 +246,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
if (cookiesString != null) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync();
}
@ -268,7 +270,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
result.success(true);
}
public static void deleteAllCookies(final MethodChannel.Result result) {
public void deleteAllCookies(final MethodChannel.Result result) {
cookieManager = getCookieManager();
if (cookieManager == null) return;
@ -282,7 +284,7 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
cookieManager.flush();
}
else {
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(Shared.applicationContext);
CookieSyncManager cookieSyncMngr = CookieSyncManager.createInstance(plugin.applicationContext);
cookieSyncMngr.startSync();
cookieManager.removeAllCookie();
result.success(true);
@ -299,5 +301,6 @@ public class MyCookieManager implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
plugin = null;
}
}

View File

@ -1,15 +1,15 @@
package com.pichillilorenzo.flutter_inappwebview;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebStorage;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
@ -17,11 +17,14 @@ public class MyWebStorage implements MethodChannel.MethodCallHandler {
static final String LOG_TAG = "MyWebStorage";
public static MethodChannel channel;
public MethodChannel channel;
public static WebStorage webStorageManager;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public MyWebStorage(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_webstoragemanager");
public MyWebStorage(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_webstoragemanager");
channel.setMethodCallHandler(this);
webStorageManager = WebStorage.getInstance();
}
@ -100,5 +103,6 @@ public class MyWebStorage implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
plugin = null;
}
}

View File

@ -14,12 +14,15 @@ import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class PlatformUtil implements MethodChannel.MethodCallHandler {
public MethodChannel channel;
protected static final String LOG_TAG = "PlatformUtil";
public MethodChannel channel;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public PlatformUtil(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_platformutil");
public PlatformUtil(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_platformutil");
channel.setMethodCallHandler(this);
}
@ -63,5 +66,6 @@ public class PlatformUtil implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
plugin = null;
}
}

View File

@ -26,12 +26,15 @@ public class ServiceWorkerManager implements MethodChannel.MethodCallHandler {
static final String LOG_TAG = "ServiceWorkerManager";
public static MethodChannel channel;
public MethodChannel channel;
@Nullable
public static ServiceWorkerControllerCompat serviceWorkerController;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public ServiceWorkerManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_android_serviceworkercontroller");
public ServiceWorkerManager(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_android_serviceworkercontroller");
channel.setMethodCallHandler(this);
if (WebViewFeature.isFeatureSupported(WebViewFeature.SERVICE_WORKER_BASIC_USAGE)) {
serviceWorkerController = ServiceWorkerControllerCompat.getInstance();
@ -152,5 +155,6 @@ public class ServiceWorkerManager implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
plugin = null;
}
}

View File

@ -1,18 +0,0 @@
package com.pichillilorenzo.flutter_inappwebview;
import android.app.Activity;
import android.content.Context;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry;
public class Shared {
public static Context applicationContext;
public static PluginRegistry.Registrar registrar;
public static BinaryMessenger messenger;
public static FlutterPlugin.FlutterAssets flutterAssets;
public static ActivityPluginBinding activityPluginBinding;
public static Activity activity;
}

View File

@ -6,9 +6,7 @@ import android.net.http.SslCertificate;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
@ -16,13 +14,11 @@ import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
@ -30,7 +26,6 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
@ -57,13 +52,13 @@ public class Util {
private Util() {}
public static String getUrlAsset(String assetFilePath) throws IOException {
String key = (Shared.registrar != null) ? Shared.registrar.lookupKeyForAsset(assetFilePath) : Shared.flutterAssets.getAssetFilePathByName(assetFilePath);
public static String getUrlAsset(InAppWebViewFlutterPlugin plugin, String assetFilePath) throws IOException {
String key = (plugin.registrar != null) ? plugin.registrar.lookupKeyForAsset(assetFilePath) : plugin.flutterAssets.getAssetFilePathByName(assetFilePath);
InputStream is = null;
IOException e = null;
try {
is = getFileAsset(assetFilePath);
is = getFileAsset(plugin, assetFilePath);
} catch (IOException ex) {
e = ex;
} finally {
@ -82,9 +77,9 @@ public class Util {
return ANDROID_ASSET_URL + key;
}
public static InputStream getFileAsset(String assetFilePath) throws IOException {
String key = (Shared.registrar != null) ? Shared.registrar.lookupKeyForAsset(assetFilePath) : Shared.flutterAssets.getAssetFilePathByName(assetFilePath);
AssetManager mg = Shared.applicationContext.getResources().getAssets();
public static InputStream getFileAsset(InAppWebViewFlutterPlugin plugin,String assetFilePath) throws IOException {
String key = (plugin.registrar != null) ? plugin.registrar.lookupKeyForAsset(assetFilePath) : plugin.flutterAssets.getAssetFilePathByName(assetFilePath);
AssetManager mg = plugin.applicationContext.getResources().getAssets();
return mg.open(key);
}
@ -136,12 +131,12 @@ public class Util {
}
}
public static PrivateKeyAndCertificates loadPrivateKeyAndCertificate(String certificatePath, String certificatePassword, String keyStoreType) {
public static PrivateKeyAndCertificates loadPrivateKeyAndCertificate(InAppWebViewFlutterPlugin plugin, String certificatePath, String certificatePassword, String keyStoreType) {
PrivateKeyAndCertificates privateKeyAndCertificates = null;
try {
InputStream certificateFileStream = getFileAsset(certificatePath);
InputStream certificateFileStream = getFileAsset(plugin, certificatePath);
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(certificateFileStream, certificatePassword != null ? certificatePassword.toCharArray() : null);

View File

@ -1,5 +1,6 @@
package com.pichillilorenzo.flutter_inappwebview;
import androidx.annotation.Nullable;
import androidx.webkit.WebViewFeature;
import io.flutter.plugin.common.BinaryMessenger;
@ -10,10 +11,13 @@ public class WebViewFeatureManager implements MethodChannel.MethodCallHandler {
static final String LOG_TAG = "WebViewFeatureManager";
public static MethodChannel channel;
public MethodChannel channel;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public WebViewFeatureManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_android_webviewfeature");
public WebViewFeatureManager(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_android_webviewfeature");
channel.setMethodCallHandler(this);
}
@ -31,5 +35,6 @@ public class WebViewFeatureManager implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
plugin = null;
}
}

View File

@ -5,8 +5,6 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import java.util.HashMap;
import java.util.Map;
@ -16,6 +14,7 @@ public class ActionBroadcastReceiver extends BroadcastReceiver {
protected static final String LOG_TAG = "ActionBroadcastReceiver";
public static final String KEY_ACTION_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_ID";
public static final String KEY_ACTION_VIEW_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.ACTION_VIEW_ID";
public static final String CHROME_MANAGER_ID = "com.pichillilorenzo.flutter_inappwebview.ChromeCustomTabs.CHROME_MANAGER_ID";
public static final String KEY_URL_TITLE = "android.intent.extra.SUBJECT";
@Override
@ -27,7 +26,10 @@ public class ActionBroadcastReceiver extends BroadcastReceiver {
int id = b.getInt(KEY_ACTION_ID);
String title = b.getString(KEY_URL_TITLE);
MethodChannel channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + viewId);
String managerId = b.getString(CHROME_MANAGER_ID);
ChromeSafariBrowserManager manager = (ChromeSafariBrowserManager) ChromeSafariBrowserManager.shared.get(managerId);
MethodChannel channel = new MethodChannel(manager.plugin.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + viewId);
Map<String, Object> obj = new HashMap<>();
obj.put("url", url);
obj.put("title", title);

View File

@ -6,6 +6,7 @@ import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import androidx.browser.customtabs.CustomTabsCallback;
import androidx.browser.customtabs.CustomTabsIntent;
@ -13,7 +14,6 @@ import androidx.browser.customtabs.CustomTabsService;
import androidx.browser.customtabs.CustomTabsSession;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import java.util.HashMap;
import java.util.List;
@ -34,6 +34,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
protected final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
protected boolean onChromeSafariBrowserOpened = false;
protected boolean onChromeSafariBrowserCompletedInitialLoad = false;
public ChromeSafariBrowserManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -45,7 +46,10 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
assert b != null;
id = b.getString("id");
channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + id);
String managerId = b.getString("managerId");
manager = (ChromeSafariBrowserManager) ChromeSafariBrowserManager.shared.get(managerId);
channel = new MethodChannel(manager.plugin.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + id);
channel.setMethodCallHandler(this);
final String url = b.getString("url");
@ -77,6 +81,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
@Override
public void onCustomTabsDisconnected() {
chromeCustomTabsActivity.close();
dispose();
}
});
@ -128,10 +133,13 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
this.close();
// https://stackoverflow.com/a/41596629/4637638
Intent myIntent = new Intent(Shared.activity, Shared.activity.getClass());
Intent myIntent = new Intent(manager.plugin.activity, manager.plugin.activity.getClass());
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
myIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Shared.activity.startActivity(myIntent);
manager.plugin.activity.startActivity(myIntent);
dispose();
result.success(true);
break;
default:
@ -186,25 +194,32 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CHROME_CUSTOM_TAB_REQUEST_CODE) {
close();
dispose();
}
}
public void close() {
customTabsSession = null;
finish();
Map<String, Object> obj = new HashMap<>();
channel.invokeMethod("onChromeSafariBrowserClosed", obj);
}
private PendingIntent createPendingIntent(int actionSourceId) {
Intent actionIntent = new Intent(this, ActionBroadcastReceiver.class);
Bundle extras = new Bundle();
extras.putInt(ActionBroadcastReceiver.KEY_ACTION_ID, actionSourceId);
extras.putString(ActionBroadcastReceiver.KEY_ACTION_VIEW_ID, id);
extras.putString(ActionBroadcastReceiver.CHROME_MANAGER_ID, manager.id);
actionIntent.putExtras(extras);
return PendingIntent.getBroadcast(
this, actionSourceId, actionIntent, 0);
this, actionSourceId, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public void dispose() {
channel.setMethodCallHandler(null);
manager = null;
}
public void close() {
customTabsSession = null;
finish();
Map<String, Object> obj = new HashMap<>();
channel.invokeMethod("onChromeSafariBrowserClosed", obj);
}
}

View File

@ -4,30 +4,38 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import androidx.annotation.Nullable;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandler {
public MethodChannel channel;
protected static final String LOG_TAG = "ChromeBrowserManager";
public MethodChannel channel;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public String id;
public static final Map<String, ChromeSafariBrowserManager> shared = new HashMap<>();
public ChromeSafariBrowserManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_chromesafaribrowser");
public ChromeSafariBrowserManager(final InAppWebViewFlutterPlugin plugin) {
this.id = UUID.randomUUID().toString();
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser");
channel.setMethodCallHandler(this);
shared.put(this.id, this);
}
@Override
public void onMethodCall(final MethodCall call, final MethodChannel.Result result) {
final Activity activity = Shared.activity;
final String id = (String) call.argument("id");
switch (call.method) {
@ -36,11 +44,11 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
String url = (String) call.argument("url");
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) call.argument("menuItemList");
open(activity, id, url, options, menuItemList, result);
open(plugin.activity, id, url, options, menuItemList, result);
}
break;
case "isAvailable":
result.success(CustomTabActivityHelper.isAvailable(activity));
result.success(CustomTabActivityHelper.isAvailable(plugin.activity));
break;
default:
result.notImplemented();
@ -52,10 +60,10 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
Intent intent = null;
Bundle extras = new Bundle();
extras.putString("fromActivity", activity.getClass().getName());
extras.putString("url", url);
extras.putBoolean("isData", false);
extras.putString("id", id);
extras.putString("managerId", this.id);
extras.putSerializable("options", options);
extras.putSerializable("menuItemList", (Serializable) menuItemList);
@ -72,5 +80,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
public void dispose() {
channel.setMethodCallHandler(null);
shared.remove(this.id);
plugin = null;
}
}

View File

@ -4,9 +4,10 @@ import android.os.Build;
import android.webkit.WebViewDatabase;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.types.URLCredential;
import com.pichillilorenzo.flutter_inappwebview.types.URLProtectionSpace;
@ -15,7 +16,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
@ -24,13 +24,16 @@ public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandle
static final String LOG_TAG = "CredentialDatabaseHandler";
public static MethodChannel channel;
public MethodChannel channel;
public static CredentialDatabase credentialDatabase;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public CredentialDatabaseHandler(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_credential_database");
public CredentialDatabaseHandler(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_credential_database");
channel.setMethodCallHandler(this);
credentialDatabase = CredentialDatabase.getInstance(Shared.applicationContext);
credentialDatabase = CredentialDatabase.getInstance(plugin.applicationContext);
}
@Override
@ -109,7 +112,7 @@ public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandle
break;
case "clearAllAuthCredentials":
credentialDatabase.clearAllAuthCredentials();
WebViewDatabase.getInstance(Shared.applicationContext).clearHttpAuthUsernamePassword();
WebViewDatabase.getInstance(plugin.applicationContext).clearHttpAuthUsernamePassword();
result.success(true);
break;
default:
@ -119,6 +122,7 @@ public class CredentialDatabaseHandler implements MethodChannel.MethodCallHandle
public void dispose() {
channel.setMethodCallHandler(null);
plugin = null;
}
}

View File

@ -7,7 +7,7 @@ import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.Util;
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
import com.pichillilorenzo.flutter_inappwebview.types.Size2D;
@ -15,7 +15,6 @@ import com.pichillilorenzo.flutter_inappwebview.types.Size2D;
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;
@ -27,11 +26,14 @@ public class HeadlessInAppWebView implements MethodChannel.MethodCallHandler {
public final MethodChannel channel;
@Nullable
public FlutterWebView flutterWebView;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public HeadlessInAppWebView(BinaryMessenger messenger, @NonNull String id, @NonNull FlutterWebView flutterWebView) {
public HeadlessInAppWebView(@NonNull final InAppWebViewFlutterPlugin plugin, @NonNull String id, @NonNull FlutterWebView flutterWebView) {
this.id = id;
this.plugin = plugin;
this.flutterWebView = flutterWebView;
this.channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_headless_inappwebview_" + id);
this.channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_headless_inappwebview_" + id);
channel.setMethodCallHandler(this);
}
@ -70,7 +72,7 @@ public class HeadlessInAppWebView implements MethodChannel.MethodCallHandler {
public void prepare(Map<String, Object> params) {
// Add the headless WebView to the view hierarchy.
// This way is also possible to take screenshots.
ViewGroup contentView = (ViewGroup) Shared.activity.findViewById(android.R.id.content);
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
if (mainView != null) {
View view = flutterWebView.getView();
@ -108,12 +110,13 @@ public class HeadlessInAppWebView implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
HeadlessInAppWebViewManager.webViews.remove(id);
ViewGroup contentView = (ViewGroup) Shared.activity.findViewById(android.R.id.content);
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
if (mainView != null) {
mainView.removeView(flutterWebView.getView());
}
flutterWebView.dispose();
flutterWebView = null;
plugin = null;
}
}

View File

@ -21,13 +21,14 @@
package com.pichillilorenzo.flutter_inappwebview.headless_in_app_webview;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import androidx.annotation.Nullable;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.FlutterWebView;
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;
import io.flutter.plugin.common.MethodChannel.Result;
@ -37,9 +38,12 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
protected static final String LOG_TAG = "HeadlessInAppWebViewManager";
public MethodChannel channel;
public static final Map<String, HeadlessInAppWebView> webViews = new HashMap<>();
@Nullable
public InAppWebViewFlutterPlugin plugin;
public HeadlessInAppWebViewManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_headless_inappwebview");
public HeadlessInAppWebViewManager(final InAppWebViewFlutterPlugin plugin) {
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_headless_inappwebview");
channel.setMethodCallHandler(this);
}
@ -51,7 +55,7 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
case "run":
{
HashMap<String, Object> params = (HashMap<String, Object>) call.argument("params");
HeadlessInAppWebViewManager.run(id, params);
run(id, params);
}
result.success(true);
break;
@ -61,9 +65,9 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
}
public static void run(String id, HashMap<String, Object> params) {
FlutterWebView flutterWebView = new FlutterWebView(Shared.messenger, Shared.activity, id, params, null);
HeadlessInAppWebView headlessInAppWebView = new HeadlessInAppWebView(Shared.messenger, id, flutterWebView);
public void run(String id, HashMap<String, Object> params) {
FlutterWebView flutterWebView = new FlutterWebView(plugin, plugin.activity, id, params);
HeadlessInAppWebView headlessInAppWebView = new HeadlessInAppWebView(plugin, id, flutterWebView);
HeadlessInAppWebViewManager.webViews.put(id, headlessInAppWebView);
headlessInAppWebView.prepare(params);
@ -72,7 +76,7 @@ public class HeadlessInAppWebViewManager implements MethodChannel.MethodCallHand
}
public void dispose() {
HeadlessInAppWebViewManager.webViews.clear();
channel.setMethodCallHandler(null);
webViews.clear();
}
}

View File

@ -23,17 +23,16 @@ import android.widget.SearchView;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewMethodHandler;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Util;
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebView;
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebViewChromeClient;
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebViewOptions;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewMethodHandler;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.pull_to_refresh.PullToRefreshLayout;
import com.pichillilorenzo.flutter_inappwebview.pull_to_refresh.PullToRefreshOptions;
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
import com.pichillilorenzo.flutter_inappwebview.types.UserScript;
import com.pichillilorenzo.flutter_inappwebview.Util;
import java.io.IOException;
import java.util.ArrayList;
@ -60,7 +59,8 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow
public String fromActivity;
private List<ActivityResultListener> activityResultListeners = new ArrayList<>();
public InAppWebViewMethodHandler methodCallDelegate;
public InAppBrowserManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -68,14 +68,18 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow
Bundle b = getIntent().getExtras();
assert b != null;
id = b.getString("id");
String managerId = b.getString("managerId");
manager = (InAppBrowserManager) InAppBrowserManager.shared.get(managerId);
windowId = b.getInt("windowId");
channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappbrowser_" + id);
channel = new MethodChannel(manager.plugin.messenger, "com.pichillilorenzo/flutter_inappbrowser_" + id);
setContentView(R.layout.activity_web_view);
Map<String, Object> pullToRefreshInitialOptions = (Map<String, Object>) b.getSerializable("pullToRefreshInitialOptions");
MethodChannel pullToRefreshLayoutChannel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_" + id);
MethodChannel pullToRefreshLayoutChannel = new MethodChannel(manager.plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_" + id);
PullToRefreshOptions pullToRefreshOptions = new PullToRefreshOptions();
pullToRefreshOptions.parse(pullToRefreshInitialOptions);
pullToRefreshLayout = findViewById(R.id.pullToRefresh);
@ -87,6 +91,7 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow
webView.windowId = windowId;
webView.inAppBrowserDelegate = this;
webView.channel = channel;
webView.plugin = manager.plugin;
methodCallDelegate = new InAppWebViewMethodHandler(webView);
channel.setMethodCallHandler(methodCallDelegate);
@ -488,8 +493,8 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow
methodCallDelegate = null;
}
if (webView != null) {
if (Shared.activityPluginBinding != null) {
Shared.activityPluginBinding.removeActivityResultListener(webView.inAppWebViewChromeClient);
if (manager.plugin.activityPluginBinding != null) {
manager.plugin.activityPluginBinding.removeActivityResultListener(webView.inAppWebViewChromeClient);
}
ViewGroup vg = (ViewGroup) (webView.getParent());
if (vg != null) {
@ -501,6 +506,7 @@ public class InAppBrowserActivity extends AppCompatActivity implements InAppBrow
webView.dispose();
webView.destroy();
webView = null;
manager = null;
}
});
webView.loadUrl("about:blank");

View File

@ -25,23 +25,25 @@ import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Parcelable;
import android.provider.Browser;
import android.net.Uri;
import android.os.Bundle;
import android.webkit.MimeTypeMap;
import android.os.Parcelable;
import android.provider.Browser;
import android.util.Log;
import android.webkit.MimeTypeMap;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.Result;
@ -51,33 +53,37 @@ import io.flutter.plugin.common.MethodChannel.Result;
*/
public class InAppBrowserManager implements MethodChannel.MethodCallHandler {
public MethodChannel channel;
protected static final String LOG_TAG = "InAppBrowserManager";
public MethodChannel channel;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public String id;
public static final Map<String, InAppBrowserManager> shared = new HashMap<>();
public InAppBrowserManager(BinaryMessenger messenger) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappbrowser");
public InAppBrowserManager(final InAppWebViewFlutterPlugin plugin) {
this.id = UUID.randomUUID().toString();
this.plugin = plugin;
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappbrowser");
channel.setMethodCallHandler(this);
shared.put(this.id, this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
final Activity activity = Shared.activity;
switch (call.method) {
case "open":
open(activity, (Map<String, Object>) call.arguments());
open(plugin.activity, (Map<String, Object>) call.arguments());
result.success(true);
break;
case "openWithSystemBrowser":
{
String url = (String) call.argument("url");
openWithSystemBrowser(activity, url, result);
openWithSystemBrowser(plugin.activity, url, result);
}
break;
default:
result.notImplemented();
}
}
public static String getMimeType(String url) {
@ -180,6 +186,7 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler {
extras.putString("initialBaseUrl", baseUrl);
extras.putString("initialHistoryUrl", historyUrl);
extras.putString("id", id);
extras.putString("managerId", this.id);
extras.putSerializable("options", (Serializable) options);
extras.putSerializable("contextMenu", (Serializable) contextMenu);
extras.putInt("windowId", windowId != null ? windowId : -1);
@ -197,5 +204,7 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler {
public void dispose() {
channel.setMethodCallHandler(null);
shared.remove(this.id);
plugin = null;
}
}

View File

@ -17,8 +17,8 @@ import androidx.annotation.NonNull;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewMethodHandler;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
import com.pichillilorenzo.flutter_inappwebview.pull_to_refresh.PullToRefreshLayout;
import com.pichillilorenzo.flutter_inappwebview.pull_to_refresh.PullToRefreshOptions;
@ -31,7 +31,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;
@ -44,9 +43,9 @@ public class FlutterWebView implements PlatformView {
public InAppWebViewMethodHandler methodCallDelegate;
public PullToRefreshLayout pullToRefreshLayout;
public FlutterWebView(BinaryMessenger messenger, final Context context, Object id,
HashMap<String, Object> params, View containerView) {
channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
public FlutterWebView(final InAppWebViewFlutterPlugin plugin, final Context context, Object id,
HashMap<String, Object> params) {
channel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_" + id);
DisplayListenerProxy displayListenerProxy = new DisplayListenerProxy();
DisplayManager displayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
@ -61,11 +60,11 @@ public class FlutterWebView implements PlatformView {
InAppWebViewOptions options = new InAppWebViewOptions();
options.parse(initialOptions);
if (Shared.activity == null) {
Log.e(LOG_TAG, "\n\n\nERROR: Shared.activity is null!!!\n\n" +
"You need to upgrade your Flutter project to use the new Java Embedding API:\n\n" +
if (plugin.activity == null) {
Log.e(LOG_TAG, "\n\n\nERROR: You need to upgrade your Flutter project to use the new Java Embedding API:\n\n" +
"- Take a look at the \"IMPORTANT Note for Android\" section here: https://github.com/pichillilorenzo/flutter_inappwebview#important-note-for-android\n" +
"- See the official wiki here: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects\n\n\n");
return;
}
List<UserScript> userScripts = new ArrayList<>();
@ -75,13 +74,13 @@ public class FlutterWebView implements PlatformView {
}
}
webView = new InAppWebView(context, channel, id, windowId, options, contextMenu, options.useHybridComposition ? null : containerView, userScripts);
webView = new InAppWebView(context, plugin, channel, id, windowId, options, contextMenu, options.useHybridComposition ? null : plugin.flutterView, userScripts);
displayListenerProxy.onPostWebViewInitialization(displayManager);
if (options.useHybridComposition) {
// set MATCH_PARENT layout params to the WebView, otherwise it won't take all the available space!
webView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
MethodChannel pullToRefreshLayoutChannel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_" + id);
MethodChannel pullToRefreshLayoutChannel = new MethodChannel(plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_pull_to_refresh_" + id);
PullToRefreshOptions pullToRefreshOptions = new PullToRefreshOptions();
pullToRefreshOptions.parse(pullToRefreshInitialOptions);
pullToRefreshLayout = new PullToRefreshLayout(context, pullToRefreshLayoutChannel, pullToRefreshOptions);

View File

@ -3,6 +3,8 @@ package com.pichillilorenzo.flutter_inappwebview.in_app_webview;
import android.content.Context;
import android.view.View;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import java.util.HashMap;
import io.flutter.plugin.common.BinaryMessenger;
@ -11,19 +13,17 @@ import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
public class FlutterWebViewFactory extends PlatformViewFactory {
private final View containerView;
private final BinaryMessenger messenger;
private final InAppWebViewFlutterPlugin plugin;
public FlutterWebViewFactory(BinaryMessenger messenger, View containerView) {
public FlutterWebViewFactory(final InAppWebViewFlutterPlugin plugin) {
super(StandardMessageCodec.INSTANCE);
this.containerView = containerView;
this.messenger = messenger;
this.plugin = plugin;
}
@Override
public PlatformView create(Context context, int id, Object args) {
HashMap<String, Object> params = (HashMap<String, Object>) args;
FlutterWebView flutterWebView = new FlutterWebView(messenger, context, id, params, containerView);
FlutterWebView flutterWebView = new FlutterWebView(plugin, context, id, params);
flutterWebView.makeInitialLoad(params);
return flutterWebView;
}

View File

@ -51,9 +51,9 @@ import androidx.annotation.RequiresApi;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;
import com.pichillilorenzo.flutter_inappwebview.InAppWebViewFlutterPlugin;
import com.pichillilorenzo.flutter_inappwebview.JavaScriptBridgeInterface;
import com.pichillilorenzo.flutter_inappwebview.R;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.Util;
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlocker;
import com.pichillilorenzo.flutter_inappwebview.content_blocker.ContentBlockerAction;
@ -102,6 +102,8 @@ final public class InAppWebView extends InputAwareWebView {
static final String LOG_TAG = "InAppWebView";
@Nullable
public InAppWebViewFlutterPlugin plugin;
@Nullable
public InAppBrowserDelegate inAppBrowserDelegate;
public MethodChannel channel;
@ -155,18 +157,20 @@ final public class InAppWebView extends InputAwareWebView {
super(context, attrs, defaultStyle);
}
public InAppWebView(Context context, MethodChannel channel, Object id,
public InAppWebView(Context context, InAppWebViewFlutterPlugin plugin,
MethodChannel channel, Object id,
@Nullable Integer windowId, InAppWebViewOptions options,
@Nullable Map<String, Object> contextMenu, View containerView,
List<UserScript> userScripts) {
super(context, containerView, options.useHybridComposition);
this.plugin = plugin;
this.channel = channel;
this.id = id;
this.windowId = windowId;
this.options = options;
this.contextMenu = contextMenu;
this.userContentController.addUserOnlyScripts(userScripts);
Shared.activity.registerForContextMenu(this);
plugin.activity.registerForContextMenu(this);
}
@Override
@ -181,7 +185,7 @@ final public class InAppWebView extends InputAwareWebView {
javaScriptBridgeInterface = new JavaScriptBridgeInterface(this);
addJavascriptInterface(javaScriptBridgeInterface, JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME);
inAppWebViewChromeClient = new InAppWebViewChromeClient(channel, inAppBrowserDelegate);
inAppWebViewChromeClient = new InAppWebViewChromeClient(plugin, channel, inAppBrowserDelegate);
setWebChromeClient(inAppWebViewChromeClient);
inAppWebViewClient = new InAppWebViewClient(channel, inAppBrowserDelegate);
@ -551,7 +555,7 @@ final public class InAppWebView extends InputAwareWebView {
}
public void loadFile(String assetFilePath) throws IOException {
loadUrl(Util.getUrlAsset(assetFilePath));
loadUrl(Util.getUrlAsset(plugin, assetFilePath));
}
public boolean isLoading() {
@ -1208,7 +1212,7 @@ final public class InAppWebView extends InputAwareWebView {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public void printCurrentPage() {
// Get a PrintManager instance
PrintManager printManager = (PrintManager) Shared.activity.getSystemService(Context.PRINT_SERVICE);
PrintManager printManager = (PrintManager) plugin.activity.getSystemService(Context.PRINT_SERVICE);
if (printManager != null) {
String jobName = getTitle() + " Document";
@ -1665,6 +1669,7 @@ final public class InAppWebView extends InputAwareWebView {
inAppWebViewClient = null;
javaScriptBridgeInterface = null;
inAppWebViewRenderProcessClient = null;
plugin = null;
super.dispose();
}

View File

@ -8,7 +8,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
@ -45,7 +44,6 @@ 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.Shared;
import com.pichillilorenzo.flutter_inappwebview.types.URLRequest;
import java.io.ByteArrayOutputStream;
@ -100,20 +98,22 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private int mOriginalOrientation;
private int mOriginalSystemUiVisibility;
@Nullable
public InAppWebViewFlutterPlugin plugin;
public InAppWebViewChromeClient(MethodChannel channel, InAppBrowserDelegate inAppBrowserDelegate) {
public InAppWebViewChromeClient(final InAppWebViewFlutterPlugin plugin, MethodChannel channel, InAppBrowserDelegate inAppBrowserDelegate) {
super();
this.plugin = plugin;
this.channel = channel;
this.inAppBrowserDelegate = inAppBrowserDelegate;
if (this.inAppBrowserDelegate != null) {
this.inAppBrowserDelegate.getActivityResultListeners().add(this);
}
if (Shared.registrar != null)
Shared.registrar.addActivityResultListener(this);
if (plugin.registrar != null)
plugin.registrar.addActivityResultListener(this);
else
Shared.activityPluginBinding.addActivityResultListener(this);
plugin.activityPluginBinding.addActivityResultListener(this);
}
@Override
@ -123,7 +123,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
@Override
public void onHideCustomView() {
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
View decorView = getRootView();
((FrameLayout) decorView).removeView(this.mCustomView);
@ -144,7 +144,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
return;
}
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
View decorView = getRootView();
this.mCustomView = paramView;
@ -228,7 +228,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
};
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
alertDialogBuilder.setMessage(alertMessage);
@ -321,7 +321,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
};
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
alertDialogBuilder.setMessage(alertMessage);
@ -440,7 +440,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
};
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
alertDialogBuilder.setMessage(alertMessage);
@ -538,7 +538,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
};
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
alertDialogBuilder.setMessage(alertMessage);
@ -733,7 +733,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
protected ViewGroup getRootView() {
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
return (ViewGroup) activity.findViewById(android.R.id.content);
}
@ -827,7 +827,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
private boolean isFileNotEmpty(Uri uri) {
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
long length;
try {
@ -868,7 +868,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{}));
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
if (chooserIntent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivityForResult(chooserIntent, PICKER_LEGACY);
} else {
@ -896,7 +896,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
chooserIntent.putExtra(Intent.EXTRA_INTENT, fileSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{}));
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
if (chooserIntent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivityForResult(chooserIntent, PICKER);
} else {
@ -909,7 +909,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
protected boolean needsCameraPermission() {
boolean needed = false;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
PackageManager packageManager = activity.getPackageManager();
try {
String[] requestedPermissions = packageManager.getPackageInfo(activity.getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions;
@ -1051,7 +1051,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
return Uri.fromFile(capturedFile);
}
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
// for versions 6.0+ (23) we use the FileProvider to avoid runtime permissions
String packageName = activity.getApplicationContext().getPackageName();
return FileProvider.getUriForFile(activity.getApplicationContext(), packageName + "." + fileProviderAuthorityExtension, capturedFile);
@ -1081,7 +1081,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
return new File(storageDir, filename);
}
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : Shared.activity;
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
File storageDir = activity.getApplicationContext().getExternalFilesDir(null);
return File.createTempFile(prefix, suffix, storageDir);
}
@ -1140,12 +1140,13 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
}
public void dispose() {
if (Shared.activityPluginBinding != null) {
Shared.activityPluginBinding.removeActivityResultListener(this);
if (plugin != null && plugin.activityPluginBinding != null) {
plugin.activityPluginBinding.removeActivityResultListener(this);
}
if (inAppBrowserDelegate != null) {
inAppBrowserDelegate.getActivityResultListeners().clear();
inAppBrowserDelegate = null;
}
plugin = null;
}
}

View File

@ -23,7 +23,6 @@ import android.webkit.WebViewClient;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.Util;
import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDatabase;
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserDelegate;
@ -444,6 +443,8 @@ public class InAppWebViewClient extends WebViewClient {
@Override
public void onReceivedClientCertRequest(final WebView view, final ClientCertRequest request) {
InAppWebView webView = (InAppWebView) view;
URI uri;
try {
uri = new URI(view.getUrl());
@ -475,7 +476,7 @@ public class InAppWebViewClient extends WebViewClient {
String certificatePath = (String) responseMap.get("certificatePath");
String certificatePassword = (String) responseMap.get("certificatePassword");
String androidKeyStoreType = (String) responseMap.get("androidKeyStoreType");
Util.PrivateKeyAndCertificates privateKeyAndCertificates = Util.loadPrivateKeyAndCertificate(certificatePath, certificatePassword, androidKeyStoreType);
Util.PrivateKeyAndCertificates privateKeyAndCertificates = Util.loadPrivateKeyAndCertificate(webView.plugin, certificatePath, certificatePassword, androidKeyStoreType);
request.proceed(privateKeyAndCertificates.privateKey, privateKeyAndCertificates.certificates);
}
return;

View File

@ -7,7 +7,6 @@ import androidx.webkit.WebMessagePortCompat;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import com.pichillilorenzo.flutter_inappwebview.in_app_webview.InAppWebView;
import java.util.ArrayList;
@ -29,7 +28,7 @@ public class WebMessageChannel implements MethodChannel.MethodCallHandler {
public WebMessageChannel(@NonNull String id, @NonNull InAppWebView webView) {
this.id = id;
this.channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappwebview_web_message_channel_" + id);
this.channel = new MethodChannel(webView.plugin.messenger, "com.pichillilorenzo/flutter_inappwebview_web_message_channel_" + id);
this.channel.setMethodCallHandler(this);
this.ports = new ArrayList<>(Arrays.asList(WebViewCompat.createWebMessageChannel(webView)));
this.webView = webView;

View File

@ -10,14 +10,13 @@ import androidx.webkit.WebMessageCompat;
import androidx.webkit.WebViewCompat;
import androidx.webkit.WebViewFeature;
import com.pichillilorenzo.flutter_inappwebview.Shared;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
@ -30,10 +29,10 @@ public class WebMessageListener implements MethodChannel.MethodCallHandler {
public JavaScriptReplyProxy replyProxy;
public MethodChannel channel;
public WebMessageListener(@NonNull String jsObjectName, @NonNull Set<String> allowedOriginRules) {
public WebMessageListener(@NonNull BinaryMessenger messenger, @NonNull String jsObjectName, @NonNull Set<String> allowedOriginRules) {
this.jsObjectName = jsObjectName;
this.allowedOriginRules = allowedOriginRules;
this.channel = new MethodChannel(Shared.messenger, "com.pichillilorenzo/flutter_inappwebview_web_message_listener_" + this.jsObjectName);
this.channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_web_message_listener_" + this.jsObjectName);
this.channel.setMethodCallHandler(this);
this.listener = new WebViewCompat.WebMessageListener() {
@Override
@ -49,7 +48,7 @@ public class WebMessageListener implements MethodChannel.MethodCallHandler {
}
@Nullable
public static WebMessageListener fromMap(@Nullable Map<String, Object> map) {
public static WebMessageListener fromMap(@NonNull BinaryMessenger messenger, @Nullable Map<String, Object> map) {
if (map == null) {
return null;
}
@ -58,7 +57,7 @@ public class WebMessageListener implements MethodChannel.MethodCallHandler {
List<String> allowedOriginRuleList = (List<String>) map.get("allowedOriginRules");
assert allowedOriginRuleList != null;
Set<String> allowedOriginRules = new HashSet<>(allowedOriginRuleList);
return new WebMessageListener(jsObjectName, allowedOriginRules);
return new WebMessageListener(messenger, jsObjectName, allowedOriginRules);
}
@Override

View File

@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/fvm/versions/2.1.0-10.0.pre/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/fvm/versions/2.1.0-10.0.pre/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"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-03-25 11:56:12.905923","version":"2.1.0-10.0.pre"}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/fvm/versions/2.1.0-10.0.pre/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"android":[{"name":"flutter_downloader","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.5.2/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"integration_test","path":"/Users/lorenzopichilli/fvm/versions/2.1.0-10.0.pre/packages/integration_test/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.0-nullsafety/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/permission_handler-5.1.0+2/","dependencies":[]},{"name":"url_launcher","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher-6.0.0-nullsafety.6/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.5-nullsafety/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.1.0-nullsafety.2/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.2.0-nullsafety/","dependencies":[]},{"name":"url_launcher_linux","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_linux-0.1.0-nullsafety.3/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.1.0-nullsafety.3/","dependencies":[]},{"name":"url_launcher_windows","path":"/Users/lorenzopichilli/.pub-cache/hosted/pub.dartlang.org/url_launcher_windows-0.1.0-nullsafety.2/","dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"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-03-28 04:12:52.120913","version":"2.1.0-10.0.pre"}

View File

@ -5455,10 +5455,10 @@ setTimeout(function() {
onWebViewCreated: (controller) {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) async {
pageLoaded.complete();
},
);
headlessWebView.onLoadStop = (controller, url) async {
pageLoaded.complete();
};
await headlessWebView.run();
expect(headlessWebView.isRunning(), true);
@ -5472,8 +5472,70 @@ setTimeout(function() {
await headlessWebView.dispose();
expect(() async => await headlessWebView.webViewController.getUrl(),
throwsA(isInstanceOf<MissingPluginException>()));
expect(headlessWebView.isRunning(), false);
});
test('take screenshot', () async {
final Completer controllerCompleter = Completer<InAppWebViewController>();
final Completer<void> pageLoaded = Completer<void>();
var headlessWebView = new HeadlessInAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse("https://github.com/flutter")),
onWebViewCreated: (controller) {
controllerCompleter.complete(controller);
},
onLoadStop: (controller, url) async {
pageLoaded.complete();
}
);
await headlessWebView.run();
expect(headlessWebView.isRunning(), true);
final InAppWebViewController controller =
await controllerCompleter.future;
await pageLoaded.future;
final String? url = (await controller.getUrl())?.toString();
expect(url, 'https://github.com/flutter');
final Size? size = await headlessWebView.getSize();
expect(size, isNotNull);
final Uint8List? screenshot = await controller.takeScreenshot();
expect(screenshot, isNotNull);
await headlessWebView.dispose();
expect(headlessWebView.isRunning(), false);
});
test('set and get custom size', () async {
final Completer controllerCompleter = Completer<InAppWebViewController>();
var headlessWebView = new HeadlessInAppWebView(
initialUrlRequest: URLRequest(url: Uri.parse("https://github.com/flutter")),
initialSize: Size(600, 800),
onWebViewCreated: (controller) {
controllerCompleter.complete(controller);
},
);
await headlessWebView.run();
expect(headlessWebView.isRunning(), true);
final Size? size = await headlessWebView.getSize();
expect(size, isNotNull);
expect(size, Size(600, 800));
await headlessWebView.setSize(Size(1080, 1920));
final Size? newSize = await headlessWebView.getSize();
expect(newSize, isNotNull);
expect(newSize, Size(1080, 1920));
await headlessWebView.dispose();
expect(headlessWebView.isRunning(), false);
});
test('set/get options', () async {
@ -5569,7 +5631,7 @@ setTimeout(function() {
throwsA(isInstanceOf<MissingPluginException>()));
});
test('openFile and close', () async {
test('openData and close', () async {
var inAppBrowser = new MyInAppBrowser();
expect(inAppBrowser.isOpened(), false);
expect(() async {

View File

@ -80,5 +80,6 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

View File

@ -25,7 +25,8 @@ class HeadlessInAppWebView implements WebView {
bool _started = false;
bool _running = false;
static const MethodChannel _sharedChannel = const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
static const MethodChannel _sharedChannel =
const MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview');
late MethodChannel _channel;
///WebView Controller that can be used to access the [InAppWebViewController] API.
@ -97,7 +98,7 @@ class HeadlessInAppWebView implements WebView {
this.androidOnRenderProcessUnresponsive,
this.androidOnFormResubmission,
@Deprecated('Use `onZoomScaleChanged` instead')
this.androidOnScaleChanged,
this.androidOnScaleChanged,
this.androidOnReceivedIcon,
this.androidOnReceivedTouchIconUrl,
this.androidOnJsBeforeUnload,
@ -108,8 +109,8 @@ class HeadlessInAppWebView implements WebView {
this.iosShouldAllowDeprecatedTLS}) {
id = IdGenerator.generate();
webViewController = new InAppWebViewController(id, this);
this._channel = MethodChannel(
'com.pichillilorenzo/flutter_headless_inappwebview_$id');
this._channel =
MethodChannel('com.pichillilorenzo/flutter_headless_inappwebview_$id');
this._channel.setMethodCallHandler(handleMethod);
}
@ -188,7 +189,8 @@ class HeadlessInAppWebView implements WebView {
///Gets the current size in pixels of the WebView.
Future<Size?> getSize() async {
Map<String, dynamic> args = <String, dynamic>{};
Map<String, dynamic> sizeMap = (await _channel.invokeMethod('getSize', args))?.cast<String, dynamic>();
Map<String, dynamic> sizeMap =
(await _channel.invokeMethod('getSize', args))?.cast<String, dynamic>();
return MapSize.fromMap(sizeMap);
}
@ -223,16 +225,12 @@ class HeadlessInAppWebView implements WebView {
androidOnGeolocationPermissionsShowPrompt;
@override
Future<PermissionRequestResponse?> Function(
InAppWebViewController controller,
String origin,
List<String> resources)? androidOnPermissionRequest;
Future<PermissionRequestResponse?> Function(InAppWebViewController controller,
String origin, List<String> resources)? androidOnPermissionRequest;
@override
Future<SafeBrowsingResponse?> Function(
InAppWebViewController controller,
Uri url,
SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit;
Future<SafeBrowsingResponse?> Function(InAppWebViewController controller,
Uri url, SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit;
@override
void Function(InAppWebViewController controller, Uri? url)?
@ -289,8 +287,7 @@ class HeadlessInAppWebView implements WebView {
void Function(InAppWebViewController controller)? onWindowBlur;
@override
void Function(InAppWebViewController controller, Uri url)?
onDownloadStart;
void Function(InAppWebViewController controller, Uri url)? onDownloadStart;
@override
void Function(InAppWebViewController controller, int activeMatchOrdinal,
@ -316,12 +313,11 @@ class HeadlessInAppWebView implements WebView {
String message)? onLoadError;
@override
void Function(InAppWebViewController controller, Uri? url,
int statusCode, String description)? onLoadHttpError;
void Function(InAppWebViewController controller, Uri? url, int statusCode,
String description)? onLoadHttpError;
@override
void Function(
InAppWebViewController controller, LoadedResource resource)?
void Function(InAppWebViewController controller, LoadedResource resource)?
onLoadResource;
@override
@ -354,8 +350,7 @@ class HeadlessInAppWebView implements WebView {
URLAuthenticationChallenge challenge)? onReceivedHttpAuthRequest;
@override
Future<ServerTrustAuthResponse?> Function(
InAppWebViewController controller,
Future<ServerTrustAuthResponse?> Function(InAppWebViewController controller,
URLAuthenticationChallenge challenge)? onReceivedServerTrustAuthRequest;
@override
@ -392,13 +387,13 @@ class HeadlessInAppWebView implements WebView {
void Function(InAppWebViewController controller)? onExitFullscreen;
@override
void Function(InAppWebViewController controller, int x, int y,
bool clampedX, bool clampedY)? onOverScrolled;
void Function(InAppWebViewController controller, int x, int y, bool clampedX,
bool clampedY)? onOverScrolled;
@override
void Function(
InAppWebViewController controller, double oldScale, double newScale)?
onZoomScaleChanged;
InAppWebViewController controller, double oldScale, double newScale)?
onZoomScaleChanged;
@override
Future<WebResourceResponse?> Function(
@ -436,17 +431,14 @@ class HeadlessInAppWebView implements WebView {
androidOnReceivedIcon;
@override
void Function(
InAppWebViewController controller, Uri url, bool precomposed)?
void Function(InAppWebViewController controller, Uri url, bool precomposed)?
androidOnReceivedTouchIconUrl;
@override
Future<JsBeforeUnloadResponse?> Function(
InAppWebViewController controller,
Future<JsBeforeUnloadResponse?> Function(InAppWebViewController controller,
JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload;
@override
void Function(
InAppWebViewController controller, LoginRequest loginRequest)?
void Function(InAppWebViewController controller, LoginRequest loginRequest)?
androidOnReceivedLoginRequest;
}

View File

@ -87,8 +87,7 @@ class InAppWebView extends StatefulWidget implements WebView {
this.androidOnRenderProcessResponsive,
this.androidOnRenderProcessUnresponsive,
this.androidOnFormResubmission,
@Deprecated('Use `onZoomScaleChanged` instead')
this.androidOnScaleChanged,
@Deprecated('Use `onZoomScaleChanged` instead') this.androidOnScaleChanged,
this.androidOnReceivedIcon,
this.androidOnReceivedTouchIconUrl,
this.androidOnJsBeforeUnload,
@ -317,8 +316,8 @@ class InAppWebView extends StatefulWidget implements WebView {
@override
final void Function(
InAppWebViewController controller, double oldScale, double newScale)?
onZoomScaleChanged;
InAppWebViewController controller, double oldScale, double newScale)?
onZoomScaleChanged;
@override
final Future<WebResourceResponse?> Function(

View File

@ -356,7 +356,9 @@ class InAppWebViewController {
}
break;
case "onZoomScaleChanged":
if ((_webview != null && (_webview!.androidOnScaleChanged != null || _webview!.onZoomScaleChanged != null)) ||
if ((_webview != null &&
(_webview!.androidOnScaleChanged != null ||
_webview!.onZoomScaleChanged != null)) ||
_inAppBrowser != null) {
double oldScale = call.arguments["oldScale"];
double newScale = call.arguments["newScale"];
@ -365,8 +367,7 @@ class InAppWebViewController {
_webview!.onZoomScaleChanged!(this, oldScale, newScale);
else
_webview!.androidOnScaleChanged!(this, oldScale, newScale);
}
else
} else
_inAppBrowser!.androidOnScaleChanged(oldScale, newScale);
}
break;

View File

@ -413,8 +413,8 @@ abstract class WebView {
///
///**Official iOS API**: https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619409-scrollviewdidzoom
final void Function(
InAppWebViewController controller, double oldScale, double newScale)?
onZoomScaleChanged;
InAppWebViewController controller, double oldScale, double newScale)?
onZoomScaleChanged;
///Event fired when the webview notifies that a loading URL has been flagged by Safe Browsing.
///The default behavior is to show an interstitial to the user, with the reporting checkbox visible.
@ -721,7 +721,7 @@ abstract class WebView {
this.androidOnRenderProcessUnresponsive,
this.androidOnFormResubmission,
@Deprecated('Use `onZoomScaleChanged` instead')
this.androidOnScaleChanged,
this.androidOnScaleChanged,
this.androidOnReceivedIcon,
this.androidOnReceivedTouchIconUrl,
this.androidOnJsBeforeUnload,

View File

@ -499,9 +499,6 @@ extension MapSize on Size {
}
Map<String, double> toMap() {
return {
'width': width,
'height': height
};
return {'width': width, 'height': height};
}
}
}