Backed out 5 changesets (bug 1173147) because bug 1201206 got backed out CLOSED TREE

Backed out changeset e0db94364c19 (bug 1173147)
Backed out changeset afd881fc08a2 (bug 1173147)
Backed out changeset 5a4df2457628 (bug 1173147)
Backed out changeset a43a907c02fe (bug 1173147)
Backed out changeset 494ff0d7f3bb (bug 1173147)
This commit is contained in:
Wes Kocher 2015-10-08 12:37:17 -07:00
Родитель badbc48d7a
Коммит 1f985be7a9
10 изменённых файлов: 23 добавлений и 180 удалений

Просмотреть файл

@ -8,10 +8,7 @@ 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";
@ -25,26 +22,6 @@ 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(), false);
Intent.ACTION_SEND, tab.getDisplayTitle());
// 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, false);
GeckoAppShell.openUriExternal(url, "text/plain", "", "", Intent.ACTION_SEND, title);
} 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, false);
GeckoAppShell.openUriExternal(text, "text/plain", "", "", Intent.ACTION_SEND, title);
// 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,7 +106,6 @@ 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;
@ -1050,17 +1049,6 @@ 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
@ -1074,20 +1062,15 @@ 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.
* @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.
* @return true if the activity started successfully; false otherwise.
*/
@WrapForJNI
public static boolean openUriExternal(String targetURI,
String mimeType,
String packageName,
String className,
String action,
String title,
final boolean showPromptInPrivateBrowsing) {
String title) {
final Context context = getContext();
final Intent intent = getOpenURIIntent(context, targetURI,
mimeType, action, title);
@ -1106,16 +1089,15 @@ public class GeckoAppShell
}
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
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);
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;
}
}

Просмотреть файл

@ -12,15 +12,14 @@ import org.mozilla.gecko.util.JSONUtils;
import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.WebActivityMapper;
import org.mozilla.gecko.widget.ExternalIntentDuringPrivateBrowsingPromptFragment;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.util.Log;
@ -54,15 +53,15 @@ public final class IntentHelper implements GeckoEventListener,
private static IntentHelper instance;
private final FragmentActivity activity;
private final Activity activity;
private IntentHelper(final FragmentActivity activity) {
private IntentHelper(Activity activity) {
this.activity = activity;
EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener) this, EVENTS);
EventDispatcher.getInstance().registerGeckoThreadListener((NativeEventListener) this, NATIVE_EVENTS);
}
public static IntentHelper init(final FragmentActivity activity) {
public static IntentHelper init(Activity activity) {
if (instance == null) {
instance = new IntentHelper(activity);
} else {
@ -123,7 +122,7 @@ public final class IntentHelper implements GeckoEventListener,
message.optString("packageName"),
message.optString("className"),
message.optString("action"),
message.optString("title"), false);
message.optString("title"));
}
private void openForResult(final JSONObject message) throws JSONException {
@ -202,8 +201,7 @@ public final class IntentHelper implements GeckoEventListener,
// (Bug 1192436) We don't know if marketIntent matches any Activities (e.g. non-Play
// Store devices). If it doesn't, clicking the link will cause no action to occur.
ExternalIntentDuringPrivateBrowsingPromptFragment.showDialogOrAndroidChooser(
activity, activity.getSupportFragmentManager(), marketIntent);
activity.startActivity(marketIntent);
callback.sendSuccess(null);
} else {

Просмотреть файл

@ -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(), false);
Intent.ACTION_SEND, info.getDisplayTitle());
// Context: Sharing via chrome homepage contextmenu list (home session should be active)
Telemetry.sendUIEvent(TelemetryContract.Event.SHARE, TelemetryContract.Method.LIST);

Просмотреть файл

@ -705,19 +705,6 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY find_matchcase "Aa">
<!ENTITY intent_uri_cannot_open "Cannot open link">
<!-- LOCALIZATION NOTE (intent_uri_private_browsing_prompt): This string will
appear in an alert when a user, who is currently in private browsing,
clicks a link that will open an external Android application. "&formatS;"
will be replaced with the name of the application that will be opened. -->
<!ENTITY intent_uri_private_browsing_prompt "This link will open in &formatS;. Are you sure you want to exit Private Browsing?">
<!-- LOCALIZATION NOTE (intent_uri_private_browsing_multiple_match_title): This
string will appear as the title of an alert when a user, who is currently
in private browsing, clicks a link that will open an external Android
application and more than one application is available to open that link.
We don't have control over the style of this dialog and it looks
unpolished when this string is longer than one line so ideally keep it
short! -->
<!ENTITY intent_uri_private_browsing_multiple_match_title "Exit Private Browsing?">
<!-- DevTools Authentication -->
<!-- LOCALIZATION NOTE (devtools_auth_scan_header): This header text appears

Просмотреть файл

@ -549,7 +549,6 @@ gbjar.sources += [
'widget/DoorHanger.java',
'widget/DoorhangerConfig.java',
'widget/EllipsisTextView.java',
'widget/ExternalIntentDuringPrivateBrowsingPromptFragment.java',
'widget/FadedMultiColorTextView.java',
'widget/FadedSingleColorTextView.java',
'widget/FadedTextView.java',

Просмотреть файл

@ -595,8 +595,6 @@
<string name="remote_tabs_last_synced">&remote_tabs_last_synced;</string>
<string name="intent_uri_cannot_open">&intent_uri_cannot_open;</string>
<string name="intent_uri_private_browsing_prompt">&intent_uri_private_browsing_prompt;</string>
<string name="intent_uri_private_browsing_multiple_match_title">&intent_uri_private_browsing_multiple_match_title;</string>
<string name="devtools_auth_scan_header">&devtools_auth_scan_header;</string>
</resources>

Просмотреть файл

@ -1,98 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
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;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import java.util.List;
/**
* A DialogFragment to contain a dialog that appears when the user clicks an Intent:// URI during private browsing. The
* dialog appears to notify the user that a clicked link will open in an external application, potentially leaking their
* browsing history.
*/
public class ExternalIntentDuringPrivateBrowsingPromptFragment extends DialogFragment {
private static final String LOGTAG = ExternalIntentDuringPrivateBrowsingPromptFragment.class.getSimpleName();
private static final String FRAGMENT_TAG = "ExternalIntentPB";
private static final String KEY_APPLICATION_NAME = "matchingApplicationName";
private static final String KEY_INTENT = "intent";
@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
final Bundle args = getArguments();
final CharSequence matchingApplicationName = args.getCharSequence(KEY_APPLICATION_NAME);
final Intent intent = args.getParcelable(KEY_INTENT);
final Context context = getActivity();
final String promptMessage = context.getString(R.string.intent_uri_private_browsing_prompt, matchingApplicationName);
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(promptMessage)
.setTitle(intent.getDataString())
.setPositiveButton(R.string.button_yes, new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int id) {
context.startActivity(intent);
}
})
.setNegativeButton(R.string.button_no, null /* we do nothing if the user rejects */ );
return builder.create();
}
/**
* @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()) {
return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, intent);
}
final PackageManager pm = context.getPackageManager();
final List<ResolveInfo> matchingActivities = pm.queryIntentActivities(intent, 0);
if (matchingActivities.size() == 1) {
final ExternalIntentDuringPrivateBrowsingPromptFragment fragment = new ExternalIntentDuringPrivateBrowsingPromptFragment();
final Bundle args = new Bundle(2);
args.putCharSequence(KEY_APPLICATION_NAME, matchingActivities.get(0).loadLabel(pm));
args.putParcelable(KEY_INTENT, intent);
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) {
// We want to show the Android Intent Chooser. However, we have no way of distinguishing regular tabs from
// private tabs to the chooser. Thus, if a user chooses "Always" in regular browsing mode, the chooser will
// not be shown and the URL will be opened. Therefore we explicitly show the chooser (which notably does not
// have an "Always" option).
final String androidChooserTitle =
context.getResources().getString(R.string.intent_uri_private_browsing_multiple_match_title);
final Intent chooserIntent = Intent.createChooser(intent, androidChooserTitle);
return ActivityHandlerHelper.startIntentAndCatch(LOGTAG, context, chooserIntent);
} 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;
}
}
}