diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index fa9db498..f04d5e7c 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -11,21 +11,9 @@
-
-
-
+
-
-
-
-
-
-
-
-
-
-
@@ -57,8 +45,8 @@
-
-
+
+
@@ -431,7 +419,6 @@
-
@@ -449,9 +436,9 @@
-
+
-
+
@@ -857,8 +844,8 @@
-
-
+
+
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java
index 732cf54a..9a722d30 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserFlutterPlugin.java
@@ -25,6 +25,9 @@ import android.annotation.TargetApi;
import android.app.Activity;
import android.annotation.SuppressLint;
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.Build;
@@ -40,7 +43,9 @@ import android.util.Log;
import java.io.IOException;
import java.io.StringReader;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
@@ -308,14 +313,51 @@ public class InAppBrowserFlutterPlugin implements MethodCallHandler {
intent.setData(uri);
}
intent.putExtra(Browser.EXTRA_APPLICATION_ID, activity.getPackageName());
- activity.startActivity(intent);
+ // CB-10795: Avoid circular loops by preventing it from opening in the current app
+ this.openExternalExcludeCurrentApp(intent);
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
} catch (java.lang.RuntimeException e) {
Log.d(LOG_TAG, "InAppBrowserFlutterPlugin: Error loading url "+url+":"+ e.toString());
}
}
- @TargetApi(8)
+ /**
+ * Opens the intent, providing a chooser that excludes the current app to avoid
+ * circular loops.
+ */
+ private void openExternalExcludeCurrentApp(Intent intent) {
+ String currentPackage = activity.getPackageName();
+ boolean hasCurrentPackage = false;
+ PackageManager pm = activity.getPackageManager();
+ List activities = pm.queryIntentActivities(intent, 0);
+ ArrayList targetIntents = new ArrayList();
+ for (ResolveInfo ri : activities) {
+ if (!currentPackage.equals(ri.activityInfo.packageName)) {
+ Intent targetIntent = (Intent)intent.clone();
+ targetIntent.setPackage(ri.activityInfo.packageName);
+ targetIntents.add(targetIntent);
+ }
+ else {
+ hasCurrentPackage = true;
+ }
+ }
+ // If the current app package isn't a target for this URL, then use
+ // the normal launch behavior
+ if (hasCurrentPackage == false || targetIntents.size() == 0) {
+ activity.startActivity(intent);
+ }
+ // If there's only one possible intent, launch it directly
+ else if (targetIntents.size() == 1) {
+ activity.startActivity(targetIntents.get(0));
+ }
+ // Otherwise, show a custom chooser without the current app listed
+ else if (targetIntents.size() > 0) {
+ Intent chooser = Intent.createChooser(targetIntents.remove(targetIntents.size()-1), null);
+ chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));
+ activity.startActivity(chooser);
+ }
+ }
+
private void open(final String url, InAppBrowserOptions options) {
Intent intent = new Intent(activity, WebViewActivity.class);
diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java
index 0a0c4f94..315b503f 100644
--- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java
+++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java
@@ -3,10 +3,12 @@ package com.pichillilorenzo.flutter_inappbrowser;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
+import android.net.http.SslError;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.HttpAuthHandler;
+import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -142,6 +144,41 @@ public class InAppBrowserWebViewClient extends WebViewClient {
InAppBrowserFlutterPlugin.channel.invokeMethod("loaderror", obj);
}
+ public void onReceivedSslError (WebView view, SslErrorHandler handler, SslError error) {
+ super.onReceivedSslError(view, handler, error);
+
+ Map obj = new HashMap<>();
+ obj.put("url", error.getUrl());
+ obj.put("code", 0);
+ obj.put("sslerror", error.getPrimaryError());
+ String message;
+ switch (error.getPrimaryError()) {
+ case SslError.SSL_DATE_INVALID:
+ message = "The date of the certificate is invalid";
+ break;
+ case SslError.SSL_EXPIRED:
+ message = "The certificate has expired";
+ break;
+ case SslError.SSL_IDMISMATCH:
+ message = "Hostname mismatch";
+ break;
+ default:
+ case SslError.SSL_INVALID:
+ message = "A generic error occurred";
+ break;
+ case SslError.SSL_NOTYETVALID:
+ message = "The certificate is not yet valid";
+ break;
+ case SslError.SSL_UNTRUSTED:
+ message = "The certificate authority is not trusted";
+ break;
+ }
+ obj.put("message", message);
+ InAppBrowserFlutterPlugin.channel.invokeMethod("loaderror", obj);
+
+ handler.cancel();
+ }
+
/**
* On received http auth request.
*/
diff --git a/ios/Classes/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowserWebViewController.swift
index 65448fd8..0910065c 100644
--- a/ios/Classes/InAppBrowserWebViewController.swift
+++ b/ios/Classes/InAppBrowserWebViewController.swift
@@ -480,7 +480,6 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
- //func webViewDidFinishLoad(_ theWebView: WKWebView) {
// update url, stop spinner, update back/forward
currentURL = webView.url
updateUrlTextField(url: (currentURL?.absoluteString)!)
@@ -490,10 +489,18 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
navigationDelegate?.webViewDidFinishLoad(webView)
}
+ func webView(_ webView: WKWebView,
+ didFailProvisionalNavigation navigation: WKNavigation!,
+ withError error: Error) {
+ print("webView:didFailProvisionalNavigationWithError - \(Int(error._code)): \(error.localizedDescription)")
+ backButton.isEnabled = webView.canGoBack
+ forwardButton.isEnabled = webView.canGoForward
+ spinner.stopAnimating()
+ navigationDelegate?.webView(webView, didFailLoadWithError: error)
+ }
+
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
- //func webView(_ theWebView: WKWebView, didFailLoadWithError error: Error) {
- // log fail message, stop spinner, update back/forward
- print("webView:didFailLoadWithError - \(Int(error._code)): \(error.localizedDescription)")
+ print("webView:didFailNavigationWithError - \(Int(error._code)): \(error.localizedDescription)")
backButton.isEnabled = webView.canGoBack
forwardButton.isEnabled = webView.canGoForward
spinner.stopAnimating()