From 8247da19e39c89b27997482395f3b5507dc77db1 Mon Sep 17 00:00:00 2001 From: Matthew Finkel Date: Sat, 12 Oct 2019 00:45:36 +0000 Subject: [PATCH] Bug 26529 - Prompt before opening external app --- .../java/org/mozilla/gecko/BrowserApp.java | 4 +++- .../base/java/org/mozilla/gecko/GeckoApp.java | 7 +++++-- .../org/mozilla/gecko/GeckoApplication.java | 7 +++++-- .../java/org/mozilla/gecko/IntentHelper.java | 15 +++++++++++---- .../mozilla/gecko/toolbar/BrowserToolbar.java | 1 + .../gecko/toolbar/ToolbarEditLayout.java | 18 ++++++++++++++---- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java index 85947047147fa..6fcd7cc547e5b 100644 --- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java @@ -176,6 +176,7 @@ import org.mozilla.gecko.util.WindowUtil; import org.mozilla.gecko.widget.ActionModePresenter; import org.mozilla.gecko.widget.AnchoredPopup; import org.mozilla.gecko.widget.AnimatedProgressBar; +import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment; import org.mozilla.gecko.widget.GeckoActionProvider; import org.mozilla.gecko.widget.SplashScreen; import org.mozilla.geckoview.DynamicToolbarAnimator; @@ -4168,7 +4169,8 @@ public class BrowserApp extends GeckoApp if (flags.contains(OnUrlOpenListener.Flags.OPEN_WITH_INTENT)) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); - startActivity(intent); + ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( + this, getSupportFragmentManager(), intent); } else { // By default this listener is used for lists where the offline reader-view icon // is shown - hence we need to redirect to the reader-view page by default. diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java index a8c0df25b1e57..6a3285d2a5edc 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -42,6 +42,7 @@ import org.mozilla.gecko.util.ThreadUtils; import org.mozilla.gecko.util.ViewUtil; import org.mozilla.gecko.widget.ActionModePresenter; import org.mozilla.gecko.widget.AnchoredPopup; +import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment; import org.mozilla.geckoview.GeckoSession; import org.mozilla.geckoview.GeckoSessionSettings; import org.mozilla.geckoview.GeckoView; @@ -765,11 +766,13 @@ public abstract class GeckoApp extends GeckoActivity if (email != null) { Uri contactUri = Uri.parse(email); Intent i = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT, contactUri); - startActivity(i); + ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( + this, getSupportFragmentManager(), i); } else if (phone != null) { Uri contactUri = Uri.parse(phone); Intent i = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT, contactUri); - startActivity(i); + ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( + this, getSupportFragmentManager(), i); } else { // something went wrong. Log.e(LOGTAG, "Received Contact:Add message with no email nor phone number"); diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java index bb3cdec7c0fe6..3801bb4d0b643 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApplication.java @@ -25,6 +25,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.Snackbar; import android.support.multidex.MultiDex; +import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Base64; import android.util.Log; @@ -64,6 +65,7 @@ import org.mozilla.gecko.util.PRNGFixes; import org.mozilla.gecko.util.ProxySelector; import org.mozilla.gecko.util.ShortcutUtils; import org.mozilla.gecko.util.ThreadUtils; +import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment; import org.mozilla.geckoview.GeckoRuntime; import org.mozilla.geckoview.GeckoRuntimeSettings; @@ -813,8 +815,9 @@ public class GeckoApplication extends Application context.getContentResolver().delete(intent.getData(), null, null); } }; - ActivityHandlerHelper.startIntentForActivity(currentActivity, chooser, - handler); + ActivityHandlerHelper.registerActivityHandler(handler); + ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( + currentActivity, ((AppCompatActivity)currentActivity).getSupportFragmentManager(), intent); } }); } diff --git a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java index c5b1666a31dae..b5853a35ae20f 100644 --- a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java +++ b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java @@ -123,7 +123,7 @@ public final class IntentHelper implements BundleEventListener { String className, String action, String title, - final boolean showPromptInPrivateBrowsing) { + boolean showPromptInPrivateBrowsing) { final Context context = getContext(); final Intent intent = getOpenURIIntent(context, targetURI, mimeType, action, title); @@ -141,10 +141,15 @@ public final class IntentHelper implements BundleEventListener { } } + // Always prompt for Intents + showPromptInPrivateBrowsing = true; + final FragmentActivity activity = getActivity(); if (!showPromptInPrivateBrowsing || activity == null) { if (activity == null) { - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + // We'll find out what this breaks. + return false; } return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, intent); } else { @@ -152,7 +157,7 @@ public final class IntentHelper implements BundleEventListener { // statically, but since this method is called from Gecko and I'm // unfamiliar with that code, this is a simpler solution. return ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( - context, activity.getSupportFragmentManager(), intent); + activity, activity.getSupportFragmentManager(), intent); } } @@ -472,7 +477,9 @@ public final class IntentHelper implements BundleEventListener { // isn't owned exclusively by Firefox, so there's no real benefit to using content:// URIs // here. try (StrictModeContext unused = StrictModeContext.allowAllVmPolicies()) { - ActivityHandlerHelper.startIntentForActivity(activity, intent, handler); + // Always prompt. + ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( + activity, activity.getSupportFragmentManager(), intent); } catch (SecurityException e) { Log.w(LOGTAG, "Forbidden to launch activity.", e); } diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java index 2bc379cecb8b3..3ba208ea0fcc6 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java @@ -222,6 +222,7 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout prefs = new ToolbarPrefs(); urlDisplayLayout.setToolbarPrefs(prefs); urlEditLayout.setToolbarPrefs(prefs); + urlEditLayout.setActivity(activity); // ScrollViews are allowed to have only one child. final View scrollChild = urlDisplayScroll.getChildAt(0); diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditLayout.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditLayout.java index a288472853504..ecd8d49f5a41a 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditLayout.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditLayout.java @@ -9,6 +9,7 @@ import android.app.Activity; import android.content.Intent; import android.graphics.drawable.Drawable; import android.speech.RecognizerIntent; +import android.support.v7.app.AppCompatActivity; import android.widget.Button; import org.mozilla.gecko.ActivityHandlerHelper; import org.mozilla.gecko.GeckoAppShell; @@ -30,6 +31,7 @@ import org.mozilla.gecko.util.HardwareUtils; import org.mozilla.gecko.util.InputOptionsUtils; import org.mozilla.gecko.util.StringUtils; import org.mozilla.gecko.util.ThreadUtils; +import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment; import org.mozilla.gecko.widget.themed.ThemedImageButton; import org.mozilla.gecko.widget.themed.ThemedLinearLayout; @@ -60,6 +62,8 @@ public class ToolbarEditLayout extends ThemedLinearLayout { private final ThemedImageButton mVoiceInput; private final ThemedImageButton mQrCode; + private Activity mActivity; + private OnFocusChangeListener mFocusChangeListener; private boolean showKeyboardOnFocus = false; // Indicates if we need to show the keyboard after the app resumes @@ -185,6 +189,10 @@ public class ToolbarEditLayout extends ThemedLinearLayout { mQrCode.setPrivateMode(isPrivate); } + public void setActivity(Activity activity) { + mActivity = activity; + } + /** * Called when the parent gains focus (on app launch and resume) */ @@ -294,8 +302,7 @@ public class ToolbarEditLayout extends ThemedLinearLayout { Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.ACTIONBAR, "voice_input_launch"); final Intent intent = InputOptionsUtils.createVoiceRecognizerIntent(getResources().getString(R.string.voicesearch_prompt)); - final Activity activity = ActivityUtils.getActivityFromContext(getContext()); - ActivityHandlerHelper.startIntentForActivity(activity, intent, new ActivityResultHandler() { + ActivityHandlerHelper.registerActivityHandler(new ActivityResultHandler() { @Override public void onActivityResult(int resultCode, Intent data) { if (resultCode != Activity.RESULT_OK) { @@ -316,6 +323,8 @@ public class ToolbarEditLayout extends ThemedLinearLayout { imm.showSoftInput(mEditText, InputMethodManager.SHOW_IMPLICIT); } }); + ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( + mActivity, ((AppCompatActivity)mActivity).getSupportFragmentManager(), intent); } private boolean qrCodeIsEnabled(Context context) { @@ -331,8 +340,7 @@ public class ToolbarEditLayout extends ThemedLinearLayout { Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.ACTIONBAR, "qrcode_input_launch"); final Intent intent = InputOptionsUtils.createQRCodeReaderIntent(); - final Activity activity = ActivityUtils.getActivityFromContext(getContext()); - ActivityHandlerHelper.startIntentForActivity(activity, intent, new ActivityResultHandler() { + ActivityHandlerHelper.registerActivityHandler(new ActivityResultHandler() { @Override public void onActivityResult(int resultCode, Intent intent) { if (resultCode == Activity.RESULT_OK) { @@ -353,5 +361,7 @@ public class ToolbarEditLayout extends ThemedLinearLayout { // as well as the actual result, which may hold a URL. } }); + ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser( + mActivity, ((AppCompatActivity)mActivity).getSupportFragmentManager(), intent); } } -- GitLab