зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1173147 - Show prompt for GeckoAppShell.openUriExternal. r=sebastian
--HG-- extra : commitid : KRygkmIjsVz extra : rebase_source : 1cdc9062847fcd133d06650cf15fa91bd5f3b314
This commit is contained in:
Родитель
e64ae0a462
Коммит
4a83ff024d
|
@ -8,7 +8,10 @@ import org.mozilla.gecko.util.ActivityResultHandler;
|
|||
import org.mozilla.gecko.util.ActivityResultHandlerMap;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
public class ActivityHandlerHelper {
|
||||
private static final String LOGTAG = "GeckoActivityHandlerHelper";
|
||||
|
@ -22,6 +25,26 @@ public class ActivityHandlerHelper {
|
|||
startIntentForActivity(GeckoAppShell.getGeckoInterface().getActivity(), intent, activityResultHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Activity, catching & logging if the Activity fails to start.
|
||||
*
|
||||
* We catch to prevent callers from passing in invalid Intents and crashing the browser.
|
||||
*
|
||||
* @return true if the Activity is successfully started, false otherwise.
|
||||
*/
|
||||
public static boolean startIntentAndCatch(final String logtag, final Context context, final Intent intent) {
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
Log.w(logtag, "Activity not found.", e);
|
||||
return false;
|
||||
} catch (final SecurityException e) {
|
||||
Log.w(logtag, "Forbidden to launch activity.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void startIntentForActivity(Activity activity, Intent intent, ActivityResultHandler activityResultHandler) {
|
||||
activity.startActivityForResult(intent, mActivityResultHandlerMap.put(activityResultHandler));
|
||||
}
|
||||
|
|
|
@ -1542,7 +1542,7 @@ public class BrowserApp extends GeckoApp
|
|||
}
|
||||
|
||||
GeckoAppShell.openUriExternal(url, "text/plain", "", "",
|
||||
Intent.ACTION_SEND, tab.getDisplayTitle());
|
||||
Intent.ACTION_SEND, tab.getDisplayTitle(), false);
|
||||
|
||||
// Context: Sharing via chrome list (no explicit session is active)
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);
|
||||
|
@ -1783,7 +1783,7 @@ public class BrowserApp extends GeckoApp
|
|||
} else if ("Reader:Share".equals(event)) {
|
||||
final String title = message.getString("title");
|
||||
final String url = message.getString("url");
|
||||
GeckoAppShell.openUriExternal(url, "text/plain", "", "", Intent.ACTION_SEND, title);
|
||||
GeckoAppShell.openUriExternal(url, "text/plain", "", "", Intent.ACTION_SEND, title, false);
|
||||
} else if ("Sanitize:ClearHistory".equals(event)) {
|
||||
handleClearHistory(message.optBoolean("clearSearchHistory", false));
|
||||
callback.sendSuccess(true);
|
||||
|
|
|
@ -639,7 +639,7 @@ public abstract class GeckoApp
|
|||
final String url = ReaderModeUtils.stripAboutReaderUrl(tab.getURL());
|
||||
text += "\n\n" + url;
|
||||
}
|
||||
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, title);
|
||||
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, title, false);
|
||||
|
||||
// Context: Sharing via chrome list (no explicit session is active)
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);
|
||||
|
|
|
@ -55,13 +55,13 @@ import org.mozilla.gecko.util.NativeJSContainer;
|
|||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.util.ProxySelector;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -106,6 +106,7 @@ import android.os.SystemClock;
|
|||
import android.os.Vibrator;
|
||||
import android.provider.Browser;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
@ -1049,6 +1050,17 @@ public class GeckoAppShell
|
|||
return true;
|
||||
}
|
||||
|
||||
@WrapForJNI
|
||||
public static boolean openUriExternal(String targetURI,
|
||||
String mimeType,
|
||||
String packageName,
|
||||
String className,
|
||||
String action,
|
||||
String title) {
|
||||
// Default to showing prompt in private browsing to be safe.
|
||||
return openUriExternal(targetURI, mimeType, packageName, className, action, title, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the inputs to <code>getOpenURIIntent</code>, plus an optional
|
||||
* package name and class name, create and fire an intent to open the
|
||||
|
@ -1062,15 +1074,20 @@ public class GeckoAppShell
|
|||
* @param action an Android action specifier, such as
|
||||
* <code>Intent.ACTION_SEND</code>.
|
||||
* @param title the title to use in <code>ACTION_SEND</code> intents.
|
||||
* @return true if the activity started successfully; false otherwise.
|
||||
* @param showPromptInPrivateBrowsing whether or not the user should be prompted when opening
|
||||
* this uri from private browsing. This should be true
|
||||
* when the user doesn't explicitly choose to open an an
|
||||
* external app (e.g. just clicked a link).
|
||||
* @return true if the activity started successfully or the user was prompted to open the
|
||||
* application; false otherwise.
|
||||
*/
|
||||
@WrapForJNI
|
||||
public static boolean openUriExternal(String targetURI,
|
||||
String mimeType,
|
||||
String packageName,
|
||||
String className,
|
||||
String action,
|
||||
String title) {
|
||||
String title,
|
||||
final boolean showPromptInPrivateBrowsing) {
|
||||
final Context context = getContext();
|
||||
final Intent intent = getOpenURIIntent(context, targetURI,
|
||||
mimeType, action, title);
|
||||
|
@ -1089,15 +1106,16 @@ public class GeckoAppShell
|
|||
}
|
||||
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.w(LOGTAG, "Activity not found.", e);
|
||||
return false;
|
||||
} catch (SecurityException e) {
|
||||
Log.w(LOGTAG, "Forbidden to launch activity.", e);
|
||||
return false;
|
||||
|
||||
if (!showPromptInPrivateBrowsing) {
|
||||
return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, intent);
|
||||
} else {
|
||||
// Ideally we retrieve the Activity from the calling args, rather than
|
||||
// statically, but since this method is called from Gecko and I'm
|
||||
// unfamiliar with that code, this is a simpler solution.
|
||||
final FragmentActivity fragmentActivity = (FragmentActivity) getGeckoInterface().getActivity();
|
||||
return ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser(
|
||||
context, fragmentActivity.getSupportFragmentManager(), intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ public final class IntentHelper implements GeckoEventListener,
|
|||
message.optString("packageName"),
|
||||
message.optString("className"),
|
||||
message.optString("action"),
|
||||
message.optString("title"));
|
||||
message.optString("title"), false);
|
||||
}
|
||||
|
||||
private void openForResult(final JSONObject message) throws JSONException {
|
||||
|
|
|
@ -197,7 +197,7 @@ public abstract class HomeFragment extends Fragment {
|
|||
return false;
|
||||
} else {
|
||||
GeckoAppShell.openUriExternal(info.url, SHARE_MIME_TYPE, "", "",
|
||||
Intent.ACTION_SEND, info.getDisplayTitle());
|
||||
Intent.ACTION_SEND, info.getDisplayTitle(), false);
|
||||
|
||||
// Context: Sharing via chrome homepage contextmenu list (home session should be active)
|
||||
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
package org.mozilla.gecko.widget;
|
||||
|
||||
import org.mozilla.gecko.ActivityHandlerHelper;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
|
@ -55,12 +56,14 @@ public class ExternalIntentDuringPrivateBrowsingPromptFragment extends DialogFra
|
|||
return builder.create();
|
||||
}
|
||||
|
||||
public static void showDialogOrAndroidChooser(final Context context, final FragmentManager fragmentManager,
|
||||
/**
|
||||
* @return true if the Activity is started or a dialog is shown. false if the Activity fails to start.
|
||||
*/
|
||||
public static boolean showDialogOrAndroidChooser(final Context context, final FragmentManager fragmentManager,
|
||||
final Intent intent) {
|
||||
final Tab selectedTab = Tabs.getInstance().getSelectedTab();
|
||||
if (selectedTab == null || !selectedTab.isPrivate()) {
|
||||
context.startActivity(intent);
|
||||
return;
|
||||
return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, intent);
|
||||
}
|
||||
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
|
@ -74,14 +77,17 @@ public class ExternalIntentDuringPrivateBrowsingPromptFragment extends DialogFra
|
|||
fragment.setArguments(args);
|
||||
|
||||
fragment.show(fragmentManager, FRAGMENT_TAG);
|
||||
// We don't know the results of the user interaction with the fragment so just return true.
|
||||
return true;
|
||||
} else if (matchingActivities.size() > 1) {
|
||||
// Android chooser dialog will be shown, which should make the users
|
||||
// aware they're entering a new application from private browsing.
|
||||
context.startActivity(intent);
|
||||
return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, intent);
|
||||
} else {
|
||||
// Normally, we show about:neterror when an Intent does not resolve
|
||||
// but we don't have the references here to do that so log instead.
|
||||
Log.w(LOGTAG, "showDialogOrAndroidChooser unexpectedly called with Intent that does not resolve");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче