diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml index 65bb3679c..317997300 100755 --- a/.idea/libraries/Flutter_Plugins.xml +++ b/.idea/libraries/Flutter_Plugins.xml @@ -1,8 +1,6 @@ - - - + diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fc0c4456..b060674a5 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java index 574b803c0..c3864a149 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java @@ -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 filePathCallbackLegacy; public static ValueCallback 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) { - - Shared.applicationContext = applicationContext; - Shared.activity = activity; - Shared.messenger = messenger; - - inAppBrowserManager = new InAppBrowserManager(messenger); - headlessInAppWebViewManager = new HeadlessInAppWebViewManager(messenger); - chromeSafariBrowserManager = new ChromeSafariBrowserManager(messenger); - + this.applicationContext = applicationContext; + this.activity = activity; + this.messenger = messenger; + this.flutterView = flutterView; + + 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 void onDetachedFromEngine(FlutterPluginBinding binding) { @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; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java index 3f4737e9b..ae0b4e03a 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewMethodHandler.java @@ -548,7 +548,7 @@ public void onReceiveValue(Boolean value) { case "addWebMessageListener": if (webView != null && WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) { Map webMessageListenerMap = (Map) call.argument("webMessageListener"); - WebMessageListener webMessageListener = WebMessageListener.fromMap(webMessageListenerMap); + WebMessageListener webMessageListener = WebMessageListener.fromMap(webView.plugin.messenger, webMessageListenerMap); try { webView.addWebMessageListener(webMessageListener); result.success(true); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java index 36ea93695..ffd4ba47a 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewStatic.java @@ -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.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 InAppWebViewStatic(BinaryMessenger messenger) { 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 void onReceiveValue(Boolean value) { 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 Map convertWebViewPackageToMap(PackageInfo webViewPackage public void dispose() { channel.setMethodCallHandler(null); + plugin = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java index 45e3a233e..547badbd5 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/JavaScriptBridgeInterface.java @@ -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; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java index dc2968019..5ed98435b 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyCookieManager.java @@ -16,7 +16,6 @@ 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 void onMethodCall(MethodCall call, MethodChannel.Result result) { 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 void onMethodCall(MethodCall call, MethodChannel.Result result) { } 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 void onMethodCall(MethodCall call, MethodChannel.Result result) { 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 void onMethodCall(MethodCall call, MethodChannel.Result result) { 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 void onMethodCall(MethodCall call, MethodChannel.Result result) { return cookieManager; } - public static void setCookie(String url, + public void setCookie(String url, String name, String value, String domain, @@ -167,7 +169,7 @@ public void onReceiveValue(Boolean aBoolean) { 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 void onReceiveValue(Boolean aBoolean) { } } - public static List> getCookies(final String url) { + public List> getCookies(final String url) { final List> cookieListMap = new ArrayList<>(); @@ -209,7 +211,7 @@ public static List> getCookies(final String url) { } - 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 void onReceiveValue(Boolean aBoolean) { 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 void onReceiveValue(Boolean aBoolean) { } } - 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 static void deleteCookies(String url, String domain, String path, final M 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 static void deleteCookies(String url, String domain, String path, final M 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 void onReceiveValue(Boolean aBoolean) { 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 static String getCookieExpirationDate(Long timestamp) { public void dispose() { channel.setMethodCallHandler(null); + plugin = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java index effd0802d..413da60c9 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/MyWebStorage.java @@ -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 void onReceiveValue(Long value) { public void dispose() { channel.setMethodCallHandler(null); + plugin = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java index 7f33775ca..8be52b35c 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/PlatformUtil.java @@ -14,12 +14,15 @@ 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 static String formatDate(long date, String format, Locale locale, TimeZon public void dispose() { channel.setMethodCallHandler(null); + plugin = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java index 4ca04b7eb..804af9466 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/ServiceWorkerManager.java @@ -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 void onMethodCall(MethodCall call, MethodChannel.Result result) { public void dispose() { channel.setMethodCallHandler(null); + plugin = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Shared.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Shared.java deleted file mode 100755 index d7012d3f9..000000000 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Shared.java +++ /dev/null @@ -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; -} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java index bccb1b6d0..5ed847173 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java @@ -6,9 +6,7 @@ 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.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.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 static String getUrlAsset(String assetFilePath) throws IOException { 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 WaitFlutterResult(Object r, String e) { } } - 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); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java index 1564bcff1..f42a3321b 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/WebViewFeatureManager.java @@ -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 void onMethodCall(MethodCall call, MethodChannel.Result result) { public void dispose() { channel.setMethodCallHandler(null); + plugin = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java index fd8ce47aa..f51d857ca 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ActionBroadcastReceiver.java @@ -5,8 +5,6 @@ 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 void onReceive(Context context, Intent intent) { 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 obj = new HashMap<>(); obj.put("url", url); obj.put("title", title); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java index aaae34657..ba8d0f069 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeCustomTabsActivity.java @@ -6,6 +6,7 @@ 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.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 @@ protected void onCreate(Bundle savedInstanceState) { 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 void onCustomTabsConnected() { @Override public void onCustomTabsDisconnected() { chromeCustomTabsActivity.close(); + dispose(); } }); @@ -128,10 +133,13 @@ public void onMethodCall(final MethodCall call, final MethodChannel.Result resul 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 @@ protected void onStop() { 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 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 obj = new HashMap<>(); + channel.invokeMethod("onChromeSafariBrowserClosed", obj); } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java index b03a3fe76..c572f4803 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/chrome_custom_tabs/ChromeSafariBrowserManager.java @@ -4,30 +4,38 @@ 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 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 void onMethodCall(final MethodCall call, final MethodChannel.Result resul String url = (String) call.argument("url"); HashMap options = (HashMap) call.argument("options"); List> menuItemList = (List>) 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 void open(Activity activity, String id, String url, HashMap 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 Size2D getSize() { 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; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java index 241142b83..6539601c0 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/headless_in_app_webview/HeadlessInAppWebViewManager.java @@ -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 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 void onMethodCall(final MethodCall call, final Result result) { case "run": { HashMap params = (HashMap) call.argument("params"); - HeadlessInAppWebViewManager.run(id, params); + run(id, params); } result.success(true); break; @@ -61,9 +65,9 @@ public void onMethodCall(final MethodCall call, final Result result) { } - public static void run(String id, HashMap 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 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 static void run(String id, HashMap params) { } public void dispose() { - HeadlessInAppWebViewManager.webViews.clear(); channel.setMethodCallHandler(null); + webViews.clear(); } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java index 031899752..e3b704e10 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserActivity.java @@ -23,17 +23,16 @@ 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 activityResultListeners = new ArrayList<>(); public InAppWebViewMethodHandler methodCallDelegate; - + public InAppBrowserManager manager; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -68,14 +68,18 @@ protected void onCreate(Bundle savedInstanceState) { 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 pullToRefreshInitialOptions = (Map) 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 @@ protected void onCreate(Bundle savedInstanceState) { 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 void dispose() { 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 void onPageFinished(WebView view, String url) { webView.dispose(); webView.destroy(); webView = null; + manager = null; } }); webView.loadUrl("about:blank"); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java index 0cca32ff0..26a82615f 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_browser/InAppBrowserManager.java @@ -25,23 +25,25 @@ 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 @@ */ public class InAppBrowserManager implements MethodChannel.MethodCallHandler { - public MethodChannel channel; protected static final String LOG_TAG = "InAppBrowserManager"; - - public InAppBrowserManager(BinaryMessenger messenger) { - channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappbrowser"); + public MethodChannel channel; + @Nullable + public InAppWebViewFlutterPlugin plugin; + public String id; + public static final Map shared = new HashMap<>(); + + 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) call.arguments()); + open(plugin.activity, (Map) 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 void open(Activity activity, Map arguments) { 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 void startInAppBrowserActivity(Activity activity, Bundle extras) { public void dispose() { channel.setMethodCallHandler(null); + shared.remove(this.id); + plugin = null; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java index c5915973a..1ef7daa2d 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebView.java @@ -17,8 +17,8 @@ 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.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 params, View containerView) { - channel = new MethodChannel(messenger, "com.pichillilorenzo/flutter_inappwebview_" + id); + public FlutterWebView(final InAppWebViewFlutterPlugin plugin, final Context context, Object id, + HashMap 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 FlutterWebView(BinaryMessenger messenger, final Context context, Object i 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 userScripts = new ArrayList<>(); @@ -75,13 +74,13 @@ public FlutterWebView(BinaryMessenger messenger, final Context context, Object i } } - 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); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebViewFactory.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebViewFactory.java index f515d0675..1476a42d0 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebViewFactory.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/FlutterWebViewFactory.java @@ -3,6 +3,8 @@ 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.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 params = (HashMap) args; - FlutterWebView flutterWebView = new FlutterWebView(messenger, context, id, params, containerView); + FlutterWebView flutterWebView = new FlutterWebView(plugin, context, id, params); flutterWebView.makeInitialLoad(params); return flutterWebView; } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java index 6ce140a52..172e464d2 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebView.java @@ -51,9 +51,9 @@ 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 @@ public InAppWebView(Context context, AttributeSet attrs, int defaultStyle) { 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 contextMenu, View containerView, List 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 @@ public void prepare() { 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 @@ public void loadUrl(URLRequest urlRequest) { } public void loadFile(String assetFilePath) throws IOException { - loadUrl(Util.getUrlAsset(assetFilePath)); + loadUrl(Util.getUrlAsset(plugin, assetFilePath)); } public boolean isLoading() { @@ -1208,7 +1212,7 @@ public void setDesktopMode(final boolean enabled) { @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 @@ public void dispose() { inAppWebViewClient = null; javaScriptBridgeInterface = null; inAppWebViewRenderProcessClient = null; + plugin = null; super.dispose(); } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java index 39ce9ce9c..224d75cd1 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewChromeClient.java @@ -8,7 +8,6 @@ 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.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 Bitmap getDefaultVideoPoster() { @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 void onShowCustomView(final View paramView, final CustomViewCallback para 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 void onClick(DialogInterface dialog, int which) { } }; - 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 void onClick(DialogInterface dialog, int which) { } }; - 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 void onClick(DialogInterface dialog, int which) { } }; - 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 void onClick(DialogInterface dialog, int which) { } }; - 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 void onReceivedTouchIconUrl(WebView view, } 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 @@ private Uri[] getSelectedFiles(Intent data, int resultCode) { } 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 void startPhotoPickerIntent(ValueCallback filePathCallback, String a } 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 boolean startPhotoPickerIntent(final ValueCallback callback, final 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 boolean startPhotoPickerIntent(final ValueCallback callback, final 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 @@ private Uri getOutputUri(String intentType) { 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 @@ private File getCapturedFile(String intentType) throws IOException { 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 void notImplemented() { } 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; } } diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java index 0b71c3b1a..98846a37a 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/in_app_webview/InAppWebViewClient.java @@ -23,7 +23,6 @@ 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 void notImplemented() { @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 void success(Object response) { 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; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageChannel.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageChannel.java index 288ade3a3..48d00985a 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageChannel.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageChannel.java @@ -7,7 +7,6 @@ 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; diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageListener.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageListener.java index bec5cadc1..16379e4c0 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageListener.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/types/WebMessageListener.java @@ -10,14 +10,13 @@ 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 allowedOriginRules) { + public WebMessageListener(@NonNull BinaryMessenger messenger, @NonNull String jsObjectName, @NonNull Set 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 void onPostMessage(@NonNull WebView view, @NonNull WebMessageCompat messa } @Nullable - public static WebMessageListener fromMap(@Nullable Map map) { + public static WebMessageListener fromMap(@NonNull BinaryMessenger messenger, @Nullable Map map) { if (map == null) { return null; } @@ -58,7 +57,7 @@ public static WebMessageListener fromMap(@Nullable Map map) { List allowedOriginRuleList = (List) map.get("allowedOriginRules"); assert allowedOriginRuleList != null; Set allowedOriginRules = new HashSet<>(allowedOriginRuleList); - return new WebMessageListener(jsObjectName, allowedOriginRules); + return new WebMessageListener(messenger, jsObjectName, allowedOriginRules); } @Override diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies index 7dcaddf28..ede4340fa 100644 --- a/example/.flutter-plugins-dependencies +++ b/example/.flutter-plugins-dependencies @@ -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"} \ No newline at end of file +{"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"} \ No newline at end of file diff --git a/example/integration_test/webview_flutter_test.dart b/example/integration_test/webview_flutter_test.dart index e944839c6..73f03bc31 100644 --- a/example/integration_test/webview_flutter_test.dart +++ b/example/integration_test/webview_flutter_test.dart @@ -5450,6 +5450,35 @@ setTimeout(function() { final Completer controllerCompleter = Completer(); final Completer pageLoaded = Completer(); + var headlessWebView = new HeadlessInAppWebView( + initialUrlRequest: URLRequest(url: Uri.parse("https://github.com/flutter")), + onWebViewCreated: (controller) { + controllerCompleter.complete(controller); + }, + ); + headlessWebView.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'); + + await headlessWebView.dispose(); + + expect(headlessWebView.isRunning(), false); + }); + + test('take screenshot', () async { + final Completer controllerCompleter = Completer(); + final Completer pageLoaded = Completer(); + var headlessWebView = new HeadlessInAppWebView( initialUrlRequest: URLRequest(url: Uri.parse("https://github.com/flutter")), onWebViewCreated: (controller) { @@ -5457,23 +5486,56 @@ setTimeout(function() { }, onLoadStop: (controller, url) async { pageLoaded.complete(); - }, + } ); await headlessWebView.run(); expect(headlessWebView.isRunning(), true); final InAppWebViewController controller = - await controllerCompleter.future; + 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(() async => await headlessWebView.webViewController.getUrl(), - throwsA(isInstanceOf())); + expect(headlessWebView.isRunning(), false); + }); + + test('set and get custom size', () async { + final Completer controllerCompleter = Completer(); + + 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())); }); - test('openFile and close', () async { + test('openData and close', () async { var inAppBrowser = new MyInAppBrowser(); expect(inAppBrowser.isOpened(), false); expect(() async { diff --git a/flutter_inappwebview.iml b/flutter_inappwebview.iml index 0adae5aa8..4cb391599 100755 --- a/flutter_inappwebview.iml +++ b/flutter_inappwebview.iml @@ -80,5 +80,6 @@ + \ No newline at end of file diff --git a/lib/src/in_app_webview/headless_in_app_webview.dart b/lib/src/in_app_webview/headless_in_app_webview.dart index 33f8d208b..8b3fccf92 100644 --- a/lib/src/in_app_webview/headless_in_app_webview.dart +++ b/lib/src/in_app_webview/headless_in_app_webview.dart @@ -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 getSize() async { Map args = {}; - Map sizeMap = (await _channel.invokeMethod('getSize', args))?.cast(); + Map sizeMap = + (await _channel.invokeMethod('getSize', args))?.cast(); return MapSize.fromMap(sizeMap); } @@ -223,16 +225,12 @@ class HeadlessInAppWebView implements WebView { androidOnGeolocationPermissionsShowPrompt; @override - Future Function( - InAppWebViewController controller, - String origin, - List resources)? androidOnPermissionRequest; + Future Function(InAppWebViewController controller, + String origin, List resources)? androidOnPermissionRequest; @override - Future Function( - InAppWebViewController controller, - Uri url, - SafeBrowsingThreat? threatType)? androidOnSafeBrowsingHit; + Future 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 Function( - InAppWebViewController controller, + Future 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 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 Function( - InAppWebViewController controller, + Future Function(InAppWebViewController controller, JsBeforeUnloadRequest jsBeforeUnloadRequest)? androidOnJsBeforeUnload; @override - void Function( - InAppWebViewController controller, LoginRequest loginRequest)? + void Function(InAppWebViewController controller, LoginRequest loginRequest)? androidOnReceivedLoginRequest; } diff --git a/lib/src/in_app_webview/in_app_webview.dart b/lib/src/in_app_webview/in_app_webview.dart index 733cc0834..7ef7ee2f4 100755 --- a/lib/src/in_app_webview/in_app_webview.dart +++ b/lib/src/in_app_webview/in_app_webview.dart @@ -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 Function( diff --git a/lib/src/in_app_webview/in_app_webview_controller.dart b/lib/src/in_app_webview/in_app_webview_controller.dart index 91beb5eca..14ac93308 100644 --- a/lib/src/in_app_webview/in_app_webview_controller.dart +++ b/lib/src/in_app_webview/in_app_webview_controller.dart @@ -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; diff --git a/lib/src/in_app_webview/webview.dart b/lib/src/in_app_webview/webview.dart index 3bc77ecf4..03e1be556 100644 --- a/lib/src/in_app_webview/webview.dart +++ b/lib/src/in_app_webview/webview.dart @@ -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, diff --git a/lib/src/util.dart b/lib/src/util.dart index fb3192d5f..2af57e03f 100644 --- a/lib/src/util.dart +++ b/lib/src/util.dart @@ -499,9 +499,6 @@ extension MapSize on Size { } Map toMap() { - return { - 'width': width, - 'height': height - }; + return {'width': width, 'height': height}; } -} \ No newline at end of file +}