You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ja...@apache.org on 2018/09/20 20:43:58 UTC
[cordova-plugin-inappbrowser] branch master updated: [CB-10795]
Exclude current app from external intent list (#154)
This is an automated email from the ASF dual-hosted git repository.
janpio pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-plugin-inappbrowser.git
The following commit(s) were added to refs/heads/master by this push:
new a078337 [CB-10795] Exclude current app from external intent list (#154)
a078337 is described below
commit a0783378fc901a84294dc66908a91f78014d3fb6
Author: Dan Polivy <da...@cellartracker.com>
AuthorDate: Thu Sep 20 13:43:52 2018 -0700
[CB-10795] Exclude current app from external intent list (#154)
On Android, if the app defines an intent-filter for a given URL, and
then tries to use inappbrowser to launch that URL via the _system
target, the default handler for that intent is the app itself.
That behavior can lead to circular loops, and ultimately is not what the
developer wants -- the link should be launched in a browser.
Because there is no easy way to find the "default" system browser on a
device, this solution will do two things:
1) Check if the app is one of the targets for this intent
2) If so, create a custom chooser with all other targets, excluding the
current app.
If the app is not a target, then the current (existing) behavior is
preserved.
The only real "downside" to this approach is that a default handler can no longer be set for these URLs within the app, and a chooser will be shown each time the user taps a link that opens in a new browser.
Fixes https://issues.apache.org/jira/browse/CB-10795
---
src/android/InAppBrowser.java | 48 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/android/InAppBrowser.java b/src/android/InAppBrowser.java
index 9a695db..92ca3c1 100644
--- a/src/android/InAppBrowser.java
+++ b/src/android/InAppBrowser.java
@@ -19,8 +19,12 @@
package org.apache.cordova.inappbrowser;
import android.annotation.SuppressLint;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Parcelable;
import android.provider.Browser;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -71,6 +75,7 @@ import org.json.JSONObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
@@ -432,7 +437,8 @@ public class InAppBrowser extends CordovaPlugin {
intent.setData(uri);
}
intent.putExtra(Browser.EXTRA_APPLICATION_ID, cordova.getActivity().getPackageName());
- this.cordova.getActivity().startActivity(intent);
+ // CB-10795: Avoid circular loops by preventing it from opening in the current app
+ this.openExternalExcludeCurrentApp(intent);
return "";
// not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
} catch (java.lang.RuntimeException e) {
@@ -442,6 +448,46 @@ public class InAppBrowser extends CordovaPlugin {
}
/**
+ * Opens the intent, providing a chooser that excludes the current app to avoid
+ * circular loops.
+ */
+ private void openExternalExcludeCurrentApp(Intent intent) {
+ String currentPackage = cordova.getActivity().getPackageName();
+ boolean hasCurrentPackage = false;
+
+ PackageManager pm = cordova.getActivity().getPackageManager();
+ List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
+ ArrayList<Intent> targetIntents = new ArrayList<Intent>();
+
+ 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) {
+ this.cordova.getActivity().startActivity(intent);
+ }
+ // If there's only one possible intent, launch it directly
+ else if (targetIntents.size() == 1) {
+ this.cordova.getActivity().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[] {}));
+ this.cordova.getActivity().startActivity(chooser);
+ }
+ }
+
+ /**
* Closes the dialog
*/
public void closeDialog() {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org